@beyondwork/docx-react-component 1.0.53 → 1.0.55

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 (99) hide show
  1. package/package.json +1 -1
  2. package/src/api/public-types.ts +125 -7
  3. package/src/index.ts +5 -0
  4. package/src/io/docx-session.ts +27 -3
  5. package/src/io/normalize/normalize-text.ts +1 -0
  6. package/src/io/ooxml/parse-field-switches.ts +134 -0
  7. package/src/io/ooxml/parse-fields.ts +28 -2
  8. package/src/model/canonical-document.ts +13 -2
  9. package/src/runtime/chart/chart-model-store.ts +88 -0
  10. package/src/runtime/chart/chart-snapshot.ts +239 -0
  11. package/src/runtime/collab/checkpoint-store.ts +1 -1
  12. package/src/runtime/collab/event-types.ts +4 -0
  13. package/src/runtime/collab/runtime-collab-sync.ts +1 -2
  14. package/src/runtime/document-runtime.ts +115 -13
  15. package/src/runtime/layout/inert-layout-facet.ts +1 -0
  16. package/src/runtime/layout/layout-engine-version.ts +58 -1
  17. package/src/runtime/layout/layout-invalidation.ts +150 -30
  18. package/src/runtime/layout/page-graph.ts +19 -0
  19. package/src/runtime/layout/paginated-layout-engine.ts +128 -19
  20. package/src/runtime/layout/project-block-fragments.ts +27 -0
  21. package/src/runtime/layout/public-facet.ts +27 -0
  22. package/src/runtime/page-number-format.ts +207 -0
  23. package/src/runtime/render/render-frame-diff.ts +38 -2
  24. package/src/runtime/surface-projection.ts +32 -3
  25. package/src/ui/WordReviewEditor.tsx +57 -3
  26. package/src/ui/headless/comment-decoration-model.ts +60 -5
  27. package/src/ui/headless/revision-decoration-model.ts +94 -6
  28. package/src/ui/shared/revision-filters.ts +16 -6
  29. package/src/ui-tailwind/chart/ChartSurface.tsx +236 -0
  30. package/src/ui-tailwind/chart/layout/axis-layout.ts +17 -9
  31. package/src/ui-tailwind/chart/layout/legend-layout.ts +231 -0
  32. package/src/ui-tailwind/chart/layout/plot-area.ts +152 -59
  33. package/src/ui-tailwind/chart/layout/title-layout.ts +184 -0
  34. package/src/ui-tailwind/chart/render/area.tsx +277 -0
  35. package/src/ui-tailwind/chart/render/bar-column.tsx +356 -0
  36. package/src/ui-tailwind/chart/render/bubble.tsx +134 -0
  37. package/src/ui-tailwind/chart/render/combo.tsx +85 -0
  38. package/src/ui-tailwind/chart/render/data-labels.tsx +513 -0
  39. package/src/ui-tailwind/chart/render/font-metrics.ts +298 -0
  40. package/src/ui-tailwind/chart/render/gridlines.ts +228 -0
  41. package/src/ui-tailwind/chart/render/line.tsx +363 -0
  42. package/src/ui-tailwind/chart/render/number-format.ts +120 -16
  43. package/src/ui-tailwind/chart/render/pie.tsx +275 -0
  44. package/src/ui-tailwind/chart/render/progressive-render.ts +103 -0
  45. package/src/ui-tailwind/chart/render/scatter.tsx +228 -0
  46. package/src/ui-tailwind/chart/render/smooth-curve.ts +101 -0
  47. package/src/ui-tailwind/chart/render/svg-primitives.ts +378 -0
  48. package/src/ui-tailwind/chart/render/unsupported.tsx +126 -0
  49. package/src/ui-tailwind/chrome/collab-audience-chip.tsx +11 -0
  50. package/src/ui-tailwind/chrome/collab-negotiation-action-bar.tsx +44 -18
  51. package/src/ui-tailwind/chrome/collab-presence-strip.tsx +68 -7
  52. package/src/ui-tailwind/chrome/collab-role-chip.tsx +21 -2
  53. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +20 -3
  54. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +102 -37
  55. package/src/ui-tailwind/chrome/tw-command-palette.tsx +358 -0
  56. package/src/ui-tailwind/chrome/tw-comment-preview.tsx +108 -0
  57. package/src/ui-tailwind/chrome/tw-context-menu.tsx +227 -0
  58. package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +136 -0
  59. package/src/ui-tailwind/chrome/tw-empty-state.tsx +76 -0
  60. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +30 -16
  61. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +23 -4
  62. package/src/ui-tailwind/chrome/tw-paste-drop-toast.tsx +113 -0
  63. package/src/ui-tailwind/chrome/tw-revision-hover-preview.tsx +150 -0
  64. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +2 -0
  65. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +38 -2
  66. package/src/ui-tailwind/chrome/tw-selection-tool-placement.ts +15 -3
  67. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +32 -20
  68. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +68 -0
  69. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +10 -10
  70. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +26 -5
  71. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +29 -22
  72. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +72 -10
  73. package/src/ui-tailwind/chrome-overlay/tw-scope-card.tsx +33 -18
  74. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +94 -0
  75. package/src/ui-tailwind/editor-surface/chart-node-view.tsx +90 -0
  76. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +20 -7
  77. package/src/ui-tailwind/editor-surface/pm-schema.ts +4 -0
  78. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +14 -0
  79. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +93 -0
  80. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +2 -1
  81. package/src/ui-tailwind/index.ts +11 -0
  82. package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +52 -2
  83. package/src/ui-tailwind/page-stack/tw-page-footer-band.tsx +13 -0
  84. package/src/ui-tailwind/page-stack/tw-page-header-band.tsx +13 -0
  85. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +8 -0
  86. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +83 -32
  87. package/src/ui-tailwind/review/tw-health-panel.tsx +174 -109
  88. package/src/ui-tailwind/review/tw-rail-card.tsx +9 -1
  89. package/src/ui-tailwind/review/tw-review-rail.tsx +36 -42
  90. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +189 -101
  91. package/src/ui-tailwind/review/tw-workflow-tab.tsx +11 -1
  92. package/src/ui-tailwind/status/tw-status-bar.tsx +114 -46
  93. package/src/ui-tailwind/theme/editor-theme.css +249 -22
  94. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +14 -1
  95. package/src/ui-tailwind/toolbar/tw-shell-header.tsx +73 -32
  96. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +49 -9
  97. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +178 -14
  98. package/src/ui-tailwind/tw-review-workspace.tsx +39 -6
  99. package/src/ui-tailwind/chrome/review-queue-bar.tsx +0 -85
