@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.
Files changed (295) hide show
  1. package/README.md +75 -0
  2. package/app.config.ts +73 -0
  3. package/components/tela/animated/animated-calculating-number.vue +16 -0
  4. package/components/tela/animated/animated-number.mdx +248 -0
  5. package/components/tela/animated/animated-number.stories.ts +52 -0
  6. package/components/tela/animated/animated-number.vue +23 -0
  7. package/components/tela/animated/animated-text.vue +124 -0
  8. package/components/tela/animated/animated-value.vue +68 -0
  9. package/components/tela/avatar/avatar.mdx +117 -0
  10. package/components/tela/avatar/avatar.stories.ts +62 -0
  11. package/components/tela/avatar/avatar.vue +71 -0
  12. package/components/tela/avatar/group/avatar-group.stories.ts +78 -0
  13. package/components/tela/avatar/group/avatar-group.vue +46 -0
  14. package/components/tela/badge/badge.mdx +154 -0
  15. package/components/tela/badge/badge.stories.ts +82 -0
  16. package/components/tela/badge/badge.vue +41 -0
  17. package/components/tela/button/button.mdx +155 -0
  18. package/components/tela/button/button.stories.ts +202 -0
  19. package/components/tela/button/button.vue +107 -0
  20. package/components/tela/card.vue +30 -0
  21. package/components/tela/chart/chart-bar.vue +58 -0
  22. package/components/tela/chat/chat.mdx +268 -0
  23. package/components/tela/chat/chat.stories.ts +253 -0
  24. package/components/tela/chat/command/index.vue +41 -0
  25. package/components/tela/chat/command/mention/index.vue +138 -0
  26. package/components/tela/chat/index.vue +112 -0
  27. package/components/tela/chat/pure-text-input/chat-text-input.vue +190 -0
  28. package/components/tela/chat/text-input/chat-text-input.stories.ts +128 -0
  29. package/components/tela/chat/text-input/index.vue +217 -0
  30. package/components/tela/chat/text-message/chat-text-message.stories.ts +138 -0
  31. package/components/tela/chat/text-message/index.vue +355 -0
  32. package/components/tela/chat/types.ts +19 -0
  33. package/components/tela/checkbox/checkbox-card.vue +30 -0
  34. package/components/tela/checkbox/checkbox.mdx +164 -0
  35. package/components/tela/checkbox/checkbox.stories.ts +104 -0
  36. package/components/tela/checkbox/checkbox.vue +43 -0
  37. package/components/tela/collapsible/Collapsible.vue +15 -0
  38. package/components/tela/collapsible/CollapsibleContent.vue +59 -0
  39. package/components/tela/collapsible/CollapsibleTrigger.vue +12 -0
  40. package/components/tela/collapsible/collapsible.mdx +157 -0
  41. package/components/tela/collapsible-section/collapsible-section.mdx +180 -0
  42. package/components/tela/collapsible-section/collapsible-section.stories.ts +53 -0
  43. package/components/tela/collapsible-section/collapsible-section.vue +51 -0
  44. package/components/tela/collapsible-section-with-actions.vue +98 -0
  45. package/components/tela/combobox/combobox-anchor.vue +24 -0
  46. package/components/tela/combobox/combobox-empty.vue +19 -0
  47. package/components/tela/combobox/combobox-group.vue +24 -0
  48. package/components/tela/combobox/combobox-indicator.vue +22 -0
  49. package/components/tela/combobox/combobox-input.vue +31 -0
  50. package/components/tela/combobox/combobox-item.vue +28 -0
  51. package/components/tela/combobox/combobox-label.vue +24 -0
  52. package/components/tela/combobox/combobox-list.vue +90 -0
  53. package/components/tela/combobox/combobox-module-selector.vue +366 -0
  54. package/components/tela/combobox/combobox-root.vue +15 -0
  55. package/components/tela/combobox/combobox-trigger.vue +12 -0
  56. package/components/tela/combobox/combobox.mdx +285 -0
  57. package/components/tela/combobox/combobox.stories.ts +232 -0
  58. package/components/tela/combobox/combobox.vue +497 -0
  59. package/components/tela/command/command-dialog.vue +22 -0
  60. package/components/tela/command/command-empty.vue +25 -0
  61. package/components/tela/command/command-group.vue +46 -0
  62. package/components/tela/command/command-input.vue +38 -0
  63. package/components/tela/command/command-item.vue +78 -0
  64. package/components/tela/command/command-list.vue +78 -0
  65. package/components/tela/command/command-separator.vue +23 -0
  66. package/components/tela/command/command-shortcut.vue +13 -0
  67. package/components/tela/command/command.vue +88 -0
  68. package/components/tela/command/dialog-base.vue +15 -0
  69. package/components/tela/command/dialog-content.vue +50 -0
  70. package/components/tela/command/utils.ts +15 -0
  71. package/components/tela/complex-table/complex-table-cell.stories.ts +145 -0
  72. package/components/tela/complex-table/complex-table-cell.vue +45 -0
  73. package/components/tela/complex-table/complex-table-header-cell.stories.ts +103 -0
  74. package/components/tela/complex-table/complex-table-header-cell.vue +48 -0
  75. package/components/tela/complex-table/complex-table-header.stories.ts +89 -0
  76. package/components/tela/complex-table/complex-table-header.vue +70 -0
  77. package/components/tela/complex-table/complex-table-row.vue +199 -0
  78. package/components/tela/complex-table/complex-table-virtualized.vue +326 -0
  79. package/components/tela/complex-table/complex-table.stories.ts +358 -0
  80. package/components/tela/complex-table/complex-table.vue +237 -0
  81. package/components/tela/complex-table/composables/table-common.ts +93 -0
  82. package/components/tela/complex-table/composables/table-selection.ts +87 -0
  83. package/components/tela/complex-table/composables/virtual-scroll.ts +252 -0
  84. package/components/tela/complex-table/styles/table-shared.css +170 -0
  85. package/components/tela/complex-table/types.ts +63 -0
  86. package/components/tela/complex-table/utils.ts +35 -0
  87. package/components/tela/confirm-button/confirm-button.vue +137 -0
  88. package/components/tela/confirmation-modal/confirmation-modal.vue +72 -0
  89. package/components/tela/copy-button.vue +86 -0
  90. package/components/tela/date-range-picker.vue +221 -0
  91. package/components/tela/dialog/dialog.mdx +170 -0
  92. package/components/tela/dialog/dialog.vue +182 -0
  93. package/components/tela/disabled-area.vue +16 -0
  94. package/components/tela/disclaimer/disclaimer.mdx +238 -0
  95. package/components/tela/disclaimer/disclaimer.stories.ts +196 -0
  96. package/components/tela/disclaimer/disclaimer.vue +125 -0
  97. package/components/tela/dropdown-menu/DropdownMenu.vue +121 -0
  98. package/components/tela/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
  99. package/components/tela/dropdown-menu/DropdownMenuContent.vue +75 -0
  100. package/components/tela/dropdown-menu/DropdownMenuGroup.vue +12 -0
  101. package/components/tela/dropdown-menu/DropdownMenuItem.vue +137 -0
  102. package/components/tela/dropdown-menu/DropdownMenuLabel.vue +26 -0
  103. package/components/tela/dropdown-menu/DropdownMenuRadioGroup.vue +18 -0
  104. package/components/tela/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
  105. package/components/tela/dropdown-menu/DropdownMenuRoot.vue +15 -0
  106. package/components/tela/dropdown-menu/DropdownMenuSeparator.vue +21 -0
  107. package/components/tela/dropdown-menu/DropdownMenuShortcut.vue +14 -0
  108. package/components/tela/dropdown-menu/DropdownMenuSub.vue +18 -0
  109. package/components/tela/dropdown-menu/DropdownMenuSubContent.vue +30 -0
  110. package/components/tela/dropdown-menu/DropdownMenuSubTrigger.vue +35 -0
  111. package/components/tela/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  112. package/components/tela/dropdown-menu/dropdown-menu.mdx +265 -0
  113. package/components/tela/dropdown-menu/dropdown-menu.stories.ts +156 -0
  114. package/components/tela/expandable-input.vue +96 -0
  115. package/components/tela/file-drop.vue +37 -0
  116. package/components/tela/file-upload/file-upload.mdx +189 -0
  117. package/components/tela/file-upload/file-upload.stories.ts +48 -0
  118. package/components/tela/file-upload/file-upload.vue +205 -0
  119. package/components/tela/filters/checkbox-filter.stories.ts +218 -0
  120. package/components/tela/filters/checkbox-filter.vue +165 -0
  121. package/components/tela/filters/date-filter.stories.ts +258 -0
  122. package/components/tela/filters/date-filter.vue +200 -0
  123. package/components/tela/filters/user-filter.stories.ts +344 -0
  124. package/components/tela/filters/user-filter.vue +271 -0
  125. package/components/tela/hover-card/hover-card.mdx +221 -0
  126. package/components/tela/hover-card/hover-card.stories.ts +87 -0
  127. package/components/tela/hover-card/hover-card.vue +61 -0
  128. package/components/tela/icon/custom.vue +319 -0
  129. package/components/tela/icon/spinner.vue +12 -0
  130. package/components/tela/icon-button/icon-button.vue +114 -0
  131. package/components/tela/icon.vue +37 -0
  132. package/components/tela/initials.vue +28 -0
  133. package/components/tela/inline-input.vue +77 -0
  134. package/components/tela/input/input.mdx +182 -0
  135. package/components/tela/input/input.stories.ts +153 -0
  136. package/components/tela/input/tela-input.vue +240 -0
  137. package/components/tela/kbd/kbd-return.vue +6 -0
  138. package/components/tela/kbd/kbd.mdx +238 -0
  139. package/components/tela/kbd/kbd.vue +18 -0
  140. package/components/tela/label/label.mdx +121 -0
  141. package/components/tela/label/label.stories.ts +37 -0
  142. package/components/tela/label/label.vue +25 -0
  143. package/components/tela/link-decoration/link-decoration.vue +19 -0
  144. package/components/tela/live-label.vue +32 -0
  145. package/components/tela/long-press-button.vue +98 -0
  146. package/components/tela/menubar/menubar-content.vue +77 -0
  147. package/components/tela/menubar/menubar-item.vue +32 -0
  148. package/components/tela/menubar/menubar-label.vue +14 -0
  149. package/components/tela/menubar/menubar-menu.vue +12 -0
  150. package/components/tela/menubar/menubar-root.vue +30 -0
  151. package/components/tela/menubar/menubar-separator.vue +17 -0
  152. package/components/tela/menubar/menubar-shortcut.vue +14 -0
  153. package/components/tela/menubar/menubar-sub-content.vue +36 -0
  154. package/components/tela/menubar/menubar-sub-trigger.vue +28 -0
  155. package/components/tela/menubar/menubar-sub.vue +20 -0
  156. package/components/tela/menubar/menubar-trigger.vue +27 -0
  157. package/components/tela/menubar/menubar.vue +298 -0
  158. package/components/tela/modal/modal.mdx +145 -0
  159. package/components/tela/modal/modal.vue +242 -0
  160. package/components/tela/multiple-select/multiple-select.mdx +274 -0
  161. package/components/tela/multiple-select/multiple-select.stories.ts +325 -0
  162. package/components/tela/multiple-select/multiple-select.vue +666 -0
  163. package/components/tela/pane.vue +110 -0
  164. package/components/tela/popover/popover-content.vue +48 -0
  165. package/components/tela/popover/popover-trigger.vue +12 -0
  166. package/components/tela/popover/popover.mdx +239 -0
  167. package/components/tela/popover/popover.stories.ts +150 -0
  168. package/components/tela/popover/popover.vue +15 -0
  169. package/components/tela/popover-list/popover-list-nested.vue +104 -0
  170. package/components/tela/popover-list/popover-list.stories.ts +330 -0
  171. package/components/tela/popover-list/popover-list.vue +191 -0
  172. package/components/tela/radio-button.vue +66 -0
  173. package/components/tela/radio-group/radio-group-item.vue +40 -0
  174. package/components/tela/radio-group/radio-group-root.vue +26 -0
  175. package/components/tela/radio-group/radio-group.mdx +78 -0
  176. package/components/tela/radio-group/radio-group.stories.ts +106 -0
  177. package/components/tela/radio-group/radio-group.vue +23 -0
  178. package/components/tela/range-calendar.stories.ts +110 -0
  179. package/components/tela/range-calendar.vue +109 -0
  180. package/components/tela/scroll-area/scroll-area.mdx +183 -0
  181. package/components/tela/scroll-area/scroll-area.vue +30 -0
  182. package/components/tela/scroll-area/scroll-bar.vue +31 -0
  183. package/components/tela/segment-toggle.stories.ts +114 -0
  184. package/components/tela/segment-toggle.vue +66 -0
  185. package/components/tela/select-menu/select-menu-content.vue +106 -0
  186. package/components/tela/select-menu/select-menu-down-button.vue +20 -0
  187. package/components/tela/select-menu/select-menu-group.vue +16 -0
  188. package/components/tela/select-menu/select-menu-item.vue +40 -0
  189. package/components/tela/select-menu/select-menu-root.vue +15 -0
  190. package/components/tela/select-menu/select-menu-trigger.vue +34 -0
  191. package/components/tela/select-menu/select-menu-up-button.vue +20 -0
  192. package/components/tela/select-menu/select-menu-value.vue +12 -0
  193. package/components/tela/select-menu/select-menu.mdx +221 -0
  194. package/components/tela/select-menu/select-menu.stories.ts +91 -0
  195. package/components/tela/select-menu/select-menu.vue +165 -0
  196. package/components/tela/selector/selector.vue +47 -0
  197. package/components/tela/sheet/sheet-close.vue +12 -0
  198. package/components/tela/sheet/sheet-content.vue +57 -0
  199. package/components/tela/sheet/sheet-description.vue +23 -0
  200. package/components/tela/sheet/sheet-footer.vue +18 -0
  201. package/components/tela/sheet/sheet-header.vue +15 -0
  202. package/components/tela/sheet/sheet-root.vue +18 -0
  203. package/components/tela/sheet/sheet-title.vue +23 -0
  204. package/components/tela/sheet/sheet-trigger.vue +12 -0
  205. package/components/tela/sheet/sheet.client.vue +150 -0
  206. package/components/tela/sheet/sheet.mdx +176 -0
  207. package/components/tela/sheet/sheet.stories.ts +201 -0
  208. package/components/tela/sheet/variants.ts +22 -0
  209. package/components/tela/side-sheet/side-sheet.mdx +131 -0
  210. package/components/tela/side-sheet/side-sheet.stories.ts +134 -0
  211. package/components/tela/side-sheet/side-sheet.vue +106 -0
  212. package/components/tela/skeleton/skeleton.mdx +165 -0
  213. package/components/tela/skeleton/skeleton.stories.ts +35 -0
  214. package/components/tela/skeleton/skeleton.vue +45 -0
  215. package/components/tela/skeleton-icon.vue +24 -0
  216. package/components/tela/span.vue +24 -0
  217. package/components/tela/star-button.vue +70 -0
  218. package/components/tela/status/status-lean.vue +30 -0
  219. package/components/tela/status/status.mdx +187 -0
  220. package/components/tela/status/status.stories.ts +160 -0
  221. package/components/tela/status/status.vue +420 -0
  222. package/components/tela/status-bar/status-bar.mdx +178 -0
  223. package/components/tela/status-bar/status-bar.stories.ts +64 -0
  224. package/components/tela/status-bar/status-bar.vue +56 -0
  225. package/components/tela/status-bar/types.ts +5 -0
  226. package/components/tela/switch/switch.mdx +118 -0
  227. package/components/tela/switch/switch.stories.ts +80 -0
  228. package/components/tela/switch/switch.vue +56 -0
  229. package/components/tela/table/table-body.vue +13 -0
  230. package/components/tela/table/table-caption.vue +13 -0
  231. package/components/tela/table/table-cell.vue +20 -0
  232. package/components/tela/table/table-empty.vue +37 -0
  233. package/components/tela/table/table-footer.vue +13 -0
  234. package/components/tela/table/table-head.vue +13 -0
  235. package/components/tela/table/table-header.vue +13 -0
  236. package/components/tela/table/table-row.vue +13 -0
  237. package/components/tela/table/table.mdx +230 -0
  238. package/components/tela/table/table.stories.ts +384 -0
  239. package/components/tela/table/table.vue +15 -0
  240. package/components/tela/tabs/tabs-content.vue +20 -0
  241. package/components/tela/tabs/tabs-indicator.vue +22 -0
  242. package/components/tela/tabs/tabs-list.vue +23 -0
  243. package/components/tela/tabs/tabs-root.vue +15 -0
  244. package/components/tela/tabs/tabs-trigger.vue +27 -0
  245. package/components/tela/tabs/tabs.mdx +138 -0
  246. package/components/tela/tabs/tabs.stories.ts +72 -0
  247. package/components/tela/tabs/tabs.vue +61 -0
  248. package/components/tela/tags/tags-select.mdx +318 -0
  249. package/components/tela/tags/tags-select.stories.ts +47 -0
  250. package/components/tela/tags/tags-select.vue +637 -0
  251. package/components/tela/tags/tags.mdx +151 -0
  252. package/components/tela/tags/tags.stories.ts +118 -0
  253. package/components/tela/tags/tags.vue +112 -0
  254. package/components/tela/textarea/textarea.mdx +102 -0
  255. package/components/tela/textarea/textarea.stories.ts +50 -0
  256. package/components/tela/textarea/textarea.vue +34 -0
  257. package/components/tela/toggle-group.vue +91 -0
  258. package/components/tela/tooltip/tooltip-content.vue +45 -0
  259. package/components/tela/tooltip/tooltip-provider.vue +12 -0
  260. package/components/tela/tooltip/tooltip-root.vue +15 -0
  261. package/components/tela/tooltip/tooltip-trigger.vue +12 -0
  262. package/components/tela/tooltip/tooltip.mdx +196 -0
  263. package/components/tela/tooltip/tooltip.stories.ts +200 -0
  264. package/components/tela/tooltip/tooltip.vue +91 -0
  265. package/components/tela/tooltip-group/tooltip-group-trigger.vue +92 -0
  266. package/components/tela/tooltip-group/tooltip-group.mdx +236 -0
  267. package/components/tela/tooltip-group/tooltip-group.stories.ts +465 -0
  268. package/components/tela/tooltip-group/tooltip-group.vue +35 -0
  269. package/components/tela/transparent-input.vue +151 -0
  270. package/components/tela/variable-icon.vue +28 -0
  271. package/components/tela/variable-input.vue +77 -0
  272. package/components/tela/wide-button/wide-button.vue +40 -0
  273. package/components.json +18 -0
  274. package/composables/status-toast.ts +67 -0
  275. package/css/reset.css +386 -0
  276. package/css/text.css +22 -0
  277. package/lib/doc-generator.ts +903 -0
  278. package/lib/extractors/volar-extract.ts +186 -0
  279. package/lib/type-resolver.ts +402 -0
  280. package/lib/utils.ts +6 -0
  281. package/modules/tela-build-docs/index.ts +139 -0
  282. package/nuxt.config.ts +80 -0
  283. package/package.json +84 -0
  284. package/plugins/test-id.ts +7 -0
  285. package/tsconfig.json +7 -0
  286. package/types/custom-icon.ts +1 -0
  287. package/types/index.ts +2 -0
  288. package/types/status.ts +1 -0
  289. package/unocss.config.ts +89 -0
  290. package/utils/component-utils.ts +30 -0
  291. package/utils/design-tokens.ts +431 -0
  292. package/utils/fold.ts +8 -0
  293. package/utils/select-menu.ts +10 -0
  294. package/utils/status.ts +1 -0
  295. 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,5 @@
1
+ export type BarStatus = 'neutral' | 'error' | 'success'
2
+ export type BarItem = {
3
+ status: BarStatus
4
+ percentage: number
5
+ }
@@ -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>