@beyondwork/docx-react-component 1.0.30 → 1.0.31
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 +1 -1
- package/src/ui-tailwind/chrome/responsive-chrome.ts +46 -0
- package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +4 -4
- package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +5 -5
- package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +3 -3
- package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +4 -4
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +14 -9
- package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +3 -3
- package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +5 -5
- package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +6 -6
- package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +9 -9
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +172 -122
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +1 -1
- package/src/ui-tailwind/editor-surface/surface-build-keys.ts +1 -3
- package/src/ui-tailwind/review/tw-review-rail.tsx +9 -1
- package/src/ui-tailwind/toolbar/toolbar-layout.ts +47 -0
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +367 -22
- package/src/ui-tailwind/tw-review-workspace.tsx +131 -4
|
@@ -34,138 +34,188 @@ const CELL_COLORS = [
|
|
|
34
34
|
] as const;
|
|
35
35
|
|
|
36
36
|
export function TwTableContextToolbar(props: TwTableContextToolbarProps) {
|
|
37
|
+
const tableContext = props.tableContext;
|
|
38
|
+
const tableSizeLabel = tableContext ? `${tableContext.rowCount} x ${tableContext.columnCount}` : null;
|
|
39
|
+
const selectionLabel = tableContext
|
|
40
|
+
? tableContext.selectedCellCount > 1
|
|
41
|
+
? `${tableContext.selectedCellCount} cells`
|
|
42
|
+
: `R${tableContext.currentCell.rowIndex + 1} C${tableContext.currentCell.columnIndex + 1}`
|
|
43
|
+
: null;
|
|
44
|
+
|
|
37
45
|
return (
|
|
38
46
|
<div
|
|
39
47
|
data-testid="table-context-toolbar"
|
|
40
|
-
className="flex flex-wrap items-
|
|
48
|
+
className="flex max-w-[min(30rem,calc(100vw-1.5rem))] flex-wrap items-start gap-1.5 rounded-lg border border-border bg-canvas px-2.5 py-1.5 shadow-sm"
|
|
41
49
|
>
|
|
42
|
-
<span className="text-[
|
|
50
|
+
<span className="text-[9px] font-semibold uppercase tracking-[0.12em] text-tertiary">
|
|
43
51
|
Table
|
|
44
52
|
</span>
|
|
53
|
+
{tableSizeLabel ? <ToolbarBadge>{tableSizeLabel}</ToolbarBadge> : null}
|
|
54
|
+
{selectionLabel ? <ToolbarBadge>{selectionLabel}</ToolbarBadge> : null}
|
|
55
|
+
{tableContext?.currentCell.isHeader ? <ToolbarBadge tone="accent">Header row</ToolbarBadge> : null}
|
|
56
|
+
|
|
57
|
+
<ToolbarSection label="Style">
|
|
58
|
+
<select
|
|
59
|
+
aria-label="Table style"
|
|
60
|
+
className="h-7 min-w-[9rem] rounded-md border border-border bg-canvas px-2 text-[11px] text-primary disabled:opacity-40"
|
|
61
|
+
disabled={
|
|
62
|
+
props.disabled ||
|
|
63
|
+
props.tableStyles.length === 0 ||
|
|
64
|
+
!props.onSetTableStyle ||
|
|
65
|
+
!tableContext?.operations.setTableStyle.enabled
|
|
66
|
+
}
|
|
67
|
+
onMouseDown={preserveEditorSelectionMouseDown}
|
|
68
|
+
onChange={(event) => props.onSetTableStyle?.(event.target.value)}
|
|
69
|
+
value={tableContext?.currentStyleId ?? ""}
|
|
70
|
+
title={tableContext?.operations.setTableStyle.reason}
|
|
71
|
+
>
|
|
72
|
+
<option value="" disabled>Table style</option>
|
|
73
|
+
{props.tableStyles.map((style) => (
|
|
74
|
+
<option key={style.styleId} value={style.styleId}>
|
|
75
|
+
{style.displayName}
|
|
76
|
+
</option>
|
|
77
|
+
))}
|
|
78
|
+
</select>
|
|
79
|
+
</ToolbarSection>
|
|
80
|
+
|
|
81
|
+
<ToolbarSection label="Rows">
|
|
82
|
+
<ToolbarButton
|
|
83
|
+
ariaLabel="Add row above"
|
|
84
|
+
capability={tableContext?.operations.addRowBefore}
|
|
85
|
+
disabled={props.disabled}
|
|
86
|
+
onClick={props.onAddRowBefore}
|
|
87
|
+
>
|
|
88
|
+
Above
|
|
89
|
+
</ToolbarButton>
|
|
90
|
+
<ToolbarButton
|
|
91
|
+
ariaLabel="Add row below"
|
|
92
|
+
capability={tableContext?.operations.addRowAfter}
|
|
93
|
+
disabled={props.disabled}
|
|
94
|
+
onClick={props.onAddRowAfter}
|
|
95
|
+
>
|
|
96
|
+
Below
|
|
97
|
+
</ToolbarButton>
|
|
98
|
+
<ToolbarButton
|
|
99
|
+
ariaLabel="Delete row"
|
|
100
|
+
capability={tableContext?.operations.deleteRow}
|
|
101
|
+
disabled={props.disabled}
|
|
102
|
+
onClick={props.onDeleteRow}
|
|
103
|
+
>
|
|
104
|
+
Delete row
|
|
105
|
+
</ToolbarButton>
|
|
106
|
+
</ToolbarSection>
|
|
45
107
|
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
108
|
+
<ToolbarSection label="Columns">
|
|
109
|
+
<ToolbarButton
|
|
110
|
+
ariaLabel="Add column left"
|
|
111
|
+
capability={tableContext?.operations.addColumnBefore}
|
|
112
|
+
disabled={props.disabled}
|
|
113
|
+
onClick={props.onAddColumnBefore}
|
|
114
|
+
>
|
|
115
|
+
Left
|
|
116
|
+
</ToolbarButton>
|
|
117
|
+
<ToolbarButton
|
|
118
|
+
ariaLabel="Add column right"
|
|
119
|
+
capability={tableContext?.operations.addColumnAfter}
|
|
120
|
+
disabled={props.disabled}
|
|
121
|
+
onClick={props.onAddColumnAfter}
|
|
122
|
+
>
|
|
123
|
+
Right
|
|
124
|
+
</ToolbarButton>
|
|
125
|
+
<ToolbarButton
|
|
126
|
+
ariaLabel="Delete column"
|
|
127
|
+
capability={tableContext?.operations.deleteColumn}
|
|
128
|
+
disabled={props.disabled}
|
|
129
|
+
onClick={props.onDeleteColumn}
|
|
130
|
+
>
|
|
131
|
+
Delete column
|
|
132
|
+
</ToolbarButton>
|
|
133
|
+
</ToolbarSection>
|
|
51
134
|
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
props.disabled
|
|
57
|
-
props.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</option>
|
|
71
|
-
))}
|
|
72
|
-
</select>
|
|
135
|
+
<ToolbarSection label="Cells">
|
|
136
|
+
<ToolbarButton
|
|
137
|
+
ariaLabel="Merge cells"
|
|
138
|
+
capability={tableContext?.operations.mergeCells}
|
|
139
|
+
disabled={props.disabled}
|
|
140
|
+
onClick={props.onMergeCells}
|
|
141
|
+
>
|
|
142
|
+
Merge
|
|
143
|
+
</ToolbarButton>
|
|
144
|
+
<ToolbarButton
|
|
145
|
+
ariaLabel="Split cell"
|
|
146
|
+
capability={tableContext?.operations.splitCell}
|
|
147
|
+
disabled={props.disabled}
|
|
148
|
+
onClick={props.onSplitCell}
|
|
149
|
+
>
|
|
150
|
+
Split
|
|
151
|
+
</ToolbarButton>
|
|
152
|
+
</ToolbarSection>
|
|
73
153
|
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
>
|
|
96
|
-
Delete row
|
|
97
|
-
</ToolbarButton>
|
|
98
|
-
<ToolbarButton
|
|
99
|
-
ariaLabel="Add column left"
|
|
100
|
-
capability={props.tableContext?.operations.addColumnBefore}
|
|
101
|
-
disabled={props.disabled}
|
|
102
|
-
onClick={props.onAddColumnBefore}
|
|
103
|
-
>
|
|
104
|
-
Column left
|
|
105
|
-
</ToolbarButton>
|
|
106
|
-
<ToolbarButton
|
|
107
|
-
ariaLabel="Add column right"
|
|
108
|
-
capability={props.tableContext?.operations.addColumnAfter}
|
|
109
|
-
disabled={props.disabled}
|
|
110
|
-
onClick={props.onAddColumnAfter}
|
|
111
|
-
>
|
|
112
|
-
Column right
|
|
113
|
-
</ToolbarButton>
|
|
114
|
-
<ToolbarButton
|
|
115
|
-
ariaLabel="Delete column"
|
|
116
|
-
capability={props.tableContext?.operations.deleteColumn}
|
|
117
|
-
disabled={props.disabled}
|
|
118
|
-
onClick={props.onDeleteColumn}
|
|
119
|
-
>
|
|
120
|
-
Delete column
|
|
121
|
-
</ToolbarButton>
|
|
122
|
-
<ToolbarButton
|
|
123
|
-
ariaLabel="Merge cells"
|
|
124
|
-
capability={props.tableContext?.operations.mergeCells}
|
|
125
|
-
disabled={props.disabled}
|
|
126
|
-
onClick={props.onMergeCells}
|
|
127
|
-
>
|
|
128
|
-
Merge
|
|
129
|
-
</ToolbarButton>
|
|
130
|
-
<ToolbarButton
|
|
131
|
-
ariaLabel="Split cell"
|
|
132
|
-
capability={props.tableContext?.operations.splitCell}
|
|
133
|
-
disabled={props.disabled}
|
|
134
|
-
onClick={props.onSplitCell}
|
|
135
|
-
>
|
|
136
|
-
Split
|
|
137
|
-
</ToolbarButton>
|
|
154
|
+
<ToolbarSection label="Fill">
|
|
155
|
+
<div className="flex items-center gap-1">
|
|
156
|
+
{CELL_COLORS.map((color) => (
|
|
157
|
+
<button
|
|
158
|
+
key={color}
|
|
159
|
+
type="button"
|
|
160
|
+
aria-label={`Set cell fill ${color}`}
|
|
161
|
+
disabled={
|
|
162
|
+
props.disabled ||
|
|
163
|
+
!props.onSetCellBackground ||
|
|
164
|
+
!tableContext?.operations.setCellBackground.enabled
|
|
165
|
+
}
|
|
166
|
+
onMouseDown={preserveEditorSelectionMouseDown}
|
|
167
|
+
onClick={() => props.onSetCellBackground?.(color)}
|
|
168
|
+
className="h-5 w-5 rounded border border-border disabled:opacity-40"
|
|
169
|
+
style={{ backgroundColor: color }}
|
|
170
|
+
title={tableContext?.operations.setCellBackground.reason}
|
|
171
|
+
/>
|
|
172
|
+
))}
|
|
173
|
+
</div>
|
|
174
|
+
</ToolbarSection>
|
|
138
175
|
|
|
139
|
-
<
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
176
|
+
<ToolbarSection label="Table">
|
|
177
|
+
<ToolbarButton
|
|
178
|
+
ariaLabel="Delete table"
|
|
179
|
+
capability={tableContext?.operations.deleteTable}
|
|
180
|
+
danger
|
|
181
|
+
disabled={props.disabled}
|
|
182
|
+
onClick={props.onDeleteTable}
|
|
183
|
+
>
|
|
184
|
+
Delete table
|
|
185
|
+
</ToolbarButton>
|
|
186
|
+
</ToolbarSection>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function ToolbarBadge(props: {
|
|
192
|
+
children: React.ReactNode;
|
|
193
|
+
tone?: "neutral" | "accent";
|
|
194
|
+
}) {
|
|
195
|
+
return (
|
|
196
|
+
<span
|
|
197
|
+
className={[
|
|
198
|
+
"rounded-full px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-[0.08em]",
|
|
199
|
+
props.tone === "accent"
|
|
200
|
+
? "bg-accent-soft text-accent"
|
|
201
|
+
: "bg-surface text-secondary",
|
|
202
|
+
].join(" ")}
|
|
203
|
+
>
|
|
204
|
+
{props.children}
|
|
205
|
+
</span>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
159
208
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
>
|
|
167
|
-
|
|
168
|
-
</
|
|
209
|
+
function ToolbarSection(props: {
|
|
210
|
+
label: string;
|
|
211
|
+
children: React.ReactNode;
|
|
212
|
+
}) {
|
|
213
|
+
return (
|
|
214
|
+
<div className="flex flex-wrap items-center gap-1 rounded-md bg-surface/60 px-1.5 py-1 ring-1 ring-border/35">
|
|
215
|
+
<span className="text-[9px] font-semibold uppercase tracking-[0.08em] text-tertiary">
|
|
216
|
+
{props.label}
|
|
217
|
+
</span>
|
|
218
|
+
<div className="flex flex-wrap items-center gap-1">{props.children}</div>
|
|
169
219
|
</div>
|
|
170
220
|
);
|
|
171
221
|
}
|
|
@@ -188,7 +238,7 @@ function ToolbarButton(props: {
|
|
|
188
238
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
189
239
|
onClick={props.onClick}
|
|
190
240
|
title={title}
|
|
191
|
-
className={`inline-flex h-
|
|
241
|
+
className={`inline-flex h-7 items-center rounded-md px-2 text-[11px] font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${
|
|
192
242
|
props.danger
|
|
193
243
|
? "text-danger hover:bg-danger/10"
|
|
194
244
|
: "text-primary hover:bg-surface"
|
|
@@ -34,7 +34,7 @@ export function createPMStateFromSnapshot(
|
|
|
34
34
|
selection: SelectionSnapshot,
|
|
35
35
|
plugins: Plugin[],
|
|
36
36
|
mediaPreviews: Record<string, MediaPreviewDescriptor> = {},
|
|
37
|
-
showUnsupportedObjectPreviews =
|
|
37
|
+
showUnsupportedObjectPreviews = false,
|
|
38
38
|
): PMStateResult {
|
|
39
39
|
const doc = buildPMDoc(surface, mediaPreviews, showUnsupportedObjectPreviews);
|
|
40
40
|
const positionMap = buildPositionMap(surface);
|
|
@@ -30,7 +30,7 @@ export function createSurfaceDocumentBuildKey(input: {
|
|
|
30
30
|
: getSurfaceIdentity(input.surface),
|
|
31
31
|
activeStory: input.activeStory,
|
|
32
32
|
mediaPreviewKey: input.mediaPreviewKey,
|
|
33
|
-
showUnsupportedObjectPreviews: input.showUnsupportedObjectPreviews ??
|
|
33
|
+
showUnsupportedObjectPreviews: input.showUnsupportedObjectPreviews ?? false,
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -46,7 +46,6 @@ export function createSurfaceDecorationKey(input: {
|
|
|
46
46
|
workflowMetadataSignature?: string;
|
|
47
47
|
activeWorkflowWorkItemId?: string | null;
|
|
48
48
|
activeWorkflowScopeIds?: readonly string[];
|
|
49
|
-
suggestionsEnabled?: boolean;
|
|
50
49
|
}): string {
|
|
51
50
|
return JSON.stringify({
|
|
52
51
|
markupDisplay: input.markupDisplay,
|
|
@@ -60,6 +59,5 @@ export function createSurfaceDecorationKey(input: {
|
|
|
60
59
|
workflowMetadataSignature: input.workflowMetadataSignature ?? null,
|
|
61
60
|
activeWorkflowWorkItemId: input.activeWorkflowWorkItemId ?? null,
|
|
62
61
|
activeWorkflowScopeIds: input.activeWorkflowScopeIds ?? [],
|
|
63
|
-
suggestionsEnabled: input.suggestionsEnabled ?? false,
|
|
64
62
|
});
|
|
65
63
|
}
|
|
@@ -20,6 +20,7 @@ export type ReviewRailTab = "comments" | "changes";
|
|
|
20
20
|
|
|
21
21
|
export interface TwReviewRailProps {
|
|
22
22
|
activeTab: ReviewRailTab;
|
|
23
|
+
variant?: "docked" | "drawer";
|
|
23
24
|
currentUserId?: string;
|
|
24
25
|
comments: CommentSidebarSnapshot;
|
|
25
26
|
trackedChanges: TrackedChangesSnapshot;
|
|
@@ -46,10 +47,17 @@ const focusRingClass =
|
|
|
46
47
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas";
|
|
47
48
|
|
|
48
49
|
export function TwReviewRail(props: TwReviewRailProps) {
|
|
50
|
+
const variant = props.variant ?? "docked";
|
|
49
51
|
return (
|
|
50
52
|
<aside
|
|
51
53
|
aria-label="Review rail"
|
|
52
|
-
|
|
54
|
+
data-wre-drawer={variant === "drawer" ? "true" : "false"}
|
|
55
|
+
className={[
|
|
56
|
+
"flex flex-col border-l border-border/60 bg-[var(--color-sidebar-tint)]",
|
|
57
|
+
variant === "drawer"
|
|
58
|
+
? "h-full w-[min(336px,calc(100vw-1rem))] max-w-full shrink-0 shadow-[0_18px_40px_-22px_var(--color-shadow-strong)]"
|
|
59
|
+
: "w-[336px] shrink-0",
|
|
60
|
+
].join(" ")}
|
|
53
61
|
>
|
|
54
62
|
<Tabs.Root
|
|
55
63
|
value={props.activeTab}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { WordReviewEditorChromePreset } from "../../api/public-types";
|
|
2
|
+
|
|
3
|
+
export interface ToolbarLayoutModelInput {
|
|
4
|
+
compactMode: boolean;
|
|
5
|
+
preset: WordReviewEditorChromePreset;
|
|
6
|
+
hasActiveListContext: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ToolbarLayoutModel {
|
|
10
|
+
showStyleSelectorsInRow: boolean;
|
|
11
|
+
showListActionsInRow: boolean;
|
|
12
|
+
showSpacingActionsInRow: boolean;
|
|
13
|
+
showInsertActionsInRow: boolean;
|
|
14
|
+
showUpdateActionsInRow: boolean;
|
|
15
|
+
showCompactOverflow: boolean;
|
|
16
|
+
showListContinuationInRow: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function resolveToolbarLayoutModel(
|
|
20
|
+
input: ToolbarLayoutModelInput,
|
|
21
|
+
): ToolbarLayoutModel {
|
|
22
|
+
if (!input.compactMode) {
|
|
23
|
+
const showListActions = input.preset === "simple" || input.preset === "advanced";
|
|
24
|
+
return {
|
|
25
|
+
showStyleSelectorsInRow: input.preset === "advanced",
|
|
26
|
+
showListActionsInRow: showListActions,
|
|
27
|
+
showSpacingActionsInRow: true,
|
|
28
|
+
showInsertActionsInRow: input.preset === "simple" || input.preset === "advanced",
|
|
29
|
+
showUpdateActionsInRow: input.preset === "advanced",
|
|
30
|
+
showCompactOverflow: false,
|
|
31
|
+
showListContinuationInRow: showListActions && input.hasActiveListContext,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const compactOverflowHasSecondaryActions =
|
|
36
|
+
input.preset === "simple" || input.preset === "advanced";
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
showStyleSelectorsInRow: false,
|
|
40
|
+
showListActionsInRow: false,
|
|
41
|
+
showSpacingActionsInRow: false,
|
|
42
|
+
showInsertActionsInRow: false,
|
|
43
|
+
showUpdateActionsInRow: false,
|
|
44
|
+
showCompactOverflow: compactOverflowHasSecondaryActions,
|
|
45
|
+
showListContinuationInRow: false,
|
|
46
|
+
};
|
|
47
|
+
}
|