@echothink-ui/documents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,683 @@
1
+ // src/components/DocumentEditorShell.tsx
2
+ import * as React from "react";
3
+ import { Badge as Badge2, IconButton } from "@echothink-ui/core";
4
+ import { ChevronRightIcon } from "@echothink-ui/icons";
5
+
6
+ // src/components/DocumentLockBadge.tsx
7
+ import { Badge, Tooltip } from "@echothink-ui/core";
8
+ import { LockIcon, UnlockIcon } from "@echothink-ui/icons";
9
+
10
+ // src/components/utils.tsx
11
+ import {
12
+ AgentRunningIcon,
13
+ ApprovalRequiredIcon,
14
+ DocumentIcon,
15
+ DownloadIcon,
16
+ ExternalLinkIcon,
17
+ SearchIcon,
18
+ StatusIcon
19
+ } from "@echothink-ui/icons";
20
+ import { jsx } from "react/jsx-runtime";
21
+ function cx(...classes) {
22
+ return classes.filter(Boolean).join(" ");
23
+ }
24
+ function documentRefLabel(documentRef) {
25
+ if (typeof documentRef === "string") return documentRef;
26
+ if (documentRef.label) return documentRef.label;
27
+ return documentRef.id;
28
+ }
29
+ function formatDateTime(value) {
30
+ if (!value) return "Unknown";
31
+ const date = new Date(value);
32
+ if (Number.isNaN(date.getTime())) return value;
33
+ return date.toLocaleString(void 0, {
34
+ dateStyle: "medium",
35
+ timeStyle: "short"
36
+ });
37
+ }
38
+ function modeLabel(mode) {
39
+ return mode.charAt(0).toUpperCase() + mode.slice(1);
40
+ }
41
+ function actionIcon(action) {
42
+ const key = `${action.id} ${action.label}`.toLowerCase();
43
+ if (key.includes("bold"))
44
+ return /* @__PURE__ */ jsx("strong", { className: "eth-doc-toolbar__format-symbol", "aria-hidden": true, children: "B" });
45
+ if (key.includes("italic"))
46
+ return /* @__PURE__ */ jsx("em", { className: "eth-doc-toolbar__format-symbol", "aria-hidden": true, children: "I" });
47
+ if (key.includes("underline"))
48
+ return /* @__PURE__ */ jsx(
49
+ "span",
50
+ {
51
+ className: "eth-doc-toolbar__format-symbol eth-doc-toolbar__format-symbol--underline",
52
+ "aria-hidden": true,
53
+ children: "U"
54
+ }
55
+ );
56
+ if (key.includes("strike"))
57
+ return /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ className: "eth-doc-toolbar__format-symbol eth-doc-toolbar__format-symbol--strike",
61
+ "aria-hidden": true,
62
+ children: "S"
63
+ }
64
+ );
65
+ if (key.includes("code"))
66
+ return /* @__PURE__ */ jsx("span", { className: "eth-doc-toolbar__format-symbol", "aria-hidden": true, children: "<>" });
67
+ if (key.includes("download") || key.includes("export")) return /* @__PURE__ */ jsx(DownloadIcon, { size: 16 });
68
+ if (key.includes("share") || key.includes("open")) return /* @__PURE__ */ jsx(ExternalLinkIcon, { size: 16 });
69
+ if (key.includes("link") || action.href) return /* @__PURE__ */ jsx(ExternalLinkIcon, { size: 16 });
70
+ if (key.includes("search") || key.includes("find")) return /* @__PURE__ */ jsx(SearchIcon, { size: 16 });
71
+ if (key.includes("agent")) return /* @__PURE__ */ jsx(AgentRunningIcon, { size: 16 });
72
+ if (key.includes("approve") || key.includes("review")) return /* @__PURE__ */ jsx(ApprovalRequiredIcon, { size: 16 });
73
+ if (key.includes("status")) return /* @__PURE__ */ jsx(StatusIcon, { size: 16 });
74
+ return /* @__PURE__ */ jsx(DocumentIcon, { size: 16 });
75
+ }
76
+
77
+ // src/components/DocumentLockBadge.tsx
78
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
79
+ var lockConfig = {
80
+ unlocked: {
81
+ label: "Unlocked",
82
+ severity: "success",
83
+ tooltip: "This document is available for editing."
84
+ },
85
+ "locked-by-user": {
86
+ label: "Locked by you",
87
+ severity: "info",
88
+ tooltip: "You currently hold the document lock."
89
+ },
90
+ "locked-by-agent": {
91
+ label: "Agent lock",
92
+ severity: "warning",
93
+ tooltip: "An agent currently holds the document lock."
94
+ },
95
+ "locked-by-other": {
96
+ label: "Locked",
97
+ severity: "danger",
98
+ tooltip: "Another user currently holds the document lock."
99
+ }
100
+ };
101
+ function DocumentLockBadge({
102
+ lockState,
103
+ owner,
104
+ since,
105
+ density = "compact",
106
+ className,
107
+ ...props
108
+ }) {
109
+ const config = lockConfig[lockState];
110
+ const Icon = lockState === "unlocked" ? UnlockIcon : LockIcon;
111
+ const visibleDetail = getVisibleDetail(lockState, owner, since);
112
+ const ownerText = owner ? ` Owner: ${owner.label}.` : "";
113
+ const sinceText = since ? ` Since: ${formatDateTime(since)}.` : "";
114
+ const tooltip = `${config.tooltip}${ownerText}${sinceText}`;
115
+ return /* @__PURE__ */ jsx2(Tooltip, { label: tooltip, children: /* @__PURE__ */ jsx2(
116
+ "span",
117
+ {
118
+ ...props,
119
+ className: cx("eth-doc-lock-badge", `eth-doc-lock-badge--${density}`, className),
120
+ "aria-label": tooltip,
121
+ "data-lock-state": lockState,
122
+ "data-eth-component": "DocumentLockBadge",
123
+ children: /* @__PURE__ */ jsx2(
124
+ Badge,
125
+ {
126
+ severity: config.severity,
127
+ className: cx("eth-doc-lock-badge__tag", `eth-doc-lock-badge__tag--${lockState}`),
128
+ children: /* @__PURE__ */ jsxs("span", { className: "eth-doc-lock-badge__content", children: [
129
+ /* @__PURE__ */ jsx2(Icon, { className: "eth-doc-lock-badge__icon", size: 12 }),
130
+ /* @__PURE__ */ jsx2("span", { className: "eth-doc-lock-badge__label", children: config.label }),
131
+ visibleDetail ? /* @__PURE__ */ jsx2("span", { className: "eth-doc-lock-badge__detail", children: visibleDetail }) : null
132
+ ] })
133
+ }
134
+ )
135
+ }
136
+ ) });
137
+ }
138
+ function getVisibleDetail(lockState, owner, since) {
139
+ const sinceLabel = since ? formatDateTime(since) : void 0;
140
+ if (lockState === "unlocked") return sinceLabel;
141
+ if (lockState === "locked-by-user") return sinceLabel;
142
+ return [owner?.label, sinceLabel].filter(Boolean).join(" / ") || void 0;
143
+ }
144
+
145
+ // src/components/DocumentEditorShell.tsx
146
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
147
+ function DocumentEditorShell({
148
+ title,
149
+ documentRef,
150
+ mode = "edit",
151
+ lockState = "unlocked",
152
+ lockOwner,
153
+ toolbar,
154
+ outline,
155
+ inspector,
156
+ children,
157
+ density = "default",
158
+ className,
159
+ ...props
160
+ }) {
161
+ const [outlineOpen, setOutlineOpen] = React.useState(Boolean(outline));
162
+ const hasOutline = Boolean(outline);
163
+ const hasInspector = Boolean(inspector);
164
+ const gridTemplateColumns = [
165
+ hasOutline && outlineOpen ? "minmax(180px, 260px)" : null,
166
+ "minmax(0, 1fr)",
167
+ hasInspector ? "minmax(220px, 320px)" : null
168
+ ].filter(Boolean).join(" ");
169
+ const gridStyle = {
170
+ "--eth-doc-editor-shell-grid-template": gridTemplateColumns
171
+ };
172
+ const ethComponent = props["data-eth-component"] ?? "DocumentEditorShell";
173
+ return /* @__PURE__ */ jsxs2(
174
+ "section",
175
+ {
176
+ ...props,
177
+ className: cx(
178
+ "eth-doc-editor-shell",
179
+ `eth-doc-editor-shell--${density}`,
180
+ hasOutline && "eth-doc-editor-shell--has-outline",
181
+ hasOutline && outlineOpen && "eth-doc-editor-shell--outline-open",
182
+ hasInspector && "eth-doc-editor-shell--has-inspector",
183
+ className
184
+ ),
185
+ "data-eth-component": ethComponent,
186
+ children: [
187
+ /* @__PURE__ */ jsxs2("header", { className: "eth-doc-editor-shell__bar", children: [
188
+ /* @__PURE__ */ jsxs2("div", { className: "eth-doc-editor-shell__title", children: [
189
+ /* @__PURE__ */ jsx3("p", { className: "eth-eyebrow", children: documentRefLabel(documentRef) }),
190
+ /* @__PURE__ */ jsx3("h2", { children: title })
191
+ ] }),
192
+ /* @__PURE__ */ jsxs2("div", { className: "eth-doc-editor-shell__status", children: [
193
+ hasOutline ? /* @__PURE__ */ jsx3(
194
+ IconButton,
195
+ {
196
+ label: outlineOpen ? "Collapse outline" : "Expand outline",
197
+ intent: "ghost",
198
+ density,
199
+ icon: /* @__PURE__ */ jsx3(
200
+ ChevronRightIcon,
201
+ {
202
+ size: 16,
203
+ style: { transform: outlineOpen ? "rotate(180deg)" : void 0 }
204
+ }
205
+ ),
206
+ "aria-expanded": outlineOpen,
207
+ onClick: () => setOutlineOpen((current) => !current)
208
+ }
209
+ ) : null,
210
+ /* @__PURE__ */ jsx3(Badge2, { severity: "neutral", children: modeLabel(mode) }),
211
+ /* @__PURE__ */ jsx3(DocumentLockBadge, { lockState, owner: lockOwner })
212
+ ] })
213
+ ] }),
214
+ toolbar ? /* @__PURE__ */ jsx3("div", { className: "eth-doc-editor-shell__toolbar", children: toolbar }) : null,
215
+ /* @__PURE__ */ jsxs2("div", { className: "eth-doc-editor-shell__grid", style: gridStyle, children: [
216
+ hasOutline && outlineOpen ? /* @__PURE__ */ jsx3("aside", { className: "eth-doc-editor-shell__outline", "aria-label": "Document outline", children: outline }) : null,
217
+ /* @__PURE__ */ jsx3("main", { className: "eth-doc-editor-shell__editor", "aria-label": "Document editor", children }),
218
+ inspector ? /* @__PURE__ */ jsx3("aside", { className: "eth-doc-editor-shell__inspector", "aria-label": "Document inspector", children: inspector }) : null
219
+ ] })
220
+ ]
221
+ }
222
+ );
223
+ }
224
+
225
+ // src/components/DocumentViewer.tsx
226
+ import * as React2 from "react";
227
+ import { Badge as Badge3 } from "@echothink-ui/core";
228
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
229
+ function DocumentViewer({
230
+ title,
231
+ content,
232
+ metadata = [],
233
+ versionRef,
234
+ annotations = [],
235
+ className,
236
+ ...props
237
+ }) {
238
+ const titleId = React2.useId();
239
+ const meta = versionRef ? [...metadata, { label: "Version", value: versionRef }] : metadata;
240
+ const labelledBy = props["aria-labelledby"] ?? titleId;
241
+ return /* @__PURE__ */ jsxs3(
242
+ "article",
243
+ {
244
+ ...props,
245
+ "aria-labelledby": labelledBy,
246
+ className: cx(
247
+ "eth-doc-viewer",
248
+ annotations.length > 0 && "eth-doc-viewer--with-annotations",
249
+ className
250
+ ),
251
+ "data-eth-component": "DocumentViewer",
252
+ children: [
253
+ /* @__PURE__ */ jsx4("header", { className: "eth-doc-viewer__header", children: /* @__PURE__ */ jsx4("h2", { id: titleId, children: title }) }),
254
+ meta.length ? /* @__PURE__ */ jsx4("dl", { className: "eth-meta-grid eth-doc-viewer__metadata", children: meta.map((item, index) => /* @__PURE__ */ jsxs3("div", { children: [
255
+ /* @__PURE__ */ jsx4("dt", { children: item.label }),
256
+ /* @__PURE__ */ jsx4("dd", { children: item.value })
257
+ ] }, `${String(item.label)}-${index}`)) }) : null,
258
+ /* @__PURE__ */ jsxs3("div", { className: "eth-doc-viewer__body", children: [
259
+ /* @__PURE__ */ jsx4("div", { className: "eth-doc-viewer__content", children: content }),
260
+ annotations.length ? /* @__PURE__ */ jsxs3("aside", { className: "eth-doc-viewer__annotations", "aria-label": "Annotations", children: [
261
+ /* @__PURE__ */ jsx4("h3", { children: "Annotations" }),
262
+ /* @__PURE__ */ jsx4("ul", { children: annotations.map((annotation) => /* @__PURE__ */ jsxs3("li", { className: "eth-doc-viewer__annotation", children: [
263
+ /* @__PURE__ */ jsxs3("div", { className: "eth-doc-viewer__annotation-header", children: [
264
+ /* @__PURE__ */ jsx4("strong", { children: annotation.author }),
265
+ annotation.range ? /* @__PURE__ */ jsx4(Badge3, { severity: "neutral", children: annotation.range }) : null,
266
+ /* @__PURE__ */ jsx4("time", { dateTime: annotation.createdAt, children: formatDateTime(annotation.createdAt) })
267
+ ] }),
268
+ /* @__PURE__ */ jsx4("p", { children: annotation.comment })
269
+ ] }, annotation.id)) })
270
+ ] }) : null
271
+ ] })
272
+ ]
273
+ }
274
+ );
275
+ }
276
+
277
+ // src/components/DocumentToolbar.tsx
278
+ import {
279
+ Button,
280
+ IconButton as IconButton2,
281
+ LinkButton
282
+ } from "@echothink-ui/core";
283
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
284
+ var modes = ["edit", "review", "view"];
285
+ function DocumentToolbar({
286
+ actions,
287
+ formattingActions = [],
288
+ mode,
289
+ onModeChange,
290
+ density = "default",
291
+ className,
292
+ ...props
293
+ }) {
294
+ return /* @__PURE__ */ jsxs4(
295
+ "div",
296
+ {
297
+ ...props,
298
+ className: cx("eth-doc-toolbar", className),
299
+ role: "toolbar",
300
+ "aria-label": "Document toolbar",
301
+ "data-eth-component": "DocumentToolbar",
302
+ children: [
303
+ formattingActions.length ? /* @__PURE__ */ jsx5(
304
+ "div",
305
+ {
306
+ className: "eth-doc-toolbar__group eth-doc-toolbar__group--formatting",
307
+ role: "group",
308
+ "aria-label": "Formatting",
309
+ children: formattingActions.map((action) => renderToolbarAction(action, density, "icon"))
310
+ }
311
+ ) : null,
312
+ mode && onModeChange ? /* @__PURE__ */ jsx5(
313
+ "div",
314
+ {
315
+ className: "eth-doc-toolbar__group eth-doc-toolbar__group--mode",
316
+ role: "group",
317
+ "aria-label": "Document mode",
318
+ children: modes.map((candidate) => /* @__PURE__ */ jsx5(
319
+ Button,
320
+ {
321
+ className: "eth-doc-toolbar__mode-button",
322
+ density,
323
+ intent: candidate === mode ? "primary" : "secondary",
324
+ "aria-pressed": candidate === mode,
325
+ onClick: () => onModeChange(candidate),
326
+ children: modeLabel(candidate)
327
+ },
328
+ candidate
329
+ ))
330
+ }
331
+ ) : null,
332
+ actions.length ? /* @__PURE__ */ jsx5(
333
+ "div",
334
+ {
335
+ className: "eth-doc-toolbar__group eth-doc-toolbar__group--actions",
336
+ role: "group",
337
+ "aria-label": "Document actions",
338
+ children: actions.map((action) => renderToolbarAction(action, density, "button"))
339
+ }
340
+ ) : null
341
+ ]
342
+ }
343
+ );
344
+ }
345
+ function renderToolbarAction(action, density, variant) {
346
+ const icon = actionIcon(action);
347
+ if (variant === "button") {
348
+ if (action.href) {
349
+ return /* @__PURE__ */ jsxs4(
350
+ LinkButton,
351
+ {
352
+ href: action.href,
353
+ density,
354
+ intent: action.intent ?? "secondary",
355
+ "aria-disabled": action.disabled,
356
+ tabIndex: action.disabled ? -1 : void 0,
357
+ className: cx(
358
+ "eth-doc-toolbar__action",
359
+ action.disabled && "eth-doc-toolbar__link--disabled"
360
+ ),
361
+ onClick: (event) => {
362
+ if (action.disabled) {
363
+ event.preventDefault();
364
+ return;
365
+ }
366
+ action.onSelect?.();
367
+ },
368
+ children: [
369
+ /* @__PURE__ */ jsx5("span", { className: "eth-doc-toolbar__action-icon", "aria-hidden": "true", children: icon }),
370
+ /* @__PURE__ */ jsx5("span", { children: action.label })
371
+ ]
372
+ },
373
+ action.id
374
+ );
375
+ }
376
+ return /* @__PURE__ */ jsx5(
377
+ Button,
378
+ {
379
+ className: "eth-doc-toolbar__action",
380
+ density,
381
+ intent: action.intent ?? "secondary",
382
+ icon,
383
+ disabled: action.disabled,
384
+ onClick: action.onSelect,
385
+ children: action.label
386
+ },
387
+ action.id
388
+ );
389
+ }
390
+ if (action.href) {
391
+ return /* @__PURE__ */ jsx5(
392
+ "a",
393
+ {
394
+ href: action.href,
395
+ "aria-label": action.label,
396
+ tabIndex: action.disabled ? -1 : void 0,
397
+ className: cx(
398
+ "eth-button",
399
+ "eth-icon-button",
400
+ "eth-doc-toolbar__icon-link",
401
+ `eth-button--${action.intent ?? "ghost"}`,
402
+ `eth-button--${density}`,
403
+ action.disabled && "eth-doc-toolbar__link--disabled"
404
+ ),
405
+ "aria-disabled": action.disabled,
406
+ onClick: (event) => {
407
+ if (action.disabled) {
408
+ event.preventDefault();
409
+ return;
410
+ }
411
+ action.onSelect?.();
412
+ },
413
+ children: /* @__PURE__ */ jsx5("span", { className: "eth-button__icon", children: icon })
414
+ },
415
+ action.id
416
+ );
417
+ }
418
+ return /* @__PURE__ */ jsx5(
419
+ IconButton2,
420
+ {
421
+ density,
422
+ intent: action.intent ?? "ghost",
423
+ label: action.label,
424
+ icon,
425
+ disabled: action.disabled,
426
+ onClick: action.onSelect
427
+ },
428
+ action.id
429
+ );
430
+ }
431
+
432
+ // src/components/DocumentOutline.tsx
433
+ import * as React3 from "react";
434
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
435
+ function DocumentOutline({
436
+ headings,
437
+ activeHeadingId,
438
+ onSelect,
439
+ className,
440
+ "aria-label": ariaLabel,
441
+ ...props
442
+ }) {
443
+ const tree = React3.useMemo(() => buildOutlineTree(headings), [headings]);
444
+ const headingCountLabel = `${headings.length} section${headings.length === 1 ? "" : "s"}`;
445
+ return /* @__PURE__ */ jsxs5(
446
+ "nav",
447
+ {
448
+ ...props,
449
+ className: cx("eth-doc-outline", className),
450
+ "aria-label": ariaLabel ?? "Document outline",
451
+ "data-eth-component": "DocumentOutline",
452
+ children: [
453
+ /* @__PURE__ */ jsxs5("div", { className: "eth-doc-outline__header", children: [
454
+ /* @__PURE__ */ jsx6("span", { className: "eth-doc-outline__label", children: "On this page" }),
455
+ /* @__PURE__ */ jsx6("span", { className: "eth-doc-outline__count", children: headingCountLabel })
456
+ ] }),
457
+ tree.length ? /* @__PURE__ */ jsx6("ol", { className: "eth-doc-outline__list", children: renderNodes(tree, activeHeadingId, onSelect) }) : /* @__PURE__ */ jsx6("p", { className: "eth-doc-outline__empty", role: "status", children: "No headings available." })
458
+ ]
459
+ }
460
+ );
461
+ }
462
+ function renderNodes(nodes, activeHeadingId, onSelect) {
463
+ return nodes.map((node) => {
464
+ const href = node.href ?? `#${node.id}`;
465
+ const isActive = node.id === activeHeadingId;
466
+ const containsActiveHeading = activeHeadingId ? node.children.some((child) => containsHeading(child, activeHeadingId)) : false;
467
+ return /* @__PURE__ */ jsxs5(
468
+ "li",
469
+ {
470
+ className: cx(
471
+ "eth-doc-outline__item",
472
+ `eth-doc-outline__item--level-${node.level}`,
473
+ isActive && "eth-doc-outline__item--active",
474
+ containsActiveHeading && "eth-doc-outline__item--contains-active"
475
+ ),
476
+ children: [
477
+ /* @__PURE__ */ jsx6(
478
+ "a",
479
+ {
480
+ className: "eth-doc-outline__link",
481
+ href,
482
+ "aria-current": isActive ? "location" : void 0,
483
+ onClick: (event) => {
484
+ if (!href.startsWith("#") && !onSelect) return;
485
+ event.preventDefault();
486
+ onSelect?.(node.id);
487
+ scrollHeadingIntoView(node.href, node.id);
488
+ },
489
+ children: /* @__PURE__ */ jsx6("span", { className: "eth-doc-outline__text", children: node.text })
490
+ }
491
+ ),
492
+ node.children.length ? /* @__PURE__ */ jsx6("ol", { className: "eth-doc-outline__list", children: renderNodes(node.children, activeHeadingId, onSelect) }) : null
493
+ ]
494
+ },
495
+ node.id
496
+ );
497
+ });
498
+ }
499
+ function containsHeading(node, id) {
500
+ return node.id === id || node.children.some((child) => containsHeading(child, id));
501
+ }
502
+ function buildOutlineTree(headings) {
503
+ const roots = [];
504
+ const stack = [{ level: 0, children: roots }];
505
+ for (const heading of headings) {
506
+ const node = { ...heading, children: [] };
507
+ while (stack.length > 1 && stack[stack.length - 1].level >= heading.level) stack.pop();
508
+ stack[stack.length - 1].children.push(node);
509
+ stack.push(node);
510
+ }
511
+ return roots;
512
+ }
513
+ function scrollHeadingIntoView(href, id) {
514
+ const targetId = href?.startsWith("#") ? href.slice(1) : id;
515
+ const target = globalThis.document?.getElementById(targetId);
516
+ target?.scrollIntoView({ block: "start", behavior: "smooth" });
517
+ }
518
+
519
+ // src/components/AgentLockedDocumentPanel.tsx
520
+ import * as React4 from "react";
521
+ import { Button as Button2, InlineNotification, Surface } from "@echothink-ui/core";
522
+ import { Fragment, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
523
+ function AgentLockedDocumentPanel({
524
+ documentRef,
525
+ lockOwner,
526
+ pendingChanges = [],
527
+ onTakeover,
528
+ onRelease,
529
+ onReviewChanges,
530
+ density = "default",
531
+ className,
532
+ ...props
533
+ }) {
534
+ const headingId = React4.useId();
535
+ const ownerLabel = lockOwner?.label ?? "An agent";
536
+ const documentLabel = documentRefLabel(documentRef);
537
+ const documentVersion = typeof documentRef === "string" ? void 0 : documentRef.version;
538
+ const pendingCountLabel = `${pendingChanges.length} ${pendingChanges.length === 1 ? "change" : "changes"}`;
539
+ const hasActions = Boolean(onReviewChanges || onRelease || onTakeover);
540
+ return /* @__PURE__ */ jsxs6(
541
+ Surface,
542
+ {
543
+ ...props,
544
+ title: "Agent document lock",
545
+ subtitle: /* @__PURE__ */ jsxs6(Fragment, { children: [
546
+ ownerLabel,
547
+ " holds the editing lock for ",
548
+ documentLabel,
549
+ "."
550
+ ] }),
551
+ severity: "warning",
552
+ density,
553
+ metadata: [
554
+ {
555
+ label: "Lock state",
556
+ value: /* @__PURE__ */ jsx7(DocumentLockBadge, { lockState: "locked-by-agent", owner: lockOwner })
557
+ },
558
+ { label: "Document", value: documentLabel },
559
+ ...documentVersion ? [{ label: "Version", value: documentVersion }] : [],
560
+ { label: "Pending changes", value: pendingCountLabel }
561
+ ],
562
+ className: cx("eth-doc-agent-lock-panel", className),
563
+ "data-eth-component": "AgentLockedDocumentPanel",
564
+ children: [
565
+ /* @__PURE__ */ jsx7("div", { className: "eth-doc-agent-lock-panel__notice", children: /* @__PURE__ */ jsxs6(InlineNotification, { severity: "warning", title: "Document locked by agent", children: [
566
+ ownerLabel,
567
+ " is preparing changes for ",
568
+ documentLabel,
569
+ ". Review staged updates before releasing the lock or taking over."
570
+ ] }) }),
571
+ /* @__PURE__ */ jsxs6("section", { className: "eth-doc-agent-lock-panel__changes-section", "aria-labelledby": headingId, children: [
572
+ /* @__PURE__ */ jsxs6("div", { className: "eth-doc-agent-lock-panel__changes-header", children: [
573
+ /* @__PURE__ */ jsx7("h3", { id: headingId, children: "Pending changes" }),
574
+ /* @__PURE__ */ jsx7("span", { className: "eth-doc-agent-lock-panel__count", children: pendingCountLabel })
575
+ ] }),
576
+ pendingChanges.length ? /* @__PURE__ */ jsx7("ol", { className: "eth-doc-agent-lock-panel__changes", children: pendingChanges.map((change) => /* @__PURE__ */ jsx7("li", { className: "eth-doc-agent-lock-panel__change", children: /* @__PURE__ */ jsxs6("div", { className: "eth-doc-agent-lock-panel__change-body", children: [
577
+ /* @__PURE__ */ jsx7("strong", { className: "eth-doc-agent-lock-panel__summary", children: change.summary }),
578
+ change.diffSnippet ? /* @__PURE__ */ jsx7("pre", { className: "eth-doc-agent-lock-panel__diff", children: change.diffSnippet }) : null
579
+ ] }) }, change.id)) }) : /* @__PURE__ */ jsx7("p", { className: "eth-doc-agent-lock-panel__empty", role: "status", children: "The agent holds the lock but has not staged changes." })
580
+ ] }),
581
+ hasActions ? /* @__PURE__ */ jsxs6("div", { className: "eth-actions eth-doc-agent-lock-panel__actions", children: [
582
+ onReviewChanges ? /* @__PURE__ */ jsx7(Button2, { intent: "primary", density, onClick: onReviewChanges, children: "Review changes" }) : null,
583
+ onRelease ? /* @__PURE__ */ jsx7(Button2, { intent: "secondary", density, onClick: onRelease, children: "Release lock" }) : null,
584
+ onTakeover ? /* @__PURE__ */ jsx7(Button2, { intent: "danger", density, onClick: onTakeover, children: "Take over" }) : null
585
+ ] }) : null
586
+ ]
587
+ }
588
+ );
589
+ }
590
+
591
+ // src/components/DocumentWorkspaceTemplate.tsx
592
+ import { EmptyState } from "@echothink-ui/core";
593
+ import { jsx as jsx8 } from "react/jsx-runtime";
594
+ function DocumentWorkspaceTemplate({
595
+ title,
596
+ documentRef,
597
+ mode = "edit",
598
+ lockState = "unlocked",
599
+ lockOwner,
600
+ actions = [],
601
+ formattingActions,
602
+ onModeChange,
603
+ headings = [],
604
+ activeHeadingId,
605
+ onSelectHeading,
606
+ inspector,
607
+ toolbar,
608
+ metadata,
609
+ versionRef,
610
+ annotations,
611
+ content,
612
+ children,
613
+ density,
614
+ ...props
615
+ }) {
616
+ const outline = headings.length ? /* @__PURE__ */ jsx8(
617
+ DocumentOutline,
618
+ {
619
+ headings,
620
+ activeHeadingId,
621
+ onSelect: onSelectHeading
622
+ }
623
+ ) : null;
624
+ const resolvedToolbar = toolbar ?? /* @__PURE__ */ jsx8(
625
+ DocumentToolbar,
626
+ {
627
+ actions,
628
+ formattingActions,
629
+ mode,
630
+ onModeChange,
631
+ density
632
+ }
633
+ );
634
+ const body = mode === "view" && content !== void 0 ? /* @__PURE__ */ jsx8(
635
+ DocumentViewer,
636
+ {
637
+ title,
638
+ content,
639
+ metadata,
640
+ versionRef,
641
+ annotations
642
+ }
643
+ ) : children ?? content ?? /* @__PURE__ */ jsx8(EmptyState, { title: "No document content" });
644
+ return /* @__PURE__ */ jsx8(
645
+ DocumentEditorShell,
646
+ {
647
+ ...props,
648
+ title,
649
+ documentRef,
650
+ mode,
651
+ lockState,
652
+ lockOwner,
653
+ toolbar: resolvedToolbar,
654
+ outline,
655
+ inspector,
656
+ density,
657
+ "data-eth-component": "DocumentWorkspaceTemplate",
658
+ children: body
659
+ }
660
+ );
661
+ }
662
+
663
+ // src/index.tsx
664
+ var DocumentsComponentNames = [
665
+ "DocumentEditorShell",
666
+ "DocumentViewer",
667
+ "DocumentToolbar",
668
+ "DocumentOutline",
669
+ "DocumentLockBadge",
670
+ "AgentLockedDocumentPanel",
671
+ "DocumentWorkspaceTemplate"
672
+ ];
673
+ export {
674
+ AgentLockedDocumentPanel,
675
+ DocumentEditorShell,
676
+ DocumentLockBadge,
677
+ DocumentOutline,
678
+ DocumentToolbar,
679
+ DocumentViewer,
680
+ DocumentWorkspaceTemplate,
681
+ DocumentsComponentNames
682
+ };
683
+ //# sourceMappingURL=index.js.map