From 98797e712ea49a15a58219b5596c1f922b9d591f Mon Sep 17 00:00:00 2001 From: alex leon Date: Wed, 2 Sep 2026 14:59:23 +0200 Subject: [PATCH 1/8] Add multiple option to select --- .../Select/multi-select.stories.tsx | 223 ++++++++++++++++++ .../src/components/Select/select.stories.tsx | 31 +-- .../src/components/Select/select.tsx | 181 ++++++++++---- libs/@hashintel/ds-components/src/main.ts | 6 +- 4 files changed, 380 insertions(+), 61 deletions(-) create mode 100644 libs/@hashintel/ds-components/src/components/Select/multi-select.stories.tsx diff --git a/libs/@hashintel/ds-components/src/components/Select/multi-select.stories.tsx b/libs/@hashintel/ds-components/src/components/Select/multi-select.stories.tsx new file mode 100644 index 00000000000..98b6df6b26d --- /dev/null +++ b/libs/@hashintel/ds-components/src/components/Select/multi-select.stories.tsx @@ -0,0 +1,223 @@ +import { useState } from "react"; + +import { css } from "@hashintel/ds-helpers/css"; + +import { Select } from "./select"; + +import type { ItemOrGroup } from "../Menu/SelectableList/selectable-list"; +import type { SelectItem } from "./select"; +import type { Story, StoryDefault } from "@ladle/react"; + +export default { + title: "Components/Select", +} satisfies StoryDefault; + +const sampleItems: Array> = [ + { value: "apple", text: "Apple" }, + { value: "banana", text: "Banana" }, + { value: "cherry", text: "Cherry" }, + { value: "date", text: "Date" }, +]; + +const noop = () => {}; + +const findItemText = ( + items: ReadonlyArray>, + value: string, +): string => { + for (const entry of items) { + if ("items" in entry) { + const found = entry.items.find((it) => it.value === value); + if (found) { + return found.text; + } + } else if (entry.value === value) { + return entry.text; + } + } + return value; +}; + +const sectionStyle = css({ + display: "flex", + flexDirection: "column", + gap: "[32px]", + background: "neutral.s10", +}); + +const groupStyle = css({ + display: "flex", + flexDirection: "column", + gap: "[12px]", +}); + +const subheadingStyle: React.CSSProperties = { + fontSize: 12, + fontWeight: 500, + color: "#666", +}; + +// Declared `as const` so a `Select` using these items can narrow `value` / +// `onChange` to the literal union of these values. +const colorItems = [ + { value: "red", text: "Red" }, + { value: "green", text: "Green" }, + { value: "blue", text: "Blue" }, + { value: "orange", text: "Orange" }, +] as const; + +type ColorValue = (typeof colorItems)[number]["value"]; + +const ColorSwatch = ({ value }: { value: string }) => ( +