@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,242 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, useAttrs, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DialogClose,
|
|
6
|
+
DialogContent,
|
|
7
|
+
DialogDescription,
|
|
8
|
+
DialogOverlay,
|
|
9
|
+
DialogPortal,
|
|
10
|
+
DialogRoot,
|
|
11
|
+
DialogTitle,
|
|
12
|
+
VisuallyHidden,
|
|
13
|
+
} from 'radix-vue'
|
|
14
|
+
|
|
15
|
+
defineOptions({
|
|
16
|
+
inheritAttrs: false,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<{
|
|
20
|
+
title?: string
|
|
21
|
+
modalWidth?: 'sm' | 'md' | 'lg'
|
|
22
|
+
compact?: boolean
|
|
23
|
+
hideDividers?: boolean
|
|
24
|
+
hideHeader?: boolean
|
|
25
|
+
overlayClass?: string
|
|
26
|
+
contentClass?: string
|
|
27
|
+
headerClass?: string
|
|
28
|
+
fullscreen?: boolean
|
|
29
|
+
dialogContentClass?: string
|
|
30
|
+
isCloseIcon?: boolean
|
|
31
|
+
isCloseIconAbsolute?: boolean
|
|
32
|
+
smallTitle?: boolean
|
|
33
|
+
titleClass?: string
|
|
34
|
+
}>(), {
|
|
35
|
+
modalWidth: 'md',
|
|
36
|
+
isCloseIcon: true,
|
|
37
|
+
isCloseIconAbsolute: false,
|
|
38
|
+
smallTitle: false,
|
|
39
|
+
})
|
|
40
|
+
const emit = defineEmits<{
|
|
41
|
+
close: []
|
|
42
|
+
}>()
|
|
43
|
+
|
|
44
|
+
const attrs = useAttrs()
|
|
45
|
+
|
|
46
|
+
const forwardedAttrs = computed(() => {
|
|
47
|
+
const { onPointerDownOutside, ...rest } = attrs as Record<string, unknown>
|
|
48
|
+
return rest
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const open = defineModel<boolean>()
|
|
52
|
+
|
|
53
|
+
watch(open, (value) => {
|
|
54
|
+
if (!value) {
|
|
55
|
+
emit('close')
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const modalMaxWidth = computed(() => {
|
|
60
|
+
return props.modalWidth === 'lg' ? 'max-w-900px' : props.modalWidth === 'sm' ? 'max-w-300px' : 'max-w-500px'
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
function handlePointerDownOutside(event: any) {
|
|
64
|
+
const target = event?.detail?.originalEvent?.target ?? event?.target
|
|
65
|
+
|
|
66
|
+
if (target instanceof Element && target.closest('[data-sonner-toast]')) {
|
|
67
|
+
event.preventDefault()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const listener = (attrs as Record<string, unknown>).onPointerDownOutside
|
|
71
|
+
if (Array.isArray(listener)) {
|
|
72
|
+
listener.forEach((handler) => {
|
|
73
|
+
if (typeof handler === 'function')
|
|
74
|
+
handler(event)
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
else if (typeof listener === 'function') {
|
|
78
|
+
listener(event)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<template>
|
|
84
|
+
<DialogRoot v-model:open="open">
|
|
85
|
+
<DialogPortal>
|
|
86
|
+
<DialogOverlay :class="`DialogOverlay ${overlayClass ?? ''}`" bg="bg-#020913/24" z-600 overflow-y-auto flex items-center justify-center :p-16px="!fullscreen">
|
|
87
|
+
<DialogContent
|
|
88
|
+
:class="`DialogContent shadow-xl ${modalMaxWidth ?? ''} ${dialogContentClass ?? ''}`"
|
|
89
|
+
z-101
|
|
90
|
+
rounded-16px
|
|
91
|
+
w-full flex="~ col"
|
|
92
|
+
min-w-100px
|
|
93
|
+
bg-white
|
|
94
|
+
v-bind="forwardedAttrs"
|
|
95
|
+
overflow-y-hidden
|
|
96
|
+
@pointer-down-outside="handlePointerDownOutside"
|
|
97
|
+
>
|
|
98
|
+
<div
|
|
99
|
+
v-if="!hideHeader" w-full flex="~" items-center
|
|
100
|
+
justify-between
|
|
101
|
+
:b-b="!props.hideDividers && '0.5px gray-200'"
|
|
102
|
+
:p="props.compact ? 'b-8px x-18px' : 'y-24px x-32px'"
|
|
103
|
+
:pt="!isCloseIcon ? '14px' : '18px'"
|
|
104
|
+
:px="isCloseIcon ? '24px' : '18px'"
|
|
105
|
+
class="DialogHeader" :class="[headerClass]"
|
|
106
|
+
>
|
|
107
|
+
<DialogTitle
|
|
108
|
+
v-if="title"
|
|
109
|
+
w-full
|
|
110
|
+
:class="cn(
|
|
111
|
+
props.isCloseIcon && !props.smallTitle ? 'heading-20-medium text-gray-900' : 'body-12-medium text-gray-500',
|
|
112
|
+
props.isCloseIcon && props.smallTitle && 'body-12-medium text-gray-500',
|
|
113
|
+
props.titleClass,
|
|
114
|
+
)"
|
|
115
|
+
leading-none
|
|
116
|
+
:mb="!props.hideDividers ? '12px' : '0'"
|
|
117
|
+
:content="props.compact ? '16px' : '20px'"
|
|
118
|
+
capitalize
|
|
119
|
+
break-all
|
|
120
|
+
>
|
|
121
|
+
<slot name="header">
|
|
122
|
+
<div flex="~" items-center justify-between min-h-24px>
|
|
123
|
+
<slot name="header-leading" />
|
|
124
|
+
<p :class="$slots['header-leading'] && 'absolute left-1/2 -translate-x-1/2'">
|
|
125
|
+
{{ title }}
|
|
126
|
+
</p>
|
|
127
|
+
</div>
|
|
128
|
+
</slot>
|
|
129
|
+
</DialogTitle>
|
|
130
|
+
|
|
131
|
+
<VisuallyHidden v-else>
|
|
132
|
+
<DialogTitle />
|
|
133
|
+
</VisuallyHidden>
|
|
134
|
+
|
|
135
|
+
<div w-32px />
|
|
136
|
+
<VisuallyHidden as-child>
|
|
137
|
+
<DialogDescription />
|
|
138
|
+
</VisuallyHidden>
|
|
139
|
+
|
|
140
|
+
<div v-if="isCloseIcon" z-1 :right="props.compact ? '12px' : '24px'">
|
|
141
|
+
<slot name="actions">
|
|
142
|
+
<DialogClose as-child>
|
|
143
|
+
<TelaIconButton
|
|
144
|
+
icon="i-ph-x" size="sm" color="secondary" button-class="text-gray-400 hover:text-gray-900"
|
|
145
|
+
:class="cn('p-6px', props.isCloseIconAbsolute && 'absolute right-20px top-20px')"
|
|
146
|
+
/>
|
|
147
|
+
</DialogClose>
|
|
148
|
+
</slot>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<VisuallyHidden v-else>
|
|
153
|
+
<DialogTitle />
|
|
154
|
+
</VisuallyHidden>
|
|
155
|
+
|
|
156
|
+
<slot name="content">
|
|
157
|
+
<div
|
|
158
|
+
flex w-full items-center justify-center relative h-full
|
|
159
|
+
class="DialogBody" :class="[
|
|
160
|
+
props.compact ? 'pb-20px' : 'px-32px py-24px',
|
|
161
|
+
contentClass,
|
|
162
|
+
]"
|
|
163
|
+
>
|
|
164
|
+
<slot />
|
|
165
|
+
</div>
|
|
166
|
+
</slot>
|
|
167
|
+
|
|
168
|
+
<div
|
|
169
|
+
v-if="$slots.footer"
|
|
170
|
+
class="DialogFooter" mt-24px :b-t="!props.hideDividers && '0.5px gray-200'"
|
|
171
|
+
py-24px flex px-32px
|
|
172
|
+
>
|
|
173
|
+
<slot name="footer" />
|
|
174
|
+
</div>
|
|
175
|
+
</DialogContent>
|
|
176
|
+
</DialogOverlay>
|
|
177
|
+
</DialogPortal>
|
|
178
|
+
</DialogRoot>
|
|
179
|
+
</template>
|
|
180
|
+
|
|
181
|
+
<style lang="css" scoped>
|
|
182
|
+
.DialogOverlay {
|
|
183
|
+
background-color: rgba(2, 9, 19, 0.24);
|
|
184
|
+
position: fixed;
|
|
185
|
+
inset: 0;
|
|
186
|
+
animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.DialogContent {
|
|
190
|
+
position: relative;
|
|
191
|
+
overflow-x: hidden;
|
|
192
|
+
width: 400px;
|
|
193
|
+
padding: 24px;
|
|
194
|
+
animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.DialogContent:focus {
|
|
198
|
+
outline: none;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.DialogHeader {
|
|
202
|
+
padding: 0px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.DialogBody {
|
|
206
|
+
padding: 0px !important;
|
|
207
|
+
justify-content: start !important;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.DialogFooter {
|
|
211
|
+
padding: 0px !important;
|
|
212
|
+
margin: 0px !important;
|
|
213
|
+
margin-top: 20px !important;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.DialogDescription {
|
|
217
|
+
margin: 10px 0 20px;
|
|
218
|
+
color: var(--mauve-11);
|
|
219
|
+
font-size: 15px;
|
|
220
|
+
line-height: 1.5;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@keyframes overlayShow {
|
|
224
|
+
from {
|
|
225
|
+
opacity: 0;
|
|
226
|
+
}
|
|
227
|
+
to {
|
|
228
|
+
opacity: 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@keyframes contentShow {
|
|
233
|
+
from {
|
|
234
|
+
opacity: 0;
|
|
235
|
+
transform: scale(0.96);
|
|
236
|
+
}
|
|
237
|
+
to {
|
|
238
|
+
opacity: 1;
|
|
239
|
+
transform: scale(1);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
</style>
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as MultipleSelectStories from './multiple-select.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={MultipleSelectStories} />
|
|
5
|
+
|
|
6
|
+
# TelaMultipleSelect
|
|
7
|
+
|
|
8
|
+
A multiple select component that allows users to select multiple options from a dropdown list. Supports search functionality, grouping, icons, custom styling, and two display variants (list and preview). Perfect for selecting multiple items with rich option data.
|
|
9
|
+
|
|
10
|
+
## Examples
|
|
11
|
+
|
|
12
|
+
### With Initial Values
|
|
13
|
+
|
|
14
|
+
<Canvas of={MultipleSelectStories.WithInitialValue} />
|
|
15
|
+
|
|
16
|
+
### With Grouping
|
|
17
|
+
|
|
18
|
+
<Canvas of={MultipleSelectStories.WithGroups} />
|
|
19
|
+
|
|
20
|
+
### With Icons
|
|
21
|
+
|
|
22
|
+
<Canvas of={MultipleSelectStories.WithIcons} />
|
|
23
|
+
|
|
24
|
+
### With External Icons
|
|
25
|
+
|
|
26
|
+
<Canvas of={MultipleSelectStories.WithExternalIcons} />
|
|
27
|
+
|
|
28
|
+
### With Search
|
|
29
|
+
|
|
30
|
+
<Canvas of={MultipleSelectStories.WithSearch} />
|
|
31
|
+
|
|
32
|
+
### Variant Comparison
|
|
33
|
+
|
|
34
|
+
<Canvas of={MultipleSelectStories.VariantComparison} />
|
|
35
|
+
|
|
36
|
+
### Max Selected Display
|
|
37
|
+
|
|
38
|
+
<Canvas of={MultipleSelectStories.MaxSelectedDisplay} />
|
|
39
|
+
|
|
40
|
+
### Read-Only
|
|
41
|
+
|
|
42
|
+
<Canvas of={MultipleSelectStories.ReadOnly} />
|
|
43
|
+
|
|
44
|
+
### Required
|
|
45
|
+
|
|
46
|
+
<Canvas of={MultipleSelectStories.Required} />
|
|
47
|
+
|
|
48
|
+
### Basic Usage
|
|
49
|
+
|
|
50
|
+
```vue
|
|
51
|
+
<script setup>
|
|
52
|
+
import { ref } from 'vue'
|
|
53
|
+
|
|
54
|
+
const selected = ref([])
|
|
55
|
+
const options = [
|
|
56
|
+
{ value: '1', label: 'Option 1' },
|
|
57
|
+
{ value: '2', label: 'Option 2' },
|
|
58
|
+
{ value: '3', label: 'Option 3' }
|
|
59
|
+
]
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<TelaMultipleSelect
|
|
64
|
+
v-model="selected"
|
|
65
|
+
:options="options"
|
|
66
|
+
placeholder="Select options"
|
|
67
|
+
/>
|
|
68
|
+
</template>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### With Grouping Code
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<TelaMultipleSelect
|
|
75
|
+
v-model="selected"
|
|
76
|
+
:options="[
|
|
77
|
+
{ value: '1', label: 'Apple', group: 'Fruits' },
|
|
78
|
+
{ value: '2', label: 'Banana', group: 'Fruits' },
|
|
79
|
+
{ value: '3', label: 'Carrot', group: 'Vegetables' },
|
|
80
|
+
{ value: '4', label: 'Broccoli', group: 'Vegetables' }
|
|
81
|
+
]"
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### With Icons Code
|
|
86
|
+
|
|
87
|
+
```vue
|
|
88
|
+
<TelaMultipleSelect
|
|
89
|
+
v-model="selected"
|
|
90
|
+
:options="[
|
|
91
|
+
{ value: '1', label: 'Profile', icon: 'i-ph-user' },
|
|
92
|
+
{ value: '2', label: 'Settings', icon: 'i-ph-gear' },
|
|
93
|
+
{ value: '3', label: 'Notifications', icon: 'i-ph-bell' }
|
|
94
|
+
]"
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### With Search Code
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<TelaMultipleSelect
|
|
102
|
+
v-model="selected"
|
|
103
|
+
:options="options"
|
|
104
|
+
allow-search
|
|
105
|
+
search-placeholder="Search technologies..."
|
|
106
|
+
/>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### List Variant (Default)
|
|
110
|
+
|
|
111
|
+
Shows selected items as a list with remove buttons:
|
|
112
|
+
|
|
113
|
+
```vue
|
|
114
|
+
<TelaMultipleSelect
|
|
115
|
+
v-model="selected"
|
|
116
|
+
:options="options"
|
|
117
|
+
variant="list"
|
|
118
|
+
:max-selected-display="5"
|
|
119
|
+
/>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Preview Variant
|
|
123
|
+
|
|
124
|
+
Shows selected items inline with a compact display:
|
|
125
|
+
|
|
126
|
+
```vue
|
|
127
|
+
<TelaMultipleSelect
|
|
128
|
+
v-model="selected"
|
|
129
|
+
:options="options"
|
|
130
|
+
variant="preview"
|
|
131
|
+
:preview-max-items="3"
|
|
132
|
+
/>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### With Description
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<TelaMultipleSelect
|
|
139
|
+
v-model="selected"
|
|
140
|
+
:options="options"
|
|
141
|
+
description="Select multiple options from the list"
|
|
142
|
+
/>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Max Selected Display Code
|
|
146
|
+
|
|
147
|
+
```vue
|
|
148
|
+
<TelaMultipleSelect
|
|
149
|
+
v-model="selected"
|
|
150
|
+
:options="options"
|
|
151
|
+
:max-selected-display="2"
|
|
152
|
+
/>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Close on Select
|
|
156
|
+
|
|
157
|
+
```vue
|
|
158
|
+
<TelaMultipleSelect
|
|
159
|
+
v-model="selected"
|
|
160
|
+
:options="options"
|
|
161
|
+
close-on-select
|
|
162
|
+
/>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Custom Button Labels
|
|
166
|
+
|
|
167
|
+
```vue
|
|
168
|
+
<TelaMultipleSelect
|
|
169
|
+
v-model="selected"
|
|
170
|
+
:options="options"
|
|
171
|
+
button-label="Add Item"
|
|
172
|
+
close-button-label="Done"
|
|
173
|
+
button-icon="i-ph-plus-circle"
|
|
174
|
+
/>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Long List with Scrolling
|
|
178
|
+
|
|
179
|
+
<Canvas of={MultipleSelectStories.WithScrolling} />
|
|
180
|
+
|
|
181
|
+
## Props
|
|
182
|
+
|
|
183
|
+
<ArgTypes />
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
type SelectMenuOption = {
|
|
187
|
+
value: string
|
|
188
|
+
label: string
|
|
189
|
+
description?: string
|
|
190
|
+
icon?: string
|
|
191
|
+
externalIconSrc?: string
|
|
192
|
+
group?: string
|
|
193
|
+
to?: string
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
type MultipleSelectProps = {
|
|
197
|
+
modelValue?: string[]
|
|
198
|
+
readOnly?: boolean
|
|
199
|
+
options: SelectMenuOption[]
|
|
200
|
+
placeholder?: string
|
|
201
|
+
required?: boolean
|
|
202
|
+
maxSelectedDisplay?: number
|
|
203
|
+
allowSearch?: boolean
|
|
204
|
+
searchPlaceholder?: string
|
|
205
|
+
buttonLabel?: string
|
|
206
|
+
closeButtonLabel?: string
|
|
207
|
+
closeOnSelect?: boolean
|
|
208
|
+
buttonIcon?: string
|
|
209
|
+
variant?: 'list' | 'preview'
|
|
210
|
+
previewMaxItems?: number
|
|
211
|
+
description?: string
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Slots
|
|
216
|
+
|
|
217
|
+
- `trigger` - Custom trigger button (receives selectedOptions, selectedValues, displayText, readOnly, buttonIcon, buttonLabel, and toggleSelection)
|
|
218
|
+
|
|
219
|
+
## Features
|
|
220
|
+
|
|
221
|
+
- **Multiple Selection**: Select multiple options with checkboxes
|
|
222
|
+
- **Two Variants**: List view or compact preview
|
|
223
|
+
- **Search Functionality**: Filter options by typing (optional)
|
|
224
|
+
- **Grouping**: Organize options by categories
|
|
225
|
+
- **Icons Support**: Use icon classes or external images
|
|
226
|
+
- **Select All/Clear All**: Batch select or deselect
|
|
227
|
+
- **Max Display Limit**: Show "+X more" for long lists
|
|
228
|
+
- **Remove Items**: Delete individual selections
|
|
229
|
+
- **Keyboard Shortcuts**: Cmd+Backspace to clear search
|
|
230
|
+
- **Empty State**: Helpful message when no results
|
|
231
|
+
- **Scrollable**: Handle large option lists
|
|
232
|
+
- **Custom Styling**: Full control over appearance
|
|
233
|
+
- **Accessible**: Keyboard navigation and screen reader support
|
|
234
|
+
|
|
235
|
+
## Events
|
|
236
|
+
|
|
237
|
+
- `update:modelValue` - Emitted when selection changes with array of values
|
|
238
|
+
- `select` - Emitted when an option is selected with the value
|
|
239
|
+
- `deselect` - Emitted when an option is deselected with the value
|
|
240
|
+
- `navigate` - Emitted when navigating to an option's `to` path
|
|
241
|
+
- `focus` - Emitted when component gains focus
|
|
242
|
+
- `blur` - Emitted when component loses focus
|
|
243
|
+
|
|
244
|
+
## Variants
|
|
245
|
+
|
|
246
|
+
### List Variant
|
|
247
|
+
|
|
248
|
+
- Shows each selected item in a bordered list
|
|
249
|
+
- Remove button for each item
|
|
250
|
+
- Displays up to `maxSelectedDisplay` items
|
|
251
|
+
- Shows "+X more" for additional items
|
|
252
|
+
|
|
253
|
+
### Preview Variant
|
|
254
|
+
|
|
255
|
+
- Inline display of selected items
|
|
256
|
+
- Comma-separated labels
|
|
257
|
+
- Popover for additional items when exceeding `previewMaxItems`
|
|
258
|
+
- More compact, suitable for tight spaces
|
|
259
|
+
|
|
260
|
+
## Keyboard Shortcuts
|
|
261
|
+
|
|
262
|
+
- `Escape` - Close dropdown
|
|
263
|
+
- `Cmd/Ctrl + Backspace` - Clear search (when search is enabled)
|
|
264
|
+
- `Space` - Toggle option checkbox
|
|
265
|
+
- `Arrow Up/Down` - Navigate options
|
|
266
|
+
|
|
267
|
+
## Accessibility
|
|
268
|
+
|
|
269
|
+
- Built on radix-vue primitives
|
|
270
|
+
- Proper ARIA attributes
|
|
271
|
+
- Checkbox indicators for selection state
|
|
272
|
+
- Keyboard navigation support
|
|
273
|
+
- Focus management
|
|
274
|
+
- Screen reader friendly labels
|