pith-ui 0.0.0-stage → 0.1.1

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 (134) hide show
  1. package/AI.md +75 -0
  2. package/API.md +3688 -0
  3. package/LICENSE +661 -0
  4. package/README.md +80 -2
  5. package/dist/composer.d.ts +38 -0
  6. package/dist/composer.d.ts.map +1 -0
  7. package/dist/composer.js +123 -0
  8. package/dist/composer.js.map +1 -0
  9. package/dist/content/conversation-reader.d.ts +19 -0
  10. package/dist/content/conversation-reader.d.ts.map +1 -0
  11. package/dist/content/conversation-reader.js +280 -0
  12. package/dist/content/conversation-reader.js.map +1 -0
  13. package/dist/content/conversation-view.d.ts +65 -0
  14. package/dist/content/conversation-view.d.ts.map +1 -0
  15. package/dist/content/conversation-view.js +140 -0
  16. package/dist/content/conversation-view.js.map +1 -0
  17. package/dist/content/image-viewer.d.ts +25 -0
  18. package/dist/content/image-viewer.d.ts.map +1 -0
  19. package/dist/content/image-viewer.js +114 -0
  20. package/dist/content/image-viewer.js.map +1 -0
  21. package/dist/content/markdown.d.ts +12 -0
  22. package/dist/content/markdown.d.ts.map +1 -0
  23. package/dist/content/markdown.js +68 -0
  24. package/dist/content/markdown.js.map +1 -0
  25. package/dist/content/paged-preview.d.ts +15 -0
  26. package/dist/content/paged-preview.d.ts.map +1 -0
  27. package/dist/content/paged-preview.js +108 -0
  28. package/dist/content/paged-preview.js.map +1 -0
  29. package/dist/content/views.d.ts +9 -0
  30. package/dist/content/views.d.ts.map +1 -0
  31. package/dist/content/views.js +53 -0
  32. package/dist/content/views.js.map +1 -0
  33. package/dist/content/welcome.d.ts +18 -0
  34. package/dist/content/welcome.d.ts.map +1 -0
  35. package/dist/content/welcome.js +54 -0
  36. package/dist/content/welcome.js.map +1 -0
  37. package/dist/core.d.ts +36 -0
  38. package/dist/core.d.ts.map +1 -0
  39. package/dist/core.js +44 -0
  40. package/dist/core.js.map +1 -0
  41. package/dist/dom.d.ts +14 -0
  42. package/dist/dom.d.ts.map +1 -0
  43. package/dist/dom.js +69 -0
  44. package/dist/dom.js.map +1 -0
  45. package/dist/files/panels.d.ts +100 -0
  46. package/dist/files/panels.d.ts.map +1 -0
  47. package/dist/files/panels.js +286 -0
  48. package/dist/files/panels.js.map +1 -0
  49. package/dist/files/systems.d.ts +91 -0
  50. package/dist/files/systems.d.ts.map +1 -0
  51. package/dist/files/systems.js +273 -0
  52. package/dist/files/systems.js.map +1 -0
  53. package/dist/forms/actions.d.ts +27 -0
  54. package/dist/forms/actions.d.ts.map +1 -0
  55. package/dist/forms/actions.js +39 -0
  56. package/dist/forms/actions.js.map +1 -0
  57. package/dist/forms/custom-connection.d.ts +62 -0
  58. package/dist/forms/custom-connection.d.ts.map +1 -0
  59. package/dist/forms/custom-connection.js +72 -0
  60. package/dist/forms/custom-connection.js.map +1 -0
  61. package/dist/forms/dialog-frame.d.ts +41 -0
  62. package/dist/forms/dialog-frame.d.ts.map +1 -0
  63. package/dist/forms/dialog-frame.js +95 -0
  64. package/dist/forms/dialog-frame.js.map +1 -0
  65. package/dist/forms/history.d.ts +16 -0
  66. package/dist/forms/history.d.ts.map +1 -0
  67. package/dist/forms/history.js +21 -0
  68. package/dist/forms/history.js.map +1 -0
  69. package/dist/forms/identity.d.ts +16 -0
  70. package/dist/forms/identity.d.ts.map +1 -0
  71. package/dist/forms/identity.js +53 -0
  72. package/dist/forms/identity.js.map +1 -0
  73. package/dist/forms/model-editor.d.ts +40 -0
  74. package/dist/forms/model-editor.d.ts.map +1 -0
  75. package/dist/forms/model-editor.js +89 -0
  76. package/dist/forms/model-editor.js.map +1 -0
  77. package/dist/forms/panels.d.ts +146 -0
  78. package/dist/forms/panels.d.ts.map +1 -0
  79. package/dist/forms/panels.js +339 -0
  80. package/dist/forms/panels.js.map +1 -0
  81. package/dist/forms/provider-login.d.ts +22 -0
  82. package/dist/forms/provider-login.d.ts.map +1 -0
  83. package/dist/forms/provider-login.js +116 -0
  84. package/dist/forms/provider-login.js.map +1 -0
  85. package/dist/forms/resource-editor.d.ts +27 -0
  86. package/dist/forms/resource-editor.d.ts.map +1 -0
  87. package/dist/forms/resource-editor.js +34 -0
  88. package/dist/forms/resource-editor.js.map +1 -0
  89. package/dist/foundations.d.ts +95 -0
  90. package/dist/foundations.d.ts.map +1 -0
  91. package/dist/foundations.js +315 -0
  92. package/dist/foundations.js.map +1 -0
  93. package/dist/index.d.ts +28 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +28 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/navigation/context-menu.d.ts +26 -0
  98. package/dist/navigation/context-menu.d.ts.map +1 -0
  99. package/dist/navigation/context-menu.js +81 -0
  100. package/dist/navigation/context-menu.js.map +1 -0
  101. package/dist/navigation/navigation.d.ts +92 -0
  102. package/dist/navigation/navigation.d.ts.map +1 -0
  103. package/dist/navigation/navigation.js +368 -0
  104. package/dist/navigation/navigation.js.map +1 -0
  105. package/dist/primitives.d.ts +310 -0
  106. package/dist/primitives.d.ts.map +1 -0
  107. package/dist/primitives.js +633 -0
  108. package/dist/primitives.js.map +1 -0
  109. package/dist/styles.css +853 -0
  110. package/dist/surface.d.ts +29 -0
  111. package/dist/surface.d.ts.map +1 -0
  112. package/dist/surface.js +154 -0
  113. package/dist/surface.js.map +1 -0
  114. package/dist/tasks/approval.d.ts +25 -0
  115. package/dist/tasks/approval.d.ts.map +1 -0
  116. package/dist/tasks/approval.js +64 -0
  117. package/dist/tasks/approval.js.map +1 -0
  118. package/dist/tasks/permission.d.ts +37 -0
  119. package/dist/tasks/permission.d.ts.map +1 -0
  120. package/dist/tasks/permission.js +73 -0
  121. package/dist/tasks/permission.js.map +1 -0
  122. package/dist/tasks/runtime.d.ts +31 -0
  123. package/dist/tasks/runtime.d.ts.map +1 -0
  124. package/dist/tasks/runtime.js +34 -0
  125. package/dist/tasks/runtime.js.map +1 -0
  126. package/dist/theme.d.ts +4 -0
  127. package/dist/theme.d.ts.map +1 -0
  128. package/dist/theme.js +6 -0
  129. package/dist/theme.js.map +1 -0
  130. package/dist/workspace.d.ts +92 -0
  131. package/dist/workspace.d.ts.map +1 -0
  132. package/dist/workspace.js +288 -0
  133. package/dist/workspace.js.map +1 -0
  134. package/package.json +27 -4
