@adea-ai/ui 0.89.1 → 0.93.2

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 (102) hide show
  1. package/README.md +22 -5
  2. package/dist/NOTICE +19 -0
  3. package/dist/components/composites/list-row/index.d.ts +1 -0
  4. package/dist/components/composites/list-row/index.d.ts.map +1 -1
  5. package/dist/components/composites/list-row/index.js +2 -1
  6. package/dist/components/composites/list-row/list-row-control.d.ts +20 -0
  7. package/dist/components/composites/list-row/list-row-control.d.ts.map +1 -0
  8. package/dist/components/composites/list-row/list-row-control.js +96 -0
  9. package/dist/components/composites/list-row/list-row-control.js.map +1 -0
  10. package/dist/components/composites/list-row/list-row.d.ts +15 -35
  11. package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
  12. package/dist/components/composites/list-row/list-row.js +88 -135
  13. package/dist/components/composites/list-row/list-row.js.map +1 -1
  14. package/dist/components/composites/tree/index.d.ts +4 -0
  15. package/dist/components/composites/tree/index.d.ts.map +1 -0
  16. package/dist/components/composites/tree/index.js +2 -0
  17. package/dist/components/composites/tree/tree-navigation.d.ts +46 -0
  18. package/dist/components/composites/tree/tree-navigation.d.ts.map +1 -0
  19. package/dist/components/composites/tree/tree-navigation.js +95 -0
  20. package/dist/components/composites/tree/tree-navigation.js.map +1 -0
  21. package/dist/components/composites/tree/tree.d.ts +64 -0
  22. package/dist/components/composites/tree/tree.d.ts.map +1 -0
  23. package/dist/components/composites/tree/tree.js +311 -0
  24. package/dist/components/composites/tree/tree.js.map +1 -0
  25. package/dist/components/conversation/message-composer.d.ts +18 -3
  26. package/dist/components/conversation/message-composer.d.ts.map +1 -1
  27. package/dist/components/conversation/message-composer.js +93 -27
  28. package/dist/components/conversation/message-composer.js.map +1 -1
  29. package/dist/components/layout/sidebar-nav/index.d.ts +1 -1
  30. package/dist/components/layout/sidebar-nav/index.d.ts.map +1 -1
  31. package/dist/components/layout/sidebar-nav/index.js +2 -2
  32. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts +19 -1
  33. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts.map +1 -1
  34. package/dist/components/layout/sidebar-nav/sidebar-nav.js +83 -17
  35. package/dist/components/layout/sidebar-nav/sidebar-nav.js.map +1 -1
  36. package/dist/components/layout/top-bar/top-bar.d.ts +6 -5
  37. package/dist/components/layout/top-bar/top-bar.d.ts.map +1 -1
  38. package/dist/components/layout/top-bar/top-bar.js +30 -7
  39. package/dist/components/layout/top-bar/top-bar.js.map +1 -1
  40. package/dist/components/ui/dialog/dialog.d.ts +2 -0
  41. package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
  42. package/dist/components/ui/dialog/dialog.js +4 -3
  43. package/dist/components/ui/dialog/dialog.js.map +1 -1
  44. package/dist/components/ui/modal-dialog/modal-dialog.d.ts +5 -2
  45. package/dist/components/ui/modal-dialog/modal-dialog.d.ts.map +1 -1
  46. package/dist/components/ui/modal-dialog/modal-dialog.js +33 -24
  47. package/dist/components/ui/modal-dialog/modal-dialog.js.map +1 -1
  48. package/dist/components/ui/textarea/index.d.ts +1 -1
  49. package/dist/components/ui/textarea/index.d.ts.map +1 -1
  50. package/dist/components/ui/textarea/index.js +2 -2
  51. package/dist/components/ui/textarea/textarea.d.ts +15 -2
  52. package/dist/components/ui/textarea/textarea.d.ts.map +1 -1
  53. package/dist/components/ui/textarea/textarea.js +47 -3
  54. package/dist/components/ui/textarea/textarea.js.map +1 -1
  55. package/dist/components/ui/tooltip/tooltip.d.ts.map +1 -1
  56. package/dist/components/ui/tooltip/tooltip.js +239 -17
  57. package/dist/components/ui/tooltip/tooltip.js.map +1 -1
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +5 -3
  61. package/dist/lib/variants.js +2 -2
  62. package/dist/r/conversation.json +1 -0
  63. package/dist/r/list-row.json +5 -0
  64. package/dist/r/registry.json +41 -2
  65. package/dist/r/src/components/composites/list-row/index.ts +1 -0
  66. package/dist/r/src/components/composites/list-row/list-row-control.tsx +108 -0
  67. package/dist/r/src/components/composites/list-row/list-row.tsx +60 -127
  68. package/dist/r/src/components/composites/tree/index.ts +3 -0
  69. package/dist/r/src/components/composites/tree/tree-navigation.ts +114 -0
  70. package/dist/r/src/components/composites/tree/tree.tsx +405 -0
  71. package/dist/r/src/components/conversation/message-composer.tsx +103 -22
  72. package/dist/r/src/components/layout/sidebar-nav/index.ts +3 -0
  73. package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
  74. package/dist/r/src/components/layout/top-bar/top-bar.tsx +34 -11
  75. package/dist/r/src/components/ui/dialog/dialog.tsx +4 -2
  76. package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
  77. package/dist/r/src/components/ui/textarea/index.ts +1 -1
  78. package/dist/r/src/components/ui/textarea/textarea.tsx +52 -10
  79. package/dist/r/src/components/ui/tooltip/tooltip.tsx +305 -10
  80. package/dist/r/src/styles/base.css +40 -0
  81. package/dist/r/textarea.json +3 -1
  82. package/dist/r/top-bar.json +3 -1
  83. package/dist/r/tree.json +29 -0
  84. package/package.json +4 -1
  85. package/registry.json +41 -2
  86. package/src/components/composites/list-row/index.ts +1 -0
  87. package/src/components/composites/list-row/list-row-control.tsx +108 -0
  88. package/src/components/composites/list-row/list-row.tsx +60 -127
  89. package/src/components/composites/tree/index.ts +3 -0
  90. package/src/components/composites/tree/tree-navigation.ts +114 -0
  91. package/src/components/composites/tree/tree.tsx +405 -0
  92. package/src/components/conversation/message-composer.tsx +103 -22
  93. package/src/components/layout/sidebar-nav/index.ts +3 -0
  94. package/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
  95. package/src/components/layout/top-bar/top-bar.tsx +34 -11
  96. package/src/components/ui/dialog/dialog.tsx +4 -2
  97. package/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
  98. package/src/components/ui/textarea/index.ts +1 -1
  99. package/src/components/ui/textarea/textarea.tsx +52 -10
  100. package/src/components/ui/tooltip/tooltip.tsx +305 -10
  101. package/src/index.ts +1 -0
  102. package/src/styles/base.css +40 -0
