@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,268 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as ChatStories from './chat.stories.ts';
3
+
4
+ <Meta of={ChatStories} />
5
+
6
+ # TelaChat
7
+
8
+ A chat component that displays threaded messages with replies, avatars, timestamps, and user information. Supports nested replies, mentions, message threading, and user identification. Useful for chat interfaces, comment systems, and collaborative communication features.
9
+
10
+ ## Examples
11
+
12
+ ### Empty State
13
+
14
+ <Canvas of={ChatStories.Empty} />
15
+
16
+ ### Nested Replies
17
+
18
+ <Canvas of={ChatStories.NestedReplies} />
19
+
20
+ ### With Mentions
21
+
22
+ <Canvas of={ChatStories.NestedRepliesWithMentions} />
23
+
24
+ ### Long Thread
25
+
26
+ <Canvas of={ChatStories.LongThread} />
27
+
28
+ ### Basic Usage
29
+
30
+ ```vue
31
+ <script setup>
32
+ import { ref } from 'vue'
33
+
34
+ const messages = ref([
35
+ {
36
+ id: '1',
37
+ content: 'Hello! How can I help you?',
38
+ timestamp: new Date(),
39
+ author: 'Support',
40
+ authorEmail: 'support@example.com'
41
+ }
42
+ ])
43
+
44
+ const currentUser = {
45
+ id: '1',
46
+ name: 'John Doe',
47
+ email: 'john@example.com'
48
+ }
49
+ </script>
50
+
51
+ <template>
52
+ <TelaChat
53
+ :messages="messages"
54
+ :current-user="currentUser"
55
+ />
56
+ </template>
57
+ ```
58
+
59
+ ### Empty State Code
60
+
61
+ ```vue
62
+ <TelaChat
63
+ :messages="[]"
64
+ :current-user="currentUser"
65
+ />
66
+ ```
67
+
68
+ ### With Replies
69
+
70
+ ```vue
71
+ <script setup>
72
+ const messages = [{
73
+ id: '1',
74
+ content: 'Main message',
75
+ timestamp: new Date(),
76
+ author: 'User',
77
+ authorEmail: 'user@example.com',
78
+ replies: [
79
+ {
80
+ id: '2',
81
+ content: 'Reply to main message',
82
+ timestamp: new Date(),
83
+ author: 'Other User',
84
+ authorEmail: 'other@example.com'
85
+ }
86
+ ]
87
+ }]
88
+ </script>
89
+
90
+ <template>
91
+ <TelaChat :messages="messages" />
92
+ </template>
93
+ ```
94
+
95
+ ### Nested Replies Code
96
+
97
+ ```vue
98
+ <script setup>
99
+ const messages = [{
100
+ id: '1',
101
+ content: 'Main message',
102
+ timestamp: new Date(),
103
+ author: 'User 1',
104
+ authorEmail: 'user1@example.com',
105
+ replies: [
106
+ {
107
+ id: '2',
108
+ content: 'First reply',
109
+ timestamp: new Date(),
110
+ author: 'User 2',
111
+ authorEmail: 'user2@example.com',
112
+ replies: [
113
+ {
114
+ id: '3',
115
+ content: 'Nested reply',
116
+ timestamp: new Date(),
117
+ author: 'User 3',
118
+ authorEmail: 'user3@example.com'
119
+ }
120
+ ]
121
+ }
122
+ ]
123
+ }]
124
+ </script>
125
+
126
+ <template>
127
+ <TelaChat :messages="messages" />
128
+ </template>
129
+ ```
130
+
131
+ ### With Mentions Code
132
+
133
+ ```vue
134
+ <script setup>
135
+ const messages = [{
136
+ id: '1',
137
+ content: '@jane@example.com Check this out!',
138
+ timestamp: new Date(),
139
+ author: 'John',
140
+ authorEmail: 'john@example.com'
141
+ }]
142
+
143
+ const otherUsers = [{
144
+ id: '2',
145
+ name: 'Jane',
146
+ email: 'jane@example.com'
147
+ }]
148
+ </script>
149
+
150
+ <template>
151
+ <TelaChat
152
+ :messages="messages"
153
+ :other-users="otherUsers"
154
+ />
155
+ </template>
156
+ ```
157
+
158
+ ### With Avatars
159
+
160
+ ```vue
161
+ <script setup>
162
+ const messages = [{
163
+ id: '1',
164
+ content: 'Hello!',
165
+ timestamp: new Date(),
166
+ author: 'John Doe',
167
+ authorEmail: 'john@example.com',
168
+ avatarUrl: 'https://example.com/avatar.jpg'
169
+ }]
170
+ </script>
171
+
172
+ <template>
173
+ <TelaChat :messages="messages" />
174
+ </template>
175
+ ```
176
+
177
+ ## Props
178
+
179
+ <ArgTypes />
180
+
181
+ ```typescript
182
+ type Message = {
183
+ id: string
184
+ content: string
185
+ timestamp: Date
186
+ author: string
187
+ authorEmail: string
188
+ avatarUrl?: string
189
+ version?: string
190
+ replies?: Message[]
191
+ }
192
+
193
+ type User = {
194
+ id: string
195
+ name: string
196
+ email: string
197
+ avatarUrl?: string
198
+ }
199
+
200
+ type ChatProps = {
201
+ messages: Message[]
202
+ currentUser?: User
203
+ otherUsers?: User[]
204
+ }
205
+ ```
206
+
207
+ ## Features
208
+
209
+ - **Threaded Messages**: Support for nested replies
210
+ - **User Identification**: Show author names and emails
211
+ - **Avatars**: Display user avatars
212
+ - **Timestamps**: Show when messages were sent
213
+ - **Mentions**: Highlight mentioned users
214
+ - **Version Info**: Show message version (for AI/bot messages)
215
+ - **Empty State**: Graceful handling of no messages
216
+ - **Scrollable**: Scroll through long conversations
217
+ - **Responsive**: Adapts to container size
218
+
219
+ ## Message Structure
220
+
221
+ Messages can be nested infinitely:
222
+
223
+ ```typescript
224
+ {
225
+ id: '1',
226
+ content: 'Parent message',
227
+ timestamp: new Date(),
228
+ author: 'User',
229
+ authorEmail: 'user@example.com',
230
+ avatarUrl: 'https://...',
231
+ version: 'v1.0',
232
+ replies: [
233
+ {
234
+ id: '2',
235
+ content: 'Child message',
236
+ // ... same structure, can have more replies
237
+ replies: []
238
+ }
239
+ ]
240
+ }
241
+ ```
242
+
243
+ ## Use Cases
244
+
245
+ - **Chat Applications**: Real-time messaging
246
+ - **Comment Systems**: Threaded discussions
247
+ - **Support Tickets**: Customer support conversations
248
+ - **Collaborative Tools**: Team communication
249
+ - **Review Systems**: Product reviews with replies
250
+ - **Q&A Forums**: Question and answer threads
251
+
252
+ ## Best Practices
253
+
254
+ 1. **Load Messages Lazily**: Paginate long conversations
255
+ 2. **Show Timestamps**: Help users track conversation flow
256
+ 3. **Highlight Mentions**: Make @mentions stand out
257
+ 4. **Limit Nesting Depth**: Avoid deep nesting (max 3-4 levels)
258
+ 5. **Provide Reply UI**: Add buttons to reply to messages
259
+ 6. **Real-time Updates**: Use WebSockets for live updates
260
+
261
+ ## Accessibility
262
+
263
+ - Semantic HTML structure
264
+ - Proper heading hierarchy
265
+ - ARIA labels for avatars
266
+ - Keyboard navigation
267
+ - Screen reader friendly timestamps
268
+ - Focus management for replies
@@ -0,0 +1,253 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import TelaChat from './index.vue'
3
+ import type { Message } from './types'
4
+
5
+ const mockMessages: Message[] = [
6
+ {
7
+ id: '1',
8
+ content: 'Hello! How can I help you today?',
9
+ timestamp: new Date('2024-03-20T10:00:00'),
10
+ authorEmail: 'ai.assistant@example.com',
11
+ author: 'AI Assistant',
12
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
13
+ version: 'v1.0',
14
+ },
15
+ {
16
+ id: '2',
17
+ content: 'I have a question about the API integration.',
18
+ timestamp: new Date('2024-03-20T10:01:00'),
19
+ authorEmail: 'john.doe@example.com',
20
+ author: 'John Doe',
21
+ },
22
+ {
23
+ id: '3',
24
+ content: 'Sure, I can help with that. What specific aspect of the API integration would you like to know about?',
25
+ timestamp: new Date('2024-03-20T10:02:00'),
26
+ authorEmail: 'ai.assistant@example.com',
27
+ author: 'AI Assistant',
28
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
29
+ version: 'v1.0',
30
+ replies: [
31
+ {
32
+ id: '4',
33
+ content: 'I\'m wondering about authentication methods.',
34
+ timestamp: new Date('2024-03-20T10:03:00'),
35
+ authorEmail: 'john.doe@example.com',
36
+ author: 'John Doe',
37
+ },
38
+ ],
39
+ },
40
+ ]
41
+
42
+ const meta = {
43
+ title: 'Tela/Chat',
44
+ component: TelaChat,
45
+ parameters: {
46
+ layout: 'centered',
47
+ docs: {
48
+ description: {
49
+ component: 'A chat component that displays threaded messages with replies, avatars, timestamps, and user information. Supports nested replies, mentions, message threading, and user identification. Useful for chat interfaces, comment systems, and collaborative communication features.',
50
+ },
51
+ },
52
+ },
53
+ argTypes: {
54
+ messages: {
55
+ control: 'object',
56
+ description: 'Array of message objects. Each message should have `id`, `content`, `timestamp`, `author`, `authorEmail`, and optionally `avatarUrl`, `version`, and `replies` (nested messages) properties.',
57
+ },
58
+ currentUser: {
59
+ control: 'object',
60
+ description: 'Current user object with `id`, `name`, `email`, and optionally `avatarUrl` properties.',
61
+ },
62
+ otherUsers: {
63
+ control: 'object',
64
+ description: 'Array of other user objects for mentions and user identification.',
65
+ },
66
+ },
67
+ args: {
68
+ messages: mockMessages,
69
+ },
70
+ } satisfies Meta<typeof TelaChat>
71
+
72
+ export default meta
73
+ type Story = StoryObj<typeof meta>
74
+
75
+ export const Default: Story = {
76
+ args: {
77
+ messages: mockMessages,
78
+ currentUser: {
79
+ id: '1',
80
+ name: 'John Doe',
81
+ email: 'john.doe@example.com',
82
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
83
+ },
84
+ otherUsers: [
85
+ {
86
+ id: '2',
87
+ name: 'Jane Doe',
88
+ email: 'jane.doe@example.com',
89
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=2',
90
+ },
91
+ ],
92
+ },
93
+ }
94
+
95
+ export const Empty: Story = {
96
+ args: {
97
+ messages: [],
98
+ currentUser: {
99
+ id: '1',
100
+ name: 'John Doe',
101
+ email: 'john.doe@example.com',
102
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
103
+ },
104
+ otherUsers: [],
105
+ },
106
+ }
107
+
108
+ export const LongThread: Story = {
109
+ args: {
110
+ messages: [
111
+ ...mockMessages,
112
+ {
113
+ id: '5',
114
+ content: 'Here\'s a detailed explanation of our authentication methods...',
115
+ timestamp: new Date('2024-03-20T10:04:00'),
116
+ author: 'AI Assistant',
117
+ authorEmail: 'ai.assistant@example.com',
118
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
119
+ version: 'v1.0',
120
+ },
121
+ {
122
+ id: '6',
123
+ content: 'Thanks! That\'s very helpful.',
124
+ timestamp: new Date('2024-03-20T10:05:00'),
125
+ authorEmail: 'john.doe@example.com',
126
+ author: 'John Doe',
127
+ },
128
+ ],
129
+ currentUser: {
130
+ id: '1',
131
+ name: 'John Doe',
132
+ email: 'john.doe@example.com',
133
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
134
+ },
135
+ otherUsers: [],
136
+ },
137
+ }
138
+
139
+ export const NestedReplies: Story = {
140
+ args: {
141
+ messages: [
142
+ {
143
+ id: '1',
144
+ content: 'Main message',
145
+ timestamp: new Date('2024-03-20T10:00:00'),
146
+ author: 'AI Assistant',
147
+ authorEmail: 'ai.assistant@example.com',
148
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
149
+ version: 'v1.0',
150
+ replies: [
151
+ {
152
+ id: '2',
153
+ content: 'First reply',
154
+ timestamp: new Date('2024-03-20T10:01:00'),
155
+ authorEmail: 'john.doe@example.com',
156
+ author: 'John Doe',
157
+ replies: [
158
+ {
159
+ id: '3',
160
+ content: 'Nested reply',
161
+ timestamp: new Date('2024-03-20T10:02:00'),
162
+ author: 'AI Assistant',
163
+ authorEmail: 'ai.assistant@example.com',
164
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
165
+ version: 'v1.0',
166
+ },
167
+ ],
168
+ },
169
+ ],
170
+ },
171
+ ],
172
+ currentUser: {
173
+ id: '1',
174
+ name: 'John Doe',
175
+ email: 'john.doe@example.com',
176
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
177
+ },
178
+ otherUsers: [],
179
+ },
180
+ }
181
+
182
+ export const NestedRepliesWithButton: Story = {
183
+ args: {
184
+ messages: [
185
+ {
186
+ id: '1',
187
+ content: 'Main message',
188
+ timestamp: new Date('2024-03-20T10:00:00'),
189
+ author: 'AI Assistant',
190
+ authorEmail: 'ai.assistant@example.com',
191
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
192
+ version: 'v1.0',
193
+ replies: [
194
+ {
195
+ id: '2',
196
+ content: 'First reply',
197
+ timestamp: new Date('2024-03-20T10:01:00'),
198
+ authorEmail: 'john.doe@example.com',
199
+ author: 'John Doe',
200
+ replies: [],
201
+ },
202
+ ],
203
+ },
204
+ ],
205
+ currentUser: {
206
+ id: '1',
207
+ name: 'John Doe',
208
+ email: 'john.doe@example.com',
209
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
210
+ },
211
+ otherUsers: [],
212
+ },
213
+ }
214
+
215
+ export const NestedRepliesWithMentions: Story = {
216
+ args: {
217
+ messages: [
218
+ {
219
+ id: '1',
220
+ content: 'Main message',
221
+ timestamp: new Date('2024-03-20T10:00:00'),
222
+ author: 'AI Assistant',
223
+ authorEmail: 'ai.assistant@example.com',
224
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
225
+ version: 'v1.0',
226
+ replies: [
227
+ {
228
+ id: '2',
229
+ content: '@jane.doe@example.com... This is a reply to the main message.',
230
+ timestamp: new Date('2024-03-20T10:01:00'),
231
+ authorEmail: 'jane.doe@example.com',
232
+ author: 'You',
233
+ replies: [],
234
+ },
235
+ ],
236
+ },
237
+ ],
238
+ currentUser: {
239
+ id: '1',
240
+ name: 'John Doe',
241
+ email: 'john.doe@example.com',
242
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=1',
243
+ },
244
+ otherUsers: [
245
+ {
246
+ id: '2',
247
+ name: 'Jane Doe',
248
+ email: 'jane.doe@example.com',
249
+ avatarUrl: 'https://api.dicebear.com/7.x/bottts/svg?seed=2',
250
+ },
251
+ ],
252
+ },
253
+ }
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import type { User } from '../types'
3
+
4
+ type CommandType = '@'
5
+
6
+ interface BaseCommandProps {
7
+ isOpen: boolean
8
+ onClose: () => void
9
+ }
10
+
11
+ interface MentionProps extends BaseCommandProps {
12
+ chatMessage: string
13
+ members: User[]
14
+ onSelect: (user: User) => void
15
+ searchTerm: string
16
+ }
17
+
18
+ type CommandProps = {
19
+ commands: CommandType[]
20
+ mentionProps?: MentionProps
21
+ }
22
+
23
+ const props = withDefaults(defineProps<CommandProps>(), {
24
+ mentionProps: undefined,
25
+ })
26
+
27
+ const hasMention = computed(() => props.commands.includes('@'))
28
+ </script>
29
+
30
+ <template>
31
+ <div>
32
+ <TelaChatCommandMention
33
+ v-if="hasMention"
34
+ v-bind="mentionProps"
35
+ >
36
+ <template #trigger>
37
+ <slot name="mention" />
38
+ </template>
39
+ </TelaChatCommandMention>
40
+ </div>
41
+ </template>
@@ -0,0 +1,138 @@
1
+ <script setup lang="ts">
2
+ import type { User } from '../../types'
3
+ import { onClickOutside } from '@vueuse/core'
4
+
5
+ const props = defineProps<{
6
+ members: User[]
7
+ chatMessage: string
8
+ isOpen: boolean
9
+ searchTerm: string
10
+ }>()
11
+
12
+ const emit = defineEmits<{
13
+ (e: 'close'): void
14
+ (e: 'select', user: User): void
15
+ }>()
16
+
17
+ const filteredUsers = computed(() => {
18
+ const isValidArray = Array.isArray(props.members) && props.members.length > 0
19
+ const hasInsufficientLength = props.searchTerm.length < 3
20
+ if (!isValidArray || hasInsufficientLength)
21
+ return props.members
22
+
23
+ const searchTerm = props.searchTerm.replace('@', '').toLowerCase()
24
+ return props.members?.filter((user) => {
25
+ const name = user.name.toLowerCase()
26
+ const email = user.email.toLowerCase()
27
+ return name.includes(searchTerm) || email.includes(searchTerm)
28
+ })
29
+ })
30
+ const isVisible = computed(() => props.isOpen && filteredUsers.value.length > 0)
31
+
32
+ const dropdownRef = ref<HTMLElement | null>(null)
33
+ onClickOutside(dropdownRef, () => {
34
+ if (props.isOpen) {
35
+ emit('close')
36
+ }
37
+ })
38
+ const selectedIndex = ref(0)
39
+
40
+ // Handle keyboard navigation
41
+ function handleKeydown(e: KeyboardEvent) {
42
+ if (!isVisible.value)
43
+ return
44
+
45
+ switch (e.key) {
46
+ case 'ArrowDown':
47
+ e.preventDefault()
48
+ selectedIndex.value = (selectedIndex.value + 1) % filteredUsers.value.length
49
+ break
50
+ case 'ArrowUp':
51
+ e.preventDefault()
52
+ selectedIndex.value = selectedIndex.value - 1 < 0
53
+ ? filteredUsers.value.length - 1
54
+ : selectedIndex.value - 1
55
+ break
56
+ case 'Enter':
57
+ e.preventDefault()
58
+ if (filteredUsers.value[selectedIndex.value]) {
59
+ emit('select', filteredUsers.value[selectedIndex.value])
60
+ }
61
+ break
62
+ case 'Escape':
63
+ e.preventDefault()
64
+ emit('close')
65
+ break
66
+ }
67
+ }
68
+
69
+ // Add keyboard event listener
70
+ onMounted(() => {
71
+ window.addEventListener('keydown', handleKeydown)
72
+ })
73
+
74
+ onUnmounted(() => {
75
+ window.removeEventListener('keydown', handleKeydown)
76
+ })
77
+ </script>
78
+
79
+ <template>
80
+ <slot name="trigger" />
81
+ <Transition name="fade">
82
+ <div
83
+ v-if="isVisible"
84
+ ref="dropdownRef"
85
+ bg-white
86
+ shadow-flying
87
+ rounded-10px
88
+ p-4px
89
+ text-gray-800
90
+ flex="~ col"
91
+ w-244px
92
+ absolute
93
+ top-full
94
+ left-0
95
+ z-10000
96
+ >
97
+ <div
98
+ v-for="(member, index) in filteredUsers"
99
+ :key="member.id"
100
+ py-9px
101
+ px-12px
102
+ transition
103
+ ease
104
+ text-left
105
+ flex
106
+ items-center
107
+ gap-12px
108
+ rounded-8px
109
+ hover="bg-gray-200"
110
+ :class="{ 'bg-gray-200': index === selectedIndex }"
111
+ cursor-pointer
112
+ @click="$emit('select', member)"
113
+ >
114
+ <TelaAvatar :src="member.avatarUrl" size="sm" />
115
+ <div flex="~ col" gap-3px text-14px>
116
+ <div body-12-semibold>
117
+ {{ member.name }}
118
+ </div>
119
+ <div text-xs text-gray-500>
120
+ {{ member.email }}
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ </Transition>
126
+ </template>
127
+
128
+ <style scoped>
129
+ .fade-enter-active,
130
+ .fade-leave-active {
131
+ transition: opacity 0.2s ease;
132
+ }
133
+
134
+ .fade-enter-from,
135
+ .fade-leave-to {
136
+ opacity: 0;
137
+ }
138
+ </style>