@tribepad/themis 1.3.4 → 1.5.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 (76) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/elements/ChatInterface/ChatInputArea.d.ts +37 -0
  3. package/dist/elements/ChatInterface/ChatInputArea.d.ts.map +1 -0
  4. package/dist/elements/ChatInterface/ChatInterface.d.ts +24 -0
  5. package/dist/elements/ChatInterface/ChatInterface.d.ts.map +1 -0
  6. package/dist/elements/ChatInterface/ChatInterface.hooks.d.ts +46 -0
  7. package/dist/elements/ChatInterface/ChatInterface.hooks.d.ts.map +1 -0
  8. package/dist/elements/ChatInterface/ChatInterface.styles.d.ts +83 -0
  9. package/dist/elements/ChatInterface/ChatInterface.styles.d.ts.map +1 -0
  10. package/dist/elements/ChatInterface/ChatInterface.types.d.ts +340 -0
  11. package/dist/elements/ChatInterface/ChatInterface.types.d.ts.map +1 -0
  12. package/dist/elements/ChatInterface/ChatLiveRegions.d.ts +13 -0
  13. package/dist/elements/ChatInterface/ChatLiveRegions.d.ts.map +1 -0
  14. package/dist/elements/ChatInterface/ChatMessageBubble.d.ts +24 -0
  15. package/dist/elements/ChatInterface/ChatMessageBubble.d.ts.map +1 -0
  16. package/dist/elements/ChatInterface/ChatMessageList.d.ts +32 -0
  17. package/dist/elements/ChatInterface/ChatMessageList.d.ts.map +1 -0
  18. package/dist/elements/ChatInterface/ChatThinkingDisplay.d.ts +20 -0
  19. package/dist/elements/ChatInterface/ChatThinkingDisplay.d.ts.map +1 -0
  20. package/dist/elements/ChatInterface/ChatTypingIndicator.d.ts +11 -0
  21. package/dist/elements/ChatInterface/ChatTypingIndicator.d.ts.map +1 -0
  22. package/dist/elements/ChatInterface/DefaultChatInput.d.ts +18 -0
  23. package/dist/elements/ChatInterface/DefaultChatInput.d.ts.map +1 -0
  24. package/dist/elements/ChatInterface/index.d.ts +7 -0
  25. package/dist/elements/ChatInterface/index.d.ts.map +1 -0
  26. package/dist/elements/ChatInterface/index.js +3 -0
  27. package/dist/elements/ChatInterface/index.js.map +1 -0
  28. package/dist/elements/ChatInterface/index.mjs +3 -0
  29. package/dist/elements/ChatInterface/index.mjs.map +1 -0
  30. package/dist/elements/DatePicker/Calendar.d.ts +1 -1
  31. package/dist/elements/DatePicker/DateField.d.ts +1 -1
  32. package/dist/elements/DatePicker/DateField.d.ts.map +1 -1
  33. package/dist/elements/DatePicker/DatePicker.d.ts +1 -1
  34. package/dist/elements/DatePicker/DatePicker.d.ts.map +1 -1
  35. package/dist/elements/DatePicker/DatePicker.types.d.ts +1 -1
  36. package/dist/elements/DatePicker/DateRangePicker.d.ts +1 -1
  37. package/dist/elements/DatePicker/DateRangePicker.d.ts.map +1 -1
  38. package/dist/elements/FileField/FileField.types.d.ts +1 -1
  39. package/dist/elements/FileField/FileProgress.variants.d.ts +1 -1
  40. package/dist/elements/OTPInput/index.js +1 -1
  41. package/dist/elements/OTPInput/index.js.map +1 -1
  42. package/dist/elements/OTPInput/index.mjs +1 -1
  43. package/dist/elements/OTPInput/index.mjs.map +1 -1
  44. package/dist/elements/Resizable/index.js +1 -1
  45. package/dist/elements/Resizable/index.js.map +1 -1
  46. package/dist/elements/Resizable/index.mjs +1 -1
  47. package/dist/elements/Resizable/index.mjs.map +1 -1
  48. package/dist/elements/TimeField/TimeField.d.ts +1 -1
  49. package/dist/elements/TimeField/TimeField.d.ts.map +1 -1
  50. package/dist/elements/Tree/Tree.d.ts +62 -0
  51. package/dist/elements/Tree/Tree.d.ts.map +1 -0
  52. package/dist/elements/Tree/Tree.styles.d.ts +28 -0
  53. package/dist/elements/Tree/Tree.styles.d.ts.map +1 -0
  54. package/dist/elements/Tree/Tree.types.d.ts +161 -0
  55. package/dist/elements/Tree/Tree.types.d.ts.map +1 -0
  56. package/dist/elements/Tree/index.d.ts +33 -0
  57. package/dist/elements/Tree/index.d.ts.map +1 -0
  58. package/dist/elements/Tree/index.js +3 -0
  59. package/dist/elements/Tree/index.js.map +1 -0
  60. package/dist/elements/Tree/index.mjs +3 -0
  61. package/dist/elements/Tree/index.mjs.map +1 -0
  62. package/dist/elements/index.d.ts +5 -0
  63. package/dist/elements/index.d.ts.map +1 -1
  64. package/dist/elements/index.js +1 -1
  65. package/dist/elements/index.js.map +1 -1
  66. package/dist/elements/index.mjs +1 -1
  67. package/dist/elements/index.mjs.map +1 -1
  68. package/dist/index.js +2 -2
  69. package/dist/index.js.map +1 -1
  70. package/dist/index.mjs +2 -2
  71. package/dist/index.mjs.map +1 -1
  72. package/dist/styles/defaults.css +3 -0
  73. package/package.json +29 -21
  74. package/src/elements/ChatInterface/ChatInterface.stories.tsx +495 -0
  75. package/src/elements/ChatInterface/README.md +408 -0
  76. package/src/elements/Tree/Tree.stories.tsx +407 -0