@@ -0,0 +1,2 @@
1
+ import { Tree, TreeRow } from "./tree.js";
2
+ export { Tree, TreeRow };
@@ -0,0 +1,46 @@
1
+ /** A visible tree row's host-owned projection metadata. */
2
+ export type TreeItemDescriptor = {
3
+ /** Stable identity shared with the host's domain item. */
4
+ id: string;
5
+ /** Stable parent identity, or null for a root item. */
6
+ parentId: string | null;
7
+ /** One-based depth exposed to assistive technology. */
8
+ level: number;
9
+ /** Whether this item can be expanded. */
10
+ expandable: boolean;
11
+ /** Whether this item is currently expanded. */
12
+ expanded: boolean;
13
+ };
14
+ export type TreeNavigationIndex = {
15
+ ids: readonly string[];
16
+ byId: ReadonlyMap<string, TreeItemDescriptor>;
17
+ indexById: ReadonlyMap<string, number>;
18
+ firstChildByParent: ReadonlyMap<string, string>;
19
+ positionById: ReadonlyMap<string, {
20
+ position: number;
21
+ setSize: number;
22
+ }>;
23
+ };
24
+ export type TreeNavigationAction = {
25
+ type: 'focus';
26
+ id: string;
27
+ } | {
28
+ type: 'expand';
29
+ id: string;
30
+ expanded: boolean;
31
+ } | {
32
+ type: 'activate';
33
+ id: string;
34
+ } | {
35
+ type: 'select';
36
+ id: string;
37
+ };
38
+ /**
39
+ * Indexes the complete expanded projection once per host update. The DOM may
40
+ * contain only a window of these rows; this index keeps keyboard movement and
41
+ * aria-setsize independent of the mounted window.
42
+ */
43
+ export declare function indexTreeItems(items: readonly TreeItemDescriptor[]): TreeNavigationIndex;
44
+ /** Resolves one keyboard event without owning tree data or host actions. */
45
+ export declare function treeNavigationAction(index: TreeNavigationIndex, activeId: string | null, key: string): TreeNavigationAction | null;
46
+ //# sourceMappingURL=tree-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/tree/tree-navigation.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAA;IACV,uDAAuD;IACvD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;IACb,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAA;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;IACtB,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC7C,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACzE,CAAA;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAElC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,GAAG,mBAAmB,CAoCxF;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,GAAG,EAAE,MAAM,GACV,oBAAoB,GAAG,IAAI,CAqC7B"}
@@ -0,0 +1,95 @@
1
+ //#region src/components/composites/tree/tree-navigation.ts
2
+ /**
3
+ * Indexes the complete expanded projection once per host update. The DOM may
4
+ * contain only a window of these rows; this index keeps keyboard movement and
5
+ * aria-setsize independent of the mounted window.
6
+ */
7
+ function indexTreeItems(items) {
8
+ const byId = /* @__PURE__ */ new Map();
9
+ const indexById = /* @__PURE__ */ new Map();
10
+ const firstChildByParent = /* @__PURE__ */ new Map();
11
+ const siblingsByParent = /* @__PURE__ */ new Map();
12
+ items.forEach((item, index) => {
13
+ if (byId.has(item.id)) throw new Error(`[adea-ui]: Tree visibleItems contains duplicate id "${item.id}".`);
14
+ byId.set(item.id, item);
15
+ indexById.set(item.id, index);
16
+ const siblings = siblingsByParent.get(item.parentId) ?? [];
17
+ siblings.push(item.id);
18
+ siblingsByParent.set(item.parentId, siblings);
19
+ if (item.parentId !== null && !firstChildByParent.has(item.parentId)) firstChildByParent.set(item.parentId, item.id);
20
+ });
21
+ const positionById = /* @__PURE__ */ new Map();
22
+ for (const siblings of siblingsByParent.values()) siblings.forEach((id, index) => {
23
+ positionById.set(id, {
24
+ position: index + 1,
25
+ setSize: siblings.length
26
+ });
27
+ });
28
+ return {
29
+ ids: items.map((item) => item.id),
30
+ byId,
31
+ indexById,
32
+ firstChildByParent,
33
+ positionById
34
+ };
35
+ }
36
+ /** Resolves one keyboard event without owning tree data or host actions. */
37
+ function treeNavigationAction(index, activeId, key) {
38
+ const { ids, byId, indexById, firstChildByParent } = index;
39
+ if (ids.length === 0) return null;
40
+ const activeIndex = activeId === null ? void 0 : indexById.get(activeId);
41
+ const active = activeId === null ? void 0 : byId.get(activeId);
42
+ if (key === "ArrowDown" || key === "ArrowUp") {
43
+ const step = key === "ArrowDown" ? 1 : -1;
44
+ const id = ids[((activeIndex ?? (step > 0 ? -1 : 0)) + step + ids.length) % ids.length];
45
+ return id === void 0 ? null : {
46
+ type: "focus",
47
+ id
48
+ };
49
+ }
50
+ if (key === "Home") return {
51
+ type: "focus",
52
+ id: ids[0]
53
+ };
54
+ if (key === "End") return {
55
+ type: "focus",
56
+ id: ids[ids.length - 1]
57
+ };
58
+ if (!active) return null;
59
+ if (key === "ArrowRight" && active.expandable) {
60
+ if (!active.expanded) return {
61
+ type: "expand",
62
+ id: active.id,
63
+ expanded: true
64
+ };
65
+ const childId = firstChildByParent.get(active.id);
66
+ return childId ? {
67
+ type: "focus",
68
+ id: childId
69
+ } : null;
70
+ }
71
+ if (key === "ArrowLeft") {
72
+ if (active.expandable && active.expanded) return {
73
+ type: "expand",
74
+ id: active.id,
75
+ expanded: false
76
+ };
77
+ if (active.parentId !== null && byId.has(active.parentId)) return {
78
+ type: "focus",
79
+ id: active.parentId
80
+ };
81
+ }
82
+ if (key === "Enter") return {
83
+ type: "activate",
84
+ id: active.id
85
+ };
86
+ if (key === " " || key === "Spacebar") return {
87
+ type: "select",
88
+ id: active.id
89
+ };
90
+ return null;
91
+ }
92
+ //#endregion
93
+ export { indexTreeItems, treeNavigationAction };
94
+
95
+ //# sourceMappingURL=tree-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.js","names":[],"sources":["../../../../src/components/composites/tree/tree-navigation.ts"],"sourcesContent":["/** A visible tree row's host-owned projection metadata. */\nexport type TreeItemDescriptor = {\n /** Stable identity shared with the host's domain item. */\n id: string\n /** Stable parent identity, or null for a root item. */\n parentId: string | null\n /** One-based depth exposed to assistive technology. */\n level: number\n /** Whether this item can be expanded. */\n expandable: boolean\n /** Whether this item is currently expanded. */\n expanded: boolean\n}\n\nexport type TreeNavigationIndex = {\n ids: readonly string[]\n byId: ReadonlyMap<string, TreeItemDescriptor>\n indexById: ReadonlyMap<string, number>\n firstChildByParent: ReadonlyMap<string, string>\n positionById: ReadonlyMap<string, { position: number; setSize: number }>\n}\n\nexport type TreeNavigationAction =\n | { type: 'focus'; id: string }\n | { type: 'expand'; id: string; expanded: boolean }\n | { type: 'activate'; id: string }\n | { type: 'select'; id: string }\n\n/**\n * Indexes the complete expanded projection once per host update. The DOM may\n * contain only a window of these rows; this index keeps keyboard movement and\n * aria-setsize independent of the mounted window.\n */\nexport function indexTreeItems(items: readonly TreeItemDescriptor[]): TreeNavigationIndex {\n const byId = new Map<string, TreeItemDescriptor>()\n const indexById = new Map<string, number>()\n const firstChildByParent = new Map<string, string>()\n const siblingsByParent = new Map<string | null, string[]>()\n\n items.forEach((item, index) => {\n if (byId.has(item.id)) {\n throw new Error(`[adea-ui]: Tree visibleItems contains duplicate id \"${item.id}\".`)\n }\n byId.set(item.id, item)\n indexById.set(item.id, index)\n\n const siblings = siblingsByParent.get(item.parentId) ?? []\n siblings.push(item.id)\n siblingsByParent.set(item.parentId, siblings)\n\n if (item.parentId !== null && !firstChildByParent.has(item.parentId)) {\n firstChildByParent.set(item.parentId, item.id)\n }\n })\n\n const positionById = new Map<string, { position: number; setSize: number }>()\n for (const siblings of siblingsByParent.values()) {\n siblings.forEach((id, index) => {\n positionById.set(id, { position: index + 1, setSize: siblings.length })\n })\n }\n\n return {\n ids: items.map((item) => item.id),\n byId,\n indexById,\n firstChildByParent,\n positionById,\n }\n}\n\n/** Resolves one keyboard event without owning tree data or host actions. */\nexport function treeNavigationAction(\n index: TreeNavigationIndex,\n activeId: string | null,\n key: string\n): TreeNavigationAction | null {\n const { ids, byId, indexById, firstChildByParent } = index\n if (ids.length === 0) return null\n\n const activeIndex = activeId === null ? undefined : indexById.get(activeId)\n const active = activeId === null ? undefined : byId.get(activeId)\n\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n const step = key === 'ArrowDown' ? 1 : -1\n const start = activeIndex ?? (step > 0 ? -1 : 0)\n const nextIndex = (start + step + ids.length) % ids.length\n const id = ids[nextIndex]\n return id === undefined ? null : { type: 'focus', id }\n }\n\n if (key === 'Home') return { type: 'focus', id: ids[0]! }\n if (key === 'End') return { type: 'focus', id: ids[ids.length - 1]! }\n if (!active) return null\n\n if (key === 'ArrowRight' && active.expandable) {\n if (!active.expanded) return { type: 'expand', id: active.id, expanded: true }\n const childId = firstChildByParent.get(active.id)\n return childId ? { type: 'focus', id: childId } : null\n }\n\n if (key === 'ArrowLeft') {\n if (active.expandable && active.expanded) {\n return { type: 'expand', id: active.id, expanded: false }\n }\n if (active.parentId !== null && byId.has(active.parentId)) {\n return { type: 'focus', id: active.parentId }\n }\n }\n\n if (key === 'Enter') return { type: 'activate', id: active.id }\n if (key === ' ' || key === 'Spacebar') return { type: 'select', id: active.id }\n return null\n}\n"],"mappings":";;;;;;AAiCA,SAAgB,eAAe,OAA2D;CACxF,MAAM,uBAAO,IAAI,IAAgC;CACjD,MAAM,4BAAY,IAAI,IAAoB;CAC1C,MAAM,qCAAqB,IAAI,IAAoB;CACnD,MAAM,mCAAmB,IAAI,IAA6B;CAE1D,MAAM,SAAS,MAAM,UAAU;EAC7B,IAAI,KAAK,IAAI,KAAK,EAAE,GAClB,MAAM,IAAI,MAAM,uDAAuD,KAAK,GAAG,GAAG;EAEpF,KAAK,IAAI,KAAK,IAAI,IAAI;EACtB,UAAU,IAAI,KAAK,IAAI,KAAK;EAE5B,MAAM,WAAW,iBAAiB,IAAI,KAAK,QAAQ,KAAK,CAAC;EACzD,SAAS,KAAK,KAAK,EAAE;EACrB,iBAAiB,IAAI,KAAK,UAAU,QAAQ;EAE5C,IAAI,KAAK,aAAa,QAAQ,CAAC,mBAAmB,IAAI,KAAK,QAAQ,GACjE,mBAAmB,IAAI,KAAK,UAAU,KAAK,EAAE;CAEjD,CAAC;CAED,MAAM,+BAAe,IAAI,IAAmD;CAC5E,KAAK,MAAM,YAAY,iBAAiB,OAAO,GAC7C,SAAS,SAAS,IAAI,UAAU;EAC9B,aAAa,IAAI,IAAI;GAAE,UAAU,QAAQ;GAAG,SAAS,SAAS;EAAO,CAAC;CACxE,CAAC;CAGH,OAAO;EACL,KAAK,MAAM,KAAK,SAAS,KAAK,EAAE;EAChC;EACA;EACA;EACA;CACF;AACF;;AAGA,SAAgB,qBACd,OACA,UACA,KAC6B;CAC7B,MAAM,EAAE,KAAK,MAAM,WAAW,uBAAuB;CACrD,IAAI,IAAI,WAAW,GAAG,OAAO;CAE7B,MAAM,cAAc,aAAa,OAAO,KAAA,IAAY,UAAU,IAAI,QAAQ;CAC1E,MAAM,SAAS,aAAa,OAAO,KAAA,IAAY,KAAK,IAAI,QAAQ;CAEhE,IAAI,QAAQ,eAAe,QAAQ,WAAW;EAC5C,MAAM,OAAO,QAAQ,cAAc,IAAI;EAGvC,MAAM,KAAK,MAFG,gBAAgB,OAAO,IAAI,KAAK,MACnB,OAAO,IAAI,UAAU,IAAI;EAEpD,OAAO,OAAO,KAAA,IAAY,OAAO;GAAE,MAAM;GAAS;EAAG;CACvD;CAEA,IAAI,QAAQ,QAAQ,OAAO;EAAE,MAAM;EAAS,IAAI,IAAI;CAAI;CACxD,IAAI,QAAQ,OAAO,OAAO;EAAE,MAAM;EAAS,IAAI,IAAI,IAAI,SAAS;CAAI;CACpE,IAAI,CAAC,QAAQ,OAAO;CAEpB,IAAI,QAAQ,gBAAgB,OAAO,YAAY;EAC7C,IAAI,CAAC,OAAO,UAAU,OAAO;GAAE,MAAM;GAAU,IAAI,OAAO;GAAI,UAAU;EAAK;EAC7E,MAAM,UAAU,mBAAmB,IAAI,OAAO,EAAE;EAChD,OAAO,UAAU;GAAE,MAAM;GAAS,IAAI;EAAQ,IAAI;CACpD;CAEA,IAAI,QAAQ,aAAa;EACvB,IAAI,OAAO,cAAc,OAAO,UAC9B,OAAO;GAAE,MAAM;GAAU,IAAI,OAAO;GAAI,UAAU;EAAM;EAE1D,IAAI,OAAO,aAAa,QAAQ,KAAK,IAAI,OAAO,QAAQ,GACtD,OAAO;GAAE,MAAM;GAAS,IAAI,OAAO;EAAS;CAEhD;CAEA,IAAI,QAAQ,SAAS,OAAO;EAAE,MAAM;EAAY,IAAI,OAAO;CAAG;CAC9D,IAAI,QAAQ,OAAO,QAAQ,YAAY,OAAO;EAAE,MAAM;EAAU,IAAI,OAAO;CAAG;CAC9E,OAAO;AACT"}
@@ -0,0 +1,64 @@
1
+ import type { ComponentProps, JSX } from 'solid-js';
2
+ import { type TreeItemDescriptor } from './tree-navigation';
3
+ type TreeAccessibleName = {
4
+ 'aria-label': string;
5
+ 'aria-labelledby'?: string;
6
+ } | {
7
+ 'aria-label'?: string;
8
+ 'aria-labelledby': string;
9
+ };
10
+ export type TreeProps = Omit<ComponentProps<'div'>, 'children' | 'role' | 'tabIndex' | 'onKeyDown' | 'aria-label' | 'aria-labelledby'> & TreeAccessibleName & {
11
+ /** Complete, ordered projection of currently visible (expanded) items. */
12
+ visibleItems: readonly TreeItemDescriptor[];
13
+ /** The host-owned identity of the row that currently owns roving focus. */
14
+ activeId: string | null;
15
+ /** Called when keyboard or pointer navigation changes the active row. */
16
+ onActiveIdChange: (id: string) => void;
17
+ /** Called for Left/Right expand and collapse requests. */
18
+ onExpand?: (id: string, expanded: boolean) => void;
19
+ /** Called for Enter or pointer activation. Domain action stays host-owned. */
20
+ onActivate?: (id: string, event: Event) => void;
21
+ /** Called for Space selection. Selection state stays host-owned. */
22
+ onSelectItem?: (id: string, event: Event) => void;
23
+ /** Ask the host window to mount/reveal an item before focus moves to it. */
24
+ onRequestReveal?: (id: string) => void;
25
+ /** Report a mounted row's border-box block size in CSS pixels for host range math. */
26
+ onRowSizeChange?: (id: string, blockSize: number) => void;
27
+ /** Declares a multi-select tree to assistive technology. */
28
+ selectionMode?: 'single' | 'multiple';
29
+ children?: JSX.Element;
30
+ };
31
+ /**
32
+ * Tree.
33
+ *
34
+ * Supplies semantic and keyboard behavior for a tree whose host owns the
35
+ * visible projection, filesystem state, row window and domain actions. The
36
+ * mounted children can be a small virtualized window; `visibleItems` remains
37
+ * the complete ordered projection so keyboard movement and sibling positions
38
+ * do not depend on which rows currently exist in the DOM.
39
+ *
40
+ * Kobalte 0.13.14 has no Tree primitive, so this component implements the
41
+ * WAI-ARIA tree row navigation contract and leaves product state to callbacks.
42
+ */
43
+ export declare function Tree(props: TreeProps): JSX.Element;
44
+ export type TreeRowProps = Omit<ComponentProps<'div'>, 'children' | 'role' | 'tabIndex' | 'onClick' | 'onFocus' | 'onDoubleClick' | 'style' | 'aria-level' | 'aria-expanded' | 'aria-selected' | 'aria-posinset' | 'aria-setsize'> & {
45
+ item: TreeItemDescriptor;
46
+ /** Host-owned selection state; omitted for non-selectable trees. */
47
+ selected?: boolean;
48
+ leading?: JSX.Element;
49
+ trailing?: JSX.Element;
50
+ children: JSX.Element;
51
+ onDoubleClick?: (id: string, event: MouseEvent & {
52
+ currentTarget: HTMLDivElement;
53
+ }) => void;
54
+ };
55
+ /**
56
+ * TreeRow.
57
+ *
58
+ * Keeps the donor's disclosure marker, leading file/folder affordance, primary
59
+ * label and trailing-action hierarchy while replacing the donor's button and
60
+ * runtime callbacks with a shared treeitem and host-owned slots/actions.
61
+ */
62
+ export declare function TreeRow(props: TreeRowProps): JSX.Element;
63
+ export type { TreeItemDescriptor } from './tree-navigation';
64
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/tree/tree.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAYnD,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAA;AAsB1B,KAAK,kBAAkB,GACnB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAA;AAExD,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,cAAc,CAAC,KAAK,CAAC,EACrB,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,iBAAiB,CAClF,GACC,kBAAkB,GAAG;IACnB,0EAA0E;IAC1E,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC3C,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,yEAAyE;IACzE,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAClD,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAC/C,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACjD,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,sFAAsF;IACtF,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD,4DAA4D;IAC5D,aAAa,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;IACrC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,eAsKpC;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,cAAc,CAAC,KAAK,CAAC,EACnB,UAAU,GACV,MAAM,GACN,UAAU,GACV,SAAS,GACT,SAAS,GACT,eAAe,GACf,OAAO,GACP,YAAY,GACZ,eAAe,GACf,eAAe,GACf,eAAe,GACf,cAAc,CACjB,GAAG;IACF,IAAI,EAAE,kBAAkB,CAAA;IACxB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG;QAAE,aAAa,EAAE,cAAc,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5F,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,eAsG1C;AAsBD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,311 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { indexTreeItems, treeNavigationAction } from "./tree-navigation.js";
3
+ import { createComponent, insert, memo, mergeProps, spread, template, use } from "solid-js/web";
4
+ import { ChevronRight } from "lucide-solid";
5
+ import { createContext, createEffect, createMemo, createUniqueId, onCleanup, splitProps, useContext } from "solid-js";
6
+ //#region src/components/composites/tree/tree.tsx
7
+ var _tmpl$ = /*#__PURE__*/ template(`<div>`);
8
+ var _tmpl$2 = /*#__PURE__*/ template(`<div><span class="flex size-3.5 shrink-0 items-center justify-center text-muted-foreground"></span><span class="min-w-0 flex-1 truncate">`);
9
+ var _tmpl$3 = /*#__PURE__*/ template(`<span class="flex size-4 shrink-0 items-center justify-center [&amp;_svg]:size-4">`);
10
+ var _tmpl$4 = /*#__PURE__*/ template(`<span class="ms-auto flex shrink-0 items-center gap-1 text-muted-foreground">`);
11
+ var TreeContext = createContext();
12
+ function useTreeContext() {
13
+ const tree = useContext(TreeContext);
14
+ if (!tree) throw new Error("[adea-ui]: TreeRow must be used inside Tree.");
15
+ return tree;
16
+ }
17
+ /**
18
+ * Tree.
19
+ *
20
+ * Supplies semantic and keyboard behavior for a tree whose host owns the
21
+ * visible projection, filesystem state, row window and domain actions. The
22
+ * mounted children can be a small virtualized window; `visibleItems` remains
23
+ * the complete ordered projection so keyboard movement and sibling positions
24
+ * do not depend on which rows currently exist in the DOM.
25
+ *
26
+ * Kobalte 0.13.14 has no Tree primitive, so this component implements the
27
+ * WAI-ARIA tree row navigation contract and leaves product state to callbacks.
28
+ */
29
+ function Tree(props) {
30
+ const [local, rest] = splitProps(props, [
31
+ "class",
32
+ "visibleItems",
33
+ "activeId",
34
+ "onActiveIdChange",
35
+ "onExpand",
36
+ "onActivate",
37
+ "onSelectItem",
38
+ "onRequestReveal",
39
+ "onRowSizeChange",
40
+ "selectionMode",
41
+ "children"
42
+ ]);
43
+ const index = createMemo(() => indexTreeItems(local.visibleItems));
44
+ const effectiveActiveId = createMemo(() => {
45
+ const candidate = local.activeId;
46
+ const visible = index();
47
+ return candidate !== null && visible.byId.has(candidate) ? candidate : visible.ids[0] ?? null;
48
+ });
49
+ const idPrefix = `tree-${createUniqueId()}`;
50
+ const rows = /* @__PURE__ */ new Map();
51
+ const rowIdsByElement = /* @__PURE__ */ new WeakMap();
52
+ let pendingFocusId = null;
53
+ let requestedRevealId = null;
54
+ let focusedId = null;
55
+ let disposed = false;
56
+ const rowSizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver((entries) => {
57
+ if (disposed) return;
58
+ for (const entry of entries) {
59
+ const id = rowIdsByElement.get(entry.target);
60
+ const blockSize = entry.borderBoxSize[0]?.blockSize ?? entry.target.offsetHeight;
61
+ if (id !== void 0 && Number.isFinite(blockSize) && blockSize > 0) local.onRowSizeChange?.(id, blockSize);
62
+ }
63
+ });
64
+ onCleanup(() => {
65
+ disposed = true;
66
+ rowSizeObserver?.disconnect();
67
+ });
68
+ const requestReveal = (id) => {
69
+ if (requestedRevealId === id) return;
70
+ requestedRevealId = id;
71
+ local.onRequestReveal?.(id);
72
+ };
73
+ const focusWhenMounted = (id) => {
74
+ queueMicrotask(() => {
75
+ if (pendingFocusId !== id || effectiveActiveId() !== id) return;
76
+ const row = rows.get(id);
77
+ if (!row || typeof document === "undefined") return;
78
+ row.focus();
79
+ if (document.activeElement === row) pendingFocusId = null;
80
+ });
81
+ };
82
+ const focusItem = (id) => {
83
+ pendingFocusId = id;
84
+ local.onActiveIdChange(id);
85
+ if (rows.has(id)) requestedRevealId = null;
86
+ else requestReveal(id);
87
+ focusWhenMounted(id);
88
+ };
89
+ const context = {
90
+ idPrefix,
91
+ activeId: effectiveActiveId,
92
+ index,
93
+ register: (id, element) => {
94
+ rows.set(id, element);
95
+ rowIdsByElement.set(element, id);
96
+ rowSizeObserver?.observe(element);
97
+ if (requestedRevealId === id) requestedRevealId = null;
98
+ if (pendingFocusId === id) focusWhenMounted(id);
99
+ },
100
+ unregister: (id, element) => {
101
+ if (rows.get(id) !== element) return;
102
+ const focusWasInside = !disposed && Boolean(element && typeof document !== "undefined" && element.contains(document.activeElement));
103
+ rows.delete(id);
104
+ if (element) {
105
+ rowIdsByElement.delete(element);
106
+ rowSizeObserver?.unobserve(element);
107
+ }
108
+ if (requestedRevealId === id) requestedRevealId = null;
109
+ if (focusWasInside) queueMicrotask(() => {
110
+ const fallbackId = effectiveActiveId();
111
+ if (!disposed && fallbackId !== null && pendingFocusId !== fallbackId) focusItem(fallbackId);
112
+ });
113
+ },
114
+ focusItem,
115
+ noteFocus: (id) => {
116
+ focusedId = id;
117
+ },
118
+ activate: (id, event) => local.onActivate?.(id, event),
119
+ onActiveIdChange: local.onActiveIdChange
120
+ };
121
+ createEffect(() => {
122
+ const activeId = effectiveActiveId();
123
+ if (activeId === null) return;
124
+ if (focusedId !== null && !index().byId.has(focusedId) && pendingFocusId !== activeId) focusItem(activeId);
125
+ else if (local.activeId !== activeId) local.onActiveIdChange(activeId);
126
+ if (!rows.has(activeId)) requestReveal(activeId);
127
+ if (pendingFocusId === activeId) focusWhenMounted(activeId);
128
+ });
129
+ const handleKeyDown = (event) => {
130
+ if (event.defaultPrevented || isActionTarget(event.target, event.currentTarget)) return;
131
+ const action = treeNavigationAction(index(), effectiveActiveId(), event.key);
132
+ if (!action) return;
133
+ event.preventDefault();
134
+ switch (action.type) {
135
+ case "focus":
136
+ focusItem(action.id);
137
+ break;
138
+ case "expand":
139
+ local.onExpand?.(action.id, action.expanded);
140
+ break;
141
+ case "activate":
142
+ local.onActivate?.(action.id, event);
143
+ break;
144
+ case "select": local.onSelectItem?.(action.id, event);
145
+ }
146
+ };
147
+ return createComponent(TreeContext.Provider, {
148
+ value: context,
149
+ get children() {
150
+ var _el$ = _tmpl$();
151
+ spread(_el$, mergeProps(rest, {
152
+ "role": "tree",
153
+ get ["aria-multiselectable"]() {
154
+ return local.selectionMode === "multiple" ? "true" : void 0;
155
+ },
156
+ "data-slot": "tree",
157
+ get ["class"]() {
158
+ return cn("flex min-w-0 flex-col", local.class);
159
+ },
160
+ "onKeyDown": handleKeyDown
161
+ }), false, true);
162
+ insert(_el$, () => local.children);
163
+ return _el$;
164
+ }
165
+ });
166
+ }
167
+ /**
168
+ * TreeRow.
169
+ *
170
+ * Keeps the donor's disclosure marker, leading file/folder affordance, primary
171
+ * label and trailing-action hierarchy while replacing the donor's button and
172
+ * runtime callbacks with a shared treeitem and host-owned slots/actions.
173
+ */
174
+ function TreeRow(props) {
175
+ const tree = useTreeContext();
176
+ const [local, rest] = splitProps(props, [
177
+ "class",
178
+ "item",
179
+ "selected",
180
+ "leading",
181
+ "trailing",
182
+ "children",
183
+ "onDoubleClick",
184
+ "ref"
185
+ ]);
186
+ let row;
187
+ let registeredId;
188
+ const id = () => local.item.id;
189
+ onCleanup(() => tree.unregister(registeredId ?? id(), row));
190
+ const setRef = (element) => {
191
+ row = element;
192
+ registeredId = id();
193
+ tree.register(registeredId, element);
194
+ };
195
+ createEffect(() => {
196
+ const nextId = id();
197
+ if (!row || registeredId === nextId) return;
198
+ if (registeredId !== void 0) tree.unregister(registeredId, row);
199
+ registeredId = nextId;
200
+ tree.register(nextId, row);
201
+ });
202
+ const handleFocus = () => {
203
+ tree.noteFocus(id());
204
+ if (tree.activeId() !== id()) tree.onActiveIdChange(id());
205
+ };
206
+ const handleClick = (event) => {
207
+ if (isActionTarget(event.target, event.currentTarget)) return;
208
+ tree.focusItem(id());
209
+ tree.activate(id(), event);
210
+ };
211
+ const handleDoubleClick = (event) => {
212
+ if (isActionTarget(event.target, event.currentTarget)) return;
213
+ local.onDoubleClick?.(id(), event);
214
+ };
215
+ const position = () => tree.index().positionById.get(id());
216
+ return (() => {
217
+ var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
218
+ var _ref$ = composeRefs(setRef, () => local.ref);
219
+ typeof _ref$ === "function" && use(_ref$, _el$2);
220
+ spread(_el$2, mergeProps(rest, {
221
+ get id() {
222
+ return rest.id ?? `${tree.idPrefix}-item-${encodeURIComponent(id())}`;
223
+ },
224
+ "role": "treeitem",
225
+ get ["aria-level"]() {
226
+ return local.item.level;
227
+ },
228
+ get ["aria-expanded"]() {
229
+ return memo(() => !!local.item.expandable)() ? local.item.expanded ? "true" : "false" : void 0;
230
+ },
231
+ get ["aria-selected"]() {
232
+ return memo(() => local.selected === void 0)() ? void 0 : local.selected ? "true" : "false";
233
+ },
234
+ get ["aria-posinset"]() {
235
+ return position()?.position;
236
+ },
237
+ get ["aria-setsize"]() {
238
+ return position()?.setSize;
239
+ },
240
+ get tabIndex() {
241
+ return tree.activeId() === id() ? 0 : -1;
242
+ },
243
+ get ["data-tree-id"]() {
244
+ return id();
245
+ },
246
+ get ["data-active"]() {
247
+ return tree.activeId() === id() ? "" : void 0;
248
+ },
249
+ get ["data-selected"]() {
250
+ return local.selected ? "" : void 0;
251
+ },
252
+ get ["data-expanded"]() {
253
+ return memo(() => !!local.item.expandable)() ? String(local.item.expanded) : void 0;
254
+ },
255
+ get ["class"]() {
256
+ return cn("group/tree-row flex min-h-row-sm w-full min-w-0 items-center gap-1.5 rounded-md pe-1.5 text-left text-sm outline-none transition-colors", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", {
257
+ "bg-primary-subtle text-foreground": local.selected,
258
+ "hover:bg-surface-hover": !local.selected
259
+ }, local.class);
260
+ },
261
+ get style() {
262
+ return { "padding-inline-start": `${6 + Math.max(0, local.item.level - 1) * 12}px` };
263
+ },
264
+ "onFocus": handleFocus,
265
+ "onClick": handleClick,
266
+ "onDblClick": handleDoubleClick
267
+ }), false, true);
268
+ insert(_el$3, (() => {
269
+ var _c$ = memo(() => !!local.item.expandable);
270
+ return () => _c$() ? createComponent(ChevronRight, {
271
+ "aria-hidden": "true",
272
+ get ["class"]() {
273
+ return cn("size-3.5 transition-transform", local.item.expanded && "rotate-90");
274
+ }
275
+ }) : null;
276
+ })());
277
+ insert(_el$2, (() => {
278
+ var _c$2 = memo(() => !!local.leading);
279
+ return () => _c$2() ? (() => {
280
+ var _el$5 = _tmpl$3();
281
+ insert(_el$5, () => local.leading);
282
+ return _el$5;
283
+ })() : null;
284
+ })(), _el$4);
285
+ insert(_el$4, () => local.children);
286
+ insert(_el$2, (() => {
287
+ var _c$3 = memo(() => !!local.trailing);
288
+ return () => _c$3() ? (() => {
289
+ var _el$6 = _tmpl$4();
290
+ insert(_el$6, () => local.trailing);
291
+ return _el$6;
292
+ })() : null;
293
+ })(), null);
294
+ return _el$2;
295
+ })();
296
+ }
297
+ function isActionTarget(target, currentTarget) {
298
+ if (!(target instanceof Element) || target === currentTarget) return false;
299
+ return Boolean(target.closest("a, button, input, textarea, select, [contenteditable=\"true\"], [role=\"button\"], [data-tree-keyboard-stop]"));
300
+ }
301
+ function composeRefs(internal, external) {
302
+ return (element) => {
303
+ internal(element);
304
+ const ref = external();
305
+ if (typeof ref === "function") ref(element);
306
+ };
307
+ }
308
+ //#endregion
309
+ export { Tree, TreeRow };
310
+
311
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","names":["ComponentProps","JSX","ChevronRight","createContext","createEffect","createMemo","createUniqueId","onCleanup","splitProps","useContext","cn","indexTreeItems","treeNavigationAction","TreeItemDescriptor","TreeNavigationIndex","TreeContextValue","idPrefix","activeId","index","register","id","element","HTMLDivElement","unregister","focusItem","noteFocus","activate","event","Event","onActiveIdChange","TreeContext","useTreeContext","tree","Error","TreeAccessibleName","TreeProps","Omit","visibleItems","onExpand","expanded","onActivate","onSelectItem","onRequestReveal","onRowSizeChange","blockSize","selectionMode","children","Element","Tree","props","local","rest","effectiveActiveId","candidate","visible","byId","has","ids","rows","Map","rowIdsByElement","WeakMap","pendingFocusId","requestedRevealId","focusedId","disposed","rowSizeObserver","ResizeObserver","undefined","entries","entry","get","target","borderBoxSize","HTMLElement","offsetHeight","Number","isFinite","disconnect","requestReveal","focusWhenMounted","queueMicrotask","row","document","focus","activeElement","context","set","observe","focusWasInside","Boolean","contains","delete","unobserve","fallbackId","handleKeyDown","EventHandler","KeyboardEvent","defaultPrevented","isActionTarget","currentTarget","action","key","preventDefault","type","_$createComponent","Provider","value","_el$","_tmpl$","_$spread","_$mergeProps","aria-multiselectable","class","_$insert","TreeRowProps","item","selected","leading","trailing","onDoubleClick","MouseEvent","TreeRow","registeredId","setRef","nextId","handleFocus","handleClick","handleDoubleClick","position","positionById","_el$2","_tmpl$2","_el$3","firstChild","_el$4","nextSibling","_ref$","composeRefs","ref","_$use","encodeURIComponent","aria-level","level","aria-expanded","_$memo","expandable","aria-selected","aria-posinset","aria-setsize","setSize","tabIndex","data-tree-id","data-active","data-selected","data-expanded","String","style","Math","max","_c$","_c$2","_el$5","_tmpl$3","_c$3","_el$6","_tmpl$4","EventTarget","closest","internal","external","_$createComponent","_$mergeProps","_$use","_$memo"],"sources":["../../../../src/components/composites/tree/tree.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { ChevronRight } from 'lucide-solid'\nimport {\n createContext,\n createEffect,\n createMemo,\n createUniqueId,\n onCleanup,\n splitProps,\n useContext,\n} from 'solid-js'\nimport { cn } from '#lib/utils'\nimport {\n indexTreeItems,\n treeNavigationAction,\n type TreeItemDescriptor,\n type TreeNavigationIndex,\n} from './tree-navigation'\n\ntype TreeContextValue = {\n idPrefix: string\n activeId: () => string | null\n index: () => TreeNavigationIndex\n register: (id: string, element: HTMLDivElement) => void\n unregister: (id: string, element: HTMLDivElement | undefined) => void\n focusItem: (id: string) => void\n noteFocus: (id: string) => void\n activate: (id: string, event: Event) => void\n onActiveIdChange: (id: string) => void\n}\n\nconst TreeContext = createContext<TreeContextValue>()\n\nfunction useTreeContext() {\n const tree = useContext(TreeContext)\n if (!tree) throw new Error('[adea-ui]: TreeRow must be used inside Tree.')\n return tree\n}\n\ntype TreeAccessibleName =\n | { 'aria-label': string; 'aria-labelledby'?: string }\n | { 'aria-label'?: string; 'aria-labelledby': string }\n\nexport type TreeProps = Omit<\n ComponentProps<'div'>,\n 'children' | 'role' | 'tabIndex' | 'onKeyDown' | 'aria-label' | 'aria-labelledby'\n> &\n TreeAccessibleName & {\n /** Complete, ordered projection of currently visible (expanded) items. */\n visibleItems: readonly TreeItemDescriptor[]\n /** The host-owned identity of the row that currently owns roving focus. */\n activeId: string | null\n /** Called when keyboard or pointer navigation changes the active row. */\n onActiveIdChange: (id: string) => void\n /** Called for Left/Right expand and collapse requests. */\n onExpand?: (id: string, expanded: boolean) => void\n /** Called for Enter or pointer activation. Domain action stays host-owned. */\n onActivate?: (id: string, event: Event) => void\n /** Called for Space selection. Selection state stays host-owned. */\n onSelectItem?: (id: string, event: Event) => void\n /** Ask the host window to mount/reveal an item before focus moves to it. */\n onRequestReveal?: (id: string) => void\n /** Report a mounted row's border-box block size in CSS pixels for host range math. */\n onRowSizeChange?: (id: string, blockSize: number) => void\n /** Declares a multi-select tree to assistive technology. */\n selectionMode?: 'single' | 'multiple'\n children?: JSX.Element\n }\n\n/**\n * Tree.\n *\n * Supplies semantic and keyboard behavior for a tree whose host owns the\n * visible projection, filesystem state, row window and domain actions. The\n * mounted children can be a small virtualized window; `visibleItems` remains\n * the complete ordered projection so keyboard movement and sibling positions\n * do not depend on which rows currently exist in the DOM.\n *\n * Kobalte 0.13.14 has no Tree primitive, so this component implements the\n * WAI-ARIA tree row navigation contract and leaves product state to callbacks.\n */\nexport function Tree(props: TreeProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'visibleItems',\n 'activeId',\n 'onActiveIdChange',\n 'onExpand',\n 'onActivate',\n 'onSelectItem',\n 'onRequestReveal',\n 'onRowSizeChange',\n 'selectionMode',\n 'children',\n ])\n\n const index = createMemo(() => indexTreeItems(local.visibleItems))\n const effectiveActiveId = createMemo(() => {\n const candidate = local.activeId\n const visible = index()\n return candidate !== null && visible.byId.has(candidate) ? candidate : (visible.ids[0] ?? null)\n })\n const idPrefix = `tree-${createUniqueId()}`\n const rows = new Map<string, HTMLDivElement>()\n const rowIdsByElement = new WeakMap<HTMLDivElement, string>()\n let pendingFocusId: string | null = null\n let requestedRevealId: string | null = null\n let focusedId: string | null = null\n let disposed = false\n const rowSizeObserver =\n typeof ResizeObserver === 'undefined'\n ? undefined\n : new ResizeObserver((entries) => {\n if (disposed) return\n for (const entry of entries) {\n const id = rowIdsByElement.get(entry.target as HTMLDivElement)\n const blockSize =\n entry.borderBoxSize[0]?.blockSize ?? (entry.target as HTMLElement).offsetHeight\n if (id !== undefined && Number.isFinite(blockSize) && blockSize > 0)\n local.onRowSizeChange?.(id, blockSize)\n }\n })\n\n onCleanup(() => {\n disposed = true\n rowSizeObserver?.disconnect()\n })\n\n const requestReveal = (id: string) => {\n if (requestedRevealId === id) return\n requestedRevealId = id\n local.onRequestReveal?.(id)\n }\n\n const focusWhenMounted = (id: string) => {\n queueMicrotask(() => {\n if (pendingFocusId !== id || effectiveActiveId() !== id) return\n const row = rows.get(id)\n if (!row || typeof document === 'undefined') return\n row.focus()\n if (document.activeElement === row) pendingFocusId = null\n })\n }\n\n const focusItem = (id: string) => {\n pendingFocusId = id\n local.onActiveIdChange(id)\n if (rows.has(id)) requestedRevealId = null\n else requestReveal(id)\n focusWhenMounted(id)\n }\n\n const context: TreeContextValue = {\n idPrefix,\n activeId: effectiveActiveId,\n index,\n register: (id, element) => {\n rows.set(id, element)\n rowIdsByElement.set(element, id)\n rowSizeObserver?.observe(element)\n if (requestedRevealId === id) requestedRevealId = null\n if (pendingFocusId === id) focusWhenMounted(id)\n },\n unregister: (id, element) => {\n if (rows.get(id) !== element) return\n const focusWasInside =\n !disposed &&\n Boolean(\n element && typeof document !== 'undefined' && element.contains(document.activeElement)\n )\n rows.delete(id)\n if (element) {\n rowIdsByElement.delete(element)\n rowSizeObserver?.unobserve(element)\n }\n if (requestedRevealId === id) requestedRevealId = null\n if (focusWasInside) {\n queueMicrotask(() => {\n const fallbackId = effectiveActiveId()\n if (!disposed && fallbackId !== null && pendingFocusId !== fallbackId)\n focusItem(fallbackId)\n })\n }\n },\n focusItem,\n noteFocus: (id) => {\n focusedId = id\n },\n activate: (id, event) => local.onActivate?.(id, event),\n onActiveIdChange: local.onActiveIdChange,\n }\n\n // A filtered or removed active ID falls back to the first visible item. This\n // keeps one treeitem in the sequential tab order while notifying the host.\n createEffect(() => {\n const activeId = effectiveActiveId()\n if (activeId === null) return\n // If a host filter removes the row that had DOM focus, move focus to the\n // same projection fallback that now owns the roving tab stop.\n if (focusedId !== null && !index().byId.has(focusedId) && pendingFocusId !== activeId) {\n focusItem(activeId)\n } else if (local.activeId !== activeId) {\n local.onActiveIdChange(activeId)\n }\n // Preserve the active row in a caller-owned virtual window, including when\n // the pane mounts with its saved active row outside the initial render range.\n if (!rows.has(activeId)) requestReveal(activeId)\n if (pendingFocusId === activeId) focusWhenMounted(activeId)\n })\n\n const handleKeyDown: JSX.EventHandler<HTMLDivElement, KeyboardEvent> = (event) => {\n if (event.defaultPrevented || isActionTarget(event.target, event.currentTarget)) return\n\n const action = treeNavigationAction(index(), effectiveActiveId(), event.key)\n if (!action) return\n event.preventDefault()\n\n switch (action.type) {\n case 'focus':\n focusItem(action.id)\n break\n case 'expand':\n local.onExpand?.(action.id, action.expanded)\n break\n case 'activate':\n local.onActivate?.(action.id, event)\n break\n case 'select':\n local.onSelectItem?.(action.id, event)\n break\n }\n }\n\n return (\n <TreeContext.Provider value={context}>\n <div\n {...rest}\n role=\"tree\"\n aria-multiselectable={local.selectionMode === 'multiple' ? 'true' : undefined}\n data-slot=\"tree\"\n class={cn('flex min-w-0 flex-col', local.class)}\n onKeyDown={handleKeyDown}\n >\n {local.children}\n </div>\n </TreeContext.Provider>\n )\n}\n\nexport type TreeRowProps = Omit<\n ComponentProps<'div'>,\n | 'children'\n | 'role'\n | 'tabIndex'\n | 'onClick'\n | 'onFocus'\n | 'onDoubleClick'\n | 'style'\n | 'aria-level'\n | 'aria-expanded'\n | 'aria-selected'\n | 'aria-posinset'\n | 'aria-setsize'\n> & {\n item: TreeItemDescriptor\n /** Host-owned selection state; omitted for non-selectable trees. */\n selected?: boolean\n leading?: JSX.Element\n trailing?: JSX.Element\n children: JSX.Element\n onDoubleClick?: (id: string, event: MouseEvent & { currentTarget: HTMLDivElement }) => void\n}\n\n/**\n * TreeRow.\n *\n * Keeps the donor's disclosure marker, leading file/folder affordance, primary\n * label and trailing-action hierarchy while replacing the donor's button and\n * runtime callbacks with a shared treeitem and host-owned slots/actions.\n */\nexport function TreeRow(props: TreeRowProps) {\n const tree = useTreeContext()\n const [local, rest] = splitProps(props, [\n 'class',\n 'item',\n 'selected',\n 'leading',\n 'trailing',\n 'children',\n 'onDoubleClick',\n 'ref',\n ])\n\n let row: HTMLDivElement | undefined\n let registeredId: string | undefined\n const id = () => local.item.id\n\n onCleanup(() => tree.unregister(registeredId ?? id(), row))\n\n const setRef = (element: HTMLDivElement) => {\n row = element\n registeredId = id()\n tree.register(registeredId, element)\n }\n\n createEffect(() => {\n const nextId = id()\n if (!row || registeredId === nextId) return\n if (registeredId !== undefined) tree.unregister(registeredId, row)\n registeredId = nextId\n tree.register(nextId, row)\n })\n\n const handleFocus = () => {\n tree.noteFocus(id())\n if (tree.activeId() !== id()) tree.onActiveIdChange(id())\n }\n\n const handleClick: JSX.EventHandler<HTMLDivElement, MouseEvent> = (event) => {\n if (isActionTarget(event.target, event.currentTarget)) return\n tree.focusItem(id())\n tree.activate(id(), event)\n }\n\n const handleDoubleClick: JSX.EventHandler<HTMLDivElement, MouseEvent> = (event) => {\n if (isActionTarget(event.target, event.currentTarget)) return\n local.onDoubleClick?.(id(), event)\n }\n\n const position = () => tree.index().positionById.get(id())\n\n return (\n <div\n {...rest}\n ref={composeRefs(setRef, () => local.ref)}\n id={rest.id ?? `${tree.idPrefix}-item-${encodeURIComponent(id())}`}\n role=\"treeitem\"\n aria-level={local.item.level}\n aria-expanded={local.item.expandable ? (local.item.expanded ? 'true' : 'false') : undefined}\n aria-selected={local.selected === undefined ? undefined : local.selected ? 'true' : 'false'}\n aria-posinset={position()?.position}\n aria-setsize={position()?.setSize}\n tabIndex={tree.activeId() === id() ? 0 : -1}\n data-tree-id={id()}\n data-active={tree.activeId() === id() ? '' : undefined}\n data-selected={local.selected ? '' : undefined}\n data-expanded={local.item.expandable ? String(local.item.expanded) : undefined}\n class={cn(\n 'group/tree-row flex min-h-row-sm w-full min-w-0 items-center gap-1.5 rounded-md pe-1.5 text-left text-sm outline-none transition-colors',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n {\n 'bg-primary-subtle text-foreground': local.selected,\n 'hover:bg-surface-hover': !local.selected,\n },\n local.class\n )}\n style={{ 'padding-inline-start': `${6 + Math.max(0, local.item.level - 1) * 12}px` }}\n onFocus={handleFocus}\n onClick={handleClick}\n onDblClick={handleDoubleClick}\n >\n <span class=\"flex size-3.5 shrink-0 items-center justify-center text-muted-foreground\">\n {local.item.expandable ? (\n <ChevronRight\n aria-hidden=\"true\"\n class={cn('size-3.5 transition-transform', local.item.expanded && 'rotate-90')}\n />\n ) : null}\n </span>\n {local.leading ? (\n <span class=\"flex size-4 shrink-0 items-center justify-center [&_svg]:size-4\">\n {local.leading}\n </span>\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">{local.children}</span>\n {local.trailing ? (\n <span class=\"ms-auto flex shrink-0 items-center gap-1 text-muted-foreground\">\n {local.trailing}\n </span>\n ) : null}\n </div>\n )\n}\n\nfunction isActionTarget(target: EventTarget | null, currentTarget: HTMLElement): boolean {\n if (!(target instanceof Element) || target === currentTarget) return false\n return Boolean(\n target.closest(\n 'a, button, input, textarea, select, [contenteditable=\"true\"], [role=\"button\"], [data-tree-keyboard-stop]'\n )\n )\n}\n\nfunction composeRefs(\n internal: (element: HTMLDivElement) => void,\n external: () => ComponentProps<'div'>['ref']\n): (element: HTMLDivElement) => void {\n return (element) => {\n internal(element)\n const ref = external()\n if (typeof ref === 'function') ref(element)\n }\n}\n\nexport type { TreeItemDescriptor } from './tree-navigation'\n"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- import type { ComponentProps, JSX } from 'solid-js';
1
+ import type { ComponentProps, JSX, Ref } from 'solid-js';
2
2
  import { Button } from '../ui/button/button';