@@ -57,6 +57,10 @@ import {
57
57
  useVisiblePageIndexRange,
58
58
  } from "./page-stack/use-visible-block-range.ts";
59
59
  import { sliceBlocksForPage } from "./editor-surface/page-slice-util.ts";
60
+ import {
61
+ findScrollAnchor,
62
+ restoreScrollAnchor,
63
+ } from "./editor-surface/scroll-anchor.ts";
60
64
  import { TwPageBlockView } from "./editor-surface/tw-page-block-view.tsx";
61
65
  import { computeLineMarkersIfEnabled } from "./page-chrome-model.ts";
62
66
  import type { SessionCapabilities } from "../runtime/session-capabilities";
@@ -140,14 +144,31 @@ export interface TwReviewWorkspaceProps {
140
144
  helpLabel?: string;
141
145
  };
142
146
  /**
143
- * Opt-in floating mode dock pinned to the bottom of the workspace.
144
- * Hosts pass the derived label / icon / actions; defaults to hidden.
147
+ * @deprecated Lane 6b §6b.U4 (designsystem §6.26).
148
+ *
149
+ * The floating bottom-center mode dock is retained for back-compat but is
150
+ * off by default. Its functionality is covered by TwShellHeader mode tabs
151
+ * + TwRoleActionRegion. To render it, hosts must supply BOTH `modeDock`
152
+ * data and `experimental.showModeDock = true`.
145
153
  */
146
154
  modeDock?: {
147
155
  label: string;
148
156
  icon?: ReactNode;
149
157
  actions?: readonly import("./chrome/tw-mode-dock").TwModeDockAction[];
150
158
  };
159
+ /**
160
+ * Experimental feature flags. Anything here is subject to change or
161
+ * removal without a major-version bump. Do not depend on these in
162
+ * production consumers.
163
+ */
164
+ experimental?: {
165
+ /**
166
+ * Re-enable the deprecated TwModeDock floating bottom dock. Defaults to
167
+ * `false` — the shell header + role action region supersede this surface
168
+ * per designsystem §6.26.
169
+ */
170
+ showModeDock?: boolean;
171
+ };
151
172
  document: ReactNode;
152
173
  workspaceMode: WorkspaceMode;
153
174
  zoomLevel?: ZoomLevel;
@@ -1152,7 +1173,22 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
1152
1173
  : undefined}
1153
1174
  onWorkspaceModeChange={(value) => {
1154
1175
  dismissSelectionToolbar();
1176
+ // L6d.U3: capture the block the viewport sits over,
1177
+ // then restore the same block's scroll offset after
1178
+ // the new mode has painted. Two rAFs: the first waits
1179
+ // for React to commit the mode change, the second
1180
+ // waits for layout + the page-break widgets to paint
1181
+ // before we write scrollTop.
1182
+ const root = scrollRootRef.current;
1183
+ const anchor = findScrollAnchor(root);
1155
1184
  props.onWorkspaceModeChange(value);
1185
+ if (anchor && typeof requestAnimationFrame === "function") {
1186
+ requestAnimationFrame(() => {
1187
+ requestAnimationFrame(() => {
1188
+ restoreScrollAnchor(scrollRootRef.current, anchor);
1189
+ });
1190
+ });
1191
+ }
1156
1192
  }}
