@meistrari/tela-build 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -0
- package/app.config.ts +73 -0
- package/components/tela/animated/animated-calculating-number.vue +16 -0
- package/components/tela/animated/animated-number.mdx +248 -0
- package/components/tela/animated/animated-number.stories.ts +52 -0
- package/components/tela/animated/animated-number.vue +23 -0
- package/components/tela/animated/animated-text.vue +124 -0
- package/components/tela/animated/animated-value.vue +68 -0
- package/components/tela/avatar/avatar.mdx +117 -0
- package/components/tela/avatar/avatar.stories.ts +62 -0
- package/components/tela/avatar/avatar.vue +71 -0
- package/components/tela/avatar/group/avatar-group.stories.ts +78 -0
- package/components/tela/avatar/group/avatar-group.vue +46 -0
- package/components/tela/badge/badge.mdx +154 -0
- package/components/tela/badge/badge.stories.ts +82 -0
- package/components/tela/badge/badge.vue +41 -0
- package/components/tela/button/button.mdx +155 -0
- package/components/tela/button/button.stories.ts +202 -0
- package/components/tela/button/button.vue +107 -0
- package/components/tela/card.vue +30 -0
- package/components/tela/chart/chart-bar.vue +58 -0
- package/components/tela/chat/chat.mdx +268 -0
- package/components/tela/chat/chat.stories.ts +253 -0
- package/components/tela/chat/command/index.vue +41 -0
- package/components/tela/chat/command/mention/index.vue +138 -0
- package/components/tela/chat/index.vue +112 -0
- package/components/tela/chat/pure-text-input/chat-text-input.vue +190 -0
- package/components/tela/chat/text-input/chat-text-input.stories.ts +128 -0
- package/components/tela/chat/text-input/index.vue +217 -0
- package/components/tela/chat/text-message/chat-text-message.stories.ts +138 -0
- package/components/tela/chat/text-message/index.vue +355 -0
- package/components/tela/chat/types.ts +19 -0
- package/components/tela/checkbox/checkbox-card.vue +30 -0
- package/components/tela/checkbox/checkbox.mdx +164 -0
- package/components/tela/checkbox/checkbox.stories.ts +104 -0
- package/components/tela/checkbox/checkbox.vue +43 -0
- package/components/tela/collapsible/Collapsible.vue +15 -0
- package/components/tela/collapsible/CollapsibleContent.vue +59 -0
- package/components/tela/collapsible/CollapsibleTrigger.vue +12 -0
- package/components/tela/collapsible/collapsible.mdx +157 -0
- package/components/tela/collapsible-section/collapsible-section.mdx +180 -0
- package/components/tela/collapsible-section/collapsible-section.stories.ts +53 -0
- package/components/tela/collapsible-section/collapsible-section.vue +51 -0
- package/components/tela/collapsible-section-with-actions.vue +98 -0
- package/components/tela/combobox/combobox-anchor.vue +24 -0
- package/components/tela/combobox/combobox-empty.vue +19 -0
- package/components/tela/combobox/combobox-group.vue +24 -0
- package/components/tela/combobox/combobox-indicator.vue +22 -0
- package/components/tela/combobox/combobox-input.vue +31 -0
- package/components/tela/combobox/combobox-item.vue +28 -0
- package/components/tela/combobox/combobox-label.vue +24 -0
- package/components/tela/combobox/combobox-list.vue +90 -0
- package/components/tela/combobox/combobox-module-selector.vue +366 -0
- package/components/tela/combobox/combobox-root.vue +15 -0
- package/components/tela/combobox/combobox-trigger.vue +12 -0
- package/components/tela/combobox/combobox.mdx +285 -0
- package/components/tela/combobox/combobox.stories.ts +232 -0
- package/components/tela/combobox/combobox.vue +497 -0
- package/components/tela/command/command-dialog.vue +22 -0
- package/components/tela/command/command-empty.vue +25 -0
- package/components/tela/command/command-group.vue +46 -0
- package/components/tela/command/command-input.vue +38 -0
- package/components/tela/command/command-item.vue +78 -0
- package/components/tela/command/command-list.vue +78 -0
- package/components/tela/command/command-separator.vue +23 -0
- package/components/tela/command/command-shortcut.vue +13 -0
- package/components/tela/command/command.vue +88 -0
- package/components/tela/command/dialog-base.vue +15 -0
- package/components/tela/command/dialog-content.vue +50 -0
- package/components/tela/command/utils.ts +15 -0
- package/components/tela/complex-table/complex-table-cell.stories.ts +145 -0
- package/components/tela/complex-table/complex-table-cell.vue +45 -0
- package/components/tela/complex-table/complex-table-header-cell.stories.ts +103 -0
- package/components/tela/complex-table/complex-table-header-cell.vue +48 -0
- package/components/tela/complex-table/complex-table-header.stories.ts +89 -0
- package/components/tela/complex-table/complex-table-header.vue +70 -0
- package/components/tela/complex-table/complex-table-row.vue +199 -0
- package/components/tela/complex-table/complex-table-virtualized.vue +326 -0
- package/components/tela/complex-table/complex-table.stories.ts +358 -0
- package/components/tela/complex-table/complex-table.vue +237 -0
- package/components/tela/complex-table/composables/table-common.ts +93 -0
- package/components/tela/complex-table/composables/table-selection.ts +87 -0
- package/components/tela/complex-table/composables/virtual-scroll.ts +252 -0
- package/components/tela/complex-table/styles/table-shared.css +170 -0
- package/components/tela/complex-table/types.ts +63 -0
- package/components/tela/complex-table/utils.ts +35 -0
- package/components/tela/confirm-button/confirm-button.vue +137 -0
- package/components/tela/confirmation-modal/confirmation-modal.vue +72 -0
- package/components/tela/copy-button.vue +86 -0
- package/components/tela/date-range-picker.vue +221 -0
- package/components/tela/dialog/dialog.mdx +170 -0
- package/components/tela/dialog/dialog.vue +182 -0
- package/components/tela/disabled-area.vue +16 -0
- package/components/tela/disclaimer/disclaimer.mdx +238 -0
- package/components/tela/disclaimer/disclaimer.stories.ts +196 -0
- package/components/tela/disclaimer/disclaimer.vue +125 -0
- package/components/tela/dropdown-menu/DropdownMenu.vue +121 -0
- package/components/tela/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
- package/components/tela/dropdown-menu/DropdownMenuContent.vue +75 -0
- package/components/tela/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/components/tela/dropdown-menu/DropdownMenuItem.vue +137 -0
- package/components/tela/dropdown-menu/DropdownMenuLabel.vue +26 -0
- package/components/tela/dropdown-menu/DropdownMenuRadioGroup.vue +18 -0
- package/components/tela/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
- package/components/tela/dropdown-menu/DropdownMenuRoot.vue +15 -0
- package/components/tela/dropdown-menu/DropdownMenuSeparator.vue +21 -0
- package/components/tela/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- package/components/tela/dropdown-menu/DropdownMenuSub.vue +18 -0
- package/components/tela/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- package/components/tela/dropdown-menu/DropdownMenuSubTrigger.vue +35 -0
- package/components/tela/dropdown-menu/DropdownMenuTrigger.vue +14 -0
- package/components/tela/dropdown-menu/dropdown-menu.mdx +265 -0
- package/components/tela/dropdown-menu/dropdown-menu.stories.ts +156 -0
- package/components/tela/expandable-input.vue +96 -0
- package/components/tela/file-drop.vue +37 -0
- package/components/tela/file-upload/file-upload.mdx +189 -0
- package/components/tela/file-upload/file-upload.stories.ts +48 -0
- package/components/tela/file-upload/file-upload.vue +205 -0
- package/components/tela/filters/checkbox-filter.stories.ts +218 -0
- package/components/tela/filters/checkbox-filter.vue +165 -0
- package/components/tela/filters/date-filter.stories.ts +258 -0
- package/components/tela/filters/date-filter.vue +200 -0
- package/components/tela/filters/user-filter.stories.ts +344 -0
- package/components/tela/filters/user-filter.vue +271 -0
- package/components/tela/hover-card/hover-card.mdx +221 -0
- package/components/tela/hover-card/hover-card.stories.ts +87 -0
- package/components/tela/hover-card/hover-card.vue +61 -0
- package/components/tela/icon/custom.vue +319 -0
- package/components/tela/icon/spinner.vue +12 -0
- package/components/tela/icon-button/icon-button.vue +114 -0
- package/components/tela/icon.vue +37 -0
- package/components/tela/initials.vue +28 -0
- package/components/tela/inline-input.vue +77 -0
- package/components/tela/input/input.mdx +182 -0
- package/components/tela/input/input.stories.ts +153 -0
- package/components/tela/input/tela-input.vue +240 -0
- package/components/tela/kbd/kbd-return.vue +6 -0
- package/components/tela/kbd/kbd.mdx +238 -0
- package/components/tela/kbd/kbd.vue +18 -0
- package/components/tela/label/label.mdx +121 -0
- package/components/tela/label/label.stories.ts +37 -0
- package/components/tela/label/label.vue +25 -0
- package/components/tela/link-decoration/link-decoration.vue +19 -0
- package/components/tela/live-label.vue +32 -0
- package/components/tela/long-press-button.vue +98 -0
- package/components/tela/menubar/menubar-content.vue +77 -0
- package/components/tela/menubar/menubar-item.vue +32 -0
- package/components/tela/menubar/menubar-label.vue +14 -0
- package/components/tela/menubar/menubar-menu.vue +12 -0
- package/components/tela/menubar/menubar-root.vue +30 -0
- package/components/tela/menubar/menubar-separator.vue +17 -0
- package/components/tela/menubar/menubar-shortcut.vue +14 -0
- package/components/tela/menubar/menubar-sub-content.vue +36 -0
- package/components/tela/menubar/menubar-sub-trigger.vue +28 -0
- package/components/tela/menubar/menubar-sub.vue +20 -0
- package/components/tela/menubar/menubar-trigger.vue +27 -0
- package/components/tela/menubar/menubar.vue +298 -0
- package/components/tela/modal/modal.mdx +145 -0
- package/components/tela/modal/modal.vue +242 -0
- package/components/tela/multiple-select/multiple-select.mdx +274 -0
- package/components/tela/multiple-select/multiple-select.stories.ts +325 -0
- package/components/tela/multiple-select/multiple-select.vue +666 -0
- package/components/tela/pane.vue +110 -0
- package/components/tela/popover/popover-content.vue +48 -0
- package/components/tela/popover/popover-trigger.vue +12 -0
- package/components/tela/popover/popover.mdx +239 -0
- package/components/tela/popover/popover.stories.ts +150 -0
- package/components/tela/popover/popover.vue +15 -0
- package/components/tela/popover-list/popover-list-nested.vue +104 -0
- package/components/tela/popover-list/popover-list.stories.ts +330 -0
- package/components/tela/popover-list/popover-list.vue +191 -0
- package/components/tela/radio-button.vue +66 -0
- package/components/tela/radio-group/radio-group-item.vue +40 -0
- package/components/tela/radio-group/radio-group-root.vue +26 -0
- package/components/tela/radio-group/radio-group.mdx +78 -0
- package/components/tela/radio-group/radio-group.stories.ts +106 -0
- package/components/tela/radio-group/radio-group.vue +23 -0
- package/components/tela/range-calendar.stories.ts +110 -0
- package/components/tela/range-calendar.vue +109 -0
- package/components/tela/scroll-area/scroll-area.mdx +183 -0
- package/components/tela/scroll-area/scroll-area.vue +30 -0
- package/components/tela/scroll-area/scroll-bar.vue +31 -0
- package/components/tela/segment-toggle.stories.ts +114 -0
- package/components/tela/segment-toggle.vue +66 -0
- package/components/tela/select-menu/select-menu-content.vue +106 -0
- package/components/tela/select-menu/select-menu-down-button.vue +20 -0
- package/components/tela/select-menu/select-menu-group.vue +16 -0
- package/components/tela/select-menu/select-menu-item.vue +40 -0
- package/components/tela/select-menu/select-menu-root.vue +15 -0
- package/components/tela/select-menu/select-menu-trigger.vue +34 -0
- package/components/tela/select-menu/select-menu-up-button.vue +20 -0
- package/components/tela/select-menu/select-menu-value.vue +12 -0
- package/components/tela/select-menu/select-menu.mdx +221 -0
- package/components/tela/select-menu/select-menu.stories.ts +91 -0
- package/components/tela/select-menu/select-menu.vue +165 -0
- package/components/tela/selector/selector.vue +47 -0
- package/components/tela/sheet/sheet-close.vue +12 -0
- package/components/tela/sheet/sheet-content.vue +57 -0
- package/components/tela/sheet/sheet-description.vue +23 -0
- package/components/tela/sheet/sheet-footer.vue +18 -0
- package/components/tela/sheet/sheet-header.vue +15 -0
- package/components/tela/sheet/sheet-root.vue +18 -0
- package/components/tela/sheet/sheet-title.vue +23 -0
- package/components/tela/sheet/sheet-trigger.vue +12 -0
- package/components/tela/sheet/sheet.client.vue +150 -0
- package/components/tela/sheet/sheet.mdx +176 -0
- package/components/tela/sheet/sheet.stories.ts +201 -0
- package/components/tela/sheet/variants.ts +22 -0
- package/components/tela/side-sheet/side-sheet.mdx +131 -0
- package/components/tela/side-sheet/side-sheet.stories.ts +134 -0
- package/components/tela/side-sheet/side-sheet.vue +106 -0
- package/components/tela/skeleton/skeleton.mdx +165 -0
- package/components/tela/skeleton/skeleton.stories.ts +35 -0
- package/components/tela/skeleton/skeleton.vue +45 -0
- package/components/tela/skeleton-icon.vue +24 -0
- package/components/tela/span.vue +24 -0
- package/components/tela/star-button.vue +70 -0
- package/components/tela/status/status-lean.vue +30 -0
- package/components/tela/status/status.mdx +187 -0
- package/components/tela/status/status.stories.ts +160 -0
- package/components/tela/status/status.vue +420 -0
- package/components/tela/status-bar/status-bar.mdx +178 -0
- package/components/tela/status-bar/status-bar.stories.ts +64 -0
- package/components/tela/status-bar/status-bar.vue +56 -0
- package/components/tela/status-bar/types.ts +5 -0
- package/components/tela/switch/switch.mdx +118 -0
- package/components/tela/switch/switch.stories.ts +80 -0
- package/components/tela/switch/switch.vue +56 -0
- package/components/tela/table/table-body.vue +13 -0
- package/components/tela/table/table-caption.vue +13 -0
- package/components/tela/table/table-cell.vue +20 -0
- package/components/tela/table/table-empty.vue +37 -0
- package/components/tela/table/table-footer.vue +13 -0
- package/components/tela/table/table-head.vue +13 -0
- package/components/tela/table/table-header.vue +13 -0
- package/components/tela/table/table-row.vue +13 -0
- package/components/tela/table/table.mdx +230 -0
- package/components/tela/table/table.stories.ts +384 -0
- package/components/tela/table/table.vue +15 -0
- package/components/tela/tabs/tabs-content.vue +20 -0
- package/components/tela/tabs/tabs-indicator.vue +22 -0
- package/components/tela/tabs/tabs-list.vue +23 -0
- package/components/tela/tabs/tabs-root.vue +15 -0
- package/components/tela/tabs/tabs-trigger.vue +27 -0
- package/components/tela/tabs/tabs.mdx +138 -0
- package/components/tela/tabs/tabs.stories.ts +72 -0
- package/components/tela/tabs/tabs.vue +61 -0
- package/components/tela/tags/tags-select.mdx +318 -0
- package/components/tela/tags/tags-select.stories.ts +47 -0
- package/components/tela/tags/tags-select.vue +637 -0
- package/components/tela/tags/tags.mdx +151 -0
- package/components/tela/tags/tags.stories.ts +118 -0
- package/components/tela/tags/tags.vue +112 -0
- package/components/tela/textarea/textarea.mdx +102 -0
- package/components/tela/textarea/textarea.stories.ts +50 -0
- package/components/tela/textarea/textarea.vue +34 -0
- package/components/tela/toggle-group.vue +91 -0
- package/components/tela/tooltip/tooltip-content.vue +45 -0
- package/components/tela/tooltip/tooltip-provider.vue +12 -0
- package/components/tela/tooltip/tooltip-root.vue +15 -0
- package/components/tela/tooltip/tooltip-trigger.vue +12 -0
- package/components/tela/tooltip/tooltip.mdx +196 -0
- package/components/tela/tooltip/tooltip.stories.ts +200 -0
- package/components/tela/tooltip/tooltip.vue +91 -0
- package/components/tela/tooltip-group/tooltip-group-trigger.vue +92 -0
- package/components/tela/tooltip-group/tooltip-group.mdx +236 -0
- package/components/tela/tooltip-group/tooltip-group.stories.ts +465 -0
- package/components/tela/tooltip-group/tooltip-group.vue +35 -0
- package/components/tela/transparent-input.vue +151 -0
- package/components/tela/variable-icon.vue +28 -0
- package/components/tela/variable-input.vue +77 -0
- package/components/tela/wide-button/wide-button.vue +40 -0
- package/components.json +18 -0
- package/composables/status-toast.ts +67 -0
- package/css/reset.css +386 -0
- package/css/text.css +22 -0
- package/lib/doc-generator.ts +903 -0
- package/lib/extractors/volar-extract.ts +186 -0
- package/lib/type-resolver.ts +402 -0
- package/lib/utils.ts +6 -0
- package/modules/tela-build-docs/index.ts +139 -0
- package/nuxt.config.ts +80 -0
- package/package.json +84 -0
- package/plugins/test-id.ts +7 -0
- package/tsconfig.json +7 -0
- package/types/custom-icon.ts +1 -0
- package/types/index.ts +2 -0
- package/types/status.ts +1 -0
- package/unocss.config.ts +89 -0
- package/utils/component-utils.ts +30 -0
- package/utils/design-tokens.ts +431 -0
- package/utils/fold.ts +8 -0
- package/utils/select-menu.ts +10 -0
- package/utils/status.ts +1 -0
- package/utils/without-keys.ts +34 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
import SegmentToggle from './segment-toggle.vue'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof SegmentToggle> = {
|
|
7
|
+
title: 'Core/SegmentToggle',
|
|
8
|
+
component: SegmentToggle,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: 'A segment toggle component that displays multiple options as connected segments. Only one option can be selected at a time. Supports v-model binding, different sizes, and disabled states. Useful for mutually exclusive option selection with a modern segmented control interface.',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
modelValue: {
|
|
20
|
+
control: 'text',
|
|
21
|
+
description: 'The currently selected option value (v-model).',
|
|
22
|
+
},
|
|
23
|
+
options: {
|
|
24
|
+
control: 'object',
|
|
25
|
+
description: 'Array of toggle options. Each option should have a `value` and `label` property.',
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
control: 'select',
|
|
29
|
+
options: ['small', 'medium'],
|
|
30
|
+
description: 'Size of the segment toggle. Controls height and padding.',
|
|
31
|
+
},
|
|
32
|
+
disabled: {
|
|
33
|
+
control: 'boolean',
|
|
34
|
+
description: 'Disable the entire segment toggle, preventing user interaction.',
|
|
35
|
+
},
|
|
36
|
+
class: {
|
|
37
|
+
control: 'text',
|
|
38
|
+
description: 'Custom CSS classes to apply to the segment toggle container.',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
args: {
|
|
42
|
+
options: [
|
|
43
|
+
{ label: 'Left', value: 'left' },
|
|
44
|
+
{ label: 'Center', value: 'center' },
|
|
45
|
+
{ label: 'Right', value: 'right' },
|
|
46
|
+
],
|
|
47
|
+
modelValue: 'left',
|
|
48
|
+
size: 'medium',
|
|
49
|
+
disabled: false,
|
|
50
|
+
},
|
|
51
|
+
render: (args) => {
|
|
52
|
+
return {
|
|
53
|
+
components: { SegmentToggle },
|
|
54
|
+
setup() {
|
|
55
|
+
const value = ref<string>(args.modelValue || '')
|
|
56
|
+
|
|
57
|
+
watch(
|
|
58
|
+
() => args.modelValue,
|
|
59
|
+
(val) => {
|
|
60
|
+
value.value = val || ''
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return { args, value }
|
|
65
|
+
},
|
|
66
|
+
template: `
|
|
67
|
+
<div style="padding: 20px; display: flex; flex-direction: column; align-items: center; gap: 16px;">
|
|
68
|
+
<SegmentToggle
|
|
69
|
+
v-model="value"
|
|
70
|
+
:options="args.options"
|
|
71
|
+
:size="args.size"
|
|
72
|
+
:disabled="args.disabled"
|
|
73
|
+
:class="args.class"
|
|
74
|
+
/>
|
|
75
|
+
<div style="font-family: monospace; font-size: 12px;">Selected: {{ value }}</div>
|
|
76
|
+
</div>
|
|
77
|
+
`,
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default meta
|
|
83
|
+
|
|
84
|
+
type Story = StoryObj<typeof meta>
|
|
85
|
+
|
|
86
|
+
export const Default: Story = {}
|
|
87
|
+
|
|
88
|
+
export const Small: Story = {
|
|
89
|
+
args: {
|
|
90
|
+
size: 'small',
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const Disabled: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
disabled: true,
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const TwoOptions: Story = {
|
|
101
|
+
args: {
|
|
102
|
+
options: [
|
|
103
|
+
{ label: 'On', value: 'on' },
|
|
104
|
+
{ label: 'Off', value: 'off' },
|
|
105
|
+
],
|
|
106
|
+
modelValue: 'on',
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const PreselectedMiddle: Story = {
|
|
111
|
+
args: {
|
|
112
|
+
modelValue: 'center',
|
|
113
|
+
},
|
|
114
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface Option {
|
|
3
|
+
label: string
|
|
4
|
+
value: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
modelValue: string
|
|
9
|
+
options: Option[]
|
|
10
|
+
class?: string
|
|
11
|
+
buttonsClass?: string
|
|
12
|
+
size?: 'small' | 'medium'
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
}>(), {
|
|
15
|
+
size: 'medium',
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'update:modelValue', value: string): void
|
|
20
|
+
}>()
|
|
21
|
+
|
|
22
|
+
const uniqueId = `segment-toggle-${Math.random().toString(36)}`
|
|
23
|
+
|
|
24
|
+
function selectTab(value: string) {
|
|
25
|
+
emit('update:modelValue', value)
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<div
|
|
31
|
+
rounded-full flex items-center gap-2px select-none p-2px min-w-68px bg-gray-100
|
|
32
|
+
:class="[
|
|
33
|
+
props.size === 'small' ? 'min-h-24px' : 'min-h-28px',
|
|
34
|
+
props.disabled && 'opacity-50 pointer-events-none cursor-not-allowed',
|
|
35
|
+
props.class,
|
|
36
|
+
]"
|
|
37
|
+
>
|
|
38
|
+
<button
|
|
39
|
+
v-for="option in options"
|
|
40
|
+
:key="option.value"
|
|
41
|
+
type="button"
|
|
42
|
+
relative body-12-semibold rounded-full transition-all duration-200 flex items-center justify-center
|
|
43
|
+
:class="[
|
|
44
|
+
props.size === 'small' ? 'h-24px px-12px min-w-50px' : 'h-28px px-24px min-w-115px',
|
|
45
|
+
props.buttonsClass,
|
|
46
|
+
]"
|
|
47
|
+
:disabled="props.disabled"
|
|
48
|
+
@click="selectTab(option.value)"
|
|
49
|
+
>
|
|
50
|
+
<span relative z-10 :class="modelValue === option.value ? 'text-gray-900' : 'text-gray-700'">{{ option.label }}</span>
|
|
51
|
+
<AnimatePresence mode="wait" :initial="false">
|
|
52
|
+
<Motion
|
|
53
|
+
v-if="modelValue === option.value"
|
|
54
|
+
aria-hidden="true"
|
|
55
|
+
:layout-id="`${uniqueId}-active-tab`"
|
|
56
|
+
absolute inset-0 bg-white shadow-tab rounded-inherit size-full
|
|
57
|
+
class="z-0"
|
|
58
|
+
:initial="{ opacity: 0 }"
|
|
59
|
+
:animate="{ opacity: 1 }"
|
|
60
|
+
:exit="{ opacity: 0 }"
|
|
61
|
+
:transition="{ duration: 0.3, type: 'spring', bounce: 0 }"
|
|
62
|
+
/>
|
|
63
|
+
</AnimatePresence>
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
SelectContent,
|
|
4
|
+
SelectViewport,
|
|
5
|
+
useForwardPropsEmits,
|
|
6
|
+
SelectPortal,
|
|
7
|
+
|
|
8
|
+
} from 'reka-ui'
|
|
9
|
+
import type { SelectContentEmits, SelectContentProps } from 'reka-ui'
|
|
10
|
+
import type { HTMLAttributes } from 'vue'
|
|
11
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
12
|
+
|
|
13
|
+
import SelectMenuDownButton from './select-menu-down-button.vue'
|
|
14
|
+
import SelectMenuUpButton from './select-menu-up-button.vue'
|
|
15
|
+
|
|
16
|
+
defineOptions({
|
|
17
|
+
inheritAttrs: false,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(
|
|
21
|
+
defineProps<SelectContentProps & { class?: HTMLAttributes['class'], enablePortal?: boolean }>(),
|
|
22
|
+
{
|
|
23
|
+
position: 'popper',
|
|
24
|
+
enablePortal: false,
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
const emits = defineEmits<SelectContentEmits>()
|
|
28
|
+
|
|
29
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
30
|
+
|
|
31
|
+
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<SelectPortal v-if="enablePortal">
|
|
36
|
+
<SelectContent
|
|
37
|
+
v-bind="{ ...forwarded, ...$attrs }"
|
|
38
|
+
:class="cn(
|
|
39
|
+
'SelectContent relative z-999 max-h-96 overflow-hidden rounded-[10px] border-[0.5px] border-gray-300 bg-white-1000',
|
|
40
|
+
props.class,
|
|
41
|
+
)"
|
|
42
|
+
:side-offset="4"
|
|
43
|
+
shadow="0 4px 16px 0 rgba(85, 91, 98, 0.14)"
|
|
44
|
+
avoid-collisions
|
|
45
|
+
>
|
|
46
|
+
<SelectMenuUpButton />
|
|
47
|
+
<SelectViewport :class="cn('p-1', position === 'popper' && 'h-[--reka-select-trigger-height] w-full min-w-[--reka-select-trigger-width]')">
|
|
48
|
+
<slot />
|
|
49
|
+
</SelectViewport>
|
|
50
|
+
<SelectMenuDownButton />
|
|
51
|
+
</SelectContent>
|
|
52
|
+
</SelectPortal>
|
|
53
|
+
<SelectContent
|
|
54
|
+
v-else
|
|
55
|
+
v-bind="{ ...forwarded, ...$attrs }"
|
|
56
|
+
:class="cn(
|
|
57
|
+
'SelectContent relative z-999 max-h-96 overflow-hidden rounded-[10px] border-[0.5px] border-gray-300 bg-white-1000',
|
|
58
|
+
props.class,
|
|
59
|
+
)"
|
|
60
|
+
:side-offset="4"
|
|
61
|
+
shadow="0 4px 16px 0 rgba(85, 91, 98, 0.14)"
|
|
62
|
+
avoid-collisions
|
|
63
|
+
>
|
|
64
|
+
<SelectMenuUpButton />
|
|
65
|
+
<SelectViewport :class="cn('p-1', position === 'popper' && 'h-[--reka-select-trigger-height] w-full min-w-[--reka-select-trigger-width]')">
|
|
66
|
+
<slot />
|
|
67
|
+
</SelectViewport>
|
|
68
|
+
<SelectMenuDownButton />
|
|
69
|
+
</SelectContent>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<style>
|
|
73
|
+
.SelectContent {
|
|
74
|
+
transform-origin: var(--reka-select-content-transform-origin);
|
|
75
|
+
|
|
76
|
+
&[data-state="open"] {
|
|
77
|
+
animation: slideDownAndFade 0.12s ease-out;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&[data-state="closed"] {
|
|
81
|
+
animation: slideUpAndFade 0.12s ease-out;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@keyframes slideDownAndFade {
|
|
86
|
+
from {
|
|
87
|
+
opacity: 0;
|
|
88
|
+
transform: translateY(2px) scale(0.97);
|
|
89
|
+
}
|
|
90
|
+
to {
|
|
91
|
+
opacity: 1;
|
|
92
|
+
transform: scale(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@keyframes slideUpAndFade {
|
|
97
|
+
from {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
transform: translateY(0) scale(1);
|
|
100
|
+
}
|
|
101
|
+
to {
|
|
102
|
+
opacity: 0;
|
|
103
|
+
transform: scale(0.97);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
4
|
+
import { SelectScrollDownButton, useForwardProps } from 'reka-ui'
|
|
5
|
+
import type { SelectScrollDownButtonProps } from 'reka-ui'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }>()
|
|
8
|
+
|
|
9
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
10
|
+
|
|
11
|
+
const forwardedProps = useForwardProps(delegatedProps)
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<SelectScrollDownButton v-bind="forwardedProps" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
|
|
16
|
+
<slot>
|
|
17
|
+
<TelaIcon name="i-ph-caret-down" text="16px" color="gray-400" />
|
|
18
|
+
</slot>
|
|
19
|
+
</SelectScrollDownButton>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SelectGroupProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import { SelectGroup } from 'reka-ui'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>()
|
|
8
|
+
|
|
9
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<SelectGroup :class="cn('w-full', props.class)" v-bind="delegatedProps">
|
|
14
|
+
<slot />
|
|
15
|
+
</SelectGroup>
|
|
16
|
+
</template>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SelectItemProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import {
|
|
6
|
+
SelectItem,
|
|
7
|
+
SelectItemIndicator,
|
|
8
|
+
SelectItemText,
|
|
9
|
+
useForwardProps,
|
|
10
|
+
} from 'reka-ui'
|
|
11
|
+
import { cn } from '@/lib/utils'
|
|
12
|
+
|
|
13
|
+
const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>()
|
|
14
|
+
|
|
15
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
16
|
+
|
|
17
|
+
const forwardedProps = useForwardProps(delegatedProps)
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<SelectItem
|
|
22
|
+
v-bind="forwardedProps"
|
|
23
|
+
:class="
|
|
24
|
+
cn(
|
|
25
|
+
'relative flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-[12px] px-[12px] py-[7px] text-body-14-medium font-460 outline-none focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
26
|
+
props.class,
|
|
27
|
+
)
|
|
28
|
+
"
|
|
29
|
+
>
|
|
30
|
+
<SelectItemText>
|
|
31
|
+
<slot />
|
|
32
|
+
</SelectItemText>
|
|
33
|
+
|
|
34
|
+
<span class="relative flex h-3.5 w-3.5 items-center justify-center">
|
|
35
|
+
<SelectItemIndicator>
|
|
36
|
+
<TelaIcon name="i-ph-check" size="14px" color="gray-500" />
|
|
37
|
+
</SelectItemIndicator>
|
|
38
|
+
</span>
|
|
39
|
+
</SelectItem>
|
|
40
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { SelectRoot, useForwardPropsEmits } from 'reka-ui'
|
|
3
|
+
import type { SelectRootProps, SelectRootEmits } from 'reka-ui'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<SelectRootProps>()
|
|
6
|
+
const emits = defineEmits<SelectRootEmits>()
|
|
7
|
+
|
|
8
|
+
const forwarded = useForwardPropsEmits(props, emits)
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<SelectRoot v-bind="forwarded">
|
|
13
|
+
<slot />
|
|
14
|
+
</SelectRoot>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SelectTriggerProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<SelectTriggerProps & { triggerIconSize?: string, class?: HTMLAttributes['class'] }>(),
|
|
9
|
+
{
|
|
10
|
+
triggerIconSize: '12px',
|
|
11
|
+
},
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
15
|
+
|
|
16
|
+
const forwardedProps = useForwardProps(delegatedProps)
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<SelectTrigger
|
|
21
|
+
v-bind="forwardedProps"
|
|
22
|
+
:class="cn(
|
|
23
|
+
'group flex h-32px w-full items-center gap-[12px] justify-between rounded-[10px] border-[0.5px] border-gray-300 bg-white-1000 pl-[12px] pr-[10px] py-[7px] text-body-14-semibold font-520 select-none text-start',
|
|
24
|
+
'data-[placeholder]:text-gray-900 data-[state=open]:text-gray-500 hover:bg-gray-100 data-[state=open]:bg-gray-100 focus-visible:outline-none [&>span]:truncate',
|
|
25
|
+
'focus-visible:ring-[0.5px] focus-visible:ring-cyan-600 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:border-gray-200 disabled:text-gray-400',
|
|
26
|
+
props.class,
|
|
27
|
+
)"
|
|
28
|
+
>
|
|
29
|
+
<slot />
|
|
30
|
+
<SelectIcon as-child>
|
|
31
|
+
<TelaIcon name="i-ph-caret-down" :size="props.triggerIconSize" color="gray-500" class="shrink-0 transition-all ease-out duration-150 group-data-[state=open]:rotate-180" />
|
|
32
|
+
</SelectIcon>
|
|
33
|
+
</SelectTrigger>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
4
|
+
import { SelectScrollUpButton, useForwardProps } from 'reka-ui'
|
|
5
|
+
import type { SelectScrollUpButtonProps } from 'reka-ui'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }>()
|
|
8
|
+
|
|
9
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
10
|
+
|
|
11
|
+
const forwardedProps = useForwardProps(delegatedProps)
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<SelectScrollUpButton v-bind="forwardedProps" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
|
|
16
|
+
<slot>
|
|
17
|
+
<TelaIcon name="i-ph-caret-up" text="16px" color="gray-400" />
|
|
18
|
+
</slot>
|
|
19
|
+
</SelectScrollUpButton>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SelectValueProps } from 'reka-ui'
|
|
3
|
+
import { SelectValue } from 'reka-ui'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<SelectValueProps>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<SelectValue v-bind="props">
|
|
10
|
+
<slot />
|
|
11
|
+
</SelectValue>
|
|
12
|
+
</template>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as SelectMenuStories from './select-menu.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={SelectMenuStories} />
|
|
5
|
+
|
|
6
|
+
# TelaSelectMenu
|
|
7
|
+
|
|
8
|
+
A flexible select menu component built on reka-ui. Allows users to select a single option from a dropdown list. Supports icons, descriptions, tooltips, grouping, and custom styling.
|
|
9
|
+
|
|
10
|
+
## Examples
|
|
11
|
+
|
|
12
|
+
### Basic Usage
|
|
13
|
+
|
|
14
|
+
```vue
|
|
15
|
+
<script setup>
|
|
16
|
+
import { ref } from 'vue'
|
|
17
|
+
|
|
18
|
+
const selected = ref('')
|
|
19
|
+
const options = [
|
|
20
|
+
{ value: 'option1', label: 'Option 1' },
|
|
21
|
+
{ value: 'option2', label: 'Option 2' },
|
|
22
|
+
{ value: 'option3', label: 'Option 3' }
|
|
23
|
+
]
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<TelaSelectMenu
|
|
28
|
+
v-model="selected"
|
|
29
|
+
:options="options"
|
|
30
|
+
placeholder="Select an option"
|
|
31
|
+
/>
|
|
32
|
+
</template>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### With Icons
|
|
36
|
+
|
|
37
|
+
```vue
|
|
38
|
+
<script setup>
|
|
39
|
+
import { ref } from 'vue'
|
|
40
|
+
|
|
41
|
+
const selected = ref('')
|
|
42
|
+
const options = [
|
|
43
|
+
{ value: 'user', label: 'User', icon: 'i-ph-user' },
|
|
44
|
+
{ value: 'settings', label: 'Settings', icon: 'i-ph-gear' },
|
|
45
|
+
{ value: 'notifications', label: 'Notifications', icon: 'i-ph-bell' }
|
|
46
|
+
]
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<TelaSelectMenu
|
|
51
|
+
v-model="selected"
|
|
52
|
+
:options="options"
|
|
53
|
+
/>
|
|
54
|
+
</template>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### With Descriptions
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<TelaSelectMenu
|
|
61
|
+
v-model="selected"
|
|
62
|
+
:options="[
|
|
63
|
+
{
|
|
64
|
+
value: 'basic',
|
|
65
|
+
label: 'Basic Plan',
|
|
66
|
+
description: 'For individuals'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
value: 'pro',
|
|
70
|
+
label: 'Pro Plan',
|
|
71
|
+
description: 'For small teams'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
value: 'enterprise',
|
|
75
|
+
label: 'Enterprise',
|
|
76
|
+
description: 'For large organizations'
|
|
77
|
+
}
|
|
78
|
+
]"
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### With External Icons
|
|
83
|
+
|
|
84
|
+
```vue
|
|
85
|
+
<TelaSelectMenu
|
|
86
|
+
v-model="framework"
|
|
87
|
+
:options="[
|
|
88
|
+
{
|
|
89
|
+
value: 'vue',
|
|
90
|
+
label: 'Vue.js',
|
|
91
|
+
externalIconSrc: 'https://vuejs.org/logo.svg'
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
value: 'react',
|
|
95
|
+
label: 'React',
|
|
96
|
+
externalIconSrc: 'https://react.dev/logo.svg'
|
|
97
|
+
}
|
|
98
|
+
]"
|
|
99
|
+
/>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Custom Trigger
|
|
103
|
+
|
|
104
|
+
```vue
|
|
105
|
+
<TelaSelectMenu v-model="selected" :options="options">
|
|
106
|
+
<template #trigger="{ currentOption }">
|
|
107
|
+
<button class="custom-trigger">
|
|
108
|
+
{{ currentOption?.label || 'Select' }}
|
|
109
|
+
</button>
|
|
110
|
+
</template>
|
|
111
|
+
</TelaSelectMenu>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Custom Styling
|
|
115
|
+
|
|
116
|
+
```vue
|
|
117
|
+
<TelaSelectMenu
|
|
118
|
+
v-model="selected"
|
|
119
|
+
:options="options"
|
|
120
|
+
trigger-class="w-300px"
|
|
121
|
+
content-class="max-h-400px"
|
|
122
|
+
item-class="py-3"
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### With Icon Background
|
|
127
|
+
|
|
128
|
+
```vue
|
|
129
|
+
<TelaSelectMenu
|
|
130
|
+
v-model="selected"
|
|
131
|
+
:options="options"
|
|
132
|
+
:icon-with-background="{
|
|
133
|
+
size: 'md',
|
|
134
|
+
backgroundClass: 'bg-blue-100'
|
|
135
|
+
}"
|
|
136
|
+
/>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Disabled State
|
|
140
|
+
|
|
141
|
+
```vue
|
|
142
|
+
<TelaSelectMenu
|
|
143
|
+
v-model="selected"
|
|
144
|
+
:options="options"
|
|
145
|
+
disabled
|
|
146
|
+
/>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Props
|
|
150
|
+
|
|
151
|
+
<ArgTypes of={SelectMenuStories} />
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
type SelectMenuOption = {
|
|
155
|
+
value: string
|
|
156
|
+
label: string
|
|
157
|
+
description?: string
|
|
158
|
+
icon?: string | Component
|
|
159
|
+
externalIconSrc?: string
|
|
160
|
+
group?: string
|
|
161
|
+
tooltipContent?: Component
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
type SelectMenuProps = {
|
|
165
|
+
modelValue?: string
|
|
166
|
+
options: SelectMenuOption[]
|
|
167
|
+
triggerClass?: string
|
|
168
|
+
contentClass?: string
|
|
169
|
+
groupClass?: string
|
|
170
|
+
itemClass?: string
|
|
171
|
+
placeholder?: string
|
|
172
|
+
triggerIconSize?: string
|
|
173
|
+
disabled?: boolean
|
|
174
|
+
iconWithBackground?: {
|
|
175
|
+
size: 'xs' | 'sm' | 'md'
|
|
176
|
+
backgroundClass: string
|
|
177
|
+
}
|
|
178
|
+
enablePortal?: boolean
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Slots
|
|
183
|
+
|
|
184
|
+
- `trigger` - Custom trigger button (receives `currentOption` as slot prop)
|
|
185
|
+
|
|
186
|
+
## Components
|
|
187
|
+
|
|
188
|
+
The SelectMenu system consists of these sub-components:
|
|
189
|
+
- `TelaSelectMenuRoot` - Root container component
|
|
190
|
+
- `TelaSelectMenuTrigger` - Trigger button
|
|
191
|
+
- `TelaSelectMenuValue` - Value display
|
|
192
|
+
- `TelaSelectMenuContent` - Dropdown content container
|
|
193
|
+
- `TelaSelectMenuGroup` - Group container for items
|
|
194
|
+
- `TelaSelectMenuItem` - Individual selectable item
|
|
195
|
+
|
|
196
|
+
## Features
|
|
197
|
+
|
|
198
|
+
- **Single Selection**: Choose one option from a list
|
|
199
|
+
- **Icons Support**: Use icon names or external image sources
|
|
200
|
+
- **Descriptions**: Add helpful context to options
|
|
201
|
+
- **Tooltips**: Show additional information on hover
|
|
202
|
+
- **Grouping**: Organize options into groups
|
|
203
|
+
- **Custom Styling**: Granular control over all parts
|
|
204
|
+
- **Portal Rendering**: Control dropdown positioning
|
|
205
|
+
- **Keyboard Navigation**: Full keyboard support
|
|
206
|
+
- **Accessible**: Built on reka-ui with proper ARIA attributes
|
|
207
|
+
|
|
208
|
+
## Events
|
|
209
|
+
|
|
210
|
+
- `update:modelValue` - Emitted when selection changes with new value
|
|
211
|
+
- `select` - Emitted when an option is selected with the value
|
|
212
|
+
- `blur` - Emitted when select loses focus
|
|
213
|
+
- `focus` - Emitted when select gains focus
|
|
214
|
+
|
|
215
|
+
## Accessibility
|
|
216
|
+
|
|
217
|
+
- Built on reka-ui primitives
|
|
218
|
+
- Proper ARIA attributes
|
|
219
|
+
- Keyboard navigation (Arrow keys, Enter, Escape)
|
|
220
|
+
- Focus management
|
|
221
|
+
- Screen reader friendly
|