From 06bc1032a6a2f963ff5894e46432ffe2e611a969 Mon Sep 17 00:00:00 2001 From: Comfy Org PR Bot Date: Thu, 22 Jan 2026 10:43:16 +0900 Subject: [PATCH] [backport cloud/1.37] feat(ui): add shadcn-vue Select components (#8234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of #8205 to `cloud/1.37` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8234-backport-cloud-1-37-feat-ui-add-shadcn-vue-Select-components-2f06d73d365081eb9437d7ef7487ca05) by [Unito](https://www.unito.io) Co-authored-by: Alexander Brown Co-authored-by: Amp Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/components/ui/AGENTS.md | 19 ++ src/components/ui/select/Select.stories.ts | 261 ++++++++++++++++++ src/components/ui/select/Select.vue | 16 ++ src/components/ui/select/SelectContent.vue | 73 +++++ src/components/ui/select/SelectGroup.vue | 17 ++ src/components/ui/select/SelectItem.vue | 37 +++ src/components/ui/select/SelectLabel.vue | 25 ++ .../ui/select/SelectScrollDownButton.vue | 27 ++ .../ui/select/SelectScrollUpButton.vue | 27 ++ src/components/ui/select/SelectSeparator.vue | 18 ++ src/components/ui/select/SelectTrigger.vue | 36 +++ src/components/ui/select/SelectValue.vue | 12 + 12 files changed, 568 insertions(+) create mode 100644 src/components/ui/AGENTS.md create mode 100644 src/components/ui/select/Select.stories.ts create mode 100644 src/components/ui/select/Select.vue create mode 100644 src/components/ui/select/SelectContent.vue create mode 100644 src/components/ui/select/SelectGroup.vue create mode 100644 src/components/ui/select/SelectItem.vue create mode 100644 src/components/ui/select/SelectLabel.vue create mode 100644 src/components/ui/select/SelectScrollDownButton.vue create mode 100644 src/components/ui/select/SelectScrollUpButton.vue create mode 100644 src/components/ui/select/SelectSeparator.vue create mode 100644 src/components/ui/select/SelectTrigger.vue create mode 100644 src/components/ui/select/SelectValue.vue diff --git a/src/components/ui/AGENTS.md b/src/components/ui/AGENTS.md new file mode 100644 index 000000000..53b9979b7 --- /dev/null +++ b/src/components/ui/AGENTS.md @@ -0,0 +1,19 @@ +# UI Component Guidelines + +## Adding New Components + +```bash +pnpm dlx shadcn-vue@latest add --yes +``` + +After adding, create `ComponentName.stories.ts` with Default, Disabled, and variant stories. + +## Reka UI Wrapper Components + +- Use reactive props destructuring with rest: `const { class: className, ...restProps } = defineProps()` +- Use `useForwardProps(restProps)` for prop forwarding, or `computed()` if adding defaults +- Import siblings directly (`./Component.vue`), not from barrel (`'.'`) +- Use `cn()` for class merging with `className` +- Use Iconify icons: `` +- Use design tokens: `bg-secondary-background`, `text-muted-foreground`, `border-border-default` +- Tailwind 4 CSS variables use parentheses: `h-(--my-var)` not `h-[--my-var]` diff --git a/src/components/ui/select/Select.stories.ts b/src/components/ui/select/Select.stories.ts new file mode 100644 index 000000000..ba2a37e48 --- /dev/null +++ b/src/components/ui/select/Select.stories.ts @@ -0,0 +1,261 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite' +import { ref } from 'vue' + +import Select from './Select.vue' +import SelectContent from './SelectContent.vue' +import SelectGroup from './SelectGroup.vue' +import SelectItem from './SelectItem.vue' +import SelectLabel from './SelectLabel.vue' +import SelectSeparator from './SelectSeparator.vue' +import SelectTrigger from './SelectTrigger.vue' +import SelectValue from './SelectValue.vue' + +const meta = { + title: 'Components/Select', + component: Select, + tags: ['autodocs'], + argTypes: { + modelValue: { + control: 'text', + description: 'Selected value' + }, + disabled: { + control: 'boolean', + description: 'When true, disables the select' + }, + 'onUpdate:modelValue': { action: 'update:modelValue' } + } +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref(args.modelValue || '') + return { value, args } + }, + template: ` + +
+ Selected: {{ value || 'None' }} +
+ ` + }), + args: { + disabled: false + } +} + +export const WithPlaceholder: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref('') + return { value, args } + }, + template: ` + + ` + }), + args: { + disabled: false + } +} + +export const Disabled: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref('apple') + return { value, args } + }, + template: ` + + ` + }) +} + +export const WithGroups: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectSeparator, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref('') + return { value, args } + }, + template: ` + +
+ Selected: {{ value || 'None' }} +
+ ` + }), + args: { + disabled: false + } +} + +export const Scrollable: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref('') + const items = Array.from({ length: 20 }, (_, i) => ({ + value: `item-${i + 1}`, + label: `Option ${i + 1}` + })) + return { value, items, args } + }, + template: ` + + ` + }), + args: { + disabled: false + } +} + +export const CustomWidth: Story = { + render: (args) => ({ + components: { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue + }, + setup() { + const value = ref('') + return { value, args } + }, + template: ` +
+ + + +
+ ` + }), + args: { + disabled: false + } +} diff --git a/src/components/ui/select/Select.vue b/src/components/ui/select/Select.vue new file mode 100644 index 000000000..f685b3189 --- /dev/null +++ b/src/components/ui/select/Select.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/ui/select/SelectContent.vue b/src/components/ui/select/SelectContent.vue new file mode 100644 index 000000000..a88e26b9f --- /dev/null +++ b/src/components/ui/select/SelectContent.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/components/ui/select/SelectGroup.vue b/src/components/ui/select/SelectGroup.vue new file mode 100644 index 000000000..11f3da9f6 --- /dev/null +++ b/src/components/ui/select/SelectGroup.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/select/SelectItem.vue b/src/components/ui/select/SelectItem.vue new file mode 100644 index 000000000..4edeeb3ca --- /dev/null +++ b/src/components/ui/select/SelectItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/src/components/ui/select/SelectLabel.vue b/src/components/ui/select/SelectLabel.vue new file mode 100644 index 000000000..bafe45da9 --- /dev/null +++ b/src/components/ui/select/SelectLabel.vue @@ -0,0 +1,25 @@ + + + diff --git a/src/components/ui/select/SelectScrollDownButton.vue b/src/components/ui/select/SelectScrollDownButton.vue new file mode 100644 index 000000000..1b1dc1a27 --- /dev/null +++ b/src/components/ui/select/SelectScrollDownButton.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/components/ui/select/SelectScrollUpButton.vue b/src/components/ui/select/SelectScrollUpButton.vue new file mode 100644 index 000000000..ee1ef9263 --- /dev/null +++ b/src/components/ui/select/SelectScrollUpButton.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/components/ui/select/SelectSeparator.vue b/src/components/ui/select/SelectSeparator.vue new file mode 100644 index 000000000..37947fd0d --- /dev/null +++ b/src/components/ui/select/SelectSeparator.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/ui/select/SelectTrigger.vue b/src/components/ui/select/SelectTrigger.vue new file mode 100644 index 000000000..768048ab1 --- /dev/null +++ b/src/components/ui/select/SelectTrigger.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/select/SelectValue.vue b/src/components/ui/select/SelectValue.vue new file mode 100644 index 000000000..4ffa580ca --- /dev/null +++ b/src/components/ui/select/SelectValue.vue @@ -0,0 +1,12 @@ + + +