@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,151 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as TagsStories from './tags.stories.ts';
3
+
4
+ <Meta of={TagsStories} />
5
+
6
+ # TelaTags
7
+
8
+ A tag component used for categorization or labeling. Helps identify or group items by topic, type, or property. Supports custom dot colors, count badges, and closeable functionality with smooth animations.
9
+
10
+ ## Examples
11
+
12
+ ### Default
13
+
14
+ <Canvas of={TagsStories.Default} />
15
+
16
+ ### With Count Badge
17
+
18
+ <Canvas of={TagsStories.WithCount} />
19
+
20
+ ### With Custom Dot Color
21
+
22
+ <Canvas of={TagsStories.WithCustomDotColor} />
23
+
24
+ ### Closeable Tags
25
+
26
+ <Canvas of={TagsStories.WithCloseable} />
27
+
28
+ ### Basic Usage
29
+
30
+ ```vue
31
+ <TelaTags dot-color="green">
32
+ Finances
33
+ </TelaTags>
34
+ ```
35
+
36
+ ### With Count Badge Code
37
+
38
+ ```vue
39
+ <TelaTags dot-color="purple" :count="5">
40
+ Technology
41
+ </TelaTags>
42
+ ```
43
+
44
+ ### Closeable Tags Code
45
+
46
+ ```vue
47
+ <script setup>
48
+ const isVisible = ref(true)
49
+ </script>
50
+
51
+ <template>
52
+ <TelaTags v-model="isVisible" dot-color="blue">
53
+ Health
54
+ </TelaTags>
55
+ </template>
56
+ ```
57
+
58
+ ### Multiple Tags with Different Colors
59
+
60
+ ```vue
61
+ <div class="flex gap-2">
62
+ <TelaTags dot-color="orange">Design</TelaTags>
63
+ <TelaTags dot-color="purple">Development</TelaTags>
64
+ <TelaTags dot-color="green">Marketing</TelaTags>
65
+ <TelaTags dot-color="red" :count="3">Urgent</TelaTags>
66
+ </div>
67
+ ```
68
+
69
+ ### Light Color Variant
70
+
71
+ ```vue
72
+ <TelaTags dot-color="blue" dot-light-color>
73
+ Light Blue
74
+ </TelaTags>
75
+ ```
76
+
77
+ ## Props
78
+
79
+ <ArgTypes />
80
+
81
+ ```typescript
82
+ type Color = 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'purple' | 'pink' | 'rose' | 'red' | 'neutral'
83
+
84
+ type TagsProps = {
85
+ class?: string
86
+ textClass?: string
87
+ dotColor?: Color
88
+ dotLightColor?: boolean
89
+ count?: number
90
+ modelValue?: boolean
91
+ }
92
+ ```
93
+
94
+ ## Slots
95
+
96
+ The Tags component supports one slot:
97
+
98
+ - `default` - Main tag content/text
99
+
100
+ ## Features
101
+
102
+ - **16 Color Options**: Support for orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, purple, pink, rose, red, and neutral colors
103
+ - **Light Color Variants**: Each color has a lighter variant (300 shade) available via `dotLightColor` prop
104
+ - **Count Badges**: Optional numerical badge display next to tag text
105
+ - **Closeable Functionality**: When `v-model` is used, the tag becomes closeable with smooth hover animations
106
+ - **Custom Styling**: Accepts custom classes for both the container and text content
107
+ - **Automatic Visibility Management**: Handles show/hide animations when closed
108
+
109
+ ## Color Options
110
+
111
+ The component supports 16 different colors for the dot indicator:
112
+
113
+ - **Warm**: orange, amber, yellow
114
+ - **Fresh**: lime, green, emerald
115
+ - **Cool**: teal, cyan, sky, blue
116
+ - **Deep**: indigo, purple
117
+ - **Vibrant**: pink, rose, red
118
+ - **Neutral**: neutral (gray)
119
+
120
+ Each color has both a standard (500 shade) and light (300 shade) variant.
121
+
122
+ ## Behavior
123
+
124
+ ### Non-Closeable Mode (Default)
125
+ When used without `v-model`, the tag is a static display element:
126
+ - Shows the dot indicator and text content
127
+ - Optionally displays a count badge
128
+ - No interaction or close functionality
129
+
130
+ ### Closeable Mode (with v-model)
131
+ When `v-model` is provided:
132
+ - Tag becomes interactive with hover effects
133
+ - Close icon (X) appears on hover with smooth animation
134
+ - Clicking the close icon hides the tag and updates the model value
135
+ - The tag remains hidden until the model value is set back to `true`
136
+
137
+ ## Styling
138
+
139
+ The tag uses a consistent design system:
140
+ - **Container**: Rounded corners (8px), subtle border, background color
141
+ - **Dot**: 8px circular indicator with customizable color
142
+ - **Text**: Medium weight, 14px font size, primary text color
143
+ - **Badge**: Filled variant with consistent spacing
144
+ - **Close Button**: Smooth scale and opacity animations on hover/exit
145
+
146
+ ## Accessibility
147
+
148
+ - Semantic HTML structure
149
+ - Proper button semantics for closeable tags
150
+ - Clear visual feedback on hover states
151
+ - Smooth animations for better UX
@@ -0,0 +1,118 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import { ref } from 'vue'
3
+ import Tags from './tags.vue'
4
+ import TelaButton from '../button/button.vue'
5
+
6
+ const meta: Meta<typeof Tags> = {
7
+ title: 'Core/Tags',
8
+ component: Tags,
9
+ parameters: {
10
+ layout: 'centered',
11
+ docs: {
12
+ description: {
13
+ component: 'Used for categorization or labeling. Helps identify or group items by topic, type, or property. Supports custom dot colors and count badges. When `v-model` is used, the tag becomes closeable with a hover animation.',
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ class: {
19
+ control: 'text',
20
+ description: 'Custom CSS classes for the tag container.',
21
+ },
22
+ textClass: {
23
+ control: 'text',
24
+ description: 'Custom CSS classes for the text content.',
25
+ },
26
+ dotColor: {
27
+ control: 'text',
28
+ description: 'Color class for the dot indicator (e.g., "green", "purple", "red", "neutral"). Uses UnoCSS color classes.',
29
+ },
30
+ dotLightColor: {
31
+ control: 'boolean',
32
+ description: 'Whether to use the light color variant for the dot indicator.',
33
+ },
34
+ count: {
35
+ control: 'number',
36
+ description: 'Optional count badge to display next to the tag text.',
37
+ },
38
+ modelValue: {
39
+ control: 'boolean',
40
+ description: 'Enables closeable functionality when set to `true`. Use `v-model` for two-way binding. When provided, the tag renders as a button and shows a close icon on hover.',
41
+ },
42
+ },
43
+ }
44
+
45
+ export default meta
46
+
47
+ type Story = StoryObj<typeof Tags>
48
+
49
+ export const Default: Story = {
50
+ render: () => ({
51
+ components: { Tags },
52
+ setup() {
53
+ return {}
54
+ },
55
+ template: `<Tags>Finances</Tags>`,
56
+ }),
57
+ }
58
+
59
+ export const WithCount: Story = {
60
+ args: {
61
+ count: 2,
62
+ },
63
+ render: () => ({
64
+ components: { Tags },
65
+ setup() {
66
+ return {}
67
+ },
68
+ template: `<Tags :count="2">Finances</Tags>`,
69
+ }),
70
+ }
71
+
72
+ export const WithCustomDotColor: Story = {
73
+ args: {
74
+ dotColor: 'purple',
75
+ count: 3,
76
+ },
77
+ render: () => ({
78
+ components: { Tags },
79
+ setup() {
80
+ return {}
81
+ },
82
+ template: `<Tags dot-color="purple" :count="3">Children</Tags>`,
83
+ }),
84
+ }
85
+
86
+ export const WithCloseable: Story = {
87
+ render: () => ({
88
+ components: { Tags, TelaButton },
89
+ setup() {
90
+ const isFirstTagVisible = ref(true)
91
+ const isSecondTagVisible = ref(true)
92
+ const isThirdTagVisible = ref(true)
93
+
94
+ function reset() {
95
+ isFirstTagVisible.value = true
96
+ isSecondTagVisible.value = true
97
+ isThirdTagVisible.value = true
98
+ }
99
+
100
+ return {
101
+ isFirstTagVisible,
102
+ isSecondTagVisible,
103
+ isThirdTagVisible,
104
+ reset,
105
+ }
106
+ },
107
+ template: `
108
+ <div flex="~ col" gap-12px>
109
+ <div flex="~" gap-6px w-300px>
110
+ <Tags v-model="isFirstTagVisible" dot-color="purple">Technology</Tags>
111
+ <Tags v-model="isSecondTagVisible" dot-color="red" :count="1">Finances</Tags>
112
+ <Tags v-model="isThirdTagVisible" dot-color="blue">Health</Tags>
113
+ </div>
114
+ <TelaButton size="sm" @click="reset" w-fit mx-auto>Reset</TelaButton>
115
+ </div>
116
+ `,
117
+ }),
118
+ }
@@ -0,0 +1,112 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+
4
+ type Color = 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'purple' | 'pink' | 'rose' | 'red' | 'neutral'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ class?: HTMLAttributes['class']
8
+ textClass?: HTMLAttributes['class']
9
+ dotColor?: Color
10
+ dotLightColor?: boolean
11
+ count?: number
12
+ modelValue?: boolean
13
+ }>(), {
14
+ dotColor: 'green',
15
+ dotLightColor: false,
16
+ modelValue: false,
17
+ })
18
+
19
+ const emit = defineEmits<{
20
+ 'update:modelValue': [value: boolean]
21
+ }>()
22
+
23
+ const isHovered = ref(false)
24
+ const isVisible = ref(true)
25
+
26
+ const hasModelValue = computed(() => props.modelValue)
27
+
28
+ function resolveColor(color: Color, lightColor = false) {
29
+ const colorMap: Record<Color, string> = {
30
+ orange: lightColor ? 'bg-orange-300' : 'bg-orange-500',
31
+ amber: lightColor ? 'bg-amber-300' : 'bg-amber-500',
32
+ yellow: lightColor ? 'bg-yellow-300' : 'bg-yellow-500',
33
+ lime: lightColor ? 'bg-lime-300' : 'bg-lime-500',
34
+ green: lightColor ? 'bg-green-300' : 'bg-green-500',
35
+ emerald: lightColor ? 'bg-emerald-300' : 'bg-emerald-500',
36
+ teal: lightColor ? 'bg-teal-300' : 'bg-teal-500',
37
+ cyan: lightColor ? 'bg-cyan-300' : 'bg-cyan-500',
38
+ sky: lightColor ? 'bg-sky-300' : 'bg-sky-500',
39
+ blue: lightColor ? 'bg-blue-300' : 'bg-blue-500',
40
+ indigo: lightColor ? 'bg-indigo-300' : 'bg-indigo-500',
41
+ purple: lightColor ? 'bg-purple-300' : 'bg-purple-500',
42
+ pink: lightColor ? 'bg-pink-300' : 'bg-pink-500',
43
+ rose: lightColor ? 'bg-rose-300' : 'bg-rose-500',
44
+ red: lightColor ? 'bg-red-300' : 'bg-red-500',
45
+ neutral: lightColor ? 'bg-neutral-300' : 'bg-neutral-500',
46
+ }
47
+
48
+ if (lightColor && !colorMap[color]) {
49
+ const colorWith300 = color.replace(/\d+$/, '300')
50
+ return `bg-${colorWith300}`
51
+ }
52
+
53
+ return colorMap[color] || `bg-${color}`
54
+ }
55
+
56
+ watch(() => props.modelValue, (newValue) => {
57
+ if (newValue) {
58
+ isVisible.value = true
59
+ }
60
+ })
61
+
62
+ function handleClose() {
63
+ if (!hasModelValue.value)
64
+ return
65
+
66
+ isVisible.value = false
67
+ isHovered.value = false
68
+
69
+ emit('update:modelValue', false)
70
+ }
71
+ </script>
72
+
73
+ <template>
74
+ <div
75
+ v-if="isVisible"
76
+ :class="cn(
77
+ 'inline-flex w-fit items-center pl-[8px] pr-[10px] py-[3px] bg-background border-[0.5px] border-border-strong rounded-[8px] select-none transition-all duration-150',
78
+ ((isHovered && hasModelValue) || count) && 'pr-[6px]',
79
+ props.class,
80
+ )"
81
+ @mouseenter="isHovered = true"
82
+ @mouseleave="isHovered = false"
83
+ >
84
+ <div class="relative z-[1] flex items-center gap-[6px] bg-[inherit]">
85
+ <div :class="cn('w-[8px] h-[8px] rounded-full', resolveColor(dotColor, dotLightColor))" />
86
+ <span :class="cn('body-14-medium text-text-primary', textClass)">
87
+ <slot />
88
+ </span>
89
+ </div>
90
+ <div class="flex items-center">
91
+ <TelaBadge v-if="count" variant="filled" class="relative z-[1] ml-[6px]">
92
+ {{ count }}
93
+ </TelaBadge>
94
+ <AnimatePresence v-if="hasModelValue">
95
+ <Motion
96
+ v-if="isHovered"
97
+ as="button"
98
+ class="ml-[4px]"
99
+ :initial="{ width: 0, x: -20, scale: 0, opacity: 0 }"
100
+ :animate="{ width: 'auto', x: 0, scale: 1, opacity: 1 }"
101
+ :exit="{ width: 0, x: -20, scale: 0, opacity: 0 }"
102
+ :transition="{ duration: 0.15, ease: 'easeOut' }"
103
+ @click="handleClose"
104
+ >
105
+ <div class="p-[2px] hover:bg-background-lowered rounded-[5px]">
106
+ <TelaIcon name="i-ph-x-bold" size="12px" color="text-secondary" />
107
+ </div>
108
+ </Motion>
109
+ </AnimatePresence>
110
+ </div>
111
+ </div>
112
+ </template>
@@ -0,0 +1,102 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as TextareaStories from './textarea.stories.ts';
3
+
4
+ <Meta of={TextareaStories} />
5
+
6
+ # TelaTextarea
7
+
8
+ A simple textarea component for multi-line text input. Supports v-model binding, default values, and can be styled with custom classes. Perfect for capturing longer text content like messages, descriptions, or comments.
9
+
10
+ ## Examples
11
+
12
+ ### Default
13
+
14
+ <Canvas of={TextareaStories.Default} />
15
+
16
+ ### With Default Value
17
+
18
+ <Canvas of={TextareaStories.WithDefaultValue} />
19
+
20
+ ### Basic Usage
21
+
22
+ ```vue
23
+ <script setup>
24
+ import { ref } from 'vue'
25
+
26
+ const message = ref('')
27
+ </script>
28
+
29
+ <template>
30
+ <TelaTextarea
31
+ v-model="message"
32
+ />
33
+ </template>
34
+ ```
35
+
36
+ ```vue
37
+ <TelaTextarea
38
+ default-value="This is the default content"
39
+ />
40
+ ```
41
+
42
+ ### Custom Styling
43
+
44
+ ```vue
45
+ <TelaTextarea
46
+ v-model="content"
47
+ class="h-200px border-blue-400"
48
+ />
49
+ ```
50
+
51
+ ### Multi-line Content
52
+
53
+ ```vue
54
+ <script setup>
55
+ import { ref } from 'vue'
56
+
57
+ const poem = ref(`In the quiet of the night,
58
+ Stars above shining bright,
59
+ Whispers of the moonlight,
60
+ Guide my dreams till morning light.`)
61
+ </script>
62
+
63
+ <template>
64
+ <TelaTextarea v-model="poem" />
65
+ </template>
66
+ ```
67
+
68
+ ## Props
69
+
70
+ <ArgTypes />
71
+
72
+ ```typescript
73
+ type TextareaProps = {
74
+ class?: string
75
+ defaultValue?: string | number
76
+ modelValue?: string | number
77
+ }
78
+ ```
79
+
80
+ ## Features
81
+
82
+ - **Two-way Binding**: Full v-model support using VueUse's useVModel
83
+ - **Default Value**: Set initial content without v-model
84
+ - **Resizable**: Non-resizable by default (resize-none), but can be overridden with classes
85
+ - **Custom Styling**: Accepts custom classes for flexible styling
86
+ - **Focus States**: Proper focus ring and border transitions
87
+ - **Disabled Support**: Standard HTML textarea disabled attribute
88
+
89
+ ## Default Styling
90
+
91
+ - **Height**: 128px (adjustable via classes)
92
+ - **Border**: 0.5px gray border with rounded corners (10px)
93
+ - **Font**: 16px size, -0.01em tracking, 24px line height
94
+ - **Colors**: White background, gray text, placeholder in gray-400
95
+ - **Focus**: Gray-400 border with gray-100 ring
96
+
97
+ ## Accessibility
98
+
99
+ - Standard textarea element with proper semantics
100
+ - Placeholder text for context
101
+ - Focus visible styles for keyboard navigation
102
+ - Disabled state support
@@ -0,0 +1,50 @@
1
+ import type { Meta, StoryObj } from '@storybook-vue/vue3'
2
+ import { fn } from '@storybook/test'
3
+ import Textarea from './textarea.vue'
4
+
5
+ const meta: Meta<typeof Textarea> = {
6
+ title: 'Core/Textarea',
7
+ component: Textarea,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A simple textarea component for multi-line text input. Supports v-model binding, default values, and can be styled with custom classes. Perfect for capturing longer text content like messages, descriptions, or comments.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ modelValue: {
18
+ control: 'text',
19
+ description: 'The v-model binding value. Supports two-way binding using VueUse\'s useVModel.',
20
+ },
21
+ defaultValue: {
22
+ control: 'text',
23
+ description: 'Initial content for the textarea. Used when v-model is not provided.',
24
+ },
25
+ class: {
26
+ control: 'text',
27
+ description: 'Additional CSS classes to apply to the textarea element. Can be used to customize height, border, colors, and other styles.',
28
+ },
29
+ },
30
+ args: {
31
+ 'onUpdate:modelValue': fn(),
32
+ },
33
+ }
34
+
35
+ export default meta
36
+
37
+ type Story = StoryObj<typeof meta>
38
+
39
+ export const Default: Story = {
40
+ render: () => ({
41
+ components: { Textarea },
42
+ template: '<Textarea />',
43
+ }),
44
+ }
45
+
46
+ export const WithDefaultValue: Story = {
47
+ args: {
48
+ defaultValue: 'This is the default content that appears when the textarea is first rendered.',
49
+ },
50
+ }
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ class?: HTMLAttributes['class']
6
+ defaultValue?: string | number
7
+ modelValue?: string | number
8
+ }>()
9
+
10
+ const emits = defineEmits<{
11
+ (e: 'update:modelValue', payload: string | number): void
12
+ }>()
13
+
14
+ const internalValue = ref(props.defaultValue ?? props.modelValue ?? '')
15
+
16
+ const currentValue = computed({
17
+ get: () => props.modelValue !== undefined ? props.modelValue : internalValue.value,
18
+ set: (value) => {
19
+ internalValue.value = value
20
+ emits('update:modelValue', value)
21
+ },
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <textarea
27
+ v-model="currentValue"
28
+ :class="cn(
29
+ 'flex h-128px resize-none w-full rounded-10px border-[0.5px] border-gray-300 bg-white-1000 px-5 py-4 text-16px tracking--0.01em leading-24px text-gray-900',
30
+ 'placeholder:text-gray-400 focus-visible:outline-none focus-within-b-gray-400 focus-within-ring-2 focus-within-ring-gray-100 disabled:cursor-not-allowed disabled:opacity-50',
31
+ props.class,
32
+ )"
33
+ />
34
+ </template>
@@ -0,0 +1,91 @@
1
+ <script setup lang="ts">
2
+ import { ToggleGroupItem, ToggleGroupRoot } from 'radix-vue'
3
+
4
+ const props = defineProps<{
5
+ modelValue: unknown
6
+ readOnly?: boolean
7
+ size?: 'sm' | 'md'
8
+ options: ({
9
+ label: string
10
+ value: unknown
11
+ icon?: string
12
+ } & Record<string, any>)[]
13
+ }>()
14
+
15
+ const emit = defineEmits(['update:modelValue'])
16
+
17
+ const currentValue = ref()
18
+ watch(() => props.modelValue, newValue => currentValue.value = String(newValue), { immediate: true })
19
+
20
+ const sizeStyles = computed(() => {
21
+ switch (props.size) {
22
+ case 'sm':
23
+ return 'text-11px py-3px px-8px'
24
+ case 'md':
25
+ default:
26
+ return 'text-11px leading-14px py-8px px-12px'
27
+ }
28
+ })
29
+
30
+ function onUpdateValue(newValue: string) {
31
+ if (props.readOnly)
32
+ return
33
+
34
+ if (newValue) {
35
+ currentValue.value = newValue
36
+ emit('update:modelValue', newValue)
37
+ }
38
+ }
39
+ </script>
40
+
41
+ <template>
42
+ <ToggleGroupRoot
43
+ :model-value="currentValue"
44
+ type="single"
45
+ rounded="8.5px"
46
+ flex-inline
47
+ font-semibold
48
+ h-30px
49
+ :class="[
50
+ readOnly && '!op-50',
51
+ ]"
52
+ class="bg-gray-300"
53
+ :disabled="readOnly"
54
+ @update:model-value="(val) => onUpdateValue(val as string)"
55
+ >
56
+ <ToggleGroupItem
57
+ v-for="option in options"
58
+ :key="String(option.value)"
59
+ :value="String(option.value)"
60
+ rounded="8.5px"
61
+ py-8px
62
+ px-12px
63
+ b-0.5px b-gray-300
64
+ flex
65
+ items-center
66
+ justify-center
67
+ body-12-medium
68
+ text-gray-700
69
+ grow
70
+ :class="[
71
+ sizeStyles,
72
+ currentValue === String(option.value) && 'bg-white subtle-shadow text-gray-800',
73
+ !readOnly && currentValue !== String(option.value) && 'hover:white-800 hover:text-gray-700 cursor-pointer',
74
+ readOnly && 'cursor-not-allowed',
75
+ ]"
76
+ class="group"
77
+ outline-gray-300
78
+ transition ease
79
+ >
80
+ <div v-if="$slots.option">
81
+ <slot name="option" :option="option" />
82
+ </div>
83
+ <div v-else flex gap-4px items-center justify-center>
84
+ <TelaIcon v-if="option.icon" :name="option.icon" size="sm" />
85
+ <span>
86
+ {{ option.label }}
87
+ </span>
88
+ </div>
89
+ </ToggleGroupItem>
90
+ </ToggleGroupRoot>
91
+ </template>