@@ -0,0 +1,407 @@
1
+ import { useState, type ReactElement } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import {
4
+ Tree,
5
+ TreeItem,
6
+ TreeItemContent,
7
+ TreeItemChevron,
8
+ } from './Tree';
9
+ import type { Selection } from './Tree.types';
10
+
11
+ const meta = {
12
+ title: 'Elements/Tree',
13
+ component: Tree,
14
+ tags: ['autodocs'],
15
+ parameters: {
16
+ layout: 'padded',
17
+ docs: {
18
+ description: {
19
+ component:
20
+ 'Accessible hierarchical list built on React Aria `Tree`. Supports keyboard navigation (Arrow keys, Home/End, type-ahead), expansion, single/multiple selection, lazy children via `hasChildItems`, and custom row content.',
21
+ },
22
+ },
23
+ },
24
+ argTypes: {
25
+ selectionMode: {
26
+ control: 'select',
27
+ options: ['none', 'single', 'multiple'],
28
+ },
29
+ variant: {
30
+ control: 'select',
31
+ options: ['default', 'bordered'],
32
+ },
33
+ size: {
34
+ control: 'select',
35
+ options: ['sm', 'default', 'lg'],
36
+ },
37
+ },
38
+ } satisfies Meta<typeof Tree>;
39
+
40
+ export default meta;
41
+ type Story = StoryObj<typeof Tree>;
42
+
43
+ function Sample(): ReactElement {
44
+ return (
45
+ <Tree aria-label="Departments" className="max-w-md">
46
+ <TreeItem id="eng" textValue="Engineering" hasChildItems>
47
+ <TreeItemContent>
48
+ <TreeItemChevron />
49
+ <span>Engineering</span>
50
+ </TreeItemContent>
51
+ <TreeItem id="eng.platform" textValue="Platform" hasChildItems>
52
+ <TreeItemContent>
53
+ <TreeItemChevron />
54
+ <span>Platform</span>
55
+ </TreeItemContent>
56
+ <TreeItem id="eng.platform.ml" textValue="ML">
57
+ <TreeItemContent>
58
+ <TreeItemChevron hasChildItems={false} />
59
+ <span>ML</span>
60
+ </TreeItemContent>
61
+ </TreeItem>
62
+ <TreeItem id="eng.platform.observability" textValue="Observability">
63
+ <TreeItemContent>
64
+ <TreeItemChevron hasChildItems={false} />
65
+ <span>Observability</span>
66
+ </TreeItemContent>
67
+ </TreeItem>
68
+ </TreeItem>
69
+ <TreeItem id="eng.tooling" textValue="Tooling">
70
+ <TreeItemContent>
71
+ <TreeItemChevron hasChildItems={false} />
72
+ <span>Tooling</span>
73
+ </TreeItemContent>
74
+ </TreeItem>
75
+ </TreeItem>
76
+ <TreeItem id="design" textValue="Design">
77
+ <TreeItemContent>
78
+ <TreeItemChevron hasChildItems={false} />
79
+ <span>Design</span>
80
+ </TreeItemContent>
81
+ </TreeItem>
82
+ </Tree>
83
+ );
84
+ }
85
+
86
+ export const Default: Story = {
87
+ render: () => <Sample />,
88
+ };
89
+
90
+ export const Bordered: Story = {
91
+ render: () => (
92
+ <Tree aria-label="Departments" variant="bordered" className="max-w-md">
93
+ <TreeItem id="a" textValue="Item A">
94
+ <TreeItemContent>
95
+ <TreeItemChevron hasChildItems={false} />
96
+ <span>Item A</span>
97
+ </TreeItemContent>
98
+ </TreeItem>
99
+ <TreeItem id="b" textValue="Item B">
100
+ <TreeItemContent>
101
+ <TreeItemChevron hasChildItems={false} />
102
+ <span>Item B</span>
103
+ </TreeItemContent>
104
+ </TreeItem>
105
+ </Tree>
106
+ ),
107
+ };
108
+
109
+ /**
110
+ * Realistic ltree-shaped hierarchy used by the selection stories. Three
111
+ * roots, each with at least one expandable subtree. Mirrors what an EOS
112
+ * Job Categories taxonomy might look like.
113
+ */
114
+ function LtreeSampleData(): ReactElement {
115
+ return (
116
+ <>
117
+ <TreeItem id="engineering" textValue="Engineering" hasChildItems>
118
+ <TreeItemContent>
119
+ <TreeItemChevron />
120
+ <span>Engineering</span>
121
+ </TreeItemContent>
122
+ <TreeItem id="engineering.platform" textValue="Platform" hasChildItems>
123
+ <TreeItemContent>
124
+ <TreeItemChevron />
125
+ <span>Platform</span>
126
+ </TreeItemContent>
127
+ <TreeItem id="engineering.platform.ml" textValue="ML">
128
+ <TreeItemContent>
129
+ <TreeItemChevron hasChildItems={false} />
130
+ <span>ML</span>
131
+ </TreeItemContent>
132
+ </TreeItem>
133
+ <TreeItem
134
+ id="engineering.platform.observability"
135
+ textValue="Observability"
136
+ >
137
+ <TreeItemContent>
138
+ <TreeItemChevron hasChildItems={false} />
139
+ <span>Observability</span>
140
+ </TreeItemContent>
141
+ </TreeItem>
142
+ </TreeItem>
143
+ <TreeItem id="engineering.tooling" textValue="Tooling" hasChildItems>
144
+ <TreeItemContent>
145
+ <TreeItemChevron />
146
+ <span>Tooling</span>
147
+ </TreeItemContent>
148
+ <TreeItem id="engineering.tooling.ci" textValue="CI/CD">
149
+ <TreeItemContent>
150
+ <TreeItemChevron hasChildItems={false} />
151
+ <span>CI/CD</span>
152
+ </TreeItemContent>
153
+ </TreeItem>
154
+ </TreeItem>
155
+ </TreeItem>
156
+
157
+ <TreeItem id="design" textValue="Design" hasChildItems>
158
+ <TreeItemContent>
159
+ <TreeItemChevron />
160
+ <span>Design</span>
161
+ </TreeItemContent>
162
+ <TreeItem id="design.brand" textValue="Brand">
163
+ <TreeItemContent>
164
+ <TreeItemChevron hasChildItems={false} />
165
+ <span>Brand</span>
166
+ </TreeItemContent>
167
+ </TreeItem>
168
+ <TreeItem id="design.product" textValue="Product">
169
+ <TreeItemContent>
170
+ <TreeItemChevron hasChildItems={false} />
171
+ <span>Product</span>
172
+ </TreeItemContent>
173
+ </TreeItem>
174
+ <TreeItem id="design.research" textValue="Research">
175
+ <TreeItemContent>
176
+ <TreeItemChevron hasChildItems={false} />
177
+ <span>Research</span>
178
+ </TreeItemContent>
179
+ </TreeItem>
180
+ </TreeItem>
181
+
182
+ <TreeItem id="operations" textValue="Operations" hasChildItems>
183
+ <TreeItemContent>
184
+ <TreeItemChevron />
185
+ <span>Operations</span>
186
+ </TreeItemContent>
187
+ <TreeItem id="operations.people" textValue="People">
188
+ <TreeItemContent>
189
+ <TreeItemChevron hasChildItems={false} />
190
+ <span>People</span>
191
+ </TreeItemContent>
192
+ </TreeItem>
193
+ <TreeItem id="operations.finance" textValue="Finance">
194
+ <TreeItemContent>
195
+ <TreeItemChevron hasChildItems={false} />
196
+ <span>Finance</span>
197
+ </TreeItemContent>
198
+ </TreeItem>
199
+ </TreeItem>
200
+ </>
201
+ );
202
+ }
203
+
204
+ export const SingleSelection: Story = {
205
+ render: () => {
206
+ function Inner(): ReactElement {
207
+ const [selected, setSelected] = useState<Selection>(
208
+ new Set(['engineering.platform.ml']),
209
+ );
210
+ return (
211
+ <div className="flex flex-col gap-3">
212
+ <Tree
213
+ aria-label="Job categories"
214
+ selectionMode="single"
215
+ selectedKeys={selected}
216
+ defaultExpandedKeys={new Set(['engineering', 'engineering.platform'])}
217
+ onSelectionChange={setSelected}
218
+ className="max-w-md"
219
+ >
220
+ <LtreeSampleData />
221
+ </Tree>
222
+ <p className="text-sm text-[var(--muted-foreground)]">
223
+ Selected:{' '}
224
+ <code>{Array.from(selected as Set<string>).join(', ') || '—'}</code>
225
+ </p>
226
+ </div>
227
+ );
228
+ }
229
+ return <Inner />;
230
+ },
231
+ };
232
+
233
+ export const MultipleSelection: Story = {
234
+ render: () => {
235
+ function Inner(): ReactElement {
236
+ const [selected, setSelected] = useState<Selection>(
237
+ new Set(['engineering.platform.ml', 'design.research']),
238
+ );
239
+ return (
240
+ <div className="flex flex-col gap-3">
241
+ <Tree
242
+ aria-label="Job categories"
243
+ selectionMode="multiple"
244
+ selectedKeys={selected}
245
+ defaultExpandedKeys={
246
+ new Set(['engineering', 'engineering.platform', 'design'])
247
+ }
248
+ onSelectionChange={setSelected}
249
+ className="max-w-md"
250
+ >
251
+ <LtreeSampleData />
252
+ </Tree>
253
+ <p className="text-sm text-[var(--muted-foreground)]">
254
+ Selected:{' '}
255
+ <code>
256
+ {Array.from(selected as Set<string>).join(', ') || '—'}
257
+ </code>
258
+ </p>
259
+ </div>
260
+ );
261
+ }
262
+ return <Inner />;
263
+ },
264
+ };
265
+
266
+ export const SingleSelectionDeepLtree: Story = {
267
+ render: () => {
268
+ function Inner(): ReactElement {
269
+ const [selected, setSelected] = useState<Selection>(new Set([]));
270
+ return (
271
+ <div className="flex flex-col gap-3">
272
+ <Tree
273
+ aria-label="Job categories — deep"
274
+ selectionMode="single"
275
+ selectedKeys={selected}
276
+ defaultExpandedKeys={
277
+ new Set([
278
+ 'engineering',
279
+ 'engineering.platform',
280
+ 'engineering.tooling',
281
+ 'design',
282
+ 'operations',
283
+ ])
284
+ }
285
+ onSelectionChange={setSelected}
286
+ className="max-w-md"
287
+ >
288
+ <LtreeSampleData />
289
+ </Tree>
290
+ <p className="text-sm text-[var(--muted-foreground)]">
291
+ Tip: use{' '}
292
+ <kbd className="rounded bg-[var(--secondary)] px-1.5 py-0.5">↓</kbd>{' '}
293
+ <kbd className="rounded bg-[var(--secondary)] px-1.5 py-0.5">↑</kbd>{' '}
294
+ to walk rows,{' '}
295
+ <kbd className="rounded bg-[var(--secondary)] px-1.5 py-0.5">→</kbd>{' '}
296
+ <kbd className="rounded bg-[var(--secondary)] px-1.5 py-0.5">←</kbd>{' '}
297
+ to expand/collapse, type-ahead to jump.
298
+ </p>
299
+ </div>
300
+ );
301
+ }
302
+ return <Inner />;
303
+ },
304
+ };
305
+
306
+ export const MultipleSelectionDeepLtree: Story = {
307
+ render: () => {
308
+ function Inner(): ReactElement {
309
+ const [selected, setSelected] = useState<Selection>(
310
+ new Set([
311
+ 'engineering.platform.observability',
312
+ 'engineering.tooling.ci',
313
+ 'design.brand',
314
+ 'operations.finance',
315
+ ]),
316
+ );
317
+ return (
318
+ <div className="flex flex-col gap-3">
319
+ <Tree
320
+ aria-label="Job categories — multi-pick"
321
+ selectionMode="multiple"
322
+ selectedKeys={selected}
323
+ defaultExpandedKeys={
324
+ new Set([
325
+ 'engineering',
326
+ 'engineering.platform',
327
+ 'engineering.tooling',
328
+ 'design',
329
+ 'operations',
330
+ ])
331
+ }
332
+ onSelectionChange={setSelected}
333
+ className="max-w-md"
334
+ >
335
+ <LtreeSampleData />
336
+ </Tree>
337
+ <p className="text-sm text-[var(--muted-foreground)]">
338
+ {Array.from(selected as Set<string>).length} selected
339
+ </p>
340
+ </div>
341
+ );
342
+ }
343
+ return <Inner />;
344
+ },
345
+ };
346
+
347
+ export const DisabledRow: Story = {
348
+ render: () => (
349
+ <Tree aria-label="Departments" disabledKeys={['eng']} className="max-w-md">
350
+ <TreeItem id="eng" textValue="Engineering">
351
+ <TreeItemContent>
352
+ <TreeItemChevron hasChildItems={false} />
353
+ <span>Engineering (disabled)</span>
354
+ </TreeItemContent>
355
+ </TreeItem>
356
+ <TreeItem id="design" textValue="Design">
357
+ <TreeItemContent>
358
+ <TreeItemChevron hasChildItems={false} />
359
+ <span>Design</span>
360
+ </TreeItemContent>
361
+ </TreeItem>
362
+ </Tree>
363
+ ),
364
+ };
365
+
366
+ export const EmptyState: Story = {
367
+ render: () => (
368
+ <Tree
369
+ aria-label="Empty"
370
+ renderEmptyState={() => <span>No items yet</span>}
371
+ className="max-w-md"
372
+ >
373
+ {[]}
374
+ </Tree>
375
+ ),
376
+ };
377
+
378
+ export const Sizes: Story = {
379
+ render: () => (
380
+ <div className="flex flex-col gap-6">
381
+ <Tree aria-label="sm" size="sm" className="max-w-md">
382
+ <TreeItem id="sm.1" textValue="Small row">
383
+ <TreeItemContent>
384
+ <TreeItemChevron hasChildItems={false} />
385
+ <span>Small row</span>
386
+ </TreeItemContent>
387
+ </TreeItem>
388
+ </Tree>
389
+ <Tree aria-label="default" className="max-w-md">
390
+ <TreeItem id="def.1" textValue="Default row">
391
+ <TreeItemContent>
392
+ <TreeItemChevron hasChildItems={false} />
393
+ <span>Default row</span>
394
+ </TreeItemContent>
395
+ </TreeItem>
396
+ </Tree>
397
+ <Tree aria-label="lg" size="lg" className="max-w-md">
398
+ <TreeItem id="lg.1" textValue="Large row">
399
+ <TreeItemContent>
400
+ <TreeItemChevron hasChildItems={false} />
401
+ <span>Large row</span>
402
+ </TreeItemContent>
403
+ </TreeItem>
404
+ </Tree>
405
+ </div>
406
+ ),
407
+ };