3
3
  /**
4
4
  * MessageComposer.
5
5
  *
6
6
  * The field a message is written in. It is a form, and it behaves like one: Enter
7
- * sends, Shift+Enter breaks the line, Escape clears the error.
7
+ * sends, Shift+Enter breaks the line, Escape clears the error from anywhere in
8
+ * the composer unless a nested control or an active IME already owns the key.
8
9
  *
9
10
  * ## What it does not know
10
11
  *
@@ -41,7 +42,7 @@ export type MessageComposerProps = Omit<ComponentProps<'form'>, 'onSubmit'> & {
41
42
  placeholder?: string;
42
43
  /** Disable the whole composer, e.g. while the channel is read-only. */
43
44
  disabled?: boolean;
44
- /** Label the send action for a context other than a message, e.g. a reply. */
45
+ /** Accessible name and tooltip for the action, e.g. "Reply". */
45
46
  submitLabel?: string;
46
47
  /** Show the keyboard hint under the field. */
47
48
  showHint?: boolean;
@@ -56,6 +57,20 @@ export type MessageComposerProps = Omit<ComponentProps<'form'>, 'onSubmit'> & {
56
57
  label: string;
57
58
  onDismiss: () => void;
58
59
  };
60
+ /** Ref to the actual message textarea, for host focus and selection behavior. */
61
+ inputRef?: Ref<HTMLTextAreaElement>;
62
+ /** Stable host-owned id for the actual textarea. */
63
+ inputId?: string;
64
+ /** Accessible name for the actual textarea. Defaults to "Message" or "Reply message". */
65
+ inputLabel?: string;
66
+ /** Additional help text associated with the actual textarea. */
67
+ inputDescription?: string;
68
+ /** Existing host description id, combined with `inputDescription` when supplied. */
69
+ inputDescribedBy?: string;
70
+ /** Comfortable uses the shared 4rem minimum and 12rem maximum field heights. */
71
+ inputSize?: 'default' | 'comfortable';
72
+ /** The shared resize behavior for the actual textarea. */
73
+ inputResize?: 'vertical' | 'none' | 'both';
59
74
  };
60
75
  export declare function MessageComposer(props: MessageComposerProps): JSX.Element;
61
76
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message-composer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAGnD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAM5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG;IAC5E,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,iEAAiE;IACjE,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAClB,0DAA0D;IAC1D,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,IAAI,CAAA;KAAE,CAAA;CACnD,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eA6I1D;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,cAAc,CAAC,OAAO,MAAM,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,eAiB1E;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,eAetD"}
1
+ {"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message-composer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAIxD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG;IAC5E,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,iEAAiE;IACjE,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAClB,0DAA0D;IAC1D,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,IAAI,CAAA;KAAE,CAAA;IAClD,iFAAiF;IACjF,QAAQ,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAA;IACnC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gFAAgF;IAChF,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;IACrC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;CAC3C,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAmM1D;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,cAAc,CAAC,OAAO,MAAM,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,eAkB1E;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,eAetD"}