@beyondwork/docx-react-component 1.0.89 → 1.0.90
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.90",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* Review-role actions here collapse what used to live in
|
|
10
10
|
* `TwReviewQueueBar` as a second strip — the review prev/next, counts,
|
|
11
11
|
* active-item label, accept/reject, markup-mode, and batch operations.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Workflow-role actions surface the scope posture menu plus work-item
|
|
13
|
+
* traversal + claim/skip/complete.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import React, { useState } from "react";
|
|
@@ -18,14 +18,12 @@ import * as Popover from "@radix-ui/react-popover";
|
|
|
18
18
|
import * as Toggle from "@radix-ui/react-toggle";
|
|
19
19
|
import * as Tooltip from "@radix-ui/react-tooltip";
|
|
20
20
|
import {
|
|
21
|
-
BookmarkCheck,
|
|
22
21
|
Check,
|
|
23
22
|
CheckCheck,
|
|
24
23
|
ChevronLeft,
|
|
25
24
|
ChevronRight,
|
|
26
25
|
CircleOff,
|
|
27
26
|
FileDiff,
|
|
28
|
-
Flag,
|
|
29
27
|
Hand,
|
|
30
28
|
MessageSquare,
|
|
31
29
|
MessageSquareDot,
|
|
@@ -48,6 +46,7 @@ import type { ScopedChromePolicy } from "../../ui/headless/scoped-chrome-policy"
|
|
|
48
46
|
import type { ToolbarChromeItemId } from "../../ui/headless/chrome-registry";
|
|
49
47
|
import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
|
|
50
48
|
import { ROLE_ACTION_SETS } from "../../ui/headless/role-action-sets";
|
|
49
|
+
import { TwDisplayModeSelector } from "../chrome/tw-display-mode-selector";
|
|
51
50
|
import { TwScopePostureMenu } from "./tw-scope-posture-menu";
|
|
52
51
|
|
|
53
52
|
/**
|
|
@@ -103,7 +102,7 @@ export interface TwRoleActionRegionProps {
|
|
|
103
102
|
onReviewSidebarTrackedChanges?: () => void;
|
|
104
103
|
onReviewSidebarComments?: () => void;
|
|
105
104
|
|
|
106
|
-
// Workflow
|
|
105
|
+
// Workflow role: assign authorable scope posture.
|
|
107
106
|
onMarkScopePosture?: (posture: ScopeRailPosture) => void;
|
|
108
107
|
|
|
109
108
|
// Review role
|
|
@@ -366,10 +365,11 @@ function RoleActionButton(arg: RoleActionButtonProps): React.JSX.Element | null
|
|
|
366
365
|
);
|
|
367
366
|
case "review-markup-mode":
|
|
368
367
|
return (
|
|
369
|
-
<
|
|
370
|
-
|
|
368
|
+
<TwDisplayModeSelector
|
|
369
|
+
value={props.markupDisplay ?? "simple"}
|
|
371
370
|
onChange={(mode) => props.onReviewMarkupMode?.(mode)}
|
|
372
371
|
disabled={!props.onReviewMarkupMode}
|
|
372
|
+
data-testid="role-review-markup-mode"
|
|
373
373
|
/>
|
|
374
374
|
);
|
|
375
375
|
case "workflow-prev":
|
|
@@ -693,30 +693,4 @@ function ReviewActiveLabel({
|
|
|
693
693
|
);
|
|
694
694
|
}
|
|
695
695
|
|
|
696
|
-
function MarkupModeSelect(arg: {
|
|
697
|
-
mode: MarkupDisplayMode;
|
|
698
|
-
onChange: (mode: MarkupDisplayMode) => void;
|
|
699
|
-
disabled?: boolean;
|
|
700
|
-
}): React.JSX.Element {
|
|
701
|
-
const Icon = arg.mode === "clean" ? BookmarkCheck : arg.mode === "all" ? Flag : Rows3;
|
|
702
|
-
return (
|
|
703
|
-
<button
|
|
704
|
-
type="button"
|
|
705
|
-
aria-label={`Markup display: ${arg.mode}`}
|
|
706
|
-
disabled={arg.disabled}
|
|
707
|
-
onMouseDown={preserveEditorSelectionMouseDown}
|
|
708
|
-
onClick={() => {
|
|
709
|
-
const next: MarkupDisplayMode =
|
|
710
|
-
arg.mode === "all" ? "clean" : arg.mode === "clean" ? "simple" : "all";
|
|
711
|
-
arg.onChange(next);
|
|
712
|
-
}}
|
|
713
|
-
data-testid="role-review-markup-mode"
|
|
714
|
-
className="inline-flex h-6 items-center gap-1 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40"
|
|
715
|
-
>
|
|
716
|
-
<Icon className="h-3.5 w-3.5" />
|
|
717
|
-
<span className="capitalize">{arg.mode}</span>
|
|
718
|
-
</button>
|
|
719
|
-
);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
696
|
export default TwRoleActionRegion;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Scope posture menu — replaces the old "Mark section" button with a
|
|
3
|
-
* topnav dropdown listing the
|
|
4
|
-
*
|
|
5
|
-
* single "marked" flag.
|
|
3
|
+
* topnav dropdown listing the authorable `ScopeRailPosture` values so
|
|
4
|
+
* workflow operators can mark regions with an explicit workflow mode
|
|
5
|
+
* instead of a single "marked" flag.
|
|
6
6
|
*
|
|
7
7
|
* Per runtime-rendering-and-chrome-phase.md §6.4, the menu lives inline
|
|
8
|
-
* in the
|
|
8
|
+
* in the workflow role's primary action region (not in the review queue
|
|
9
9
|
* strip). Postures align 1:1 with the rail vocabulary so the rail
|
|
10
|
-
* updates visually as soon as the user picks one.
|
|
10
|
+
* updates visually as soon as the user picks one. Runtime-only postures
|
|
11
|
+
* like preserve-only and blocked-import still render in overlays, but
|
|
12
|
+
* they are not choices users can assign from this product menu.
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
import React, { useState } from "react";
|
|
@@ -17,7 +19,6 @@ import {
|
|
|
17
19
|
ChevronDown,
|
|
18
20
|
Eye,
|
|
19
21
|
Flag,
|
|
20
|
-
Lock,
|
|
21
22
|
MessageCircle,
|
|
22
23
|
Pencil,
|
|
23
24
|
Sparkles,
|
|
@@ -35,12 +36,12 @@ export interface TwScopePostureMenuProps {
|
|
|
35
36
|
"data-testid"?: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
interface
|
|
39
|
+
export interface ScopePostureMenuEntry {
|
|
39
40
|
posture: ScopeRailPosture;
|
|
40
41
|
label: string;
|
|
41
42
|
hint: string;
|
|
42
43
|
icon: React.ComponentType<{ className?: string }>;
|
|
43
|
-
tone: "accent" | "warning" | "comment" | "secondary"
|
|
44
|
+
tone: "accent" | "warning" | "comment" | "secondary";
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
/**
|
|
@@ -49,7 +50,7 @@ interface PostureEntry {
|
|
|
49
50
|
* glyphs via the `data-icon` attribute). Extract both into a single
|
|
50
51
|
* source of truth in a follow-up.
|
|
51
52
|
*/
|
|
52
|
-
const
|
|
53
|
+
export const SCOPE_POSTURE_MENU_ENTRIES: readonly ScopePostureMenuEntry[] = [
|
|
53
54
|
{
|
|
54
55
|
posture: "edit",
|
|
55
56
|
label: "Edit scope",
|
|
@@ -85,22 +86,11 @@ const POSTURE_ENTRIES: readonly PostureEntry[] = [
|
|
|
85
86
|
icon: Flag,
|
|
86
87
|
tone: "warning",
|
|
87
88
|
},
|
|
88
|
-
{
|
|
89
|
-
posture: "preserve-only",
|
|
90
|
-
label: "Preserve only",
|
|
91
|
-
hint: "Blocked — export-preserving only",
|
|
92
|
-
icon: Lock,
|
|
93
|
-
tone: "danger",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
posture: "blocked-import",
|
|
97
|
-
label: "Blocked import",
|
|
98
|
-
hint: "Blocked — imported region is locked",
|
|
99
|
-
icon: Lock,
|
|
100
|
-
tone: "danger",
|
|
101
|
-
},
|
|
102
89
|
];
|
|
103
90
|
|
|
91
|
+
export const SCOPE_POSTURE_MENU_POSTURES: readonly ScopeRailPosture[] =
|
|
92
|
+
SCOPE_POSTURE_MENU_ENTRIES.map((entry) => entry.posture);
|
|
93
|
+
|
|
104
94
|
export function TwScopePostureMenu(props: TwScopePostureMenuProps): React.JSX.Element {
|
|
105
95
|
const [open, setOpen] = useState(false);
|
|
106
96
|
|
|
@@ -131,7 +121,7 @@ export function TwScopePostureMenu(props: TwScopePostureMenuProps): React.JSX.El
|
|
|
131
121
|
<div className="mb-1 px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary">
|
|
132
122
|
Mark section with posture
|
|
133
123
|
</div>
|
|
134
|
-
{
|
|
124
|
+
{SCOPE_POSTURE_MENU_ENTRIES.map((entry) => (
|
|
135
125
|
<Popover.Close key={entry.posture} asChild>
|
|
136
126
|
<button
|
|
137
127
|
type="button"
|
|
@@ -163,7 +153,7 @@ export function TwScopePostureMenu(props: TwScopePostureMenuProps): React.JSX.El
|
|
|
163
153
|
);
|
|
164
154
|
}
|
|
165
155
|
|
|
166
|
-
function toneClass(tone:
|
|
156
|
+
function toneClass(tone: ScopePostureMenuEntry["tone"]): string {
|
|
167
157
|
switch (tone) {
|
|
168
158
|
case "accent":
|
|
169
159
|
return "text-accent";
|
|
@@ -171,8 +161,6 @@ function toneClass(tone: PostureEntry["tone"]): string {
|
|
|
171
161
|
return "text-warning";
|
|
172
162
|
case "comment":
|
|
173
163
|
return "text-comment";
|
|
174
|
-
case "danger":
|
|
175
|
-
return "text-danger";
|
|
176
164
|
case "secondary":
|
|
177
165
|
default:
|
|
178
166
|
return "text-secondary";
|
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
type ScopedChromePolicy,
|
|
70
70
|
} from "../../ui/headless/scoped-chrome-policy";
|
|
71
71
|
import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
|
|
72
|
+
import { TwDisplayModeSelector } from "../chrome/tw-display-mode-selector";
|
|
72
73
|
import { type MarkupDisplayMode } from "./tw-role-action-region";
|
|
73
74
|
import { TwToolbarIconButton } from "./tw-toolbar-icon-button";
|
|
74
75
|
|
|
@@ -123,6 +124,8 @@ export interface TwToolbarProps {
|
|
|
123
124
|
onToggleSidebar?: () => void;
|
|
124
125
|
onZoomChange?: (level: ZoomLevel) => void;
|
|
125
126
|
onShowTrackedChangesChange: (show: boolean) => void;
|
|
127
|
+
/** Top-toolbar fallback for changing redline/comment display when review context band is not active. */
|
|
128
|
+
onMarkupDisplayChange?: (mode: MarkupDisplayMode) => void;
|
|
126
129
|
onRestartNumbering?: () => void;
|
|
127
130
|
onContinueNumbering?: () => void;
|
|
128
131
|
onUpdateFields?: () => void;
|
|
@@ -262,6 +265,10 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
262
265
|
const showTrackedChangesToggle =
|
|
263
266
|
isToolbarChromeItemVisible(scopedChromePolicy, "tracked-changes-toggle") &&
|
|
264
267
|
!isChromeItemOwnedByRoleRegion("tracked-changes-toggle", props.role);
|
|
268
|
+
const showMarkupDisplaySelector =
|
|
269
|
+
props.markupDisplay !== undefined &&
|
|
270
|
+
props.onMarkupDisplayChange !== undefined &&
|
|
271
|
+
!isChromeItemOwnedByRoleRegion("review-markup-mode", props.role);
|
|
265
272
|
const showRightClusterComment =
|
|
266
273
|
isToolbarChromeItemVisible(scopedChromePolicy, "comment") &&
|
|
267
274
|
!isChromeItemOwnedByRoleRegion("comment", props.role);
|
|
@@ -695,6 +702,17 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
695
702
|
</>
|
|
696
703
|
) : null}
|
|
697
704
|
|
|
705
|
+
{showMarkupDisplaySelector ? (
|
|
706
|
+
<>
|
|
707
|
+
<TwDisplayModeSelector
|
|
708
|
+
value={props.markupDisplay!}
|
|
709
|
+
onChange={(mode) => props.onMarkupDisplayChange?.(mode)}
|
|
710
|
+
data-testid="toolbar-display-mode-selector"
|
|
711
|
+
/>
|
|
712
|
+
<div className="mx-1 h-4 w-px bg-border" />
|
|
713
|
+
</>
|
|
714
|
+
) : null}
|
|
715
|
+
|
|
698
716
|
{/* View mode toggle group: Canvas (clean, flowing) / Page (layout-sensitive) */}
|
|
699
717
|
{isToolbarChromeItemVisible(scopedChromePolicy, "workspace-mode") ? (
|
|
700
718
|
<ToggleGroup.Root
|
|
@@ -878,6 +878,10 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
878
878
|
dismissSelectionToolbar();
|
|
879
879
|
props.onShowTrackedChangesChange(show);
|
|
880
880
|
}}
|
|
881
|
+
onMarkupDisplayChange={(mode) => {
|
|
882
|
+
dismissSelectionToolbar();
|
|
883
|
+
props.onReviewMarkupModeChange?.(mode);
|
|
884
|
+
}}
|
|
881
885
|
role={viewState.editorRole}
|
|
882
886
|
reviewQueue={props.reviewQueue}
|
|
883
887
|
markupDisplay={markupDisplay}
|