@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,117 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as AvatarStories from './avatar.stories.ts';
3
+
4
+ <Meta of={AvatarStories} />
5
+
6
+ # TelaAvatar
7
+
8
+ A flexible avatar component that displays user images with fallback support. Automatically falls back to initials when no image is provided or when image loading fails. Supports multiple sizes and includes skeleton loading state.
9
+
10
+ ## Examples
11
+
12
+ ### With Initials Fallback
13
+
14
+ <Canvas of={AvatarStories.Initials} />
15
+
16
+ ### Broken Image Fallback
17
+
18
+ <Canvas of={AvatarStories.Broken} />
19
+
20
+ ### Basic Usage
21
+
22
+ ```vue
23
+ <TelaAvatar
24
+ image="https://example.com/avatar.jpg"
25
+ alt="John Doe"
26
+ size="md"
27
+ />
28
+ ```
29
+
30
+ ### With Initials Fallback Code
31
+
32
+ ```vue
33
+ <TelaAvatar
34
+ alt="John Doe"
35
+ size="md"
36
+ />
37
+ ```
38
+
39
+ The component automatically generates initials from the `alt` text when no image is provided.
40
+
41
+ ### Different Sizes
42
+
43
+ ```vue
44
+ <TelaAvatar image="..." size="2xs" alt="User" />
45
+ <TelaAvatar image="..." size="xs" alt="User" />
46
+ <TelaAvatar image="..." size="sm" alt="User" />
47
+ <TelaAvatar image="..." size="md" alt="User" />
48
+ ```
49
+
50
+ ### Broken Image Fallback Code
51
+
52
+ When an image fails to load, the component shows a broken image icon.
53
+
54
+ ### Custom Styling
55
+
56
+ ```vue
57
+ <TelaAvatar
58
+ image="..."
59
+ alt="User"
60
+ class="ring-2 ring-blue-500"
61
+ />
62
+ ```
63
+
64
+ ### Avatar Group
65
+
66
+ ```vue
67
+ <div class="flex -space-x-2">
68
+ <TelaAvatar image="..." alt="User 1" size="sm" />
69
+ <TelaAvatar image="..." alt="User 2" size="sm" />
70
+ <TelaAvatar image="..." alt="User 3" size="sm" />
71
+ <TelaAvatar image="..." alt="User 4" size="sm" />
72
+ </div>
73
+ ```
74
+
75
+ ## Props
76
+
77
+ <ArgTypes />
78
+
79
+ ```typescript
80
+ type AvatarSize = '2xs' | 'xs' | 'sm' | 'md'
81
+
82
+ type AvatarProps = {
83
+ image?: string
84
+ size?: AvatarSize
85
+ alt?: string
86
+ class?: string
87
+ }
88
+ ```
89
+
90
+ ## Features
91
+
92
+ - **Image Support**: Display user profile pictures
93
+ - **Fallback Initials**: Automatically generated from alt text
94
+ - **Error Handling**: Shows icon when image fails to load
95
+ - **Multiple Sizes**: Four size options (2xs, xs, sm, md)
96
+ - **Skeleton Loading**: Shows skeleton while image loads
97
+ - **Custom Styling**: Accepts custom classes
98
+ - **Accessible**: Proper alt text for screen readers
99
+
100
+ ## Sizes
101
+
102
+ - **2xs**: Extra extra small (smallest size)
103
+ - **xs**: Extra small
104
+ - **sm**: Small
105
+ - **md**: Medium (default)
106
+
107
+ ## Components
108
+
109
+ The Avatar system works with:
110
+ - `TelaAvatarGroup` - Container for multiple avatars with overlap
111
+
112
+ ## Accessibility
113
+
114
+ - Alt text required for images
115
+ - Initials fallback maintains context
116
+ - Proper img semantics
117
+ - Screen reader friendly
@@ -0,0 +1,62 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+
3
+ import Avatar from './avatar.vue'
4
+
5
+ const meta: Meta<typeof Avatar> = {
6
+ title: 'Core/Avatar',
7
+ component: Avatar,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A flexible avatar component that displays user images with fallback support. Automatically falls back to initials when no image is provided or when image loading fails. Supports multiple sizes and includes skeleton loading state.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ image: {
18
+ control: 'text',
19
+ description: 'URL of the image to display. If not provided or loading fails, the component will show initials or a broken image icon.',
20
+ },
21
+ size: {
22
+ control: 'select',
23
+ options: ['2xs', 'xs', 'sm', 'md'],
24
+ description: 'Size of the avatar. Controls width and height dimensions.',
25
+ },
26
+ alt: {
27
+ control: 'text',
28
+ description: 'Alternative text for the image. Used for accessibility and as fallback text for initials when image is not available.',
29
+ },
30
+ class: {
31
+ control: 'text',
32
+ description: 'Custom CSS classes to apply to the avatar container.',
33
+ },
34
+ },
35
+ }
36
+
37
+ export default meta
38
+
39
+ type Story = StoryObj<typeof meta>
40
+
41
+ export const Default: Story = {
42
+ args: {
43
+ image: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=150&h=150&fit=crop&crop=faces',
44
+ size: 'md',
45
+ alt: 'Avatar',
46
+ },
47
+ }
48
+
49
+ export const Initials: Story = {
50
+ args: {
51
+ ...Default.args,
52
+ image: undefined,
53
+ alt: 'John Doe',
54
+ },
55
+ }
56
+
57
+ export const Broken: Story = {
58
+ args: {
59
+ ...Default.args,
60
+ image: 'broken-url',
61
+ },
62
+ }
@@ -0,0 +1,71 @@
1
+ <script setup lang=ts>
2
+ export type AvatarSize = '2xs' | 'xs' | 'sm' | 'md'
3
+
4
+ const props = defineProps<{
5
+ image?: string
6
+ size?: AvatarSize
7
+ alt?: string
8
+ class?: string
9
+ }>()
10
+
11
+ const errorLoadingImage = ref(false)
12
+ const sizes = {
13
+ '2xs': {
14
+ width: 16,
15
+ height: 16,
16
+ },
17
+ 'xs': {
18
+ width: 24,
19
+ height: 24,
20
+ },
21
+ 'sm': {
22
+ width: 32,
23
+ height: 32,
24
+ },
25
+ 'md': {
26
+ width: 40,
27
+ height: 40,
28
+ },
29
+ 'default': {
30
+ width: 40,
31
+ height: 40,
32
+ },
33
+ }
34
+ const resolvedSize = computed(() => props.size ?? 'default')
35
+ const style = computed(() => ({
36
+ width: `${sizes[resolvedSize.value].width}px`,
37
+ height: `${sizes[resolvedSize.value].height}px`,
38
+ }))
39
+ watch(() => props.image, () => {
40
+ errorLoadingImage.value = false
41
+ })
42
+ </script>
43
+
44
+ <template>
45
+ <div
46
+ class="rounded-6px" :class="props.class"
47
+ bg-cover
48
+ bg-center
49
+ overflow-hidden
50
+ flex items-center justify-center
51
+ :style="style"
52
+ >
53
+ <ClientOnly v-if="image && !errorLoadingImage">
54
+ <img
55
+ :alt="alt"
56
+ :src="image"
57
+ :width="sizes[resolvedSize].width"
58
+ :height="sizes[resolvedSize].height"
59
+ loading="lazy"
60
+ rounded-6px object-cover
61
+ :style="style"
62
+ @error="() => errorLoadingImage = true"
63
+ >
64
+ <template #fallback>
65
+ <TelaSkeleton :style="style" />
66
+ </template>
67
+ </ClientOnly>
68
+ <TelaIcon v-else-if="errorLoadingImage" name="i-ph-image-broken" text="black/560" size="lg" />
69
+ <TelaInitials v-else-if="alt" :size="size" :word="alt" />
70
+ </div>
71
+ </template>
@@ -0,0 +1,78 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import TelaAvatarGroup from './avatar-group.vue'
3
+
4
+ const meta = {
5
+ title: 'Core/AvatarGroup',
6
+ component: TelaAvatarGroup,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'An avatar group component that displays multiple avatars in a stacked or overlapping layout. Supports maximum display limits with "+X more" indicator, different sizes per avatar, and custom styling. Useful for showing teams, collaborators, or groups of users.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ images: {
18
+ control: 'object',
19
+ description: 'Array of avatar objects. Each object should have `image` (URL), `alt` (text), and optionally `size` ("2xs", "xs", "sm", "md") properties.',
20
+ },
21
+ max: {
22
+ control: 'number',
23
+ description: 'Maximum number of avatars to display before showing "+X more" indicator.',
24
+ },
25
+ othersSize: {
26
+ control: 'select',
27
+ options: ['2xs', 'xs', 'sm', 'md'],
28
+ description: 'Size of the "+X more" indicator avatar.',
29
+ },
30
+ },
31
+ args: {
32
+ images: [
33
+ { image: 'https://i.pravatar.cc/150?img=1', alt: 'User 1' },
34
+ { image: 'https://i.pravatar.cc/150?img=2', alt: 'User 2' },
35
+ { image: 'https://i.pravatar.cc/150?img=3', alt: 'User 3' },
36
+ { image: 'https://i.pravatar.cc/150?img=4', alt: 'User 4' },
37
+ { image: 'https://i.pravatar.cc/150?img=5', alt: 'User 5' },
38
+ ],
39
+ },
40
+ } satisfies Meta<typeof TelaAvatarGroup>
41
+
42
+ export default meta
43
+ type Story = StoryObj<typeof meta>
44
+
45
+ export const Default: Story = {
46
+ args: {},
47
+ }
48
+
49
+ export const WithMaxLimit: Story = {
50
+ args: {
51
+ max: 3,
52
+ },
53
+ }
54
+
55
+ export const DifferentSizes: Story = {
56
+ args: {
57
+ images: [
58
+ { image: 'https://i.pravatar.cc/150?img=1', alt: 'User 1', size: '2xs' },
59
+ { image: 'https://i.pravatar.cc/150?img=2', alt: 'User 2', size: 'xs' },
60
+ { image: 'https://i.pravatar.cc/150?img=3', alt: 'User 3', size: 'sm' },
61
+ { image: 'https://i.pravatar.cc/150?img=4', alt: 'User 4', size: 'md' },
62
+ ],
63
+ },
64
+ }
65
+
66
+ export const WithCustomOthersSize: Story = {
67
+ args: {
68
+ max: 3,
69
+ othersSize: 'xs',
70
+ images: [
71
+ { image: 'https://i.pravatar.cc/150?img=1', alt: 'User 1' },
72
+ { image: 'https://i.pravatar.cc/150?img=2', alt: 'User 2' },
73
+ { image: 'https://i.pravatar.cc/150?img=3', alt: 'User 3' },
74
+ { image: 'https://i.pravatar.cc/150?img=4', alt: 'User 4' },
75
+ { image: 'https://i.pravatar.cc/150?img=5', alt: 'User 5' },
76
+ ],
77
+ },
78
+ }
@@ -0,0 +1,46 @@
1
+ <script setup lang=ts>
2
+ export type AvatarSize = '2xs' | 'xs' | 'sm' | 'md'
3
+
4
+ const props = defineProps<{
5
+ images: {
6
+ image?: string
7
+ alt: string
8
+ size?: AvatarSize
9
+ }[]
10
+ max?: number
11
+ othersSize?: AvatarSize
12
+ }>()
13
+
14
+ const resolvedMax = computed(() => props.max ?? props.images.length)
15
+ const visibleImages = computed(() => props.images.slice(0, resolvedMax.value))
16
+ const remainingImages = computed(() => props.images.length - visibleImages.value.length)
17
+ </script>
18
+
19
+ <template>
20
+ <div flex items-center>
21
+ <div relative flex>
22
+ <TelaAvatar
23
+ v-for="(image, index) in visibleImages"
24
+ :key="image.image"
25
+ :image="image.image"
26
+ :alt="image.alt"
27
+ :size="image.size ?? othersSize ?? 'md'"
28
+ rounded-full
29
+ :style="{ marginLeft: index > 0 ? '-8px' : '0', boxShadow: '0 0 0 3px white' }"
30
+ />
31
+ <div
32
+ v-if="remainingImages > 0"
33
+ body-12-regular
34
+ text-gray-600
35
+ :style="{ marginLeft: '-8px' }"
36
+ >
37
+ <TelaAvatar
38
+ :alt="`${remainingImages}`"
39
+ :size="othersSize ?? 'md'"
40
+ rounded-full
41
+ :style="{ boxShadow: '0 0 0 3px white' }"
42
+ />
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </template>
@@ -0,0 +1,154 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as BadgeStories from './badge.stories.ts';
3
+
4
+ <Meta of={BadgeStories} />
5
+
6
+ # TelaBadge
7
+
8
+ A versatile badge component for displaying small pieces of information, counts, or status indicators. Supports outline and filled variants, icons, and can function as a link.
9
+
10
+ ## Examples
11
+
12
+ ### Outline Variant (Default)
13
+
14
+ <Canvas of={BadgeStories.Outline} />
15
+
16
+ ### Filled Variant
17
+
18
+ <Canvas of={BadgeStories.Filled} />
19
+
20
+ ### With Icon
21
+
22
+ <Canvas of={BadgeStories.WithIcon} />
23
+
24
+ ### Basic Usage
25
+
26
+ ```vue
27
+ <TelaBadge>Badge Label</TelaBadge>
28
+ ```
29
+
30
+ ### Outline Variant Code
31
+
32
+ ```vue
33
+ <TelaBadge variant="outline">Outline Badge</TelaBadge>
34
+ ```
35
+
36
+ ### Filled Variant Code
37
+
38
+ ```vue
39
+ <TelaBadge variant="filled">Filled Badge</TelaBadge>
40
+ ```
41
+
42
+ ### With Icon Code
43
+
44
+ ```vue
45
+ <TelaBadge icon="i-ph-star">Featured</TelaBadge>
46
+ <TelaBadge icon="i-ph-check">Verified</TelaBadge>
47
+ <TelaBadge icon="i-ph-warning">Warning</TelaBadge>
48
+ ```
49
+
50
+ ### As Link
51
+
52
+ ```vue
53
+ <TelaBadge to="/profile">View Profile</TelaBadge>
54
+ <TelaBadge to="https://example.com" target="_blank">
55
+ External Link
56
+ </TelaBadge>
57
+ ```
58
+
59
+ ### Custom Styling
60
+
61
+ ```vue
62
+ <TelaBadge
63
+ container-class="bg-blue-100 border-blue-300"
64
+ text-class="text-blue-700 font-bold"
65
+ >
66
+ Custom Badge
67
+ </TelaBadge>
68
+ ```
69
+
70
+ ### Status Badges
71
+
72
+ ```vue
73
+ <TelaBadge variant="filled" container-class="bg-green-100" text-class="text-green-700">
74
+ Active
75
+ </TelaBadge>
76
+ <TelaBadge variant="filled" container-class="bg-yellow-100" text-class="text-yellow-700">
77
+ Pending
78
+ </TelaBadge>
79
+ <TelaBadge variant="filled" container-class="bg-red-100" text-class="text-red-700">
80
+ Inactive
81
+ </TelaBadge>
82
+ ```
83
+
84
+ ### Count Badges
85
+
86
+ ```vue
87
+ <TelaBadge variant="filled">2</TelaBadge>
88
+ <TelaBadge variant="filled">99+</TelaBadge>
89
+ ```
90
+
91
+ ### With Button
92
+
93
+ ```vue
94
+ <TelaButton>
95
+ Messages
96
+ <TelaBadge variant="filled" container-class="ml-2">5</TelaBadge>
97
+ </TelaButton>
98
+ ```
99
+
100
+ ## Props
101
+
102
+ <ArgTypes />
103
+
104
+ ```typescript
105
+ type BadgeVariant = 'outline' | 'filled'
106
+
107
+ type BadgeProps = {
108
+ variant?: BadgeVariant
109
+ containerClass?: string
110
+ textClass?: string
111
+ icon?: string
112
+ to?: string
113
+ }
114
+ ```
115
+
116
+ ## Features
117
+
118
+ - **Two Variants**: Outline and filled styles
119
+ - **Icon Support**: Add icons before text
120
+ - **Link Functionality**: Works as a link when `to` is provided
121
+ - **Custom Styling**: Full control over container and text styles
122
+ - **Flexible Content**: Display text, numbers, or combinations
123
+ - **Compact Size**: Small footprint for tight spaces
124
+ - **Inline Display**: Works well inline with text or buttons
125
+
126
+ ## Variants
127
+
128
+ ### Outline
129
+
130
+ - Transparent background
131
+ - Visible border
132
+ - Default variant
133
+
134
+ ### Filled
135
+
136
+ - Colored background
137
+ - No border
138
+ - Higher emphasis
139
+
140
+ ## Use Cases
141
+
142
+ - **Status Indicators**: Show active/inactive states
143
+ - **Counts**: Display notification or item counts
144
+ - **Labels**: Tag items with categories or types
145
+ - **Feature Flags**: Mark new or beta features
146
+ - **Inline Links**: Create small clickable links
147
+ - **Pills**: Create pill-shaped UI elements
148
+
149
+ ## Accessibility
150
+
151
+ - Semantic markup
152
+ - Link badges have proper anchor behavior
153
+ - Icon badges maintain text content for context
154
+ - Custom classes allow ARIA attributes
@@ -0,0 +1,82 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import Badge from './badge.vue'
3
+
4
+ const meta: Meta<typeof Badge> = {
5
+ title: 'Core/Badge',
6
+ component: Badge,
7
+ parameters: {
8
+ layout: 'centered',
9
+ docs: {
10
+ description: {
11
+ component: 'A versatile button component with multiple variants, sizes, and states. Supports icons, and can function as a link when provided with a `to` prop. Built for consistent UI interactions across the application.',
12
+ },
13
+ },
14
+ },
15
+ argTypes: {
16
+ variant: {
17
+ control: 'select',
18
+ options: ['outline', 'filled'],
19
+ description: 'Variant of the badge. Outline is the default style, filled is a filled background.',
20
+ },
21
+ class: {
22
+ control: 'text',
23
+ description: 'Custom CSS classes to apply to the badge container.',
24
+ },
25
+ textClass: {
26
+ control: 'text',
27
+ description: 'Custom CSS classes to apply to the badge text.',
28
+ },
29
+ icon: {
30
+ control: 'text',
31
+ description: 'Icon class or name to display in the badge. Use icon names like "i-ph-plus" or similar iconify classes.',
32
+ },
33
+ to: {
34
+ control: 'boolean',
35
+ description: 'Link to navigate to when the badge is clicked.',
36
+ },
37
+ },
38
+ }
39
+
40
+ export default meta
41
+
42
+ type Story = StoryObj<typeof Badge>
43
+
44
+ export const Default: Story = {
45
+ render: args => ({
46
+ components: { Badge },
47
+ setup() {
48
+ return { args }
49
+ },
50
+ template: `<Badge v-bind="args">Badge Label</Badge>`,
51
+ }),
52
+ }
53
+
54
+ export const Outline: Story = {
55
+ render: args => ({
56
+ components: { Badge },
57
+ setup() {
58
+ return { args }
59
+ },
60
+ template: `<Badge v-bind="args" variant="outline">Badge Label</Badge>`,
61
+ }),
62
+ }
63
+
64
+ export const Filled: Story = {
65
+ render: args => ({
66
+ components: { Badge },
67
+ setup() {
68
+ return { args }
69
+ },
70
+ template: `<Badge v-bind="args" variant="filled">2</Badge>`,
71
+ }),
72
+ }
73
+
74
+ export const WithIcon: Story = {
75
+ render: args => ({
76
+ components: { Badge },
77
+ setup() {
78
+ return { args }
79
+ },
80
+ template: `<Badge v-bind="args" icon="i-ph-eye-slash-bold">Badge Label</Badge>`,
81
+ }),
82
+ }
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import { NuxtLink } from '#components'
3
+ import type { HTMLAttributes } from 'vue'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ class?: HTMLAttributes['class']
7
+ textClass?: HTMLAttributes['class']
8
+ variant?: 'outline' | 'filled'
9
+ icon?: string
10
+ to?: boolean
11
+ }>(), {
12
+ variant: 'outline',
13
+ to: false,
14
+ })
15
+
16
+ const tag = computed(() => props.to ? NuxtLink : 'div')
17
+ </script>
18
+
19
+ <template>
20
+ <component
21
+ :is="tag"
22
+ :class="cn(
23
+ 'inline-block px-[5px] rounded-[5px] select-none',
24
+ variant === 'outline' && 'border-[0.5px] ring-border-strong',
25
+ variant === 'filled' && 'bg-background-lowered',
26
+ props.class,
27
+ )"
28
+ >
29
+ <span
30
+ :class="cn(
31
+ 'flex items-center gap-[4px] text-[9px] whitespace-nowrap font-580 leading-[16px] tracking-[0.04rem] uppercase',
32
+ variant === 'outline' && 'text-tertiary',
33
+ variant === 'filled' && 'text-secondary tracking-normal',
34
+ textClass,
35
+ )"
36
+ >
37
+ <TelaIcon v-if="icon" :name="icon" size="10px" />
38
+ <slot />
39
+ </span>
40
+ </component>
41
+ </template>