@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,23 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { reactiveOmit } from '@vueuse/core'
4
+ import { TabsList } from 'reka-ui'
5
+ import type { TabsListProps } from 'reka-ui'
6
+ import { cn } from '@/lib/utils'
7
+
8
+ const props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()
9
+
10
+ const delegatedProps = reactiveOmit(props, 'class')
11
+ </script>
12
+
13
+ <template>
14
+ <TabsList
15
+ v-bind="delegatedProps"
16
+ :class="cn(
17
+ 'relative inline-flex border-b-[0.5px] border-gray-200 items-center bg-white-1000 px-2 py-0.5',
18
+ props.class,
19
+ )"
20
+ >
21
+ <slot />
22
+ </TabsList>
23
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import type { TabsRootEmits, TabsRootProps } from 'reka-ui'
3
+ import { TabsRoot, useForwardPropsEmits } from 'reka-ui'
4
+
5
+ const props = defineProps<TabsRootProps>()
6
+ const emits = defineEmits<TabsRootEmits>()
7
+
8
+ const forwarded = useForwardPropsEmits(props, emits)
9
+ </script>
10
+
11
+ <template>
12
+ <TabsRoot v-bind="forwarded">
13
+ <slot />
14
+ </TabsRoot>
15
+ </template>
@@ -0,0 +1,27 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { reactiveOmit } from '@vueuse/core'
4
+ import { TabsTrigger, useForwardProps } from 'reka-ui'
5
+ import type { TabsTriggerProps } from 'reka-ui'
6
+ import { cn } from '@/lib/utils'
7
+
8
+ const props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()
9
+
10
+ const delegatedProps = reactiveOmit(props, 'class')
11
+
12
+ const forwardedProps = useForwardProps(delegatedProps)
13
+ </script>
14
+
15
+ <template>
16
+ <TabsTrigger
17
+ v-bind="forwardedProps"
18
+ :class="cn(
19
+ 'inline-flex cursor-pointer items-center justify-center whitespace-nowrap px-[6px] py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none text-gray-400 hover:text-black disabled:opacity-50 data-[state=active]:text-black data-[state=active]:shadow-sm',
20
+ props.class,
21
+ )"
22
+ >
23
+ <span class="truncate">
24
+ <slot />
25
+ </span>
26
+ </TabsTrigger>
27
+ </template>
@@ -0,0 +1,138 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as TabsStories from './tabs.stories.ts';
3
+
4
+ <Meta of={TabsStories} />
5
+
6
+ # TelaTabs
7
+
8
+ A tabs component that organizes content into separate panels accessible via tab buttons. Supports v-model binding for the selected tab and provides a content slot for displaying tab-specific content. Useful for organizing related content into distinct sections.
9
+
10
+ ## Examples
11
+
12
+ ### Basic Usage
13
+
14
+ ```vue
15
+ <script setup>
16
+ import { ref } from 'vue'
17
+
18
+ const selectedTab = ref('overview')
19
+
20
+ const tabs = [
21
+ { tab: 'overview', label: 'Overview' },
22
+ { tab: 'details', label: 'Details' },
23
+ { tab: 'settings', label: 'Settings' }
24
+ ]
25
+ </script>
26
+
27
+ <template>
28
+ <TelaTabs v-model="selectedTab" :options="tabs">
29
+ <template #content>
30
+ <div v-if="selectedTab === 'overview'">
31
+ <h3>Overview Content</h3>
32
+ <p>Overview information goes here</p>
33
+ </div>
34
+ <div v-else-if="selectedTab === 'details'">
35
+ <h3>Details Content</h3>
36
+ <p>Detailed information goes here</p>
37
+ </div>
38
+ <div v-else-if="selectedTab === 'settings'">
39
+ <h3>Settings Content</h3>
40
+ <p>Settings options go here</p>
41
+ </div>
42
+ </template>
43
+ </TelaTabs>
44
+ </template>
45
+ ```
46
+
47
+ ### With Default Value
48
+
49
+ ```vue
50
+ <TelaTabs
51
+ v-model="selectedTab"
52
+ :options="tabs"
53
+ default-value="details"
54
+ >
55
+ <template #content>
56
+ <!-- Tab content -->
57
+ </template>
58
+ </TelaTabs>
59
+ ```
60
+
61
+ ### Dynamic Tab Content
62
+
63
+ ```vue
64
+ <script setup>
65
+ import { ref, computed } from 'vue'
66
+
67
+ const selectedTab = ref('tab1')
68
+ const tabs = [
69
+ { tab: 'tab1', label: 'First Tab' },
70
+ { tab: 'tab2', label: 'Second Tab' },
71
+ { tab: 'tab3', label: 'Third Tab' }
72
+ ]
73
+
74
+ const content = computed(() => {
75
+ const contentMap = {
76
+ tab1: 'Content for first tab',
77
+ tab2: 'Content for second tab',
78
+ tab3: 'Content for third tab'
79
+ }
80
+ return contentMap[selectedTab.value]
81
+ })
82
+ </script>
83
+
84
+ <template>
85
+ <TelaTabs v-model="selectedTab" :options="tabs">
86
+ <template #content>
87
+ <div>{{ content }}</div>
88
+ </template>
89
+ </TelaTabs>
90
+ </template>
91
+ ```
92
+
93
+ ## Props
94
+
95
+ <ArgTypes />
96
+
97
+ ```typescript
98
+ type TabOption = {
99
+ tab: string // value
100
+ label: string // display text
101
+ }
102
+
103
+ type TabsProps = {
104
+ modelValue?: string
105
+ options: TabOption[]
106
+ defaultValue?: string
107
+ }
108
+ ```
109
+
110
+ ## Slots
111
+
112
+ - `content` - Tab panel content area
113
+
114
+ ## Components
115
+
116
+ The Tabs system consists of these reka-ui components:
117
+ - `TelaTabsRoot` - Root tabs container
118
+ - `TelaTabsList` - Container for tab triggers
119
+ - `TelaTabsTrigger` - Individual tab button
120
+ - `TelaTabsContent` - Tab panel content
121
+ - `TelaTabsIndicator` - Visual indicator for active tab
122
+
123
+ ## Features
124
+
125
+ - **Two-way Binding**: Full v-model support for selected tab
126
+ - **Default Value**: Set initial tab on mount
127
+ - **Keyboard Navigation**: Arrow keys to switch tabs, Enter/Space to activate
128
+ - **Accessible**: Built on reka-ui with proper ARIA attributes
129
+ - **Flexible Content**: Use slots for custom tab panel content
130
+ - **Visual Indicator**: Animated indicator shows active tab
131
+
132
+ ## Accessibility
133
+
134
+ - Built on reka-ui primitives
135
+ - Proper ARIA attributes (role="tablist", role="tab", role="tabpanel")
136
+ - Keyboard navigation (Arrow keys, Home, End, Space, Enter)
137
+ - Focus management between tabs
138
+ - Selected state properly conveyed to screen readers
@@ -0,0 +1,72 @@
1
+ import { ref } from 'vue'
2
+ import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import Tabs from './tabs.vue'
4
+
5
+ const meta: Meta<typeof Tabs> = {
6
+ title: 'Core/Tabs',
7
+ component: Tabs,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A tabs component that organizes content into separate panels accessible via tab buttons. Supports v-model binding for the selected tab and provides a content slot for displaying tab-specific content. Useful for organizing related content into distinct sections.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ modelValue: {
18
+ control: 'text',
19
+ description: 'The currently selected tab value (v-model).',
20
+ },
21
+ options: {
22
+ control: 'object',
23
+ description: 'Array of tab options. Each option should have a `tab` (value) and `label` (display text) property.',
24
+ },
25
+ defaultValue: {
26
+ control: 'text',
27
+ description: 'Default selected tab value when component first mounts.',
28
+ },
29
+ },
30
+ }
31
+
32
+ export default meta
33
+
34
+ type Story = StoryObj<typeof meta>
35
+
36
+ export const Default: Story = {
37
+ render: args => ({
38
+ components: { Tabs },
39
+ setup() {
40
+ const selectedTab = ref('tab1')
41
+ return { selectedTab, args }
42
+ },
43
+ template: `
44
+ <Tabs v-model="selectedTab" :options="args.options" :default-value="args.defaultValue">
45
+ <template #content>
46
+ <div min-w-250px>
47
+ <div v-if="selectedTab === 'tab1'" class="flex flex-col gap-2">
48
+ <h3 body-16-semibold>Tab 1 Content</h3>
49
+ <p body-14-regular>This is the content for Tab 1.</p>
50
+ </div>
51
+ <div v-else-if="selectedTab === 'tab2'" class="flex flex-col gap-2">
52
+ <h3 body-16-semibold>Tab 2 Content</h3>
53
+ <p body-14-regular>This is the content for Tab 2.</p>
54
+ </div>
55
+ <div v-else-if="selectedTab === 'tab3'" class="flex flex-col gap-2">
56
+ <h3 body-16-semibold>Tab 3 Content</h3>
57
+ <p body-14-regular>This is the content for Tab 3.</p>
58
+ </div>
59
+ </div>
60
+ </template>
61
+ </Tabs>
62
+ `,
63
+ }),
64
+ args: {
65
+ options: [
66
+ { tab: 'tab1', label: 'Tab 1' },
67
+ { tab: 'tab2', label: 'Tab 2' },
68
+ { tab: 'tab3', label: 'Tab 3' },
69
+ ],
70
+ defaultValue: 'tab1',
71
+ },
72
+ }
@@ -0,0 +1,61 @@
1
+ <script setup lang="ts">
2
+ import type { TabsRootProps } from 'reka-ui'
3
+ import type { HTMLAttributes } from 'vue'
4
+
5
+ import TelaTabsRoot from './tabs-root.vue'
6
+ import TelaTabsList from './tabs-list.vue'
7
+ import TelaTabsIndicator from './tabs-indicator.vue'
8
+ import TelaTabsTrigger from './tabs-trigger.vue'
9
+ import TelaTabsContent from './tabs-content.vue'
10
+
11
+ type Option = { tab: string, label: string }
12
+
13
+ interface Props extends TabsRootProps {
14
+ options: Option[]
15
+ defaultValue?: string
16
+ tabsListClass?: HTMLAttributes['class']
17
+ tabsTriggerClass?: HTMLAttributes['class']
18
+ tabsContentClass?: HTMLAttributes['class']
19
+ }
20
+
21
+ const props = defineProps<Props>()
22
+
23
+ const tabs = computed(() => {
24
+ if (!props.options || props.options.length === 0) {
25
+ return []
26
+ }
27
+ return props.options.map(option => option.tab)
28
+ })
29
+
30
+ const selectedTab = defineModel<string>({ required: true })
31
+ const defaultTab = computed(() => {
32
+ if (props.defaultValue) {
33
+ return props.defaultValue
34
+ }
35
+ if (props.options && props.options.length > 0) {
36
+ return props.options[0].tab
37
+ }
38
+ return ''
39
+ })
40
+
41
+ function getLabel(tab: string) {
42
+ if (!props.options) {
43
+ return ''
44
+ }
45
+ return props.options.find(option => option.tab === tab)?.label || ''
46
+ }
47
+ </script>
48
+
49
+ <template>
50
+ <TelaTabsRoot v-model="selectedTab" :default-value="defaultTab">
51
+ <TelaTabsList :class="cn('px-0 gap-3', tabsListClass)">
52
+ <TelaTabsIndicator />
53
+ <TelaTabsTrigger v-for="tab in tabs" :key="tab" :value="tab" :class="cn('px-0', tabsTriggerClass)">
54
+ {{ getLabel(tab) }}
55
+ </TelaTabsTrigger>
56
+ </TelaTabsList>
57
+ <TelaTabsContent :value="selectedTab" :class="cn('pt-4', tabsContentClass)">
58
+ <slot name="content" />
59
+ </TelaTabsContent>
60
+ </TelaTabsRoot>
61
+ </template>
@@ -0,0 +1,318 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as TagsSelectStories from './tags-select.stories.ts';
3
+
4
+ <Meta of={TagsSelectStories} />
5
+
6
+ # TelaTagsSelect
7
+
8
+ A comprehensive tag management component that combines selection, creation, and editing capabilities in a popover interface. Displays selected tags as overlapping colored dots (up to 3) with a mask effect, and provides a full-featured interface for managing tags with 16 color options.
9
+
10
+ ## Examples
11
+
12
+ ### Default
13
+
14
+ <Canvas of={TagsSelectStories.Default} />
15
+
16
+ ### Basic Usage
17
+
18
+ ```vue
19
+ <script setup>
20
+ const selectedTags = ref([
21
+ { id: '1', name: 'Design', color: 'purple' },
22
+ { id: '2', name: 'Development', color: 'blue' }
23
+ ])
24
+
25
+ const availableTags = ref([
26
+ { id: '1', name: 'Design', color: 'purple' },
27
+ { id: '2', name: 'Development', color: 'blue' },
28
+ { id: '3', name: 'Marketing', color: 'green' }
29
+ ])
30
+ </script>
31
+
32
+ <template>
33
+ <TelaTagsSelect
34
+ v-model="selectedTags"
35
+ :options="availableTags"
36
+ />
37
+ </template>
38
+ ```
39
+
40
+ ### With Custom Labels
41
+
42
+ ```vue
43
+ <TelaTagsSelect
44
+ v-model="selectedTags"
45
+ :options="availableTags"
46
+ create-tag-label="Nova tag"
47
+ selected-label="selecionadas"
48
+ new-tag-label="Nova tag"
49
+ edit-tag-label="Editar tag"
50
+ define-name-placeholder="Defina um nome"
51
+ add-new-name-placeholder="Adicionar novo nome"
52
+ create-button-label="Criar"
53
+ save-changes-button-label="Salvar alterações"
54
+ />
55
+ ```
56
+
57
+ ### Programmatic Tag Management
58
+
59
+ ```vue
60
+ <script setup>
61
+ const selectedTags = ref([])
62
+ const availableTags = ref([
63
+ { id: '1', name: 'Work', color: 'blue' },
64
+ { id: '2', name: 'Personal', color: 'green' },
65
+ { id: '3', name: 'Urgent', color: 'red' }
66
+ ])
67
+
68
+ function addTag(tag) {
69
+ selectedTags.value = [...selectedTags.value, tag]
70
+ }
71
+
72
+ function removeTag(tagId) {
73
+ selectedTags.value = selectedTags.value.filter(t => t.id !== tagId)
74
+ }
75
+
76
+ function clearAll() {
77
+ selectedTags.value = []
78
+ }
79
+ </script>
80
+
81
+ <template>
82
+ <div class="flex flex-col gap-4">
83
+ <TelaTagsSelect
84
+ v-model="selectedTags"
85
+ :options="availableTags"
86
+ />
87
+
88
+ <div class="flex gap-2">
89
+ <TelaButton size="sm" @click="clearAll">
90
+ Clear All
91
+ </TelaButton>
92
+ <TelaButton size="sm" variant="secondary" @click="addTag(availableTags[0])">
93
+ Select First
94
+ </TelaButton>
95
+ </div>
96
+ </div>
97
+ </template>
98
+ ```
99
+
100
+ ### Read-Only Display
101
+
102
+ ```vue
103
+ <script setup>
104
+ const tags = ref([
105
+ { id: '1', name: 'Completed', color: 'green' },
106
+ { id: '2', name: 'Reviewed', color: 'blue' },
107
+ { id: '3', name: 'Published', color: 'purple' }
108
+ ])
109
+ </script>
110
+
111
+ <template>
112
+ <TelaTagsSelect
113
+ :model-value="tags"
114
+ :options="tags"
115
+ />
116
+ </template>
117
+ ```
118
+
119
+ ## Props
120
+
121
+ <ArgTypes />
122
+
123
+ ```typescript
124
+ type Color = 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'purple' | 'pink' | 'rose' | 'red' | 'neutral'
125
+
126
+ interface Tag {
127
+ id: string
128
+ color: Color
129
+ name: string
130
+ isSelected?: boolean // Computed internally, don't include when passing tags
131
+ }
132
+
133
+ type TagsSelectProps = {
134
+ class?: string
135
+ labelClass?: string
136
+ modelValue?: Tag[]
137
+ options: Tag[]
138
+ createTagLabel?: string
139
+ selectedLabel?: string
140
+ newTagLabel?: string
141
+ editTagLabel?: string
142
+ defineNamePlaceholder?: string
143
+ addNewNamePlaceholder?: string
144
+ createButtonLabel?: string
145
+ saveChangesButtonLabel?: string
146
+ }
147
+ ```
148
+
149
+ ## Features
150
+
151
+ ### Tag Management Interface
152
+ - **Three Content Views**:
153
+ 1. **New Tag**: Create new tags with name and color selection
154
+ 2. **Existing Tags**: Browse, select, and manage existing tags
155
+ 3. **Edit Tag**: Modify tag name and color
156
+
157
+ ### Visual Feedback
158
+ - **Overlapping Dots**: Shows up to 3 tag colors with a mask effect
159
+ - **Dynamic Label**: Updates based on selection state
160
+ - "Create tag" when no tags exist
161
+ - "X tags" when tags exist but none selected
162
+ - "X selected" when tags are selected
163
+
164
+ ### Tag Creation
165
+ - Name input with enter key support
166
+ - 16 color options in an 8-column grid
167
+ - Real-time color preview
168
+ - Automatic selection upon creation
169
+ - "Create More" option to add multiple tags
170
+
171
+ ### Tag Selection
172
+ - Visual checkbox for each tag
173
+ - Colored dot indicator showing tag color
174
+ - Hover states with edit button
175
+ - Multi-select capability
176
+ - Apply button to confirm selections
177
+
178
+ ### Tag Editing
179
+ - Edit existing tag names
180
+ - Change tag colors
181
+ - Updates all instances of the tag
182
+ - Preserves selection state during edits
183
+ - Cancel option to discard changes
184
+
185
+ ### Animations & Transitions
186
+ - **Popover**: Smooth slide-down/fade-in animation (120ms)
187
+ - **Content Switching**: Slide transitions between views with spring physics
188
+ - **Height Animation**: Smooth height transitions when switching content
189
+ - **Spring Configuration**: Natural bounce-free animations (duration: 500ms)
190
+
191
+ ## Color Options
192
+
193
+ The component supports 16 different colors:
194
+
195
+ **Warm Colors:**
196
+ - orange, amber, yellow
197
+
198
+ **Fresh Colors:**
199
+ - lime, green, emerald
200
+
201
+ **Cool Colors:**
202
+ - teal, cyan, sky, blue
203
+
204
+ **Deep Colors:**
205
+ - indigo, purple
206
+
207
+ **Vibrant Colors:**
208
+ - pink, rose, red
209
+
210
+ **Neutral:**
211
+ - neutral (gray)
212
+
213
+ Each color is available in both standard (500 shade) and light (300 shade) variants.
214
+
215
+ ## Behavior
216
+
217
+ ### Tag Merging
218
+ The component intelligently merges `modelValue` and `options` to create a complete list of available tags:
219
+ - Uses tag `id` as the unique identifier
220
+ - Prevents duplicates automatically
221
+ - Maintains selection state across merges
222
+
223
+ ### Selection State
224
+ - Selection is tracked internally using tag IDs
225
+ - Changes are emitted via `update:modelValue` event
226
+ - Supports v-model for two-way binding
227
+ - Selection state persists during editing operations
228
+
229
+ ### Keyboard Support
230
+ - **Enter**: Create new tag or save edited tag
231
+ - Tab navigation through color options
232
+ - Escape to close popover (via Reka UI)
233
+
234
+ ### Dot Display Logic
235
+ 1. **With Selected Tags**: Shows first 3 selected tags' colors
236
+ 2. **With Available Tags**: Shows first 3 available tags' colors
237
+ 3. **No Tags**: Shows placeholder dots (2 neutral + 1 with plus icon)
238
+
239
+ ## Popover States
240
+
241
+ ### Trigger Button
242
+ - Displays overlapping colored dots
243
+ - Shows dynamic label text
244
+ - Hover and open states with background changes
245
+ - Smooth transitions (80ms ease-in-out)
246
+
247
+ ### Content Panel
248
+ - 220px width
249
+ - Shadow and border styling
250
+ - Smooth entry/exit animations
251
+ - Automatic positioning via Reka UI
252
+ - 8px offset from trigger
253
+
254
+ ## Styling
255
+
256
+ ### Dot Mask Effect
257
+ The overlapping dot effect is achieved using CSS mask:
258
+ ```css
259
+ .dot-mask:not(:last-child) {
260
+ mask-image: radial-gradient(circle 6px at right center, transparent 6px, #fff 6px);
261
+ }
262
+ ```
263
+
264
+ ### Animation Keyframes
265
+ - **slideDownAndFade**: Entry animation with scale and translate
266
+ - **slideUpAndFade**: Exit animation with scale and translate
267
+ - Transform origin set to popover content origin
268
+
269
+ ## Integration with Form Systems
270
+
271
+ The component works seamlessly with form libraries:
272
+
273
+ ```vue
274
+ <script setup>
275
+ import { useForm } from 'vee-validate'
276
+
277
+ const { values } = useForm({
278
+ initialValues: {
279
+ tags: []
280
+ }
281
+ })
282
+ </script>
283
+
284
+ <template>
285
+ <Field v-slot="{ value, handleChange }" name="tags">
286
+ <TelaTagsSelect
287
+ :model-value="value"
288
+ :options="availableTags"
289
+ @update:model-value="handleChange"
290
+ />
291
+ </Field>
292
+ </template>
293
+ ```
294
+
295
+ ## Accessibility
296
+
297
+ - Proper popover semantics via Reka UI
298
+ - Keyboard navigation support
299
+ - Focus management on open/close
300
+ - Clear visual feedback for interactive elements
301
+ - Semantic button and form elements
302
+ - Proper ARIA attributes from Reka UI
303
+
304
+ ## Performance Considerations
305
+
306
+ - Efficient tag merging with Set-based deduplication
307
+ - Computed properties for derived state
308
+ - Reactive refs for optimal reactivity
309
+ - Animation optimizations with GPU-accelerated transforms
310
+ - Lazy content rendering based on selected view
311
+
312
+ ## Best Practices
313
+
314
+ 1. **Always provide unique IDs**: Each tag must have a unique `id` property
315
+ 2. **Don't include `isSelected`**: This property is computed internally
316
+ 3. **Use v-model**: Prefer v-model over manual event handling
317
+ 4. **Provide options**: Always pass available tags via the `options` prop
318
+ 5. **Localize labels**: Use the label props for internationalization support