@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,178 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as StatusBarStories from './status-bar.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={StatusBarStories} />
|
|
5
|
+
|
|
6
|
+
# TelaStatusBar
|
|
7
|
+
|
|
8
|
+
A status bar component that displays a visual representation of status distribution using colored segments. Each segment represents a percentage of the total with different status types (success, error, neutral, etc.). Useful for showing progress, status breakdowns, or distribution metrics.
|
|
9
|
+
|
|
10
|
+
## Examples
|
|
11
|
+
|
|
12
|
+
### Equal Distribution
|
|
13
|
+
|
|
14
|
+
<Canvas of={StatusBarStories.Default} />
|
|
15
|
+
|
|
16
|
+
### All Success
|
|
17
|
+
|
|
18
|
+
<Canvas of={StatusBarStories.AllSuccess} />
|
|
19
|
+
|
|
20
|
+
### Disabled State
|
|
21
|
+
|
|
22
|
+
<Canvas of={StatusBarStories.Disabled} />
|
|
23
|
+
|
|
24
|
+
### Basic Usage
|
|
25
|
+
|
|
26
|
+
```vue
|
|
27
|
+
<script setup>
|
|
28
|
+
import { ref } from 'vue'
|
|
29
|
+
|
|
30
|
+
const statusItems = [
|
|
31
|
+
{ status: 'success', percentage: 60 },
|
|
32
|
+
{ status: 'error', percentage: 25 },
|
|
33
|
+
{ status: 'neutral', percentage: 15 }
|
|
34
|
+
]
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<TelaStatusBar :items="statusItems" />
|
|
39
|
+
</template>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Equal Distribution Code
|
|
43
|
+
|
|
44
|
+
```vue
|
|
45
|
+
<TelaStatusBar
|
|
46
|
+
:items="[
|
|
47
|
+
{ status: 'success', percentage: 33 },
|
|
48
|
+
{ status: 'error', percentage: 33 },
|
|
49
|
+
{ status: 'neutral', percentage: 34 }
|
|
50
|
+
]"
|
|
51
|
+
/>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### All Success Code
|
|
55
|
+
|
|
56
|
+
```vue
|
|
57
|
+
<TelaStatusBar
|
|
58
|
+
:items="[
|
|
59
|
+
{ status: 'success', percentage: 100 }
|
|
60
|
+
]"
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<TelaStatusBar
|
|
66
|
+
:items="statusItems"
|
|
67
|
+
disabled
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Custom Distribution
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<TelaStatusBar
|
|
75
|
+
:items="[
|
|
76
|
+
{ status: 'success', percentage: 70 },
|
|
77
|
+
{ status: 'warning', percentage: 20 },
|
|
78
|
+
{ status: 'error', percentage: 10 }
|
|
79
|
+
]"
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Task Progress
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<script setup>
|
|
87
|
+
import { ref, computed } from 'vue'
|
|
88
|
+
|
|
89
|
+
const tasks = ref([
|
|
90
|
+
{ status: 'completed', count: 45 },
|
|
91
|
+
{ status: 'failed', count: 5 },
|
|
92
|
+
{ status: 'pending', count: 10 }
|
|
93
|
+
])
|
|
94
|
+
|
|
95
|
+
const total = computed(() =>
|
|
96
|
+
tasks.value.reduce((sum, task) => sum + task.count, 0)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
const statusItems = computed(() =>
|
|
100
|
+
tasks.value.map(task => ({
|
|
101
|
+
status: task.status === 'completed' ? 'success' :
|
|
102
|
+
task.status === 'failed' ? 'error' : 'neutral',
|
|
103
|
+
percentage: Math.round((task.count / total.value) * 100)
|
|
104
|
+
}))
|
|
105
|
+
)
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<template>
|
|
109
|
+
<div>
|
|
110
|
+
<TelaStatusBar :items="statusItems" />
|
|
111
|
+
<div class="mt-2 text-sm text-gray-600">
|
|
112
|
+
{{ tasks[0].count }} completed,
|
|
113
|
+
{{ tasks[1].count }} failed,
|
|
114
|
+
{{ tasks[2].count }} pending
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Props
|
|
121
|
+
|
|
122
|
+
<ArgTypes />
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
type StatusType = 'success' | 'error' | 'neutral' | 'warning' | 'info'
|
|
126
|
+
|
|
127
|
+
type StatusItem = {
|
|
128
|
+
status: StatusType
|
|
129
|
+
percentage: number // 0-100
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
type StatusBarProps = {
|
|
133
|
+
items: StatusItem[]
|
|
134
|
+
disabled?: boolean
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Status Colors
|
|
139
|
+
|
|
140
|
+
- **success**: Green - Completed, successful, or positive states
|
|
141
|
+
- **error**: Red - Failed, error, or negative states
|
|
142
|
+
- **neutral**: Gray - Pending, neutral, or inactive states
|
|
143
|
+
- **warning**: Yellow/Orange - Warning or caution states
|
|
144
|
+
- **info**: Blue - Informational states
|
|
145
|
+
|
|
146
|
+
## Features
|
|
147
|
+
|
|
148
|
+
- **Visual Distribution**: Clear visual representation of status breakdown
|
|
149
|
+
- **Multiple Segments**: Support for multiple status types
|
|
150
|
+
- **Percentage-based**: Each segment sized by percentage
|
|
151
|
+
- **Color-coded**: Different colors for each status type
|
|
152
|
+
- **Disabled State**: Muted appearance when disabled
|
|
153
|
+
- **Responsive**: Adapts to container width
|
|
154
|
+
- **Smooth Rendering**: Clean segment transitions
|
|
155
|
+
|
|
156
|
+
## Best Practices
|
|
157
|
+
|
|
158
|
+
1. **Percentages Must Sum to 100**: Ensure all percentages add up to 100
|
|
159
|
+
2. **Use Appropriate Status Types**: Choose status colors that match meaning
|
|
160
|
+
3. **Provide Context**: Add labels or descriptions to explain what the bar represents
|
|
161
|
+
4. **Minimum Segment Size**: Very small percentages may be hard to see
|
|
162
|
+
5. **Consistent Colors**: Use status colors consistently across your app
|
|
163
|
+
|
|
164
|
+
## Use Cases
|
|
165
|
+
|
|
166
|
+
- **Task Progress**: Show completed vs. pending vs. failed tasks
|
|
167
|
+
- **Test Results**: Display pass/fail/skip test counts
|
|
168
|
+
- **Resource Allocation**: Visualize resource distribution
|
|
169
|
+
- **Status Distribution**: Show breakdown of item statuses
|
|
170
|
+
- **Health Metrics**: Display system health indicators
|
|
171
|
+
- **Quality Scores**: Visualize quality distribution
|
|
172
|
+
|
|
173
|
+
## Accessibility
|
|
174
|
+
|
|
175
|
+
- Decorative visual indicator
|
|
176
|
+
- Should be paired with text labels
|
|
177
|
+
- Consider providing ARIA labels for screen readers
|
|
178
|
+
- Disabled state visually distinguishable
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import StatusBar from './status-bar.vue'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Tela/StatusBar',
|
|
6
|
+
component: StatusBar,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: 'A status bar component that displays a visual representation of status distribution using colored segments. Each segment represents a percentage of the total with different status types (success, error, neutral, etc.). Useful for showing progress, status breakdowns, or distribution metrics.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
argTypes: {
|
|
16
|
+
items: {
|
|
17
|
+
control: 'object',
|
|
18
|
+
description: 'Array of status items. Each item should have a `status` (e.g., "success", "error", "neutral") and `percentage` (0-100) property. Percentages should sum to 100.',
|
|
19
|
+
},
|
|
20
|
+
disabled: {
|
|
21
|
+
control: 'boolean',
|
|
22
|
+
description: 'Disable the status bar, showing it in a muted/disabled state.',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
args: {
|
|
26
|
+
items: [
|
|
27
|
+
{ status: 'success', percentage: 33 },
|
|
28
|
+
{ status: 'error', percentage: 33 },
|
|
29
|
+
{ status: 'neutral', percentage: 34 },
|
|
30
|
+
],
|
|
31
|
+
disabled: false,
|
|
32
|
+
},
|
|
33
|
+
} satisfies Meta<typeof StatusBar>
|
|
34
|
+
|
|
35
|
+
export default meta
|
|
36
|
+
type Story = StoryObj<typeof StatusBar>
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
items: [
|
|
41
|
+
{ status: 'success', percentage: 33 },
|
|
42
|
+
{ status: 'error', percentage: 33 },
|
|
43
|
+
{ status: 'neutral', percentage: 34 },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const AllSuccess: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
items: [
|
|
51
|
+
{ status: 'success', percentage: 100 },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const Disabled: Story = {
|
|
57
|
+
args: {
|
|
58
|
+
items: [
|
|
59
|
+
{ status: 'success', percentage: 50 },
|
|
60
|
+
{ status: 'neutral', percentage: 50 },
|
|
61
|
+
],
|
|
62
|
+
disabled: true,
|
|
63
|
+
},
|
|
64
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BarItem } from './types'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
items: BarItem[]
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
function getBarItemClass(item: BarItem) {
|
|
10
|
+
if (item.status === 'success')
|
|
11
|
+
return 'bg-[#02C78C]'
|
|
12
|
+
if (item.status === 'error')
|
|
13
|
+
return 'bg-[#EC615D]'
|
|
14
|
+
if (item.status === 'neutral')
|
|
15
|
+
return 'bg-[#BBC4CD]'
|
|
16
|
+
}
|
|
17
|
+
const filteredItems = computed(() => props.items.filter(item => item.percentage > 0))
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div
|
|
22
|
+
flex
|
|
23
|
+
items-center
|
|
24
|
+
justify-center
|
|
25
|
+
w-80px
|
|
26
|
+
h-12px
|
|
27
|
+
gap-6px
|
|
28
|
+
p-4px
|
|
29
|
+
mt-4px
|
|
30
|
+
:class="disabled ? 'opacity-40' : 'opacity-100'"
|
|
31
|
+
>
|
|
32
|
+
<div
|
|
33
|
+
v-if="filteredItems.length === 0"
|
|
34
|
+
flex
|
|
35
|
+
items-center
|
|
36
|
+
justify-center
|
|
37
|
+
h-4px
|
|
38
|
+
rounded-3px
|
|
39
|
+
bg-gray-300
|
|
40
|
+
opacity-24
|
|
41
|
+
w-full
|
|
42
|
+
/>
|
|
43
|
+
<div
|
|
44
|
+
v-for="item in filteredItems"
|
|
45
|
+
v-else
|
|
46
|
+
:key="item.status"
|
|
47
|
+
flex
|
|
48
|
+
items-center
|
|
49
|
+
justify-center
|
|
50
|
+
h-4px
|
|
51
|
+
rounded-3px
|
|
52
|
+
:class="getBarItemClass(item)"
|
|
53
|
+
:style="{ width: `${item.percentage}%` }"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as SwitchStories from './switch.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={SwitchStories} />
|
|
5
|
+
|
|
6
|
+
# TelaSwitch
|
|
7
|
+
|
|
8
|
+
A toggle switch component for boolean values. Supports v-model binding, different sizes, and custom thumb content via slots. Useful for enabling/disabling features, toggling settings, and other binary choices.
|
|
9
|
+
|
|
10
|
+
## Examples
|
|
11
|
+
|
|
12
|
+
### All Sizes
|
|
13
|
+
|
|
14
|
+
<Canvas of={SwitchStories.Sizes} />
|
|
15
|
+
|
|
16
|
+
### With Icon
|
|
17
|
+
|
|
18
|
+
<Canvas of={SwitchStories.WithIcon} />
|
|
19
|
+
|
|
20
|
+
### Basic Usage
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<script setup>
|
|
24
|
+
import { ref } from 'vue'
|
|
25
|
+
|
|
26
|
+
const enabled = ref(false)
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<TelaSwitch v-model="enabled" />
|
|
31
|
+
</template>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### All Sizes Code
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<TelaSwitch size="sm" />
|
|
38
|
+
<TelaSwitch size="md" />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<script setup>
|
|
43
|
+
import { ref } from 'vue'
|
|
44
|
+
|
|
45
|
+
const isDarkMode = ref(false)
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<TelaSwitch v-model="isDarkMode">
|
|
50
|
+
<template #thumb>
|
|
51
|
+
<TelaIcon
|
|
52
|
+
v-if="isDarkMode"
|
|
53
|
+
name="i-ph-moon"
|
|
54
|
+
size="12px"
|
|
55
|
+
color="#aaa"
|
|
56
|
+
/>
|
|
57
|
+
<TelaIcon
|
|
58
|
+
v-else
|
|
59
|
+
name="i-ph-sun"
|
|
60
|
+
size="12px"
|
|
61
|
+
color="#aaa"
|
|
62
|
+
/>
|
|
63
|
+
</template>
|
|
64
|
+
</TelaSwitch>
|
|
65
|
+
</template>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Disabled State
|
|
69
|
+
|
|
70
|
+
```vue
|
|
71
|
+
<TelaSwitch disabled :model-value="true" />
|
|
72
|
+
<TelaSwitch disabled :model-value="false" />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Props
|
|
76
|
+
|
|
77
|
+
<ArgTypes />
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
type SwitchSize = 'sm' | 'md'
|
|
81
|
+
|
|
82
|
+
type SwitchProps = {
|
|
83
|
+
modelValue?: boolean
|
|
84
|
+
size?: SwitchSize
|
|
85
|
+
disabled?: boolean
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Slots
|
|
90
|
+
|
|
91
|
+
The Switch component supports:
|
|
92
|
+
|
|
93
|
+
- `thumb` - Custom content inside the switch thumb (e.g., icons)
|
|
94
|
+
|
|
95
|
+
## Features
|
|
96
|
+
|
|
97
|
+
- **Two-way Binding**: Full v-model support for reactive state
|
|
98
|
+
- **Multiple Sizes**: Small (32x20px) and medium (40x24px) options
|
|
99
|
+
- **Custom Thumb Content**: Use slots to add icons or other content to the thumb
|
|
100
|
+
- **Disabled State**: Proper disabled styling and interaction prevention
|
|
101
|
+
- **Smooth Animations**: Transitions for thumb movement and color changes
|
|
102
|
+
- **Accessible**: Built on reka-ui with proper ARIA attributes
|
|
103
|
+
- **Keyboard Support**: Can be toggled with keyboard (Space/Enter)
|
|
104
|
+
|
|
105
|
+
## Colors
|
|
106
|
+
|
|
107
|
+
- **Unchecked**: Gray background (#E5E7EB)
|
|
108
|
+
- **Checked**: Green background (#10B981)
|
|
109
|
+
- **Hover**: Slightly darker shades
|
|
110
|
+
- **Disabled**: Reduced opacity with cursor not-allowed
|
|
111
|
+
|
|
112
|
+
## Accessibility
|
|
113
|
+
|
|
114
|
+
- Built on reka-ui's SwitchRoot and SwitchThumb primitives
|
|
115
|
+
- Proper ARIA attributes for screen readers
|
|
116
|
+
- Keyboard navigation support
|
|
117
|
+
- Focus visible ring for keyboard users
|
|
118
|
+
- Disabled state properly conveyed
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import Switch from './switch.vue'
|
|
4
|
+
import TelaIcon from '../icon.vue'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Switch> = {
|
|
7
|
+
title: 'Core/Switch',
|
|
8
|
+
component: Switch,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
docs: {
|
|
12
|
+
description: {
|
|
13
|
+
component: 'A toggle switch component for boolean values. Supports v-model binding, different sizes, and custom thumb content via slots. Useful for enabling/disabling features, toggling settings, and other binary choices.',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
argTypes: {
|
|
18
|
+
modelValue: {
|
|
19
|
+
control: 'boolean',
|
|
20
|
+
description: 'The checked state of the switch (v-model). True when on, false when off.',
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
control: 'radio',
|
|
24
|
+
options: ['sm', 'md'],
|
|
25
|
+
description: 'Size of the switch. Controls the overall dimensions.',
|
|
26
|
+
},
|
|
27
|
+
disabled: {
|
|
28
|
+
control: 'boolean',
|
|
29
|
+
description: 'Disable the switch, preventing user interaction.',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default meta
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj<typeof meta>
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
render: () => ({
|
|
40
|
+
components: { Switch },
|
|
41
|
+
template: `<Switch />`,
|
|
42
|
+
}),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const Sizes: Story = {
|
|
46
|
+
render: args => ({
|
|
47
|
+
components: { Switch },
|
|
48
|
+
setup() {
|
|
49
|
+
return { args }
|
|
50
|
+
},
|
|
51
|
+
template: `
|
|
52
|
+
<div class="flex items-center gap-10px">
|
|
53
|
+
<Switch v-bind="args" />
|
|
54
|
+
<Switch v-bind="args" size="md" />
|
|
55
|
+
</div>
|
|
56
|
+
`,
|
|
57
|
+
}),
|
|
58
|
+
args: {
|
|
59
|
+
size: 'sm',
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const WithIcon: Story = {
|
|
64
|
+
render: args => ({
|
|
65
|
+
components: { Switch, TelaIcon },
|
|
66
|
+
setup() {
|
|
67
|
+
const isDarkMode = ref(false)
|
|
68
|
+
|
|
69
|
+
return { args, isDarkMode }
|
|
70
|
+
},
|
|
71
|
+
template: `
|
|
72
|
+
<Switch v-model="isDarkMode">
|
|
73
|
+
<template #thumb>
|
|
74
|
+
<TelaIcon v-if="isDarkMode" name="i-ph-moon" size="12px" color="#aaa" />
|
|
75
|
+
<TelaIcon v-else name="i-ph-sun" size="12px" color="#aaa" />
|
|
76
|
+
</template>
|
|
77
|
+
</Switch>
|
|
78
|
+
`,
|
|
79
|
+
}),
|
|
80
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
SwitchRoot,
|
|
7
|
+
SwitchThumb,
|
|
8
|
+
useForwardPropsEmits,
|
|
9
|
+
} from 'reka-ui'
|
|
10
|
+
import type { SwitchRootEmits, SwitchRootProps } from 'reka-ui'
|
|
11
|
+
|
|
12
|
+
import { cn } from '@/lib/utils'
|
|
13
|
+
|
|
14
|
+
type SwitchSize = 'sm' | 'md'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'], size?: SwitchSize }>()
|
|
17
|
+
|
|
18
|
+
const emits = defineEmits<SwitchRootEmits>()
|
|
19
|
+
|
|
20
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
21
|
+
|
|
22
|
+
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|
23
|
+
|
|
24
|
+
const resolvedSize = computed(() => props.size || 'sm')
|
|
25
|
+
|
|
26
|
+
const sizeStyle = computed(() => (({
|
|
27
|
+
sm: 'w-32px h-20px',
|
|
28
|
+
md: 'w-40px h-24px',
|
|
29
|
+
}) as Record<SwitchSize, string>)[resolvedSize.value] ?? '')
|
|
30
|
+
|
|
31
|
+
const thumbSizeStyle = computed(() => (({
|
|
32
|
+
sm: 'w-16px h-16px data-[state=checked]:translate-x-3',
|
|
33
|
+
md: 'w-20px h-20px data-[state=checked]:translate-x-4',
|
|
34
|
+
}) as Record<SwitchSize, string>)[resolvedSize.value] ?? '')
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<SwitchRoot
|
|
39
|
+
v-bind="forwarded"
|
|
40
|
+
:class="cn(
|
|
41
|
+
'peer inline-flex w-32px h-20px shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-600 disabled:cursor-not-allowed disabled:opacity-50',
|
|
42
|
+
'data-[state=unchecked]:bg-gray-300 data-[state=unchecked]:hover:bg-#ccd2d9 data-[state=checked]:bg-green-500 data-[state=checked]:hover:bg-green-600',
|
|
43
|
+
sizeStyle,
|
|
44
|
+
props.class,
|
|
45
|
+
)"
|
|
46
|
+
>
|
|
47
|
+
<SwitchThumb
|
|
48
|
+
:class="cn(
|
|
49
|
+
'flex items-center justify-center rounded-full bg-white-1000 ring-0 transition-[transform,colors] hover:bg-gray-100 data-[state=checked]:drop-shadow-md',
|
|
50
|
+
thumbSizeStyle,
|
|
51
|
+
)"
|
|
52
|
+
>
|
|
53
|
+
<slot name="thumb" />
|
|
54
|
+
</SwitchThumb>
|
|
55
|
+
</SwitchRoot>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<tbody :class="cn('[&_tr:last-child]:border-0', props.class)">
|
|
11
|
+
<slot />
|
|
12
|
+
</tbody>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<caption :class="cn('mt-4 text-sm text-muted-foreground', props.class)">
|
|
11
|
+
<slot />
|
|
12
|
+
</caption>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<td
|
|
11
|
+
:class="
|
|
12
|
+
cn(
|
|
13
|
+
'p-4 align-middle [&:has([role=checkbox])]:pr-0',
|
|
14
|
+
props.class,
|
|
15
|
+
)
|
|
16
|
+
"
|
|
17
|
+
>
|
|
18
|
+
<slot />
|
|
19
|
+
</td>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import TableCell from './table-cell.vue'
|
|
5
|
+
import TableRow from './table-row.vue'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
class?: HTMLAttributes['class']
|
|
9
|
+
colspan?: number
|
|
10
|
+
}>(), {
|
|
11
|
+
colspan: 1,
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const delegatedProps = computed(() => {
|
|
15
|
+
const { class: _, ...delegated } = props
|
|
16
|
+
|
|
17
|
+
return delegated
|
|
18
|
+
})
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<TableRow>
|
|
23
|
+
<TableCell
|
|
24
|
+
:class="
|
|
25
|
+
cn(
|
|
26
|
+
'p-4 whitespace-nowrap align-middle text-sm text-foreground',
|
|
27
|
+
props.class,
|
|
28
|
+
)
|
|
29
|
+
"
|
|
30
|
+
v-bind="delegatedProps"
|
|
31
|
+
>
|
|
32
|
+
<div class="flex items-center justify-center py-10">
|
|
33
|
+
<slot />
|
|
34
|
+
</div>
|
|
35
|
+
</TableCell>
|
|
36
|
+
</TableRow>
|
|
37
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<tfoot :class="cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)">
|
|
11
|
+
<slot />
|
|
12
|
+
</tfoot>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<th :class="cn('h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0', props.class)">
|
|
11
|
+
<slot />
|
|
12
|
+
</th>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class']
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<thead :class="cn('[&_tr]:border-b', props.class)">
|
|
11
|
+
<slot />
|
|
12
|
+
</thead>
|
|
13
|
+
</template>
|