@beyondwork/docx-react-component 1.0.36 → 1.0.37
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/README.md +103 -13
- package/package.json +1 -1
- package/src/api/package-version.ts +13 -0
- package/src/api/public-types.ts +83 -0
- package/src/core/commands/index.ts +18 -1
- package/src/core/selection/mapping.ts +6 -0
- package/src/io/docx-session.ts +24 -9
- package/src/io/export/build-app-properties-xml.ts +88 -0
- package/src/io/export/serialize-comments.ts +6 -1
- package/src/io/export/serialize-footnotes.ts +10 -9
- package/src/io/export/serialize-headers-footers.ts +11 -10
- package/src/io/export/serialize-main-document.ts +337 -50
- package/src/io/export/serialize-numbering.ts +115 -24
- package/src/io/export/serialize-tables.ts +13 -11
- package/src/io/export/table-properties-xml.ts +35 -16
- package/src/io/export/twip.ts +66 -0
- package/src/io/normalize/normalize-text.ts +5 -0
- package/src/io/ooxml/parse-footnotes.ts +2 -1
- package/src/io/ooxml/parse-headers-footers.ts +2 -1
- package/src/io/ooxml/parse-main-document.ts +21 -1
- package/src/legal/bookmarks.ts +78 -0
- package/src/model/canonical-document.ts +11 -0
- package/src/review/store/scope-tag-diff.ts +130 -0
- package/src/runtime/document-navigation.ts +1 -305
- package/src/runtime/document-runtime.ts +173 -11
- package/src/runtime/layout/docx-font-loader.ts +143 -0
- package/src/runtime/layout/index.ts +188 -0
- package/src/runtime/layout/inert-layout-facet.ts +45 -0
- package/src/runtime/layout/layout-engine-instance.ts +618 -0
- package/src/runtime/layout/layout-invalidation.ts +257 -0
- package/src/runtime/layout/layout-measurement-provider.ts +175 -0
- package/src/runtime/layout/measurement-backend-canvas.ts +307 -0
- package/src/runtime/layout/measurement-backend-empirical.ts +208 -0
- package/src/runtime/layout/page-fragment-mapper.ts +179 -0
- package/src/runtime/layout/page-graph.ts +433 -0
- package/src/runtime/layout/page-layout-snapshot-adapter.ts +70 -0
- package/src/runtime/layout/page-story-resolver.ts +195 -0
- package/src/runtime/layout/paginated-layout-engine.ts +788 -0
- package/src/runtime/layout/public-facet.ts +705 -0
- package/src/runtime/layout/resolved-formatting-document.ts +317 -0
- package/src/runtime/layout/resolved-formatting-state.ts +430 -0
- package/src/runtime/scope-tag-registry.ts +95 -0
- package/src/runtime/surface-projection.ts +1 -0
- package/src/runtime/text-ack-range.ts +49 -0
- package/src/ui/WordReviewEditor.tsx +15 -0
- package/src/ui/editor-runtime-boundary.ts +10 -1
- package/src/ui/editor-surface-controller.tsx +3 -0
- package/src/ui/headless/chrome-registry.ts +235 -0
- package/src/ui/headless/scoped-chrome-policy.ts +164 -0
- package/src/ui/headless/selection-tool-context.ts +2 -0
- package/src/ui/headless/selection-tool-resolver.ts +36 -17
- package/src/ui-tailwind/editor-surface/fast-text-edit-lane.ts +333 -0
- package/src/ui-tailwind/editor-surface/local-edit-session-state.ts +89 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +21 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +8 -1
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +73 -13
- package/src/ui-tailwind/editor-surface/predicted-position-map.ts +78 -0
- package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +63 -0
- package/src/ui-tailwind/editor-surface/predicted-tx-gate.ts +39 -0
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +173 -6
- package/src/ui-tailwind/theme/editor-theme.css +40 -14
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +2 -2
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +235 -166
- package/src/ui-tailwind/tw-review-workspace.tsx +27 -1
|
@@ -56,9 +56,14 @@ import type {
|
|
|
56
56
|
ZoomLevel,
|
|
57
57
|
} from "../../api/public-types";
|
|
58
58
|
import type { SessionCapabilities } from "../../runtime/session-capabilities";
|
|
59
|
+
import {
|
|
60
|
+
getToolbarChromePlacement,
|
|
61
|
+
isToolbarChromeItemVisible,
|
|
62
|
+
resolveScopedChromePolicy,
|
|
63
|
+
type ScopedChromePolicy,
|
|
64
|
+
} from "../../ui/headless/scoped-chrome-policy";
|
|
59
65
|
import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
|
|
60
66
|
import { TwHealthPanel } from "../review/tw-health-panel";
|
|
61
|
-
import { resolveToolbarLayoutModel } from "./toolbar-layout";
|
|
62
67
|
import { TwToolbarIconButton } from "./tw-toolbar-icon-button";
|
|
63
68
|
|
|
64
69
|
export interface TwToolbarProps {
|
|
@@ -68,6 +73,7 @@ export interface TwToolbarProps {
|
|
|
68
73
|
blockedReasons?: WorkflowBlockedCommandReason[];
|
|
69
74
|
showDiagnosticsChrome?: boolean;
|
|
70
75
|
interactionPolicy?: ToolbarInteractionPolicy;
|
|
76
|
+
scopedChromePolicy?: ScopedChromePolicy;
|
|
71
77
|
preset?: WordReviewEditorChromePreset;
|
|
72
78
|
compactMode?: boolean;
|
|
73
79
|
workspaceMode: WorkspaceMode;
|
|
@@ -152,27 +158,55 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
152
158
|
const canEdit = props.interactionPolicy?.canFormatText ?? (caps ? caps.canEdit : false);
|
|
153
159
|
const canInsertStructural = props.interactionPolicy?.canInsertStructural ?? canEdit;
|
|
154
160
|
const canAddComment = props.interactionPolicy?.canAddComment ?? (caps ? caps.canAddComment : false);
|
|
155
|
-
const showStyleSelectors = preset === "advanced";
|
|
156
|
-
const showAdvancedFormatting = preset === "advanced";
|
|
157
|
-
const showFormattingColors = preset !== "review";
|
|
158
|
-
const showInsertMenu = preset === "simple" || preset === "advanced";
|
|
159
|
-
const showTrackedChangesToggle = preset !== "simple";
|
|
160
161
|
const showDiagnosticsChrome = props.showDiagnosticsChrome ?? true;
|
|
161
|
-
const
|
|
162
|
-
const showListActions = preset === "simple" || preset === "advanced";
|
|
163
|
-
const showUpdateActions = preset === "advanced";
|
|
164
|
-
const showSidebarToggle = props.showSidebarToggle ?? false;
|
|
165
|
-
const layoutModel = resolveToolbarLayoutModel({
|
|
166
|
-
compactMode: isCompact,
|
|
162
|
+
const scopedChromePolicy = props.scopedChromePolicy ?? resolveScopedChromePolicy({
|
|
167
163
|
preset,
|
|
168
|
-
|
|
164
|
+
compactMode: isCompact,
|
|
165
|
+
capabilities: caps,
|
|
166
|
+
interactionGuardSnapshot: props.interactionPolicy
|
|
167
|
+
? ({
|
|
168
|
+
effectiveMode: props.interactionPolicy.mode,
|
|
169
|
+
blockedReasons: props.blockedReasons ?? [],
|
|
170
|
+
} as any)
|
|
171
|
+
: undefined,
|
|
172
|
+
activeListContext: props.activeListContext,
|
|
169
173
|
});
|
|
174
|
+
const showStyleSelectors = isToolbarChromeItemVisible(scopedChromePolicy, "text-style-selectors");
|
|
175
|
+
const showInlineFormatting = isToolbarChromeItemVisible(scopedChromePolicy, "inline-formatting");
|
|
176
|
+
const showAdvancedFormatting = preset === "advanced" && showInlineFormatting;
|
|
177
|
+
const showTextColors = isToolbarChromeItemVisible(scopedChromePolicy, "text-colors");
|
|
178
|
+
const showParagraphAlignment = isToolbarChromeItemVisible(scopedChromePolicy, "paragraph-alignment");
|
|
179
|
+
const showInsertMenu = isToolbarChromeItemVisible(scopedChromePolicy, "insert-actions");
|
|
180
|
+
const showTrackedChangesToggle = isToolbarChromeItemVisible(scopedChromePolicy, "tracked-changes-toggle");
|
|
181
|
+
const showHealth =
|
|
182
|
+
showDiagnosticsChrome &&
|
|
183
|
+
isToolbarChromeItemVisible(scopedChromePolicy, "health") &&
|
|
184
|
+
Boolean(props.compatibility && props.warnings);
|
|
185
|
+
const showListActions = isToolbarChromeItemVisible(scopedChromePolicy, "list-actions");
|
|
186
|
+
const showUpdateActions = isToolbarChromeItemVisible(scopedChromePolicy, "update-actions");
|
|
187
|
+
const showSidebarToggle =
|
|
188
|
+
(props.showSidebarToggle ?? false) &&
|
|
189
|
+
isToolbarChromeItemVisible(scopedChromePolicy, "sidebar-toggle");
|
|
190
|
+
const showStyleSelectorsInRow = getToolbarChromePlacement(scopedChromePolicy, "text-style-selectors") === "inline";
|
|
191
|
+
const showListActionsInRow = getToolbarChromePlacement(scopedChromePolicy, "list-actions") === "inline";
|
|
192
|
+
const showSpacingActionsInRow = getToolbarChromePlacement(scopedChromePolicy, "indentation") === "inline";
|
|
193
|
+
const showListContinuationInRow =
|
|
194
|
+
getToolbarChromePlacement(scopedChromePolicy, "list-continuation") === "inline";
|
|
195
|
+
const showInsertActionsInRow = getToolbarChromePlacement(scopedChromePolicy, "insert-actions") === "inline";
|
|
196
|
+
const showUpdateActionsInRow = getToolbarChromePlacement(scopedChromePolicy, "update-actions") === "inline";
|
|
197
|
+
const showCompactOverflow =
|
|
198
|
+
getToolbarChromePlacement(scopedChromePolicy, "text-style-selectors") === "overflow" ||
|
|
199
|
+
getToolbarChromePlacement(scopedChromePolicy, "list-actions") === "overflow" ||
|
|
200
|
+
getToolbarChromePlacement(scopedChromePolicy, "indentation") === "overflow" ||
|
|
201
|
+
getToolbarChromePlacement(scopedChromePolicy, "list-continuation") === "overflow" ||
|
|
202
|
+
getToolbarChromePlacement(scopedChromePolicy, "insert-actions") === "overflow" ||
|
|
203
|
+
getToolbarChromePlacement(scopedChromePolicy, "update-actions") === "overflow";
|
|
170
204
|
const showPostFormattingDivider =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
205
|
+
showListActionsInRow ||
|
|
206
|
+
showSpacingActionsInRow ||
|
|
207
|
+
showInsertActionsInRow ||
|
|
208
|
+
showUpdateActionsInRow ||
|
|
209
|
+
showCompactOverflow;
|
|
176
210
|
const zoomLabel =
|
|
177
211
|
typeof zoomLevel === "number"
|
|
178
212
|
? `${zoomLevel}%`
|
|
@@ -185,8 +219,8 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
185
219
|
className={[
|
|
186
220
|
"shrink-0 rounded-xl border border-border/70 bg-canvas/92 px-2.5 shadow-[0_8px_20px_-18px_var(--color-shadow-strong)] backdrop-blur-sm",
|
|
187
221
|
isCompact
|
|
188
|
-
? "flex min-h-
|
|
189
|
-
: "flex h-
|
|
222
|
+
? "flex min-h-10 flex-wrap items-center gap-1.5 py-1.5"
|
|
223
|
+
: "flex h-10 items-center gap-1",
|
|
190
224
|
].join(" ")}
|
|
191
225
|
>
|
|
192
226
|
{/* Left cluster: undo/redo + formatting */}
|
|
@@ -205,7 +239,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
205
239
|
/>
|
|
206
240
|
<div className="mx-1 h-4 w-px bg-border" />
|
|
207
241
|
|
|
208
|
-
{showStyleSelectors &&
|
|
242
|
+
{showStyleSelectors && showStyleSelectorsInRow ? (
|
|
209
243
|
<>
|
|
210
244
|
<ToolbarParagraphStyleSelect
|
|
211
245
|
disabled={!canEdit || paragraphStyles.length === 0 || !props.onSetParagraphStyle}
|
|
@@ -229,69 +263,79 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
229
263
|
</>
|
|
230
264
|
) : null}
|
|
231
265
|
|
|
232
|
-
|
|
233
|
-
icon={Bold}
|
|
234
|
-
label="Bold"
|
|
235
|
-
active={props.formattingState?.bold ?? false}
|
|
236
|
-
disabled={!canEdit}
|
|
237
|
-
onClick={props.onToggleBold}
|
|
238
|
-
/>
|
|
239
|
-
<TwToolbarIconButton
|
|
240
|
-
icon={Italic}
|
|
241
|
-
label="Italic"
|
|
242
|
-
active={props.formattingState?.italic ?? false}
|
|
243
|
-
disabled={!canEdit}
|
|
244
|
-
onClick={props.onToggleItalic}
|
|
245
|
-
/>
|
|
246
|
-
<TwToolbarIconButton
|
|
247
|
-
icon={Underline}
|
|
248
|
-
label="Underline"
|
|
249
|
-
active={props.formattingState?.underline ?? false}
|
|
250
|
-
disabled={!canEdit}
|
|
251
|
-
onClick={props.onToggleUnderline}
|
|
252
|
-
/>
|
|
253
|
-
{showAdvancedFormatting ? (
|
|
254
|
-
<ToolbarFormattingOverflow
|
|
255
|
-
disabled={!canEdit}
|
|
256
|
-
formattingState={props.formattingState}
|
|
257
|
-
onToggleStrikethrough={props.onToggleStrikethrough}
|
|
258
|
-
onToggleSuperscript={props.onToggleSuperscript}
|
|
259
|
-
onToggleSubscript={props.onToggleSubscript}
|
|
260
|
-
/>
|
|
261
|
-
) : null}
|
|
262
|
-
{showFormattingColors ? (
|
|
266
|
+
{showInlineFormatting ? (
|
|
263
267
|
<>
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (value) {
|
|
271
|
-
props.onSetTextColor?.(value);
|
|
272
|
-
}
|
|
273
|
-
}}
|
|
274
|
-
title="Text color"
|
|
268
|
+
<TwToolbarIconButton
|
|
269
|
+
icon={Bold}
|
|
270
|
+
label="Bold"
|
|
271
|
+
active={props.formattingState?.bold ?? false}
|
|
272
|
+
disabled={!canEdit}
|
|
273
|
+
onClick={props.onToggleBold}
|
|
275
274
|
/>
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
title="Highlight color"
|
|
275
|
+
<TwToolbarIconButton
|
|
276
|
+
icon={Italic}
|
|
277
|
+
label="Italic"
|
|
278
|
+
active={props.formattingState?.italic ?? false}
|
|
279
|
+
disabled={!canEdit}
|
|
280
|
+
onClick={props.onToggleItalic}
|
|
283
281
|
/>
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
282
|
+
<TwToolbarIconButton
|
|
283
|
+
icon={Underline}
|
|
284
|
+
label="Underline"
|
|
285
|
+
active={props.formattingState?.underline ?? false}
|
|
286
|
+
disabled={!canEdit}
|
|
287
|
+
onClick={props.onToggleUnderline}
|
|
288
288
|
/>
|
|
289
|
+
{showAdvancedFormatting ? (
|
|
290
|
+
<ToolbarFormattingOverflow
|
|
291
|
+
disabled={!canEdit}
|
|
292
|
+
formattingState={props.formattingState}
|
|
293
|
+
onToggleStrikethrough={props.onToggleStrikethrough}
|
|
294
|
+
onToggleSuperscript={props.onToggleSuperscript}
|
|
295
|
+
onToggleSubscript={props.onToggleSubscript}
|
|
296
|
+
/>
|
|
297
|
+
) : null}
|
|
298
|
+
</>
|
|
299
|
+
) : null}
|
|
300
|
+
{showTextColors || showParagraphAlignment ? (
|
|
301
|
+
<>
|
|
302
|
+
{showTextColors ? (
|
|
303
|
+
<>
|
|
304
|
+
<ToolbarColorPopover
|
|
305
|
+
ariaLabel="Text color"
|
|
306
|
+
colors={TEXT_COLORS.map((value) => ({ value, label: value }))}
|
|
307
|
+
disabled={!canEdit || !props.onSetTextColor}
|
|
308
|
+
icon={<Baseline className="h-3.5 w-3.5" />}
|
|
309
|
+
onSelect={(value) => {
|
|
310
|
+
if (value) {
|
|
311
|
+
props.onSetTextColor?.(value);
|
|
312
|
+
}
|
|
313
|
+
}}
|
|
314
|
+
title="Text color"
|
|
315
|
+
/>
|
|
316
|
+
<ToolbarColorPopover
|
|
317
|
+
ariaLabel="Highlight color"
|
|
318
|
+
colors={HIGHLIGHT_COLORS.map((entry) => ({ value: entry.value, label: entry.label }))}
|
|
319
|
+
disabled={!canEdit || !props.onSetHighlightColor}
|
|
320
|
+
icon={<Highlighter className="h-3.5 w-3.5" />}
|
|
321
|
+
onSelect={(value) => props.onSetHighlightColor?.(value)}
|
|
322
|
+
title="Highlight color"
|
|
323
|
+
/>
|
|
324
|
+
</>
|
|
325
|
+
) : null}
|
|
326
|
+
{showParagraphAlignment ? (
|
|
327
|
+
<ToolbarAlignmentPopover
|
|
328
|
+
activeAlignment={props.formattingState?.alignment}
|
|
329
|
+
disabled={!canEdit || !props.onSetAlignment}
|
|
330
|
+
onSelect={(alignment) => props.onSetAlignment?.(alignment)}
|
|
331
|
+
/>
|
|
332
|
+
) : null}
|
|
289
333
|
</>
|
|
290
334
|
) : null}
|
|
291
335
|
|
|
292
336
|
{showPostFormattingDivider ? <div className="mx-1 h-4 w-px bg-border" /> : null}
|
|
293
337
|
|
|
294
|
-
{showListActions &&
|
|
338
|
+
{showListActions && showListActionsInRow ? (
|
|
295
339
|
<>
|
|
296
340
|
<TwToolbarIconButton
|
|
297
341
|
icon={List}
|
|
@@ -309,7 +353,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
309
353
|
/>
|
|
310
354
|
</>
|
|
311
355
|
) : null}
|
|
312
|
-
{
|
|
356
|
+
{showSpacingActionsInRow ? (
|
|
313
357
|
<>
|
|
314
358
|
<TwToolbarIconButton
|
|
315
359
|
icon={Outdent}
|
|
@@ -325,7 +369,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
325
369
|
/>
|
|
326
370
|
</>
|
|
327
371
|
) : null}
|
|
328
|
-
{
|
|
372
|
+
{showListContinuationInRow ? (
|
|
329
373
|
<>
|
|
330
374
|
<button
|
|
331
375
|
type="button"
|
|
@@ -333,7 +377,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
333
377
|
disabled={!canEdit || !props.onRestartNumbering}
|
|
334
378
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
335
379
|
onClick={props.onRestartNumbering}
|
|
336
|
-
className={`inline-flex h-
|
|
380
|
+
className={`inline-flex h-6 items-center rounded-md px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
337
381
|
>
|
|
338
382
|
Restart
|
|
339
383
|
</button>
|
|
@@ -343,13 +387,13 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
343
387
|
disabled={!canEdit || !props.onContinueNumbering}
|
|
344
388
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
345
389
|
onClick={props.onContinueNumbering}
|
|
346
|
-
className={`inline-flex h-
|
|
390
|
+
className={`inline-flex h-6 items-center rounded-md px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
347
391
|
>
|
|
348
392
|
Continue
|
|
349
393
|
</button>
|
|
350
394
|
</>
|
|
351
395
|
) : null}
|
|
352
|
-
{showInsertMenu &&
|
|
396
|
+
{showInsertMenu && showInsertActionsInRow ? (
|
|
353
397
|
<ToolbarInsertMenu
|
|
354
398
|
disabled={!canInsertStructural}
|
|
355
399
|
onInsertImage={props.onInsertImage}
|
|
@@ -358,7 +402,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
358
402
|
onInsertTable={props.onInsertTable}
|
|
359
403
|
/>
|
|
360
404
|
) : null}
|
|
361
|
-
{showUpdateActions &&
|
|
405
|
+
{showUpdateActions && showUpdateActionsInRow ? (
|
|
362
406
|
<>
|
|
363
407
|
<button
|
|
364
408
|
type="button"
|
|
@@ -366,7 +410,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
366
410
|
disabled={!canEdit || !props.onUpdateFields}
|
|
367
411
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
368
412
|
onClick={props.onUpdateFields}
|
|
369
|
-
className={`inline-flex h-
|
|
413
|
+
className={`inline-flex h-6 items-center rounded-md px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
370
414
|
>
|
|
371
415
|
Fields
|
|
372
416
|
</button>
|
|
@@ -376,23 +420,25 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
376
420
|
disabled={!canEdit || !props.onUpdateTableOfContents}
|
|
377
421
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
378
422
|
onClick={props.onUpdateTableOfContents}
|
|
379
|
-
className={`inline-flex h-
|
|
423
|
+
className={`inline-flex h-6 items-center rounded-md px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
380
424
|
>
|
|
381
425
|
TOC
|
|
382
426
|
</button>
|
|
383
427
|
</>
|
|
384
428
|
) : null}
|
|
385
|
-
{
|
|
429
|
+
{showCompactOverflow ? (
|
|
386
430
|
<ToolbarCompactOverflow
|
|
387
431
|
activeListContext={props.activeListContext}
|
|
388
432
|
canEdit={canEdit}
|
|
389
433
|
canInsertStructural={canInsertStructural}
|
|
390
434
|
formattingState={props.formattingState}
|
|
391
435
|
paragraphStyles={paragraphStyles}
|
|
392
|
-
showInsertMenu={
|
|
393
|
-
showListActions={
|
|
394
|
-
|
|
395
|
-
|
|
436
|
+
showInsertMenu={getToolbarChromePlacement(scopedChromePolicy, "insert-actions") === "overflow"}
|
|
437
|
+
showListActions={getToolbarChromePlacement(scopedChromePolicy, "list-actions") === "overflow"}
|
|
438
|
+
showParagraphActions={getToolbarChromePlacement(scopedChromePolicy, "indentation") === "overflow"}
|
|
439
|
+
showListContinuation={getToolbarChromePlacement(scopedChromePolicy, "list-continuation") === "overflow"}
|
|
440
|
+
showStyleSelectors={getToolbarChromePlacement(scopedChromePolicy, "text-style-selectors") === "overflow"}
|
|
441
|
+
showUpdateActions={getToolbarChromePlacement(scopedChromePolicy, "update-actions") === "overflow"}
|
|
396
442
|
onSetParagraphStyle={props.onSetParagraphStyle}
|
|
397
443
|
onSetFontFamily={props.onSetFontFamily}
|
|
398
444
|
onSetFontSize={props.onSetFontSize}
|
|
@@ -412,14 +458,15 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
412
458
|
) : null}
|
|
413
459
|
|
|
414
460
|
{/* Story focus breadcrumb — visible when editing a secondary story */}
|
|
415
|
-
{props.activeStory && props.activeStory.kind !== "main"
|
|
461
|
+
{props.activeStory && props.activeStory.kind !== "main" &&
|
|
462
|
+
isToolbarChromeItemVisible(scopedChromePolicy, "story-breadcrumb") ? (
|
|
416
463
|
<>
|
|
417
464
|
<div className="mx-1 h-4 w-px bg-border" />
|
|
418
465
|
<button
|
|
419
466
|
type="button"
|
|
420
467
|
onClick={props.onCloseStory}
|
|
421
468
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
422
|
-
className={`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-
|
|
469
|
+
className={`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] font-medium text-accent hover:bg-surface transition-colors outline-none ${focusRingClass}`}
|
|
423
470
|
aria-label={`Editing ${storyLabel(props.activeStory)} — click to return to main body`}
|
|
424
471
|
>
|
|
425
472
|
<span className="text-secondary">←</span>
|
|
@@ -431,6 +478,14 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
431
478
|
|
|
432
479
|
{/* Right cluster: comment, track changes, markup, view, export */}
|
|
433
480
|
<div className={`flex items-center gap-0.5 ${isCompact ? "ml-auto flex-wrap justify-end" : ""}`}>
|
|
481
|
+
{scopedChromePolicy.scopeStatusLabel ? (
|
|
482
|
+
<>
|
|
483
|
+
<span className="inline-flex h-6 items-center rounded-full bg-surface px-2 text-[10px] font-medium text-secondary ring-1 ring-border/50">
|
|
484
|
+
{scopedChromePolicy.scopeStatusLabel}
|
|
485
|
+
</span>
|
|
486
|
+
<div className="mx-1 h-4 w-px bg-border" />
|
|
487
|
+
</>
|
|
488
|
+
) : null}
|
|
434
489
|
{showSidebarToggle ? (
|
|
435
490
|
<>
|
|
436
491
|
<TwToolbarIconButton
|
|
@@ -443,13 +498,15 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
443
498
|
</>
|
|
444
499
|
) : null}
|
|
445
500
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
501
|
+
{isToolbarChromeItemVisible(scopedChromePolicy, "comment") ? (
|
|
502
|
+
<TwToolbarIconButton
|
|
503
|
+
icon={MessageSquare}
|
|
504
|
+
label="Add comment"
|
|
505
|
+
disabled={!canAddComment}
|
|
506
|
+
emphasis
|
|
507
|
+
onClick={props.onAddComment}
|
|
508
|
+
/>
|
|
509
|
+
) : null}
|
|
453
510
|
|
|
454
511
|
{showTrackedChangesToggle ? (
|
|
455
512
|
<>
|
|
@@ -460,9 +517,9 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
460
517
|
onPressedChange={props.onShowTrackedChangesChange}
|
|
461
518
|
disabled={caps ? !caps.trackChangesSupported : false}
|
|
462
519
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
463
|
-
className={`inline-flex h-
|
|
520
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-canvas data-[state=on]:text-accent data-[state=on]:ring-1 data-[state=on]:ring-accent/30 data-[state=on]:shadow-sm outline-none disabled:opacity-40 ${focusRingClass}`}
|
|
464
521
|
>
|
|
465
|
-
{props.showTrackedChanges ? <Eye className="h-
|
|
522
|
+
{props.showTrackedChanges ? <Eye className="h-3.5 w-3.5" /> : <EyeOff className="h-3.5 w-3.5" />}
|
|
466
523
|
</Toggle.Root>
|
|
467
524
|
</Tooltip.Trigger>
|
|
468
525
|
<Tooltip.Portal>
|
|
@@ -480,21 +537,22 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
480
537
|
) : null}
|
|
481
538
|
|
|
482
539
|
{/* View mode toggle group: Canvas (clean, flowing) / Page (layout-sensitive) */}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
540
|
+
{isToolbarChromeItemVisible(scopedChromePolicy, "workspace-mode") ? (
|
|
541
|
+
<ToggleGroup.Root
|
|
542
|
+
type="single"
|
|
543
|
+
value={workspaceMode}
|
|
544
|
+
onValueChange={(v: string) => {
|
|
545
|
+
if (v) props.onWorkspaceModeChange(v as WorkspaceMode);
|
|
546
|
+
}}
|
|
547
|
+
className="flex items-center gap-0.5"
|
|
548
|
+
>
|
|
491
549
|
<Tooltip.Root>
|
|
492
550
|
<Tooltip.Trigger asChild>
|
|
493
551
|
<ToggleGroup.Item
|
|
494
552
|
value="canvas"
|
|
495
553
|
aria-label="Canvas workspace"
|
|
496
554
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
497
|
-
className={`inline-flex h-
|
|
555
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-canvas data-[state=on]:text-accent data-[state=on]:ring-1 data-[state=on]:ring-accent/30 data-[state=on]:shadow-sm outline-none ${focusRingClass}`}
|
|
498
556
|
>
|
|
499
557
|
<Monitor className="h-3.5 w-3.5" />
|
|
500
558
|
</ToggleGroup.Item>
|
|
@@ -511,7 +569,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
511
569
|
value="page"
|
|
512
570
|
aria-label="Page workspace"
|
|
513
571
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
514
|
-
className={`inline-flex h-
|
|
572
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-canvas data-[state=on]:text-accent data-[state=on]:ring-1 data-[state=on]:ring-accent/30 data-[state=on]:shadow-sm outline-none ${focusRingClass}`}
|
|
515
573
|
>
|
|
516
574
|
<FileText className="h-3.5 w-3.5" />
|
|
517
575
|
</ToggleGroup.Item>
|
|
@@ -522,10 +580,11 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
522
580
|
</Tooltip.Content>
|
|
523
581
|
</Tooltip.Portal>
|
|
524
582
|
</Tooltip.Root>
|
|
525
|
-
|
|
583
|
+
</ToggleGroup.Root>
|
|
584
|
+
) : null}
|
|
526
585
|
|
|
527
586
|
{/* Zoom controls — available in all workspace modes */}
|
|
528
|
-
{props.onZoomChange ? (
|
|
587
|
+
{isToolbarChromeItemVisible(scopedChromePolicy, "zoom") && props.onZoomChange ? (
|
|
529
588
|
<>
|
|
530
589
|
<div className="mx-1 h-4 w-px bg-border" />
|
|
531
590
|
<div className="flex items-center gap-0.5">
|
|
@@ -534,7 +593,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
534
593
|
<button
|
|
535
594
|
type="button"
|
|
536
595
|
aria-label="Zoom out"
|
|
537
|
-
className={`inline-flex h-
|
|
596
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}
|
|
538
597
|
disabled={typeof zoomLevel === "number" && zoomLevel <= 50}
|
|
539
598
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
540
599
|
onClick={() => {
|
|
@@ -560,7 +619,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
560
619
|
type="button"
|
|
561
620
|
aria-label={`Zoom: ${zoomLabel}`}
|
|
562
621
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
563
|
-
className={`inline-flex h-
|
|
622
|
+
className={`inline-flex h-6 items-center justify-center rounded-md px-1.5 text-[10px] font-medium text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}
|
|
564
623
|
>
|
|
565
624
|
{zoomLabel}
|
|
566
625
|
</button>
|
|
@@ -604,7 +663,7 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
604
663
|
<button
|
|
605
664
|
type="button"
|
|
606
665
|
aria-label="Zoom in"
|
|
607
|
-
className={`inline-flex h-
|
|
666
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}
|
|
608
667
|
disabled={typeof zoomLevel === "number" && zoomLevel >= 200}
|
|
609
668
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
610
669
|
onClick={() => {
|
|
@@ -635,9 +694,9 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
635
694
|
type="button"
|
|
636
695
|
aria-label="Document health"
|
|
637
696
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
638
|
-
className={`relative inline-flex h-
|
|
697
|
+
className={`relative inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface hover:text-primary outline-none ${focusRingClass}`}
|
|
639
698
|
>
|
|
640
|
-
<AlertCircle className="h-
|
|
699
|
+
<AlertCircle className="h-3.5 w-3.5" />
|
|
641
700
|
{(caps?.healthIssueCount ?? 0) > 0 ? (
|
|
642
701
|
<span className="absolute -top-0.5 -right-0.5 flex h-3 min-w-[12px] items-center justify-center rounded-full bg-tertiary text-[8px] font-medium text-white">
|
|
643
702
|
{caps?.healthIssueCount}
|
|
@@ -672,13 +731,15 @@ export function TwToolbar(props: TwToolbarProps) {
|
|
|
672
731
|
</>
|
|
673
732
|
) : null}
|
|
674
733
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
734
|
+
{isToolbarChromeItemVisible(scopedChromePolicy, "export") ? (
|
|
735
|
+
<TwToolbarIconButton
|
|
736
|
+
icon={Download}
|
|
737
|
+
label={caps?.exportBlocked ? "Export blocked" : "Download document"}
|
|
738
|
+
disabled={caps ? !caps.canExport : true}
|
|
739
|
+
emphasis
|
|
740
|
+
onClick={props.onExport}
|
|
741
|
+
/>
|
|
742
|
+
) : null}
|
|
682
743
|
</div>
|
|
683
744
|
</header>
|
|
684
745
|
);
|
|
@@ -706,7 +767,7 @@ function ToolbarParagraphStyleSelect(props: {
|
|
|
706
767
|
aria-disabled={props.disabled || undefined}
|
|
707
768
|
data-disabled={props.disabled ? "" : undefined}
|
|
708
769
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
709
|
-
className={`inline-flex h-
|
|
770
|
+
className={`inline-flex h-6 min-w-[7.5rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
710
771
|
>
|
|
711
772
|
<Select.Value placeholder="Style" />
|
|
712
773
|
<Select.Icon>
|
|
@@ -723,7 +784,7 @@ function ToolbarParagraphStyleSelect(props: {
|
|
|
723
784
|
<Select.Viewport className="p-1">
|
|
724
785
|
{props.styles.map((style) => (
|
|
725
786
|
<Select.Item
|
|
726
|
-
className={`flex cursor-pointer items-center rounded-md px-2
|
|
787
|
+
className={`flex cursor-pointer items-center rounded-md px-2 py-1 text-[11px] text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-canvas data-[state=checked]:text-accent data-[state=checked]:ring-1 data-[state=checked]:ring-accent/20 ${focusRingClass}`}
|
|
727
788
|
key={style.styleId}
|
|
728
789
|
value={style.styleId}
|
|
729
790
|
>
|
|
@@ -755,7 +816,7 @@ function ToolbarFontFamilySelect(props: {
|
|
|
755
816
|
aria-disabled={props.disabled || undefined}
|
|
756
817
|
data-disabled={props.disabled ? "" : undefined}
|
|
757
818
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
758
|
-
className={`inline-flex h-
|
|
819
|
+
className={`inline-flex h-6 min-w-[6.5rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
759
820
|
>
|
|
760
821
|
<Select.Value placeholder="Font" />
|
|
761
822
|
<Select.Icon>
|
|
@@ -772,7 +833,7 @@ function ToolbarFontFamilySelect(props: {
|
|
|
772
833
|
<Select.Viewport className="p-1">
|
|
773
834
|
{FONT_FAMILIES.map((font) => (
|
|
774
835
|
<Select.Item
|
|
775
|
-
className={`flex cursor-pointer items-center rounded-md px-2
|
|
836
|
+
className={`flex cursor-pointer items-center rounded-md px-2 py-1 text-[11px] text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-canvas data-[state=checked]:text-accent data-[state=checked]:ring-1 data-[state=checked]:ring-accent/20 ${focusRingClass}`}
|
|
776
837
|
key={font}
|
|
777
838
|
value={font}
|
|
778
839
|
>
|
|
@@ -805,7 +866,7 @@ function ToolbarFontSizeSelect(props: {
|
|
|
805
866
|
aria-disabled={props.disabled || undefined}
|
|
806
867
|
data-disabled={props.disabled ? "" : undefined}
|
|
807
868
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
808
|
-
className={`inline-flex h-
|
|
869
|
+
className={`inline-flex h-6 min-w-[3.5rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
809
870
|
>
|
|
810
871
|
<Select.Value placeholder="Size" />
|
|
811
872
|
<Select.Icon>
|
|
@@ -822,7 +883,7 @@ function ToolbarFontSizeSelect(props: {
|
|
|
822
883
|
<Select.Viewport className="p-1">
|
|
823
884
|
{FONT_SIZES.map((size) => (
|
|
824
885
|
<Select.Item
|
|
825
|
-
className={`flex cursor-pointer items-center rounded-md px-2
|
|
886
|
+
className={`flex cursor-pointer items-center rounded-md px-2 py-1 text-[11px] text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-canvas data-[state=checked]:text-accent data-[state=checked]:ring-1 data-[state=checked]:ring-accent/20 ${focusRingClass}`}
|
|
826
887
|
key={size}
|
|
827
888
|
value={String(size)}
|
|
828
889
|
>
|
|
@@ -844,6 +905,8 @@ function ToolbarCompactOverflow(props: {
|
|
|
844
905
|
paragraphStyles: StyleCatalogSnapshot["paragraphs"];
|
|
845
906
|
showInsertMenu: boolean;
|
|
846
907
|
showListActions: boolean;
|
|
908
|
+
showParagraphActions: boolean;
|
|
909
|
+
showListContinuation: boolean;
|
|
847
910
|
showStyleSelectors: boolean;
|
|
848
911
|
showUpdateActions: boolean;
|
|
849
912
|
onSetParagraphStyle?: (styleId: string) => void;
|
|
@@ -891,7 +954,7 @@ function ToolbarCompactOverflow(props: {
|
|
|
891
954
|
aria-expanded={open}
|
|
892
955
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
893
956
|
onClick={() => setOpen((value) => !value)}
|
|
894
|
-
className={`inline-flex h-
|
|
957
|
+
className={`inline-flex h-6 items-center gap-1 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface outline-none ${focusRingClass}`}
|
|
895
958
|
>
|
|
896
959
|
More
|
|
897
960
|
<ChevronDown className="h-3.5 w-3.5 text-tertiary" />
|
|
@@ -971,31 +1034,36 @@ function ToolbarCompactOverflow(props: {
|
|
|
971
1034
|
</div>
|
|
972
1035
|
) : null}
|
|
973
1036
|
|
|
974
|
-
|
|
975
|
-
<div className="
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1037
|
+
{props.showParagraphActions || (props.showListContinuation && props.activeListContext) ? (
|
|
1038
|
+
<div className="space-y-1">
|
|
1039
|
+
<div className="px-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary">
|
|
1040
|
+
Paragraph
|
|
1041
|
+
</div>
|
|
1042
|
+
{props.showParagraphActions ? (
|
|
1043
|
+
<>
|
|
1044
|
+
<ToolbarMenuButton
|
|
1045
|
+
ariaLabel="Outdent"
|
|
1046
|
+
disabled={!props.canEdit || !props.onOutdent}
|
|
1047
|
+
icon={<Outdent className="h-3.5 w-3.5" />}
|
|
1048
|
+
label="Outdent"
|
|
1049
|
+
onClick={() => {
|
|
1050
|
+
props.onOutdent?.();
|
|
1051
|
+
setOpen(false);
|
|
1052
|
+
}}
|
|
1053
|
+
/>
|
|
1054
|
+
<ToolbarMenuButton
|
|
1055
|
+
ariaLabel="Indent"
|
|
1056
|
+
disabled={!props.canEdit || !props.onIndent}
|
|
1057
|
+
icon={<Indent className="h-3.5 w-3.5" />}
|
|
1058
|
+
label="Indent"
|
|
1059
|
+
onClick={() => {
|
|
1060
|
+
props.onIndent?.();
|
|
1061
|
+
setOpen(false);
|
|
1062
|
+
}}
|
|
1063
|
+
/>
|
|
1064
|
+
</>
|
|
1065
|
+
) : null}
|
|
1066
|
+
{props.showListContinuation && props.activeListContext ? (
|
|
999
1067
|
<>
|
|
1000
1068
|
<ToolbarMenuButton
|
|
1001
1069
|
ariaLabel="Restart numbering"
|
|
@@ -1018,8 +1086,9 @@ function ToolbarCompactOverflow(props: {
|
|
|
1018
1086
|
}}
|
|
1019
1087
|
/>
|
|
1020
1088
|
</>
|
|
1021
|
-
|
|
1022
|
-
|
|
1089
|
+
) : null}
|
|
1090
|
+
</div>
|
|
1091
|
+
) : null}
|
|
1023
1092
|
|
|
1024
1093
|
{props.showInsertMenu ? (
|
|
1025
1094
|
<div className="space-y-1">
|
|
@@ -1047,7 +1116,7 @@ function ToolbarCompactOverflow(props: {
|
|
|
1047
1116
|
}}
|
|
1048
1117
|
/>
|
|
1049
1118
|
<label
|
|
1050
|
-
className={`flex h-
|
|
1119
|
+
className={`flex h-7 cursor-pointer items-center gap-2 rounded-md px-2 text-left text-[11px] font-medium text-primary transition-colors hover:bg-surface ${
|
|
1051
1120
|
!props.canInsertStructural || !props.onInsertImage ? "pointer-events-none opacity-40" : ""
|
|
1052
1121
|
}`}
|
|
1053
1122
|
>
|
|
@@ -1131,7 +1200,7 @@ function ToolbarFormattingOverflow(props: {
|
|
|
1131
1200
|
disabled={props.disabled}
|
|
1132
1201
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1133
1202
|
onClick={() => setOpen((value) => !value)}
|
|
1134
|
-
className={`inline-flex h-
|
|
1203
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
1135
1204
|
>
|
|
1136
1205
|
<MoreHorizontal className="h-3.5 w-3.5" />
|
|
1137
1206
|
</button>
|
|
@@ -1206,7 +1275,7 @@ function ToolbarColorPopover(props: {
|
|
|
1206
1275
|
disabled={props.disabled}
|
|
1207
1276
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1208
1277
|
onClick={() => setOpen((value) => !value)}
|
|
1209
|
-
className={`inline-flex h-
|
|
1278
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
1210
1279
|
>
|
|
1211
1280
|
{props.icon}
|
|
1212
1281
|
</button>
|
|
@@ -1234,7 +1303,7 @@ function ToolbarColorPopover(props: {
|
|
|
1234
1303
|
props.onSelect(color.value);
|
|
1235
1304
|
setOpen(false);
|
|
1236
1305
|
}}
|
|
1237
|
-
className={`inline-flex h-
|
|
1306
|
+
className={`inline-flex h-7 items-center justify-center rounded-md border border-border text-[10px] font-medium text-primary transition-transform hover:scale-[1.04] disabled:cursor-not-allowed disabled:opacity-40 ${
|
|
1238
1307
|
color.value ? "" : "bg-surface"
|
|
1239
1308
|
} ${focusRingClass}`}
|
|
1240
1309
|
style={color.value ? { backgroundColor: color.value } : undefined}
|
|
@@ -1273,7 +1342,7 @@ function ToolbarAlignmentPopover(props: {
|
|
|
1273
1342
|
disabled={props.disabled}
|
|
1274
1343
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1275
1344
|
onClick={() => setOpen((value) => !value)}
|
|
1276
|
-
className={`inline-flex h-
|
|
1345
|
+
className={`inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
1277
1346
|
>
|
|
1278
1347
|
{(alignments.find((entry) => entry.value === props.activeAlignment) ?? alignments[0])?.icon}
|
|
1279
1348
|
</button>
|
|
@@ -1346,7 +1415,7 @@ function ToolbarInsertMenu(props: {
|
|
|
1346
1415
|
disabled={props.disabled}
|
|
1347
1416
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1348
1417
|
onClick={() => setOpen((value) => !value)}
|
|
1349
|
-
className={`inline-flex h-
|
|
1418
|
+
className={`inline-flex h-6 items-center gap-1 rounded-md border border-border bg-canvas px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
1350
1419
|
>
|
|
1351
1420
|
Insert
|
|
1352
1421
|
<ChevronDown className="h-3.5 w-3.5 text-tertiary" />
|
|
@@ -1382,7 +1451,7 @@ function ToolbarInsertMenu(props: {
|
|
|
1382
1451
|
}}
|
|
1383
1452
|
/>
|
|
1384
1453
|
<label
|
|
1385
|
-
className={`flex h-
|
|
1454
|
+
className={`flex h-7 cursor-pointer items-center gap-2 rounded-md px-2 text-[11px] font-medium text-primary transition-colors hover:bg-surface ${
|
|
1386
1455
|
props.disabled || !props.onInsertImage ? "pointer-events-none opacity-40" : ""
|
|
1387
1456
|
}`}
|
|
1388
1457
|
>
|
|
@@ -1431,7 +1500,7 @@ function ToolbarPopoverActionButton(props: {
|
|
|
1431
1500
|
disabled={props.disabled}
|
|
1432
1501
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1433
1502
|
onClick={props.onClick}
|
|
1434
|
-
className={`inline-flex h-
|
|
1503
|
+
className={`inline-flex h-7 items-center justify-center rounded-md border border-border transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${
|
|
1435
1504
|
props.active ? "bg-canvas text-accent ring-1 ring-accent/30 shadow-sm" : "bg-canvas text-secondary hover:bg-surface"
|
|
1436
1505
|
} ${focusRingClass}`}
|
|
1437
1506
|
>
|
|
@@ -1454,7 +1523,7 @@ function ToolbarMenuButton(props: {
|
|
|
1454
1523
|
disabled={props.disabled}
|
|
1455
1524
|
onMouseDown={preserveEditorSelectionMouseDown}
|
|
1456
1525
|
onClick={props.onClick}
|
|
1457
|
-
className={`flex h-
|
|
1526
|
+
className={`flex h-7 w-full items-center gap-2 rounded-md px-2 text-left text-[11px] font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
|
|
1458
1527
|
>
|
|
1459
1528
|
<span className="text-secondary">{props.icon}</span>
|
|
1460
1529
|
<span>{props.label}</span>
|