@@ -0,0 +1,315 @@
1
+ import { controlDisabled, Generation, Lifetime, setControlPending } from './core.js';
2
+ import { iconElement, setText, uniqueId } from './dom.js';
3
+ export function adoptAction(node, options = {}) {
4
+ const life = options.onAction ? new Lifetime() : undefined;
5
+ const generation = options.onAction ? new Generation() : undefined;
6
+ let state = { disabled: node.disabled };
7
+ let localPending = false;
8
+ let disposed = false;
9
+ let glyph = node.querySelector(':scope > svg') ?? undefined;
10
+ const caption = options.caption ?? [...node.children].find((child) => child instanceof HTMLElement && child.tagName === 'SPAN');
11
+ const iconOnly = !caption && !!glyph && ![...node.childNodes].some(child => child.nodeType === Node.TEXT_NODE && child.textContent?.trim());
12
+ let iconName;
13
+ const update = (next) => {
14
+ if (disposed)
15
+ return;
16
+ state = { ...state, ...next };
17
+ if (next.label != null) {
18
+ if (caption)
19
+ setText(caption, next.label);
20
+ else if (iconOnly)
21
+ node.setAttribute('aria-label', next.label);
22
+ else
23
+ setText(node, next.label);
24
+ }
25
+ if (next.intent != null) {
26
+ for (const intent of ['neutral', 'primary', 'danger'])
27
+ node.classList.toggle(`pui-${intent}`, next.intent === intent);
28
+ }
29
+ if (next.density != null) {
30
+ node.classList.toggle('pui-normal', next.density === 'normal');
31
+ node.classList.toggle('pui-compact', next.density === 'compact');
32
+ }
33
+ if (next.appearance != null)
34
+ node.classList.toggle('pui-secondary-button', next.appearance === 'secondary');
35
+ // Adopted nodes keep their host-owned attributes unless explicitly updated.
36
+ if (next.disabled != null || next.pending != null || localPending) {
37
+ // A retained product action can also be pending in the application's
38
+ // adapter or native-copy controller. Only clear pending that we own.
39
+ if (state.pending != null || options.onAction)
40
+ setControlPending(node, !!(state.pending || localPending));
41
+ node.disabled = controlDisabled(node, !!(state.disabled || state.pending || localPending));
42
+ node.setAttribute('aria-busy', String(!!(state.pending || localPending || node.dataset.controlPending || node.dataset.copyPending)));
43
+ }
44
+ if (next.title != null)
45
+ node.title = next.title;
46
+ if (next.icon != null && iconName !== next.icon) {
47
+ glyph?.remove();
48
+ iconName = next.icon;
49
+ glyph = next.icon ? iconElement(next.icon) : undefined;
50
+ if (glyph)
51
+ node.prepend(glyph);
52
+ }
53
+ };
54
+ // A delegated product action has no local handler and needs no second listener.
55
+ if (options.onAction)
56
+ life.listen(node, 'click', (() => {
57
+ if (node.disabled || localPending || disposed)
58
+ return;
59
+ const seq = generation.next();
60
+ localPending = true;
61
+ update(state);
62
+ const complete = (result) => {
63
+ if (generation.current(seq) && result && !result.ok)
64
+ options.onError?.(result.error);
65
+ };
66
+ const failed = (reason) => {
67
+ if (generation.current(seq))
68
+ options.onError?.(reason instanceof Error ? reason.message : String(reason));
69
+ };
70
+ const finish = () => {
71
+ if (!generation.current(seq))
72
+ return;
73
+ localPending = false;
74
+ // Include both properties so releasing local pending can enable an action,
75
+ // while a newer external disabled state remains authoritative.
76
+ update({ ...state, disabled: !!state.disabled, pending: !!state.pending });
77
+ };
78
+ try {
79
+ const result = options.onAction();
80
+ if (result && 'then' in result)
81
+ void result.then(complete).catch(failed).finally(finish);
82
+ else {
83
+ complete(result);
84
+ finish();
85
+ }
86
+ }
87
+ catch (reason) {
88
+ failed(reason);
89
+ finish();
90
+ }
91
+ }));
92
+ return { element: node, update, destroy() { disposed = true; generation?.destroy(); life?.destroy(); } };
93
+ }
94
+ /** Reconcile native options by their stable value without replacing the select.
95
+ * Callers decide the fallback when a preferred value has disappeared.
96
+ */
97
+ export function reconcileSelectOptions(control, entries, preferred) {
98
+ const selected = new Set(preferred == null ? [...control.selectedOptions].map(option => option.value) : [preferred]);
99
+ const existing = new Map();
100
+ for (const option of control.options) {
101
+ const group = existing.get(option.value) ?? [];
102
+ group.push(option);
103
+ existing.set(option.value, group);
104
+ }
105
+ const keep = new Set();
106
+ entries.forEach((entry, index) => {
107
+ const option = existing.get(entry.value)?.shift() ?? document.createElement('option');
108
+ keep.add(option);
109
+ if (option.value !== entry.value)
110
+ option.value = entry.value;
111
+ if (option.textContent !== entry.label)
112
+ option.textContent = entry.label;
113
+ if (option.disabled !== !!entry.disabled)
114
+ option.disabled = !!entry.disabled;
115
+ if (control.options[index] !== option)
116
+ control.insertBefore(option, control.options[index] ?? null);
117
+ });
118
+ for (const option of [...control.options])
119
+ if (!keep.has(option))
120
+ option.remove();
121
+ if (control.multiple) {
122
+ for (const option of control.options)
123
+ if (option.selected !== selected.has(option.value))
124
+ option.selected = selected.has(option.value);
125
+ }
126
+ else {
127
+ const value = preferred ?? [...selected][0] ?? '';
128
+ if (control.value !== value || !selected.size)
129
+ control.value = value;
130
+ }
131
+ }
132
+ export function adoptNativeControl(control, options = {}) {
133
+ const life = options.onInput || options.onChange ? new Lifetime() : undefined;
134
+ let disposed = false;
135
+ const originalDescriptions = new Set((control.getAttribute('aria-describedby') ?? '').split(/\s+/).filter(Boolean));
136
+ const ownedDescriptions = new Set();
137
+ if (options.label) {
138
+ if (!control.id)
139
+ control.id = uniqueId('pui-input');
140
+ options.label.htmlFor = control.id;
141
+ }
142
+ for (const node of [options.description, options.error])
143
+ if (node) {
144
+ if (!node.id)
145
+ node.id = uniqueId('pui-field-message');
146
+ ownedDescriptions.add(node.id);
147
+ }
148
+ if (options.error)
149
+ options.error.setAttribute('role', 'alert');
150
+ const update = (state) => {
151
+ if (disposed)
152
+ return;
153
+ if (state.label != null && options.label)
154
+ setText(options.label, state.label);
155
+ if (state.disabled != null)
156
+ control.disabled = state.disabled;
157
+ if (state.required != null)
158
+ control.required = state.required;
159
+ if (state.readOnly != null && !(control instanceof HTMLSelectElement))
160
+ control.readOnly = state.readOnly;
161
+ if (state.placeholder != null && !(control instanceof HTMLSelectElement))
162
+ control.placeholder = state.placeholder;
163
+ if (state.description != null && options.description) {
164
+ setText(options.description, state.description);
165
+ options.description.hidden = !state.description;
166
+ }
167
+ if (state.error != null) {
168
+ control.setAttribute('aria-invalid', String(!!state.error));
169
+ if (options.error) {
170
+ setText(options.error, state.error);
171
+ options.error.hidden = !state.error;
172
+ }
173
+ }
174
+ if (options.description || options.error) {
175
+ // Preserve descriptions supplied by the host or another owned component.
176
+ const ids = new Set([...originalDescriptions, ...(control.getAttribute('aria-describedby') ?? '').split(/\s+/).filter(Boolean)]);
177
+ for (const id of ownedDescriptions)
178
+ ids.delete(id);
179
+ if (options.description && !options.description.hidden && options.description.textContent)
180
+ ids.add(options.description.id);
181
+ if (options.error && !options.error.hidden && options.error.textContent)
182
+ ids.add(options.error.id);
183
+ if (ids.size)
184
+ control.setAttribute('aria-describedby', [...ids].join(' '));
185
+ else
186
+ control.removeAttribute('aria-describedby');
187
+ }
188
+ };
189
+ if (options.onInput)
190
+ life.listen(control, 'input', (event => options.onInput(control.value, event)));
191
+ if (options.onChange)
192
+ life.listen(control, 'change', (event => options.onChange(control.value, event)));
193
+ return { element: control, update, getValue: () => control.value,
194
+ getChecked: () => control instanceof HTMLInputElement && control.checked,
195
+ reset(value) { if (disposed)
196
+ return; if (typeof value === 'boolean' && control instanceof HTMLInputElement)
197
+ control.checked = value;
198
+ else if (typeof value === 'string' && control.value !== value)
199
+ control.value = value; },
200
+ focus() { if (!disposed)
201
+ control.focus(); }, destroy() { disposed = true; life?.destroy(); } };
202
+ }
203
+ export function adoptFeedback(node, options) {
204
+ let disposed = false;
205
+ const update = (state) => {
206
+ if (disposed)
207
+ return;
208
+ const tone = state.tone ?? (options.presentation === 'status' ? 'neutral' : 'info');
209
+ if (options.presentation !== 'inline') {
210
+ const prefix = options.presentation === 'notice' ? 'pui-notice' : 'pui-status';
211
+ node.classList.add(prefix);
212
+ for (const value of ['info', 'neutral', 'success', 'warning', 'error'])
213
+ node.classList.toggle(`${prefix}-${value}`, tone === value);
214
+ }
215
+ if (options.presentation !== 'status')
216
+ node.setAttribute('role', tone === 'error' || tone === 'warning' ? 'alert' : 'status');
217
+ if (options.autoHide !== false)
218
+ node.hidden = !state.message;
219
+ setText(node, state.message);
220
+ };
221
+ return { element: node, update, destroy() { disposed = true; } };
222
+ }
223
+ export function adoptActionLayout(node, kind) {
224
+ let disposed = false;
225
+ return { element: node, update(state) {
226
+ if (disposed)
227
+ return;
228
+ if (state.align != null)
229
+ node.dataset.align = state.align;
230
+ if (state.density != null)
231
+ node.classList.toggle('pui-compact', state.density === 'compact');
232
+ if (state.label != null) {
233
+ node.setAttribute('role', 'group');
234
+ node.setAttribute('aria-label', state.label);
235
+ }
236
+ node.dataset.puiActionLayout = kind;
237
+ }, destroy() { disposed = true; } };
238
+ }
239
+ /** Owned controllers for existing product templates; not a renderer or observer.
240
+ * Controllers are lazy. Reconciliation prunes owned handles without rescanning
241
+ * long message histories or allocating a controller for every static button.
242
+ */
243
+ export function adoptProductParts(owner) {
244
+ const actions = new Map();
245
+ const controls = new Map();
246
+ const feedbacks = new Map();
247
+ const layouts = new Map();
248
+ let disposed = false;
249
+ const action = (node) => {
250
+ let handle = actions.get(node);
251
+ if (!handle) {
252
+ handle = adoptAction(node);
253
+ if (disposed)
254
+ handle.destroy();
255
+ else
256
+ actions.set(node, handle);
257
+ }
258
+ return handle;
259
+ };
260
+ const control = (node) => {
261
+ let handle = controls.get(node);
262
+ if (!handle) {
263
+ handle = adoptNativeControl(node);
264
+ if (disposed)
265
+ handle.destroy();
266
+ else
267
+ controls.set(node, handle);
268
+ }
269
+ return handle;
270
+ };
271
+ const feedback = (node) => {
272
+ let handle = feedbacks.get(node);
273
+ if (!handle) {
274
+ handle = adoptFeedback(node, { presentation: 'inline', autoHide: false });
275
+ if (disposed)
276
+ handle.destroy();
277
+ else
278
+ feedbacks.set(node, handle);
279
+ }
280
+ return handle;
281
+ };
282
+ const layout = (node, kind) => {
283
+ let handle = layouts.get(node);
284
+ if (!handle) {
285
+ handle = adoptActionLayout(node, kind);
286
+ if (disposed)
287
+ handle.destroy();
288
+ else
289
+ layouts.set(node, handle);
290
+ }
291
+ return handle;
292
+ };
293
+ const update = () => {
294
+ if (disposed)
295
+ return;
296
+ for (const map of [actions, controls, feedbacks, layouts])
297
+ for (const [node, handle] of map) {
298
+ if (!owner.contains(node) && node !== owner) {
299
+ handle.destroy();
300
+ map.delete(node);
301
+ }
302
+ }
303
+ };
304
+ return { update, action, control, feedback, layout, destroy() {
305
+ if (disposed)
306
+ return;
307
+ disposed = true;
308
+ for (const map of [actions, controls, feedbacks, layouts]) {
309
+ for (const handle of map.values())
310
+ handle.destroy();
311
+ map.clear();
312
+ }
313
+ } };
314
+ }
315
+ //# sourceMappingURL=foundations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundations.js","sourceRoot":"","sources":["../src/foundations.ts"],"names":[],"mappings":"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","sourcesContent":["import { controlDisabled, Generation, Lifetime, setControlPending } from './core.js';\nimport type { ActionResult, Density, Intent, UIAction } from './core.js';\nimport { iconElement, setText, uniqueId } from './dom.js';\n\n/** Private controllers shared by factories and the retained product templates.\n * Adoption does not replace nodes, move controls or infer business availability.\n */\nexport interface ActionState {\n label?: string;\n intent?: Intent;\n density?: Density;\n disabled?: boolean;\n pending?: boolean;\n icon?: string;\n title?: string;\n appearance?: 'standard' | 'secondary';\n}\nexport interface ActionController {\n readonly element: HTMLButtonElement;\n update(state: Readonly<ActionState>): void;\n destroy(): void;\n}\nexport function adoptAction(node: HTMLButtonElement, options: {\n caption?: HTMLElement;\n onAction?: UIAction;\n onError?: (message: string) => void;\n} = {}): ActionController {\n const life = options.onAction ? new Lifetime() : undefined;\n const generation = options.onAction ? new Generation() : undefined;\n let state: ActionState = { disabled: node.disabled };\n let localPending = false; let disposed = false;\n let glyph = node.querySelector<SVGSVGElement>(':scope > svg') ?? undefined;\n const caption = options.caption ?? [...node.children].find((child): child is HTMLElement => child instanceof HTMLElement && child.tagName === 'SPAN');\n const iconOnly = !caption && !!glyph && ![...node.childNodes].some(child => child.nodeType === Node.TEXT_NODE && child.textContent?.trim());\n let iconName: string | undefined;\n const update = (next: Readonly<ActionState>): void => {\n if (disposed) return;\n state = { ...state, ...next };\n if (next.label != null) {\n if (caption) setText(caption, next.label);\n else if (iconOnly) node.setAttribute('aria-label', next.label);\n else setText(node, next.label);\n }\n if (next.intent != null) {\n for (const intent of ['neutral', 'primary', 'danger']) node.classList.toggle(`pui-${intent}`, next.intent === intent);\n }\n if (next.density != null) {\n node.classList.toggle('pui-normal', next.density === 'normal');\n node.classList.toggle('pui-compact', next.density === 'compact');\n }\n if (next.appearance != null) node.classList.toggle('pui-secondary-button', next.appearance === 'secondary');\n // Adopted nodes keep their host-owned attributes unless explicitly updated.\n if (next.disabled != null || next.pending != null || localPending) {\n // A retained product action can also be pending in the application's\n // adapter or native-copy controller. Only clear pending that we own.\n if (state.pending != null || options.onAction) setControlPending(node, !!(state.pending || localPending));\n node.disabled = controlDisabled(node, !!(state.disabled || state.pending || localPending));\n node.setAttribute('aria-busy', String(!!(state.pending || localPending || node.dataset.controlPending || node.dataset.copyPending)));\n }\n if (next.title != null) node.title = next.title;\n if (next.icon != null && iconName !== next.icon) {\n glyph?.remove(); iconName = next.icon;\n glyph = next.icon ? iconElement(next.icon) : undefined;\n if (glyph) node.prepend(glyph);\n }\n };\n // A delegated product action has no local handler and needs no second listener.\n if (options.onAction) life!.listen(node, 'click', (() => {\n if (node.disabled || localPending || disposed) return;\n const seq = generation!.next(); localPending = true; update(state);\n const complete = (result: void | ActionResult): void => {\n if (generation!.current(seq) && result && !result.ok) options.onError?.(result.error);\n };\n const failed = (reason: unknown): void => {\n if (generation!.current(seq)) options.onError?.(reason instanceof Error ? reason.message : String(reason));\n };\n const finish = (): void => {\n if (!generation!.current(seq)) return;\n localPending = false;\n // Include both properties so releasing local pending can enable an action,\n // while a newer external disabled state remains authoritative.\n update({ ...state, disabled: !!state.disabled, pending: !!state.pending });\n };\n try {\n const result = options.onAction!();\n if (result && 'then' in result) void result.then(complete).catch(failed).finally(finish);\n else { complete(result); finish(); }\n } catch (reason) { failed(reason); finish(); }\n }) as EventListener);\n return { element: node, update, destroy() { disposed = true; generation?.destroy(); life?.destroy(); } };\n}\n\nexport type NativeControl = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\nexport interface NativeSelectOption { value: string; label: string; disabled?: boolean; }\n/** Reconcile native options by their stable value without replacing the select.\n * Callers decide the fallback when a preferred value has disappeared.\n */\nexport function reconcileSelectOptions(control: HTMLSelectElement, entries: readonly NativeSelectOption[], preferred?: string): void {\n const selected = new Set(preferred == null ? [...control.selectedOptions].map(option => option.value) : [preferred]);\n const existing = new Map<string, HTMLOptionElement[]>();\n for (const option of control.options) { const group = existing.get(option.value) ?? []; group.push(option); existing.set(option.value, group); }\n const keep = new Set<HTMLOptionElement>();\n entries.forEach((entry, index) => {\n const option = existing.get(entry.value)?.shift() ?? document.createElement('option');\n keep.add(option);\n if (option.value !== entry.value) option.value = entry.value;\n if (option.textContent !== entry.label) option.textContent = entry.label;\n if (option.disabled !== !!entry.disabled) option.disabled = !!entry.disabled;\n if (control.options[index] !== option) control.insertBefore(option, control.options[index] ?? null);\n });\n for (const option of [...control.options]) if (!keep.has(option)) option.remove();\n if (control.multiple) {\n for (const option of control.options) if (option.selected !== selected.has(option.value)) option.selected = selected.has(option.value);\n } else {\n const value = preferred ?? [...selected][0] ?? '';\n if (control.value !== value || !selected.size) control.value = value;\n }\n}\nexport interface NativeControlState {\n label?: string;\n description?: string;\n error?: string;\n disabled?: boolean;\n required?: boolean;\n readOnly?: boolean;\n placeholder?: string;\n}\nexport interface NativeControlController {\n readonly element: NativeControl;\n update(state: Readonly<NativeControlState>): void;\n getValue(): string;\n getChecked(): boolean;\n reset(value: string | boolean): void;\n focus(): void;\n destroy(): void;\n}\nexport function adoptNativeControl(control: NativeControl, options: {\n label?: HTMLLabelElement;\n description?: HTMLElement;\n error?: HTMLElement;\n onInput?: (value: string, event: Event) => void;\n onChange?: (value: string, event: Event) => void;\n} = {}): NativeControlController {\n const life = options.onInput || options.onChange ? new Lifetime() : undefined; let disposed = false;\n const originalDescriptions = new Set((control.getAttribute('aria-describedby') ?? '').split(/\\s+/).filter(Boolean));\n const ownedDescriptions = new Set<string>();\n if (options.label) {\n if (!control.id) control.id = uniqueId('pui-input');\n options.label.htmlFor = control.id;\n }\n for (const node of [options.description, options.error]) if (node) {\n if (!node.id) node.id = uniqueId('pui-field-message');\n ownedDescriptions.add(node.id);\n }\n if (options.error) options.error.setAttribute('role', 'alert');\n const update = (state: Readonly<NativeControlState>): void => {\n if (disposed) return;\n if (state.label != null && options.label) setText(options.label, state.label);\n if (state.disabled != null) control.disabled = state.disabled;\n if (state.required != null) control.required = state.required;\n if (state.readOnly != null && !(control instanceof HTMLSelectElement)) control.readOnly = state.readOnly;\n if (state.placeholder != null && !(control instanceof HTMLSelectElement)) control.placeholder = state.placeholder;\n if (state.description != null && options.description) {\n setText(options.description, state.description); options.description.hidden = !state.description;\n }\n if (state.error != null) {\n control.setAttribute('aria-invalid', String(!!state.error));\n if (options.error) { setText(options.error, state.error); options.error.hidden = !state.error; }\n }\n if (options.description || options.error) {\n // Preserve descriptions supplied by the host or another owned component.\n const ids = new Set([...originalDescriptions, ...(control.getAttribute('aria-describedby') ?? '').split(/\\s+/).filter(Boolean)]);\n for (const id of ownedDescriptions) ids.delete(id);\n if (options.description && !options.description.hidden && options.description.textContent) ids.add(options.description.id);\n if (options.error && !options.error.hidden && options.error.textContent) ids.add(options.error.id);\n if (ids.size) control.setAttribute('aria-describedby', [...ids].join(' ')); else control.removeAttribute('aria-describedby');\n }\n };\n if (options.onInput) life!.listen(control, 'input', (event => options.onInput!(control.value, event)) as EventListener);\n if (options.onChange) life!.listen(control, 'change', (event => options.onChange!(control.value, event)) as EventListener);\n return { element: control, update, getValue: () => control.value,\n getChecked: () => control instanceof HTMLInputElement && control.checked,\n reset(value) { if (disposed) return; if (typeof value === 'boolean' && control instanceof HTMLInputElement) control.checked = value; else if (typeof value === 'string' && control.value !== value) control.value = value; },\n focus() { if (!disposed) control.focus(); }, destroy() { disposed = true; life?.destroy(); } };\n}\n\nexport interface FeedbackState { message: string; tone?: 'info' | 'neutral' | 'success' | 'warning' | 'error'; }\nexport interface FeedbackController {\n readonly element: HTMLElement;\n update(state: Readonly<FeedbackState>): void;\n destroy(): void;\n}\nexport function adoptFeedback(node: HTMLElement, options: {\n presentation: 'notice' | 'inline' | 'status';\n autoHide?: boolean;\n}): FeedbackController {\n let disposed = false;\n const update = (state: Readonly<FeedbackState>): void => {\n if (disposed) return;\n const tone = state.tone ?? (options.presentation === 'status' ? 'neutral' : 'info');\n if (options.presentation !== 'inline') {\n const prefix = options.presentation === 'notice' ? 'pui-notice' : 'pui-status';\n node.classList.add(prefix);\n for (const value of ['info', 'neutral', 'success', 'warning', 'error']) node.classList.toggle(`${prefix}-${value}`, tone === value);\n }\n if (options.presentation !== 'status') node.setAttribute('role', tone === 'error' || tone === 'warning' ? 'alert' : 'status');\n if (options.autoHide !== false) node.hidden = !state.message;\n setText(node, state.message);\n };\n return { element: node, update, destroy() { disposed = true; } };\n}\n\nexport interface ActionLayoutState { align?: 'start' | 'end' | 'between'; density?: Density; label?: string; }\nexport function adoptActionLayout(node: HTMLElement, kind: 'actions' | 'toolbar'): {\n readonly element: HTMLElement;\n update(state: Readonly<ActionLayoutState>): void;\n destroy(): void;\n} {\n let disposed = false;\n return { element: node, update(state) {\n if (disposed) return;\n if (state.align != null) node.dataset.align = state.align;\n if (state.density != null) node.classList.toggle('pui-compact', state.density === 'compact');\n if (state.label != null) { node.setAttribute('role', 'group'); node.setAttribute('aria-label', state.label); }\n node.dataset.puiActionLayout = kind;\n }, destroy() { disposed = true; } };\n}\n\n/** Owned controllers for existing product templates; not a renderer or observer.\n * Controllers are lazy. Reconciliation prunes owned handles without rescanning\n * long message histories or allocating a controller for every static button.\n */\nexport function adoptProductParts(owner: HTMLElement): {\n update(): void;\n action(node: HTMLButtonElement): ActionController;\n control(node: NativeControl): NativeControlController;\n feedback(node: HTMLElement): FeedbackController;\n layout(node: HTMLElement, kind: 'actions' | 'toolbar'): ReturnType<typeof adoptActionLayout>;\n destroy(): void;\n} {\n const actions = new Map<HTMLButtonElement, ActionController>();\n const controls = new Map<NativeControl, NativeControlController>();\n const feedbacks = new Map<HTMLElement, FeedbackController>();\n const layouts = new Map<HTMLElement, ReturnType<typeof adoptActionLayout>>();\n let disposed = false;\n const action = (node: HTMLButtonElement): ActionController => {\n let handle = actions.get(node); if (!handle) { handle = adoptAction(node); if (disposed) handle.destroy(); else actions.set(node, handle); } return handle;\n };\n const control = (node: NativeControl): NativeControlController => {\n let handle = controls.get(node); if (!handle) { handle = adoptNativeControl(node); if (disposed) handle.destroy(); else controls.set(node, handle); } return handle;\n };\n const feedback = (node: HTMLElement): FeedbackController => {\n let handle = feedbacks.get(node); if (!handle) { handle = adoptFeedback(node, { presentation: 'inline', autoHide: false }); if (disposed) handle.destroy(); else feedbacks.set(node, handle); } return handle;\n };\n const layout = (node: HTMLElement, kind: 'actions' | 'toolbar'): ReturnType<typeof adoptActionLayout> => {\n let handle = layouts.get(node); if (!handle) { handle = adoptActionLayout(node, kind); if (disposed) handle.destroy(); else layouts.set(node, handle); } return handle;\n };\n const update = (): void => {\n if (disposed) return;\n for (const map of [actions, controls, feedbacks, layouts]) for (const [node, handle] of map) {\n if (!owner.contains(node) && node !== owner) { handle.destroy(); map.delete(node as never); }\n }\n };\n return { update, action, control, feedback, layout, destroy() {\n if (disposed) return; disposed = true;\n for (const map of [actions, controls, feedbacks, layouts]) { for (const handle of map.values()) handle.destroy(); map.clear(); }\n } };\n}\n\n"]}
@@ -0,0 +1,28 @@
1
+ export * from './core.js';
2
+ export * from './dom.js';
3
+ export * from './primitives.js';
4
+ export * from './theme.js';
5
+ export * from './workspace.js';
6
+ export * from './composer.js';
7
+ export * from './content/markdown.js';
8
+ export * from './content/conversation-reader.js';
9
+ export * from './content/conversation-view.js';
10
+ export * from './content/paged-preview.js';
11
+ export * from './content/image-viewer.js';
12
+ export * from './content/welcome.js';
13
+ export * from './forms/panels.js';
14
+ export * from './forms/model-editor.js';
15
+ export * from './forms/custom-connection.js';
16
+ export * from './forms/resource-editor.js';
17
+ export * from './forms/history.js';
18
+ export * from './forms/provider-login.js';
19
+ export * from './forms/dialog-frame.js';
20
+ export * from './forms/actions.js';
21
+ export * from './files/panels.js';
22
+ export * from './files/systems.js';
23
+ export * from './navigation/navigation.js';
24
+ export * from './navigation/context-menu.js';
25
+ export * from './tasks/approval.js';
26
+ export * from './tasks/permission.js';
27
+ export * from './tasks/runtime.js';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ export * from './core.js';
2
+ export * from './dom.js';
3
+ export * from './primitives.js';
4
+ export * from './theme.js';
5
+ export * from './workspace.js';
6
+ export * from './composer.js';
7
+ export * from './content/markdown.js';
8
+ export * from './content/conversation-reader.js';
9
+ export * from './content/conversation-view.js';
10
+ export * from './content/paged-preview.js';
11
+ export * from './content/image-viewer.js';
12
+ export * from './content/welcome.js';
13
+ export * from './forms/panels.js';
14
+ export * from './forms/model-editor.js';
15
+ export * from './forms/custom-connection.js';
16
+ export * from './forms/resource-editor.js';
17
+ export * from './forms/history.js';
18
+ export * from './forms/provider-login.js';
19
+ export * from './forms/dialog-frame.js';
20
+ export * from './forms/actions.js';
21
+ export * from './files/panels.js';
22
+ export * from './files/systems.js';
23
+ export * from './navigation/navigation.js';
24
+ export * from './navigation/context-menu.js';
25
+ export * from './tasks/approval.js';
26
+ export * from './tasks/permission.js';
27
+ export * from './tasks/runtime.js';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from './core.js';\nexport * from './dom.js';\nexport * from './primitives.js';\nexport * from './theme.js';\nexport * from './workspace.js';\nexport * from './composer.js';\nexport * from './content/markdown.js';\nexport * from './content/conversation-reader.js';\nexport * from './content/conversation-view.js';\nexport * from './content/paged-preview.js';\nexport * from './content/image-viewer.js';\nexport * from './content/welcome.js';\nexport * from './forms/panels.js';\nexport * from './forms/model-editor.js';\nexport * from './forms/custom-connection.js';\nexport * from './forms/resource-editor.js';\nexport * from './forms/history.js';\nexport * from './forms/provider-login.js';\nexport * from './forms/dialog-frame.js';\nexport * from './forms/actions.js';\nexport * from './files/panels.js';\nexport * from './files/systems.js';\nexport * from './navigation/navigation.js';\nexport * from './navigation/context-menu.js';\nexport * from './tasks/approval.js';\nexport * from './tasks/permission.js';\nexport * from './tasks/runtime.js';\n"]}
@@ -0,0 +1,26 @@
1
+ import type { UIBlock } from '../core.js';
2
+ export interface ContextMenuItem {
3
+ id?: string;
4
+ label: string;
5
+ action?: string;
6
+ sdkAction?: string;
7
+ danger?: boolean;
8
+ disabled?: boolean;
9
+ idle?: {
10
+ conversationId?: string;
11
+ workspaceId?: string;
12
+ };
13
+ }
14
+ export interface ContextMenuState {
15
+ label: string;
16
+ items: readonly ContextMenuItem[];
17
+ }
18
+ export declare function createContextMenu(options?: {
19
+ element?: HTMLElement;
20
+ onDismiss?: (restoreFocus: boolean) => void;
21
+ onAction?: (item: ContextMenuItem) => void;
22
+ }): UIBlock<ContextMenuState> & {
23
+ open(trigger: HTMLElement, state: ContextMenuState): void;
24
+ close(restoreFocus?: boolean): void;
25
+ };
26
+ //# sourceMappingURL=context-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../src/navigation/context-menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACtG,IAAI,CAAC,EAAE;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;CACxD;AACD,MAAM,WAAW,gBAAgB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAA;CAAC;AACpF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE;IAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG;IAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAC,CAkC9R"}
@@ -0,0 +1,81 @@
1
+ import { installMenuNavigation } from '../surface.js';
2
+ import { adoptProductParts } from '../foundations.js';
3
+ export function createContextMenu(options = {}) {
4
+ const element = options.element || document.createElement('div');
5
+ if (!options.element) {
6
+ element.className = 'pui-sidebar-conversation-menu pui-context-menu';
7
+ element.setAttribute('role', 'menu');
8
+ element.hidden = true;
9
+ }
10
+ const abort = new AbortController();
11
+ let trigger = null;
12
+ let destroyed = false;
13
+ const parts = adoptProductParts(element);
14
+ const rows = new Map();
15
+ const actions = new Map();
16
+ const close = (restoreFocus = false) => { element.hidden = true; trigger?.setAttribute('aria-expanded', 'false'); if (restoreFocus)
17
+ trigger?.focus(); trigger = null; };
18
+ const dismiss = (restoreFocus) => { close(restoreFocus); options.onDismiss?.(restoreFocus); };
19
+ const navigation = installMenuNavigation(element, { onDismiss: dismiss, isOpen: () => !element.hidden, closeOnOutside: true, contains: target => !!trigger?.contains(target) });
20
+ const update = (state) => {
21
+ if (destroyed)
22
+ return;
23
+ element.setAttribute('aria-label', state.label);
24
+ const keep = new Set();
25
+ let cursor = element.firstElementChild;
26
+ for (const [index, item] of state.items.entries()) {
27
+ const key = item.id ?? `${item.action || ''}/${item.sdkAction || ''}/${index}`;
28
+ keep.add(key);
29
+ let button = rows.get(key);
30
+ if (!button) {
31
+ button = document.createElement('button');
32
+ button.type = 'button';
33
+ button.setAttribute('role', 'menuitem');
34
+ rows.set(key, button);
35
+ }
36
+ parts.action(button).update({ label: item.label, disabled: !!item.disabled });
37
+ button.classList.toggle('pui-destructive-menu-item', !!item.danger);
38
+ if (item.action)
39
+ button.dataset.action = item.action;
40
+ else
41
+ delete button.dataset.action;
42
+ if (item.sdkAction)
43
+ button.dataset.sdk = item.sdkAction;
44
+ else
45
+ delete button.dataset.sdk;
46
+ for (const name of ['idleAction', 'idleConversation', 'idleWorkspace'])
47
+ delete button.dataset[name];
48
+ if (item.idle) {
49
+ button.dataset.idleAction = '';
50
+ if (item.idle.conversationId)
51
+ button.dataset.idleConversation = item.idle.conversationId;
52
+ if (item.idle.workspaceId)
53
+ button.dataset.idleWorkspace = item.idle.workspaceId;
54
+ }
55
+ actions.set(button, item);
56
+ if (cursor !== button)
57
+ element.insertBefore(button, cursor);
58
+ cursor = button.nextElementSibling;
59
+ }
60
+ for (const [key, button] of rows)
61
+ if (!keep.has(key)) {
62
+ button.remove();
63
+ rows.delete(key);
64
+ actions.delete(button);
65
+ }
66
+ parts.update();
67
+ };
68
+ if (options.onAction)
69
+ element.addEventListener('click', event => { const button = event.target.closest('button'); const item = button ? actions.get(button) : undefined; if (item && !button.disabled)
70
+ options.onAction(item); }, { signal: abort.signal });
71
+ const onScroll = (event) => { if (!element.hidden && event.target instanceof Node && !element.contains(event.target))
72
+ dismiss(false); };
73
+ document.addEventListener('scroll', onScroll, { capture: true, passive: true, signal: abort.signal });
74
+ window.addEventListener('resize', () => { if (!element.hidden)
75
+ dismiss(false); }, { signal: abort.signal });
76
+ return { element, update, close, open(source, state) { if (destroyed)
77
+ return; close(); trigger = source; trigger.setAttribute('aria-expanded', 'true'); update(state); element.hidden = false; const rect = source.getBoundingClientRect(); element.style.left = `${Math.max(8, Math.min(rect.right, window.innerWidth - element.offsetWidth - 8))}px`; element.style.top = `${Math.max(8, Math.min(rect.bottom + 4, window.innerHeight - element.offsetHeight - 8))}px`; navigation.focus(); }, destroy() { if (destroyed)
78
+ return; destroyed = true; close(); navigation.destroy(); abort.abort(); parts.destroy(); rows.clear(); actions.clear(); if (!options.element)
79
+ element.remove(); } };
80
+ }
81
+ //# sourceMappingURL=context-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../../src/navigation/context-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UIBlock } from '../core.js';\nimport { installMenuNavigation } from '../surface.js';\nimport { adoptProductParts } from '../foundations.js';\nexport interface ContextMenuItem {\n id?: string; label: string; action?: string; sdkAction?: string; danger?: boolean; disabled?: boolean;\n idle?: {conversationId?: string; workspaceId?: string};\n}\nexport interface ContextMenuState {label: string; items: readonly ContextMenuItem[]}\nexport function createContextMenu(options: {element?: HTMLElement; onDismiss?: (restoreFocus: boolean) => void; onAction?: (item: ContextMenuItem) => void} = {}): UIBlock<ContextMenuState> & {open(trigger: HTMLElement, state: ContextMenuState): void; close(restoreFocus?: boolean): void} {\n const element = options.element || document.createElement('div');\n if (!options.element) {element.className = 'pui-sidebar-conversation-menu pui-context-menu'; element.setAttribute('role', 'menu'); element.hidden = true;}\n const abort = new AbortController(); let trigger: HTMLElement | null = null; let destroyed = false;\n const parts = adoptProductParts(element);\n const rows = new Map<string, HTMLButtonElement>();\n const actions = new Map<HTMLButtonElement, ContextMenuItem>();\n const close = (restoreFocus = false) => {element.hidden = true; trigger?.setAttribute('aria-expanded', 'false'); if (restoreFocus) trigger?.focus(); trigger = null;};\n const dismiss = (restoreFocus: boolean) => {close(restoreFocus); options.onDismiss?.(restoreFocus);};\n const navigation = installMenuNavigation(element, {onDismiss: dismiss, isOpen: () => !element.hidden, closeOnOutside: true, contains: target => !!trigger?.contains(target)});\n const update = (state: Readonly<ContextMenuState>) => {\n if (destroyed) return; element.setAttribute('aria-label', state.label);\n const keep = new Set<string>(); let cursor = element.firstElementChild;\n for (const [index, item] of state.items.entries()) {\n const key = item.id ?? `${item.action || ''}/${item.sdkAction || ''}/${index}`; keep.add(key);\n let button = rows.get(key);\n if (!button) {button = document.createElement('button'); button.type = 'button'; button.setAttribute('role', 'menuitem'); rows.set(key, button);}\n parts.action(button).update({label: item.label, disabled: !!item.disabled});\n button.classList.toggle('pui-destructive-menu-item', !!item.danger);\n if (item.action) button.dataset.action = item.action; else delete button.dataset.action;\n if (item.sdkAction) button.dataset.sdk = item.sdkAction; else delete button.dataset.sdk;\n for (const name of ['idleAction', 'idleConversation', 'idleWorkspace']) delete button.dataset[name];\n if (item.idle) {button.dataset.idleAction = ''; if (item.idle.conversationId) button.dataset.idleConversation = item.idle.conversationId; if (item.idle.workspaceId) button.dataset.idleWorkspace = item.idle.workspaceId;}\n actions.set(button, item);\n if (cursor !== button) element.insertBefore(button, cursor); cursor = button.nextElementSibling;\n }\n for (const [key, button] of rows) if (!keep.has(key)) {button.remove(); rows.delete(key); actions.delete(button);}\n parts.update();\n };\n if (options.onAction) element.addEventListener('click', event => {const button = (event.target as Element).closest<HTMLButtonElement>('button'); const item = button ? actions.get(button) : undefined; if (item && !button!.disabled) options.onAction!(item);}, {signal: abort.signal});\n const onScroll = (event: Event) => {if (!element.hidden && event.target instanceof Node && !element.contains(event.target)) dismiss(false);};\n document.addEventListener('scroll', onScroll, {capture: true, passive: true, signal: abort.signal});\n window.addEventListener('resize', () => {if (!element.hidden) dismiss(false);}, {signal: abort.signal});\n return {element, update, close, open(source, state) {if (destroyed) return; close(); trigger = source; trigger.setAttribute('aria-expanded', 'true'); update(state); element.hidden = false; const rect = source.getBoundingClientRect(); element.style.left = `${Math.max(8, Math.min(rect.right, window.innerWidth - element.offsetWidth - 8))}px`; element.style.top = `${Math.max(8, Math.min(rect.bottom + 4, window.innerHeight - element.offsetHeight - 8))}px`; navigation.focus();}, destroy() {if (destroyed) return; destroyed = true; close(); navigation.destroy(); abort.abort(); parts.destroy(); rows.clear(); actions.clear(); if (!options.element) element.remove();}};\n}\n"]}