1157
1193
  onToggleSidebar={() => {
1158
1194
  dismissSelectionToolbar();
@@ -1220,9 +1256,6 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
1220
1256
  </div>
1221
1257
  ) : null}
1222
1258
 
1223
- {/* Legacy TwReviewQueueBar is suppressed — review role's action region
1224
- now owns queue prev/next + counts inline in the top toolbar. */}
1225
-
1226
1259
  {chromeVisibility.alerts ? <TwAlertBanner
1227
1260
  snapshot={snapshot}
1228
1261
  preserveOnlyCount={preserveOnlyCount}
@@ -1784,7 +1817,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
1784
1817
  </div>
1785
1818
  ) : null}
1786
1819
  </div>
1787
- {props.modeDock ? (
1820
+ {props.modeDock && props.experimental?.showModeDock === true ? (
1788
1821
  <TwModeDock
1789
1822
  label={props.modeDock.label}
1790
1823
  icon={props.modeDock.icon}
@@ -1,85 +0,0 @@
1
- import React from "react";
2
-
3
- import { ChevronLeft, ChevronRight, MessageSquareText, Rows3 } from "lucide-react";
4
-
5
- import type { ReviewQueueSnapshot } from "../../api/public-types";
6
- import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
7
-
8
- /** @deprecated Use the role action region (TwRoleActionRegion) for queue navigation. */
9
- export interface TwReviewQueueBarProps {
10
- queue: ReviewQueueSnapshot;
11
- onPrevious?: () => void;
12
- onNext?: () => void;
13
- }
14
-
15
- const buttonClass =
16
- "inline-flex h-8 items-center gap-1 rounded-lg border border-border/80 bg-canvas px-2.5 text-xs font-medium text-secondary transition-colors hover:bg-surface-raised focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas disabled:cursor-not-allowed disabled:opacity-40";
17
-
18
- export function TwReviewQueueBar(props: TwReviewQueueBarProps) {
19
- const activeItem = props.queue.items[props.queue.activeIndex] ?? null;
20
- const activeLabel =
21
- activeItem?.label ??
22
- (props.queue.totalCount > 0 ? "Review queue" : "No review items");
23
- const activeKindLabel = activeItem ? formatReviewQueueItemKind(activeItem.kind) : null;
24
-
25
- return (
26
- <div className="border-b border-border/80 bg-surface/80 px-3 py-2.5 backdrop-blur-sm">
27
- <div className="flex flex-wrap items-center gap-2">
28
- <button
29
- type="button"
30
- aria-label="Previous review item"
31
- className={buttonClass}
32
- disabled={props.queue.totalCount === 0}
33
- onMouseDown={preserveEditorSelectionMouseDown}
34
- onClick={props.onPrevious}
35
- >
36
- <ChevronLeft className="h-3.5 w-3.5" />
37
- Prev
38
- </button>
39
- <button
40
- type="button"
41
- aria-label="Next review item"
42
- className={buttonClass}
43
- disabled={props.queue.totalCount === 0}
44
- onMouseDown={preserveEditorSelectionMouseDown}
45
- onClick={props.onNext}
46
- >
47
- Next
48
- <ChevronRight className="h-3.5 w-3.5" />
49
- </button>
50
- <div className="ml-auto flex flex-wrap items-center gap-2 text-xs text-secondary">
51
- <span className="inline-flex items-center gap-1 rounded-full bg-canvas px-2.5 py-1 font-medium text-primary">
52
- <MessageSquareText className="h-3.5 w-3.5 text-comment" />
53
- {props.queue.openCount} open
54
- </span>
55
- <span className="inline-flex items-center gap-1 rounded-full bg-canvas px-2.5 py-1 font-medium text-primary">
56
- <Rows3 className="h-3.5 w-3.5 text-accent" />
57
- {props.queue.totalCount} total
58
- </span>
59
- </div>
60
- </div>
61
- <div className="mt-2 flex items-center gap-2 min-w-0">
62
- {activeKindLabel ? (
63
- <span
64
- className="inline-flex shrink-0 rounded-full bg-canvas px-2 py-0.5 text-[11px] font-medium text-secondary"
65
- data-testid="review-queue-item-kind"
66
- >
67
- {activeKindLabel}
68
- </span>
69
- ) : null}
70
- <div className="min-w-0 truncate text-sm font-medium text-primary">{activeLabel}</div>
71
- </div>
72
- </div>
73
- );
74
- }
75
-
76
- function formatReviewQueueItemKind(kind: ReviewQueueSnapshot["items"][number]["kind"]): string {
77
- switch (kind) {
78
- case "comment":
79
- return "Comment";
80
- case "change":
81
- return "Redline";
82
- case "section_mark":
83
- return "Tag";
84
- }
85
- }