@stll/folio-react 0.5.0 → 0.6.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/{CommentsSidebar-BMD21hiD.js → CommentsSidebar-_utmEkA9.js} +1 -1
- package/dist/{FindReplaceDialog-By2OhOPu.js → FindReplaceDialog-DLdBekSR.js} +4 -2
- package/dist/{FootnotePropertiesDialog-CoPGKND_.js → FootnotePropertiesDialog-CUjq9c6H.js} +4 -2
- package/dist/{ImagePositionDialog-B_md0l56.js → ImagePositionDialog-BMuO9rLT.js} +4 -2
- package/dist/{ImagePropertiesDialog-UcGv8qr3.js → ImagePropertiesDialog-C8iEgdmN.js} +4 -2
- package/dist/{PageSetupDialog-Ba7bs6m3.js → PageSetupDialog-BKsSMCGb.js} +4 -2
- package/dist/{TablePropertiesDialog-Ci6h1tk2.js → TablePropertiesDialog-Dw8gvL78.js} +4 -2
- package/dist/compat/eigenpal.d.ts +1 -1
- package/dist/compat/eigenpal.js +1 -1
- package/dist/dialogs-CzvXYJyG.js +1080 -0
- package/dist/dialogs-j7qyw17x.d.ts +318 -0
- package/dist/dialogs.d.ts +2 -0
- package/dist/dialogs.js +8 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +11 -2
- package/dist/messages.js +1 -26
- package/dist/{renderAsync-C_Jb8BBI.d.ts → renderAsync-B7UJsZye.d.ts} +3 -2
- package/dist/{renderAsync-B4SrVWHb.js → renderAsync-CwHTsxBN.js} +26 -855
- package/dist/rolldown-runtime-BBjsoOtd.js +27 -0
- package/dist/standalone.css +1 -1
- package/dist/useFindReplace-BPBpMWS9.js +842 -0
- package/package.json +5 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { a as FolioUIProvider, i as DEFAULT_COMPONENTS, n as findInDocument, o as useFolioUI, r as scrollToMatch, s as cn, t as useFindReplace$1 } from "./useFindReplace-BPBpMWS9.js";
|
|
1
2
|
import { t as messages_exports } from "./messages.js";
|
|
2
3
|
import * as React$1 from "react";
|
|
3
|
-
import React, { Component, Suspense, cloneElement, createContext, forwardRef, isValidElement, lazy, memo, useCallback,
|
|
4
|
+
import React, { Component, Suspense, cloneElement, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
5
|
import { AlertCircleIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, BaselineIcon, BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ClipboardCopyIcon, EyeIcon, FileIcon, GlobeIcon, ImageIcon, IndentDecreaseIcon, IndentIncreaseIcon, InfoIcon, ItalicIcon, LinkIcon, ListIcon, ListOrderedIcon, MoreHorizontalIcon, PaintbrushIcon, PenLineIcon, PencilIcon, PilcrowIcon, Redo2Icon, RulerIcon, SeparatorHorizontalIcon, SquarePenIcon, StickyNoteIcon, TableIcon, TableOfContentsIcon, TypeIcon, UnderlineIcon, Undo2Icon, UnlinkIcon, XIcon } from "lucide-react";
|
|
5
6
|
import { IntlProvider, useTranslations } from "use-intl";
|
|
6
7
|
import { applyFolioAIEditOperations, createFolioAIEditSnapshot, getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
|
|
@@ -74,12 +75,6 @@ import { expectFontFamilyMarkAttrs, expectImageAttrs, expectTableAttrs, expectTa
|
|
|
74
75
|
import { extractEmbeddedFonts } from "@stll/folio-core/fonts/embeddedFonts";
|
|
75
76
|
import { panic } from "better-result";
|
|
76
77
|
import { collectRemoteSelections, createHiddenEditorManager, createHiddenEditorState } from "@stll/folio-core/controller/hiddenEditorManager";
|
|
77
|
-
import { Checkbox } from "@base-ui/react/checkbox";
|
|
78
|
-
import { Popover } from "@base-ui/react/popover";
|
|
79
|
-
import { Dialog } from "@base-ui/react/dialog";
|
|
80
|
-
import { Input } from "@base-ui/react/input";
|
|
81
|
-
import { Menu } from "@base-ui/react/menu";
|
|
82
|
-
import { Select } from "@base-ui/react/select";
|
|
83
78
|
import { createFolioAIEditSnapshot as createFolioAIEditSnapshot$1 } from "@stll/folio-core/ai-edits/snapshot";
|
|
84
79
|
import { getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex } from "@stll/folio-core/types/block-id";
|
|
85
80
|
import { CONTENT_CONTROL_WIDGET_EVENT_NAME, dispatchDatePick, dispatchDropdownPick } from "@stll/folio-core/prosemirror/plugins/contentControlWidgets";
|
|
@@ -2297,15 +2292,17 @@ function renderHeaderFooterContentByRId(source, hfPMs, contentWidth, metrics, op
|
|
|
2297
2292
|
function getSectionHeaderFooterRefs(documentModel) {
|
|
2298
2293
|
const body = documentModel?.package.document;
|
|
2299
2294
|
if (!body) return;
|
|
2295
|
+
const documentEvenAndOddHeaders = documentModel.package.settings?.evenAndOddHeaders === true;
|
|
2300
2296
|
const sections = body.sections;
|
|
2301
|
-
if (sections && sections.length > 0) return sections.map((section) => getHeaderFooterRefsFromSectionProperties(section.properties));
|
|
2297
|
+
if (sections && sections.length > 0) return sections.map((section) => getHeaderFooterRefsFromSectionProperties(section.properties, documentEvenAndOddHeaders));
|
|
2302
2298
|
const finalProps = body.finalSectionProperties;
|
|
2303
2299
|
if (!finalProps) return;
|
|
2304
|
-
return [getHeaderFooterRefsFromSectionProperties(finalProps)];
|
|
2300
|
+
return [getHeaderFooterRefsFromSectionProperties(finalProps, documentEvenAndOddHeaders)];
|
|
2305
2301
|
}
|
|
2306
|
-
function getHeaderFooterRefsFromSectionProperties(props) {
|
|
2302
|
+
function getHeaderFooterRefsFromSectionProperties(props, documentEvenAndOddHeaders) {
|
|
2307
2303
|
const refs = {};
|
|
2308
2304
|
if (props.titlePg !== void 0) refs.titlePg = props.titlePg;
|
|
2305
|
+
refs.evenAndOddHeaders = props.evenAndOddHeaders ?? documentEvenAndOddHeaders;
|
|
2309
2306
|
for (const ref of props.headerReferences ?? []) if (ref.type === "default") refs.headerDefault = ref.rId;
|
|
2310
2307
|
else if (ref.type === "first") refs.headerFirst = ref.rId;
|
|
2311
2308
|
else refs.headerEven = ref.rId;
|
|
@@ -6108,487 +6105,6 @@ function generateVerticalTicks(pageHeightTwips, zoom, unit) {
|
|
|
6108
6105
|
return ticks;
|
|
6109
6106
|
}
|
|
6110
6107
|
//#endregion
|
|
6111
|
-
//#region src/lib/utils.ts
|
|
6112
|
-
/** Merge class names, filtering out falsy values. */
|
|
6113
|
-
function cn(...inputs) {
|
|
6114
|
-
return inputs.filter(Boolean).join(" ");
|
|
6115
|
-
}
|
|
6116
|
-
//#endregion
|
|
6117
|
-
//#region src/ui/defaults/button.tsx
|
|
6118
|
-
/**
|
|
6119
|
-
* Built-in, dependency-free Button used when a consumer does not inject one.
|
|
6120
|
-
*
|
|
6121
|
-
* Renders a native, accessible `<button>` honoring the `FolioButtonProps`
|
|
6122
|
-
* subset. The minimal default styling lives in `editor.css`
|
|
6123
|
-
* (`.folio-default-button*` classes, keyed off folio's `--doc-*` variables with
|
|
6124
|
-
* safe fallbacks) rather than inline styles, so a caller's `className` can
|
|
6125
|
-
* override the defaults through the normal cascade. Consumers that want
|
|
6126
|
-
* polished chrome inject their own design-system Button via `DocxEditor`'s
|
|
6127
|
-
* `components` prop.
|
|
6128
|
-
*/
|
|
6129
|
-
function DefaultButton({ variant = "default", size = "sm", className, children, ...props }) {
|
|
6130
|
-
return /* @__PURE__ */ jsx("button", {
|
|
6131
|
-
type: "button",
|
|
6132
|
-
className: cn("folio-default-button", `folio-default-button--${variant}`, `folio-default-button--${size}`, className),
|
|
6133
|
-
...props,
|
|
6134
|
-
children
|
|
6135
|
-
});
|
|
6136
|
-
}
|
|
6137
|
-
//#endregion
|
|
6138
|
-
//#region src/ui/defaults/checkbox.tsx
|
|
6139
|
-
/**
|
|
6140
|
-
* Built-in, dependency-light Checkbox used when a consumer does not inject one.
|
|
6141
|
-
* Wraps `@base-ui/react`'s accessible Checkbox primitive with a minimal check
|
|
6142
|
-
* indicator; consumers inject their own design-system Checkbox for full polish.
|
|
6143
|
-
*/
|
|
6144
|
-
function DefaultCheckbox({ className, ...props }) {
|
|
6145
|
-
return /* @__PURE__ */ jsx(Checkbox.Root, {
|
|
6146
|
-
className: cn("folio-default-checkbox", className),
|
|
6147
|
-
...props,
|
|
6148
|
-
children: /* @__PURE__ */ jsx(Checkbox.Indicator, {
|
|
6149
|
-
className: "folio-default-checkbox-indicator",
|
|
6150
|
-
children: /* @__PURE__ */ jsx("svg", {
|
|
6151
|
-
"aria-hidden": "true",
|
|
6152
|
-
fill: "none",
|
|
6153
|
-
height: "14",
|
|
6154
|
-
stroke: "currentColor",
|
|
6155
|
-
strokeLinecap: "round",
|
|
6156
|
-
strokeLinejoin: "round",
|
|
6157
|
-
strokeWidth: "3",
|
|
6158
|
-
viewBox: "0 0 24 24",
|
|
6159
|
-
width: "14",
|
|
6160
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
6161
|
-
children: /* @__PURE__ */ jsx("path", { d: "M5.252 12.7 10.2 18.63 18.748 5.37" })
|
|
6162
|
-
})
|
|
6163
|
-
})
|
|
6164
|
-
});
|
|
6165
|
-
}
|
|
6166
|
-
//#endregion
|
|
6167
|
-
//#region src/ui/defaults/color-picker.tsx
|
|
6168
|
-
/**
|
|
6169
|
-
* Built-in, dependency-light ColorPicker used when a consumer does not inject
|
|
6170
|
-
* one. Wraps `@base-ui/react`'s Popover primitive (focus management,
|
|
6171
|
-
* portalling, collision-aware positioning) and renders the `presets` as a row
|
|
6172
|
-
* of swatch buttons plus a native `<input type="color">` for a custom color.
|
|
6173
|
-
* `onSelect` emits a preset value or a 6-char uppercase hex (no `#`), matching
|
|
6174
|
-
* the design-system ColorPicker contract. Consumers inject a polished picker
|
|
6175
|
-
* via `DocxEditor`'s `components` prop.
|
|
6176
|
-
*/
|
|
6177
|
-
const swatchColor = (preset) => preset.color ?? `#${preset.value}`;
|
|
6178
|
-
const normalizeHex = (hex) => hex.replace(/^#/u, "").toUpperCase();
|
|
6179
|
-
const EMPTY_PRESETS = [];
|
|
6180
|
-
function DefaultColorPicker({ value, onSelect, onClear, presets = EMPTY_PRESETS, columns = 8, children }) {
|
|
6181
|
-
return /* @__PURE__ */ jsxs(Popover.Root, { children: [/* @__PURE__ */ jsx(Popover.Trigger, {
|
|
6182
|
-
nativeButton: false,
|
|
6183
|
-
render: /* @__PURE__ */ jsx("div", { className: "folio-default-color-picker-trigger" }),
|
|
6184
|
-
children
|
|
6185
|
-
}), /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
|
|
6186
|
-
align: "start",
|
|
6187
|
-
className: "folio-default-popover-positioner folio-root",
|
|
6188
|
-
side: "bottom",
|
|
6189
|
-
sideOffset: 4,
|
|
6190
|
-
children: /* @__PURE__ */ jsxs(Popover.Popup, {
|
|
6191
|
-
className: "folio-default-color-picker-popup",
|
|
6192
|
-
children: [
|
|
6193
|
-
onClear && /* @__PURE__ */ jsx(Popover.Close, {
|
|
6194
|
-
className: "folio-default-color-picker-clear",
|
|
6195
|
-
onClick: onClear,
|
|
6196
|
-
children: "No color"
|
|
6197
|
-
}),
|
|
6198
|
-
/* @__PURE__ */ jsx("div", {
|
|
6199
|
-
className: "folio-default-color-picker-swatches",
|
|
6200
|
-
style: { gridTemplateColumns: `repeat(${columns}, 1fr)` },
|
|
6201
|
-
children: presets.map((preset) => /* @__PURE__ */ jsx(Popover.Close, {
|
|
6202
|
-
"aria-label": preset.label,
|
|
6203
|
-
className: cn("folio-default-color-picker-swatch", value === preset.value && "folio-default-color-picker-swatch--selected"),
|
|
6204
|
-
onClick: () => onSelect?.(preset.value),
|
|
6205
|
-
style: { backgroundColor: swatchColor(preset) },
|
|
6206
|
-
title: preset.label
|
|
6207
|
-
}, preset.value))
|
|
6208
|
-
}),
|
|
6209
|
-
/* @__PURE__ */ jsxs("label", {
|
|
6210
|
-
className: "folio-default-color-picker-custom",
|
|
6211
|
-
children: ["Custom", /* @__PURE__ */ jsx("input", {
|
|
6212
|
-
"aria-label": "Custom color",
|
|
6213
|
-
onChange: (event) => onSelect?.(normalizeHex(event.target.value)),
|
|
6214
|
-
type: "color",
|
|
6215
|
-
value: value ? `#${normalizeHex(value)}` : "#000000"
|
|
6216
|
-
})]
|
|
6217
|
-
})
|
|
6218
|
-
]
|
|
6219
|
-
})
|
|
6220
|
-
}) })] });
|
|
6221
|
-
}
|
|
6222
|
-
//#endregion
|
|
6223
|
-
//#region src/ui/defaults/date-picker-popover.tsx
|
|
6224
|
-
/**
|
|
6225
|
-
* Built-in, dependency-light DatePickerPopover used when a consumer does not
|
|
6226
|
-
* inject one. Renders a native `<input type="date">` whose value is an ISO
|
|
6227
|
-
* `yyyy-mm-dd` string; `onChange` emits that string (or `null` when cleared),
|
|
6228
|
-
* matching the design-system picker contract. Consumers inject a polished
|
|
6229
|
-
* calendar via `DocxEditor`'s `components` prop.
|
|
6230
|
-
*/
|
|
6231
|
-
const toISODate = (value) => {
|
|
6232
|
-
if (value === null) return "";
|
|
6233
|
-
if (value instanceof Date) return `${value.getFullYear().toString().padStart(4, "0")}-${(value.getMonth() + 1).toString().padStart(2, "0")}-${value.getDate().toString().padStart(2, "0")}`;
|
|
6234
|
-
return value.length >= 10 ? value.slice(0, 10) : value;
|
|
6235
|
-
};
|
|
6236
|
-
function DefaultDatePickerPopover({ value, onChange, defaultOpen = false }) {
|
|
6237
|
-
return /* @__PURE__ */ jsx("input", {
|
|
6238
|
-
autoFocus: defaultOpen,
|
|
6239
|
-
className: "folio-default-date-input",
|
|
6240
|
-
onChange: (event) => onChange(event.target.value || null),
|
|
6241
|
-
type: "date",
|
|
6242
|
-
value: toISODate(value)
|
|
6243
|
-
});
|
|
6244
|
-
}
|
|
6245
|
-
//#endregion
|
|
6246
|
-
//#region src/ui/defaults/dialog.tsx
|
|
6247
|
-
/**
|
|
6248
|
-
* Built-in, dependency-light Dialog parts used when a consumer does not inject
|
|
6249
|
-
* its own. Each part wraps the matching `@base-ui/react` primitive — the same
|
|
6250
|
-
* accessible primitive the app design system wraps — with minimal styling.
|
|
6251
|
-
* Folio's chrome positions the popup itself via `className`, so the default
|
|
6252
|
-
* popup is a bare portalled surface (no viewport grid); consumers inject a
|
|
6253
|
-
* polished Dialog through `DocxEditor`'s `components` prop.
|
|
6254
|
-
*/
|
|
6255
|
-
function DefaultDialogRoot(props) {
|
|
6256
|
-
return /* @__PURE__ */ jsx(Dialog.Root, { ...props });
|
|
6257
|
-
}
|
|
6258
|
-
function DefaultDialogPortal({ children, ...props }) {
|
|
6259
|
-
return /* @__PURE__ */ jsx(Dialog.Portal, {
|
|
6260
|
-
...props,
|
|
6261
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
6262
|
-
className: "folio-root",
|
|
6263
|
-
style: { display: "contents" },
|
|
6264
|
-
children
|
|
6265
|
-
})
|
|
6266
|
-
});
|
|
6267
|
-
}
|
|
6268
|
-
function DefaultDialogBackdrop({ className, ...props }) {
|
|
6269
|
-
return /* @__PURE__ */ jsx(Dialog.Backdrop, {
|
|
6270
|
-
className: cn("folio-default-dialog-backdrop", className),
|
|
6271
|
-
...props
|
|
6272
|
-
});
|
|
6273
|
-
}
|
|
6274
|
-
function DefaultDialogPopup({ className, ...props }) {
|
|
6275
|
-
return /* @__PURE__ */ jsx(Dialog.Popup, {
|
|
6276
|
-
className: cn("folio-default-dialog-popup", className),
|
|
6277
|
-
...props
|
|
6278
|
-
});
|
|
6279
|
-
}
|
|
6280
|
-
function DefaultDialogTitle({ className, ...props }) {
|
|
6281
|
-
return /* @__PURE__ */ jsx(Dialog.Title, {
|
|
6282
|
-
className: cn("folio-default-dialog-title", className),
|
|
6283
|
-
...props
|
|
6284
|
-
});
|
|
6285
|
-
}
|
|
6286
|
-
function DefaultDialogClose({ className, ...props }) {
|
|
6287
|
-
return /* @__PURE__ */ jsx(Dialog.Close, {
|
|
6288
|
-
className: cn("folio-default-dialog-close", className),
|
|
6289
|
-
...props
|
|
6290
|
-
});
|
|
6291
|
-
}
|
|
6292
|
-
const DefaultDialog = {
|
|
6293
|
-
Root: DefaultDialogRoot,
|
|
6294
|
-
Portal: DefaultDialogPortal,
|
|
6295
|
-
Backdrop: DefaultDialogBackdrop,
|
|
6296
|
-
Popup: DefaultDialogPopup,
|
|
6297
|
-
Title: DefaultDialogTitle,
|
|
6298
|
-
Close: DefaultDialogClose
|
|
6299
|
-
};
|
|
6300
|
-
//#endregion
|
|
6301
|
-
//#region src/ui/defaults/input.tsx
|
|
6302
|
-
/**
|
|
6303
|
-
* Built-in, dependency-light Input used when a consumer does not inject one.
|
|
6304
|
-
*
|
|
6305
|
-
* Wraps `@base-ui/react`'s Input primitive, honoring the `nativeInput` escape
|
|
6306
|
-
* hatch (render a plain `<input>` when the caller needs uncontrolled native
|
|
6307
|
-
* behavior) and folio's `size` shorthand. Styling is intentionally minimal;
|
|
6308
|
-
* consumers inject their own design-system Input for full polish.
|
|
6309
|
-
*/
|
|
6310
|
-
function DefaultInput({ className, size = "default", nativeInput = false, ...props }) {
|
|
6311
|
-
const inputClassName = cn("folio-default-input", className);
|
|
6312
|
-
const numericSize = typeof size === "number" ? size : void 0;
|
|
6313
|
-
if (nativeInput) return /* @__PURE__ */ jsx("input", {
|
|
6314
|
-
className: inputClassName,
|
|
6315
|
-
"data-size": typeof size === "string" ? size : void 0,
|
|
6316
|
-
size: numericSize,
|
|
6317
|
-
...props
|
|
6318
|
-
});
|
|
6319
|
-
return /* @__PURE__ */ jsx(Input, {
|
|
6320
|
-
className: inputClassName,
|
|
6321
|
-
"data-size": typeof size === "string" ? size : void 0,
|
|
6322
|
-
size: numericSize,
|
|
6323
|
-
...props
|
|
6324
|
-
});
|
|
6325
|
-
}
|
|
6326
|
-
//#endregion
|
|
6327
|
-
//#region src/ui/defaults/menu.tsx
|
|
6328
|
-
/**
|
|
6329
|
-
* Built-in, dependency-light Menu parts used when a consumer does not inject
|
|
6330
|
-
* its own. Each part wraps the matching `@base-ui/react` primitive (real
|
|
6331
|
-
* keyboard navigation, portalling, collision-aware positioning) with minimal
|
|
6332
|
-
* styling. Consumers inject a polished Menu via `DocxEditor`'s `components`
|
|
6333
|
-
* prop.
|
|
6334
|
-
*/
|
|
6335
|
-
function DefaultMenuRoot(props) {
|
|
6336
|
-
return /* @__PURE__ */ jsx(Menu.Root, { ...props });
|
|
6337
|
-
}
|
|
6338
|
-
function DefaultMenuTrigger({ nativeButton = true, ...props }) {
|
|
6339
|
-
return /* @__PURE__ */ jsx(Menu.Trigger, {
|
|
6340
|
-
nativeButton,
|
|
6341
|
-
...props
|
|
6342
|
-
});
|
|
6343
|
-
}
|
|
6344
|
-
function DefaultMenuPopup({ className, children, align = "center", side = "bottom", sideOffset = 4, alignOffset, ...props }) {
|
|
6345
|
-
return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
|
|
6346
|
-
align,
|
|
6347
|
-
alignOffset,
|
|
6348
|
-
className: "folio-default-menu-positioner folio-root",
|
|
6349
|
-
side,
|
|
6350
|
-
sideOffset,
|
|
6351
|
-
children: /* @__PURE__ */ jsx(Menu.Popup, {
|
|
6352
|
-
className: cn("folio-default-menu-popup", className),
|
|
6353
|
-
...props,
|
|
6354
|
-
children
|
|
6355
|
-
})
|
|
6356
|
-
}) });
|
|
6357
|
-
}
|
|
6358
|
-
function DefaultMenuItem({ className, ...props }) {
|
|
6359
|
-
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
6360
|
-
className: cn("folio-default-menu-item", className),
|
|
6361
|
-
...props
|
|
6362
|
-
});
|
|
6363
|
-
}
|
|
6364
|
-
function DefaultMenuCheckboxItem({ className, children, ...props }) {
|
|
6365
|
-
return /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
|
|
6366
|
-
className: cn("folio-default-menu-checkbox-item", className),
|
|
6367
|
-
...props,
|
|
6368
|
-
children: [/* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {
|
|
6369
|
-
className: "folio-default-menu-checkbox-indicator",
|
|
6370
|
-
children: /* @__PURE__ */ jsx("svg", {
|
|
6371
|
-
"aria-hidden": "true",
|
|
6372
|
-
fill: "none",
|
|
6373
|
-
height: "14",
|
|
6374
|
-
stroke: "currentColor",
|
|
6375
|
-
strokeLinecap: "round",
|
|
6376
|
-
strokeLinejoin: "round",
|
|
6377
|
-
strokeWidth: "3",
|
|
6378
|
-
viewBox: "0 0 24 24",
|
|
6379
|
-
width: "14",
|
|
6380
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
6381
|
-
children: /* @__PURE__ */ jsx("path", { d: "M5.252 12.7 10.2 18.63 18.748 5.37" })
|
|
6382
|
-
})
|
|
6383
|
-
}), /* @__PURE__ */ jsx("span", { children })]
|
|
6384
|
-
});
|
|
6385
|
-
}
|
|
6386
|
-
function DefaultMenuGroup(props) {
|
|
6387
|
-
return /* @__PURE__ */ jsx(Menu.Group, { ...props });
|
|
6388
|
-
}
|
|
6389
|
-
function DefaultMenuGroupLabel({ className, ...props }) {
|
|
6390
|
-
return /* @__PURE__ */ jsx(Menu.GroupLabel, {
|
|
6391
|
-
className: cn("folio-default-menu-group-label", className),
|
|
6392
|
-
...props
|
|
6393
|
-
});
|
|
6394
|
-
}
|
|
6395
|
-
function DefaultMenuSeparator({ className, ...props }) {
|
|
6396
|
-
return /* @__PURE__ */ jsx(Menu.Separator, {
|
|
6397
|
-
className: cn("folio-default-menu-separator", className),
|
|
6398
|
-
...props
|
|
6399
|
-
});
|
|
6400
|
-
}
|
|
6401
|
-
const DefaultMenu = {
|
|
6402
|
-
Root: DefaultMenuRoot,
|
|
6403
|
-
Trigger: DefaultMenuTrigger,
|
|
6404
|
-
Popup: DefaultMenuPopup,
|
|
6405
|
-
Item: DefaultMenuItem,
|
|
6406
|
-
CheckboxItem: DefaultMenuCheckboxItem,
|
|
6407
|
-
Group: DefaultMenuGroup,
|
|
6408
|
-
GroupLabel: DefaultMenuGroupLabel,
|
|
6409
|
-
Separator: DefaultMenuSeparator
|
|
6410
|
-
};
|
|
6411
|
-
//#endregion
|
|
6412
|
-
//#region src/ui/defaults/outline-rail.tsx
|
|
6413
|
-
/**
|
|
6414
|
-
* Built-in, dependency-light OutlineRail used when a consumer does not inject
|
|
6415
|
-
* one. Renders the outline as a plain semantic `<nav>` list of clickable
|
|
6416
|
-
* entries indented by level; clicking an entry calls `onJump` with the resolved
|
|
6417
|
-
* scroll container. Consumers inject the polished tick-rail + hover panel via
|
|
6418
|
-
* `DocxEditor`'s `components` prop.
|
|
6419
|
-
*/
|
|
6420
|
-
function DefaultOutlineRail({ items, scrollContainerRef, onJump, activeId, topOffset = 0, panelWidth = 300, ariaLabel = "Outline" }) {
|
|
6421
|
-
if (items.length < 2) return null;
|
|
6422
|
-
return /* @__PURE__ */ jsx("nav", {
|
|
6423
|
-
"aria-label": ariaLabel,
|
|
6424
|
-
className: "folio-default-outline-rail",
|
|
6425
|
-
style: {
|
|
6426
|
-
top: topOffset,
|
|
6427
|
-
width: panelWidth
|
|
6428
|
-
},
|
|
6429
|
-
children: /* @__PURE__ */ jsx("ul", {
|
|
6430
|
-
className: "folio-default-outline-list",
|
|
6431
|
-
children: items.map((item) => {
|
|
6432
|
-
const isActive = item.id === activeId;
|
|
6433
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
|
|
6434
|
-
"aria-current": isActive ? "true" : void 0,
|
|
6435
|
-
className: cn("folio-default-outline-item", isActive && "folio-default-outline-item--active"),
|
|
6436
|
-
onClick: () => {
|
|
6437
|
-
const container = scrollContainerRef.current;
|
|
6438
|
-
if (container) onJump(item.id, container);
|
|
6439
|
-
},
|
|
6440
|
-
style: { paddingInlineStart: `${item.level * 12 + 8}px` },
|
|
6441
|
-
title: item.label,
|
|
6442
|
-
type: "button",
|
|
6443
|
-
children: item.label
|
|
6444
|
-
}) }, item.id);
|
|
6445
|
-
})
|
|
6446
|
-
})
|
|
6447
|
-
});
|
|
6448
|
-
}
|
|
6449
|
-
//#endregion
|
|
6450
|
-
//#region src/ui/defaults/popover.tsx
|
|
6451
|
-
/**
|
|
6452
|
-
* Built-in, dependency-light Popover parts used when a consumer does not inject
|
|
6453
|
-
* its own. Each part wraps the matching `@base-ui/react` primitive (real focus
|
|
6454
|
-
* management, portalling, and collision-aware positioning) with minimal
|
|
6455
|
-
* styling. Consumers inject a polished Popover via `DocxEditor`'s `components`
|
|
6456
|
-
* prop.
|
|
6457
|
-
*/
|
|
6458
|
-
function DefaultPopoverRoot(props) {
|
|
6459
|
-
return /* @__PURE__ */ jsx(Popover.Root, { ...props });
|
|
6460
|
-
}
|
|
6461
|
-
function DefaultPopoverTrigger(props) {
|
|
6462
|
-
return /* @__PURE__ */ jsx(Popover.Trigger, { ...props });
|
|
6463
|
-
}
|
|
6464
|
-
function DefaultPopoverPopup({ className, children, side = "bottom", align = "center", sideOffset = 4, alignOffset = 0, ...props }) {
|
|
6465
|
-
return /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
|
|
6466
|
-
align,
|
|
6467
|
-
alignOffset,
|
|
6468
|
-
className: "folio-default-popover-positioner folio-root",
|
|
6469
|
-
side,
|
|
6470
|
-
sideOffset,
|
|
6471
|
-
children: /* @__PURE__ */ jsx(Popover.Popup, {
|
|
6472
|
-
className: cn("folio-default-popover-popup", className),
|
|
6473
|
-
...props,
|
|
6474
|
-
children
|
|
6475
|
-
})
|
|
6476
|
-
}) });
|
|
6477
|
-
}
|
|
6478
|
-
function DefaultPopoverClose(props) {
|
|
6479
|
-
return /* @__PURE__ */ jsx(Popover.Close, { ...props });
|
|
6480
|
-
}
|
|
6481
|
-
const DefaultPopover = {
|
|
6482
|
-
Root: DefaultPopoverRoot,
|
|
6483
|
-
Trigger: DefaultPopoverTrigger,
|
|
6484
|
-
Popup: DefaultPopoverPopup,
|
|
6485
|
-
Close: DefaultPopoverClose
|
|
6486
|
-
};
|
|
6487
|
-
//#endregion
|
|
6488
|
-
//#region src/ui/defaults/select.tsx
|
|
6489
|
-
/**
|
|
6490
|
-
* Built-in, dependency-light Select parts used when a consumer does not inject
|
|
6491
|
-
* its own. Each part wraps the matching `@base-ui/react` primitive (real
|
|
6492
|
-
* listbox semantics, keyboard navigation, portalled positioning) with minimal
|
|
6493
|
-
* styling. The default popup omits the scroll arrows and item-aligned
|
|
6494
|
-
* positioning of a fully styled design-system Select; consumers inject their
|
|
6495
|
-
* own Select via `DocxEditor`'s `components` prop for that polish.
|
|
6496
|
-
*/
|
|
6497
|
-
function DefaultSelectRoot(props) {
|
|
6498
|
-
return /* @__PURE__ */ jsx(Select.Root, { ...props });
|
|
6499
|
-
}
|
|
6500
|
-
function DefaultSelectTrigger({ className, children, size, ...props }) {
|
|
6501
|
-
return /* @__PURE__ */ jsxs(Select.Trigger, {
|
|
6502
|
-
className: cn("folio-default-select-trigger", className),
|
|
6503
|
-
"data-size": size,
|
|
6504
|
-
...props,
|
|
6505
|
-
children: [children, /* @__PURE__ */ jsx(Select.Icon, {
|
|
6506
|
-
className: "folio-default-select-icon",
|
|
6507
|
-
children: /* @__PURE__ */ jsx("svg", {
|
|
6508
|
-
"aria-hidden": "true",
|
|
6509
|
-
fill: "none",
|
|
6510
|
-
height: "16",
|
|
6511
|
-
stroke: "currentColor",
|
|
6512
|
-
strokeLinecap: "round",
|
|
6513
|
-
strokeLinejoin: "round",
|
|
6514
|
-
strokeWidth: "2",
|
|
6515
|
-
viewBox: "0 0 24 24",
|
|
6516
|
-
width: "16",
|
|
6517
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
6518
|
-
children: /* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5M7 9l5-5 5 5" })
|
|
6519
|
-
})
|
|
6520
|
-
})]
|
|
6521
|
-
});
|
|
6522
|
-
}
|
|
6523
|
-
function DefaultSelectValue({ className, ...props }) {
|
|
6524
|
-
return /* @__PURE__ */ jsx(Select.Value, {
|
|
6525
|
-
className: cn("folio-default-select-value", className),
|
|
6526
|
-
...props
|
|
6527
|
-
});
|
|
6528
|
-
}
|
|
6529
|
-
function DefaultSelectPopup({ className, children, ...props }) {
|
|
6530
|
-
return /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, {
|
|
6531
|
-
align: "start",
|
|
6532
|
-
className: "folio-default-select-positioner folio-root",
|
|
6533
|
-
side: "bottom",
|
|
6534
|
-
sideOffset: 4,
|
|
6535
|
-
children: /* @__PURE__ */ jsx(Select.Popup, {
|
|
6536
|
-
className: cn("folio-default-select-popup", className),
|
|
6537
|
-
...props,
|
|
6538
|
-
children: /* @__PURE__ */ jsx(Select.List, { children })
|
|
6539
|
-
})
|
|
6540
|
-
}) });
|
|
6541
|
-
}
|
|
6542
|
-
function DefaultSelectItem({ className, children, ...props }) {
|
|
6543
|
-
return /* @__PURE__ */ jsx(Select.Item, {
|
|
6544
|
-
className: cn("folio-default-select-item", className),
|
|
6545
|
-
...props,
|
|
6546
|
-
children: /* @__PURE__ */ jsx(Select.ItemText, { children })
|
|
6547
|
-
});
|
|
6548
|
-
}
|
|
6549
|
-
//#endregion
|
|
6550
|
-
//#region src/ui/folio-ui.tsx
|
|
6551
|
-
const DEFAULT_COMPONENTS = {
|
|
6552
|
-
Button: DefaultButton,
|
|
6553
|
-
Dialog: DefaultDialog,
|
|
6554
|
-
Select: {
|
|
6555
|
-
Root: DefaultSelectRoot,
|
|
6556
|
-
Trigger: DefaultSelectTrigger,
|
|
6557
|
-
Value: DefaultSelectValue,
|
|
6558
|
-
Popup: DefaultSelectPopup,
|
|
6559
|
-
Item: DefaultSelectItem
|
|
6560
|
-
},
|
|
6561
|
-
Menu: DefaultMenu,
|
|
6562
|
-
Popover: DefaultPopover,
|
|
6563
|
-
Input: DefaultInput,
|
|
6564
|
-
Checkbox: DefaultCheckbox,
|
|
6565
|
-
ColorPicker: DefaultColorPicker,
|
|
6566
|
-
DatePickerPopover: DefaultDatePickerPopover,
|
|
6567
|
-
OutlineRail: DefaultOutlineRail
|
|
6568
|
-
};
|
|
6569
|
-
const FolioUIContext = createContext(DEFAULT_COMPONENTS);
|
|
6570
|
-
/**
|
|
6571
|
-
* Merge a consumer's partial overrides over the built-in defaults: every key is
|
|
6572
|
-
* present (defaults fill the gaps), and each provided override wins. Pure, so
|
|
6573
|
-
* the resolution contract is unit-tested independently of React.
|
|
6574
|
-
*/
|
|
6575
|
-
function resolveFolioComponents(components) {
|
|
6576
|
-
return components ? {
|
|
6577
|
-
...DEFAULT_COMPONENTS,
|
|
6578
|
-
...components
|
|
6579
|
-
} : DEFAULT_COMPONENTS;
|
|
6580
|
-
}
|
|
6581
|
-
function FolioUIProvider({ components, children }) {
|
|
6582
|
-
const value = resolveFolioComponents(components);
|
|
6583
|
-
return /* @__PURE__ */ jsx(FolioUIContext.Provider, {
|
|
6584
|
-
value,
|
|
6585
|
-
children
|
|
6586
|
-
});
|
|
6587
|
-
}
|
|
6588
|
-
function useFolioUI() {
|
|
6589
|
-
return useContext(FolioUIContext);
|
|
6590
|
-
}
|
|
6591
|
-
//#endregion
|
|
6592
6108
|
//#region src/components/aiEditRange.ts
|
|
6593
6109
|
const resolveFolioAIBlockRange = ({ blockId, doc, snapshot }) => {
|
|
6594
6110
|
const paraId = getFolioParaIdFromBlockId(blockId);
|
|
@@ -6986,357 +6502,6 @@ function ContentControlWidgetsOverlay({ getEditorView }) {
|
|
|
6986
6502
|
}), document.body);
|
|
6987
6503
|
}
|
|
6988
6504
|
//#endregion
|
|
6989
|
-
//#region src/components/dialogs/findReplaceUtils.ts
|
|
6990
|
-
/**
|
|
6991
|
-
* Find & Replace Utility Functions
|
|
6992
|
-
*
|
|
6993
|
-
* Pure utility functions for text search, pattern matching, and document search.
|
|
6994
|
-
* Extracted from FindReplaceDialog.tsx.
|
|
6995
|
-
*/
|
|
6996
|
-
/**
|
|
6997
|
-
* Create default find options
|
|
6998
|
-
*/
|
|
6999
|
-
function createDefaultFindOptions() {
|
|
7000
|
-
return {
|
|
7001
|
-
matchCase: false,
|
|
7002
|
-
matchWholeWord: false,
|
|
7003
|
-
useRegex: false
|
|
7004
|
-
};
|
|
7005
|
-
}
|
|
7006
|
-
/**
|
|
7007
|
-
* Find all matches of search text in content
|
|
7008
|
-
*/
|
|
7009
|
-
function findAllMatches(content, searchText, options) {
|
|
7010
|
-
if (!content || !searchText) return [];
|
|
7011
|
-
const matches = [];
|
|
7012
|
-
let searchFor = searchText;
|
|
7013
|
-
if (!options.matchCase) searchFor = searchText.toLowerCase();
|
|
7014
|
-
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
7015
|
-
let pattern;
|
|
7016
|
-
if (options.matchWholeWord) pattern = `\\b${escapeRegex(searchFor)}\\b`;
|
|
7017
|
-
else pattern = escapeRegex(searchFor);
|
|
7018
|
-
const flags = options.matchCase ? "g" : "gi";
|
|
7019
|
-
const regex = new RegExp(pattern, flags);
|
|
7020
|
-
let match;
|
|
7021
|
-
while ((match = regex.exec(content)) !== null) {
|
|
7022
|
-
matches.push({
|
|
7023
|
-
start: match.index,
|
|
7024
|
-
end: match.index + match[0].length
|
|
7025
|
-
});
|
|
7026
|
-
if (match[0].length === 0) regex.lastIndex++;
|
|
7027
|
-
}
|
|
7028
|
-
return matches;
|
|
7029
|
-
}
|
|
7030
|
-
/**
|
|
7031
|
-
* Get plain text from a run
|
|
7032
|
-
*/
|
|
7033
|
-
function getRunText(run) {
|
|
7034
|
-
let text = "";
|
|
7035
|
-
for (const item of run.content) if (item.type === "text") text += item.text;
|
|
7036
|
-
else if (item.type === "tab") text += " ";
|
|
7037
|
-
else if (item.type === "break" && item.breakType === "textWrapping") text += "\n";
|
|
7038
|
-
return text;
|
|
7039
|
-
}
|
|
7040
|
-
function getHyperlinkText(hyperlink) {
|
|
7041
|
-
let text = "";
|
|
7042
|
-
for (const child of hyperlink.children) if (child.type === "run") text += getRunText(child);
|
|
7043
|
-
return text;
|
|
7044
|
-
}
|
|
7045
|
-
function getParagraphContentText(content) {
|
|
7046
|
-
if (content.type === "run") return getRunText(content);
|
|
7047
|
-
if (content.type === "hyperlink") return getHyperlinkText(content);
|
|
7048
|
-
if (content.type === "inlineSdt") {
|
|
7049
|
-
let text = "";
|
|
7050
|
-
for (const child of content.content) text += getParagraphContentText(child);
|
|
7051
|
-
return text;
|
|
7052
|
-
}
|
|
7053
|
-
if (content.type === "simpleField") {
|
|
7054
|
-
let text = "";
|
|
7055
|
-
for (const child of content.content) {
|
|
7056
|
-
if (child.type === "run") {
|
|
7057
|
-
text += getRunText(child);
|
|
7058
|
-
continue;
|
|
7059
|
-
}
|
|
7060
|
-
text += getHyperlinkText(child);
|
|
7061
|
-
}
|
|
7062
|
-
return text;
|
|
7063
|
-
}
|
|
7064
|
-
if (content.type === "complexField") {
|
|
7065
|
-
let text = "";
|
|
7066
|
-
for (const run of content.fieldResult) text += getRunText(run);
|
|
7067
|
-
return text;
|
|
7068
|
-
}
|
|
7069
|
-
return "";
|
|
7070
|
-
}
|
|
7071
|
-
/**
|
|
7072
|
-
* Get plain text from a paragraph
|
|
7073
|
-
*/
|
|
7074
|
-
function getParagraphPlainText(paragraph) {
|
|
7075
|
-
let text = "";
|
|
7076
|
-
for (const item of paragraph.content) text += getParagraphContentText(item);
|
|
7077
|
-
return text;
|
|
7078
|
-
}
|
|
7079
|
-
/**
|
|
7080
|
-
* Find all matches in a document
|
|
7081
|
-
*/
|
|
7082
|
-
function findInDocument(document, searchText, options) {
|
|
7083
|
-
if (!document || !searchText) return [];
|
|
7084
|
-
const matches = [];
|
|
7085
|
-
const body = document.package.document;
|
|
7086
|
-
if (!isDocumentBody(body)) return matches;
|
|
7087
|
-
forEachParagraph(body.content, (block, paragraphIndex) => {
|
|
7088
|
-
const paragraphMatches = findInParagraph(block, searchText, options, paragraphIndex);
|
|
7089
|
-
matches.push(...paragraphMatches);
|
|
7090
|
-
});
|
|
7091
|
-
return matches;
|
|
7092
|
-
}
|
|
7093
|
-
function forEachParagraph(blocks, visit) {
|
|
7094
|
-
let paragraphIndex = 0;
|
|
7095
|
-
const walkBlocks = (items) => {
|
|
7096
|
-
for (const block of items) {
|
|
7097
|
-
if (isParagraph(block)) {
|
|
7098
|
-
visit(block, paragraphIndex);
|
|
7099
|
-
paragraphIndex++;
|
|
7100
|
-
continue;
|
|
7101
|
-
}
|
|
7102
|
-
if (isTable(block)) {
|
|
7103
|
-
walkTable(block);
|
|
7104
|
-
continue;
|
|
7105
|
-
}
|
|
7106
|
-
if (isBlockSdt(block)) walkBlocks(block.content);
|
|
7107
|
-
}
|
|
7108
|
-
};
|
|
7109
|
-
const walkTable = (table) => {
|
|
7110
|
-
for (const row of table.rows) {
|
|
7111
|
-
if (!isTableRow(row)) continue;
|
|
7112
|
-
for (const cell of row.cells) {
|
|
7113
|
-
if (!isTableCell(cell)) continue;
|
|
7114
|
-
walkBlocks(cell.content);
|
|
7115
|
-
}
|
|
7116
|
-
}
|
|
7117
|
-
};
|
|
7118
|
-
walkBlocks(blocks);
|
|
7119
|
-
}
|
|
7120
|
-
function isRecord(value) {
|
|
7121
|
-
return typeof value === "object" && value !== null;
|
|
7122
|
-
}
|
|
7123
|
-
function isDocumentBody(value) {
|
|
7124
|
-
return isRecord(value) && Array.isArray(value["content"]);
|
|
7125
|
-
}
|
|
7126
|
-
function isParagraph(value) {
|
|
7127
|
-
return isRecord(value) && value["type"] === "paragraph" && Array.isArray(value["content"]);
|
|
7128
|
-
}
|
|
7129
|
-
function isTable(value) {
|
|
7130
|
-
return isRecord(value) && value["type"] === "table" && Array.isArray(value["rows"]);
|
|
7131
|
-
}
|
|
7132
|
-
function isTableRow(value) {
|
|
7133
|
-
return isRecord(value) && Array.isArray(value["cells"]);
|
|
7134
|
-
}
|
|
7135
|
-
function isTableCell(value) {
|
|
7136
|
-
return isRecord(value) && Array.isArray(value["content"]);
|
|
7137
|
-
}
|
|
7138
|
-
function isBlockSdt(value) {
|
|
7139
|
-
return isRecord(value) && value["type"] === "blockSdt" && Array.isArray(value["content"]);
|
|
7140
|
-
}
|
|
7141
|
-
/**
|
|
7142
|
-
* Find matches in a single paragraph
|
|
7143
|
-
*/
|
|
7144
|
-
function findInParagraph(paragraph, searchText, options, paragraphIndex) {
|
|
7145
|
-
const matches = [];
|
|
7146
|
-
const paragraphText = getParagraphPlainText(paragraph);
|
|
7147
|
-
if (!paragraphText) return matches;
|
|
7148
|
-
const textMatches = findAllMatches(paragraphText, searchText, options);
|
|
7149
|
-
for (const match of textMatches) {
|
|
7150
|
-
const contentInfo = findContentAtOffset(paragraph, match.start);
|
|
7151
|
-
matches.push({
|
|
7152
|
-
paragraphIndex,
|
|
7153
|
-
contentIndex: contentInfo.contentIndex,
|
|
7154
|
-
startOffset: match.start,
|
|
7155
|
-
endOffset: match.end,
|
|
7156
|
-
text: paragraphText.slice(match.start, match.end)
|
|
7157
|
-
});
|
|
7158
|
-
}
|
|
7159
|
-
return matches;
|
|
7160
|
-
}
|
|
7161
|
-
/**
|
|
7162
|
-
* Find the content (run) at a specific character offset in a paragraph
|
|
7163
|
-
*/
|
|
7164
|
-
function findContentAtOffset(paragraph, offset) {
|
|
7165
|
-
let currentOffset = 0;
|
|
7166
|
-
let contentIndex = 0;
|
|
7167
|
-
for (const item of paragraph.content) {
|
|
7168
|
-
const itemLength = getParagraphContentText(item).length;
|
|
7169
|
-
if (currentOffset + itemLength > offset) return {
|
|
7170
|
-
contentIndex,
|
|
7171
|
-
runIndex: contentIndex,
|
|
7172
|
-
offsetInContent: offset - currentOffset
|
|
7173
|
-
};
|
|
7174
|
-
currentOffset += itemLength;
|
|
7175
|
-
contentIndex++;
|
|
7176
|
-
}
|
|
7177
|
-
return {
|
|
7178
|
-
contentIndex: Math.max(0, paragraph.content.length - 1),
|
|
7179
|
-
runIndex: Math.max(0, paragraph.content.length - 1),
|
|
7180
|
-
offsetInContent: 0
|
|
7181
|
-
};
|
|
7182
|
-
}
|
|
7183
|
-
/**
|
|
7184
|
-
* Scroll to a match in the document
|
|
7185
|
-
*/
|
|
7186
|
-
function scrollToMatch(containerElement, match) {
|
|
7187
|
-
if (!containerElement) return;
|
|
7188
|
-
(containerElement.querySelector(`[data-paragraph-index="${match.paragraphIndex}"]`) ?? containerElement.querySelector(`.layout-paragraph[data-block-id="block-${match.paragraphIndex + 1}"]`) ?? containerElement.querySelectorAll(".layout-paragraph").item(match.paragraphIndex)).scrollIntoView({
|
|
7189
|
-
behavior: prefersReducedMotionBehavior(),
|
|
7190
|
-
block: "center"
|
|
7191
|
-
});
|
|
7192
|
-
}
|
|
7193
|
-
//#endregion
|
|
7194
|
-
//#region src/components/dialogs/useFindReplace.ts
|
|
7195
|
-
/**
|
|
7196
|
-
* useFindReplace Hook
|
|
7197
|
-
*
|
|
7198
|
-
* React hook for managing find/replace dialog state.
|
|
7199
|
-
* Extracted from FindReplaceDialog.tsx.
|
|
7200
|
-
*/
|
|
7201
|
-
/**
|
|
7202
|
-
* Hook for managing find/replace dialog state
|
|
7203
|
-
*/
|
|
7204
|
-
function useFindReplace$1(hookOptions) {
|
|
7205
|
-
const [state, setState] = useState({
|
|
7206
|
-
...closedDialogState(hookOptions?.initialReplaceMode ? "replace" : "find"),
|
|
7207
|
-
searchText: "",
|
|
7208
|
-
replaceText: "",
|
|
7209
|
-
options: createDefaultFindOptions(),
|
|
7210
|
-
matches: [],
|
|
7211
|
-
currentIndex: 0
|
|
7212
|
-
});
|
|
7213
|
-
return {
|
|
7214
|
-
state,
|
|
7215
|
-
openFind: useCallback((selectedText) => {
|
|
7216
|
-
setState((prev) => ({
|
|
7217
|
-
...prev,
|
|
7218
|
-
...openDialogState("find"),
|
|
7219
|
-
searchText: selectedText || prev.searchText,
|
|
7220
|
-
matches: [],
|
|
7221
|
-
currentIndex: 0
|
|
7222
|
-
}));
|
|
7223
|
-
}, []),
|
|
7224
|
-
openReplace: useCallback((selectedText) => {
|
|
7225
|
-
setState((prev) => ({
|
|
7226
|
-
...prev,
|
|
7227
|
-
...openDialogState("replace"),
|
|
7228
|
-
searchText: selectedText || prev.searchText,
|
|
7229
|
-
matches: [],
|
|
7230
|
-
currentIndex: 0
|
|
7231
|
-
}));
|
|
7232
|
-
}, []),
|
|
7233
|
-
close: useCallback(() => {
|
|
7234
|
-
setState((prev) => ({
|
|
7235
|
-
...prev,
|
|
7236
|
-
...closedDialogState(prev.lastMode)
|
|
7237
|
-
}));
|
|
7238
|
-
}, []),
|
|
7239
|
-
toggle: useCallback(() => {
|
|
7240
|
-
setState((prev) => ({
|
|
7241
|
-
...prev,
|
|
7242
|
-
...prev.dialog.status === "closed" ? openDialogState(prev.lastMode) : closedDialogState(prev.lastMode)
|
|
7243
|
-
}));
|
|
7244
|
-
}, []),
|
|
7245
|
-
setSearchText: useCallback((text) => {
|
|
7246
|
-
setState((prev) => ({
|
|
7247
|
-
...prev,
|
|
7248
|
-
searchText: text
|
|
7249
|
-
}));
|
|
7250
|
-
}, []),
|
|
7251
|
-
setReplaceText: useCallback((text) => {
|
|
7252
|
-
setState((prev) => ({
|
|
7253
|
-
...prev,
|
|
7254
|
-
replaceText: text
|
|
7255
|
-
}));
|
|
7256
|
-
}, []),
|
|
7257
|
-
setOptions: useCallback((options) => {
|
|
7258
|
-
setState((prev) => ({
|
|
7259
|
-
...prev,
|
|
7260
|
-
options: {
|
|
7261
|
-
...prev.options,
|
|
7262
|
-
...options
|
|
7263
|
-
}
|
|
7264
|
-
}));
|
|
7265
|
-
}, []),
|
|
7266
|
-
setMatches: useCallback((matches, currentIndex = 0) => {
|
|
7267
|
-
const newIndex = Math.max(0, Math.min(currentIndex, matches.length - 1));
|
|
7268
|
-
setState((prev) => ({
|
|
7269
|
-
...prev,
|
|
7270
|
-
matches,
|
|
7271
|
-
currentIndex: matches.length > 0 ? newIndex : 0
|
|
7272
|
-
}));
|
|
7273
|
-
hookOptions?.onMatchesChange?.(matches);
|
|
7274
|
-
if (matches.length > 0) hookOptions?.onCurrentMatchChange?.(matches[newIndex] ?? null, newIndex);
|
|
7275
|
-
else hookOptions?.onCurrentMatchChange?.(null, -1);
|
|
7276
|
-
}, [hookOptions]),
|
|
7277
|
-
goToNextMatch: useCallback(() => {
|
|
7278
|
-
let newIndex = 0;
|
|
7279
|
-
setState((prev) => {
|
|
7280
|
-
if (prev.matches.length === 0) return prev;
|
|
7281
|
-
newIndex = (prev.currentIndex + 1) % prev.matches.length;
|
|
7282
|
-
return {
|
|
7283
|
-
...prev,
|
|
7284
|
-
currentIndex: newIndex
|
|
7285
|
-
};
|
|
7286
|
-
});
|
|
7287
|
-
return newIndex;
|
|
7288
|
-
}, []),
|
|
7289
|
-
goToPreviousMatch: useCallback(() => {
|
|
7290
|
-
let newIndex = 0;
|
|
7291
|
-
setState((prev) => {
|
|
7292
|
-
if (prev.matches.length === 0) return prev;
|
|
7293
|
-
newIndex = prev.currentIndex === 0 ? prev.matches.length - 1 : prev.currentIndex - 1;
|
|
7294
|
-
return {
|
|
7295
|
-
...prev,
|
|
7296
|
-
currentIndex: newIndex
|
|
7297
|
-
};
|
|
7298
|
-
});
|
|
7299
|
-
return newIndex;
|
|
7300
|
-
}, []),
|
|
7301
|
-
goToMatch: useCallback((index) => {
|
|
7302
|
-
setState((prev) => {
|
|
7303
|
-
if (prev.matches.length === 0 || index < 0 || index >= prev.matches.length) return prev;
|
|
7304
|
-
return {
|
|
7305
|
-
...prev,
|
|
7306
|
-
currentIndex: index
|
|
7307
|
-
};
|
|
7308
|
-
});
|
|
7309
|
-
}, []),
|
|
7310
|
-
getCurrentMatch: useCallback(() => {
|
|
7311
|
-
if (state.matches.length === 0) return null;
|
|
7312
|
-
return state.matches[state.currentIndex] || null;
|
|
7313
|
-
}, [state.matches, state.currentIndex]),
|
|
7314
|
-
hasMatches: useCallback(() => state.matches.length > 0, [state.matches.length])
|
|
7315
|
-
};
|
|
7316
|
-
}
|
|
7317
|
-
function closedDialogState(mode) {
|
|
7318
|
-
return {
|
|
7319
|
-
dialog: { status: "closed" },
|
|
7320
|
-
lastMode: mode
|
|
7321
|
-
};
|
|
7322
|
-
}
|
|
7323
|
-
function openDialogState(mode) {
|
|
7324
|
-
if (mode === "replace") return {
|
|
7325
|
-
dialog: {
|
|
7326
|
-
status: "open",
|
|
7327
|
-
mode: "replace"
|
|
7328
|
-
},
|
|
7329
|
-
lastMode: "replace"
|
|
7330
|
-
};
|
|
7331
|
-
return {
|
|
7332
|
-
dialog: {
|
|
7333
|
-
status: "open",
|
|
7334
|
-
mode: "find"
|
|
7335
|
-
},
|
|
7336
|
-
lastMode: "find"
|
|
7337
|
-
};
|
|
7338
|
-
}
|
|
7339
|
-
//#endregion
|
|
7340
6505
|
//#region src/components/DocumentOutline.tsx
|
|
7341
6506
|
const DocumentOutline = ({ headings, scrollContainerRef, topOffset, docSize, onHeadingClick }) => {
|
|
7342
6507
|
const OutlineRail = useFolioUI().OutlineRail;
|
|
@@ -7417,12 +6582,12 @@ const DocumentOutline = ({ headings, scrollContainerRef, topOffset, docSize, onH
|
|
|
7417
6582
|
};
|
|
7418
6583
|
//#endregion
|
|
7419
6584
|
//#region src/components/DocxEditorDialogs.tsx
|
|
7420
|
-
const FindReplaceDialog = lazy(() => import("./FindReplaceDialog-
|
|
7421
|
-
const TablePropertiesDialog = lazy(() => import("./TablePropertiesDialog-
|
|
7422
|
-
const ImagePositionDialog = lazy(() => import("./ImagePositionDialog-
|
|
7423
|
-
const ImagePropertiesDialog = lazy(() => import("./ImagePropertiesDialog-
|
|
7424
|
-
const FootnotePropertiesDialog = lazy(() => import("./FootnotePropertiesDialog-
|
|
7425
|
-
const PageSetupDialog = lazy(() => import("./PageSetupDialog-
|
|
6585
|
+
const FindReplaceDialog = lazy(() => import("./FindReplaceDialog-DLdBekSR.js").then((n) => n.n).then((m) => ({ default: m.FindReplaceDialog })));
|
|
6586
|
+
const TablePropertiesDialog = lazy(() => import("./TablePropertiesDialog-Dw8gvL78.js").then((n) => n.n).then((m) => ({ default: m.TablePropertiesDialog })));
|
|
6587
|
+
const ImagePositionDialog = lazy(() => import("./ImagePositionDialog-BMuO9rLT.js").then((n) => n.n).then((m) => ({ default: m.ImagePositionDialog })));
|
|
6588
|
+
const ImagePropertiesDialog = lazy(() => import("./ImagePropertiesDialog-C8iEgdmN.js").then((n) => n.n).then((m) => ({ default: m.ImagePropertiesDialog })));
|
|
6589
|
+
const FootnotePropertiesDialog = lazy(() => import("./FootnotePropertiesDialog-CUjq9c6H.js").then((n) => n.n).then((m) => ({ default: m.FootnotePropertiesDialog })));
|
|
6590
|
+
const PageSetupDialog = lazy(() => import("./PageSetupDialog-BKsSMCGb.js").then((n) => n.n).then((m) => ({ default: m.PageSetupDialog })));
|
|
7426
6591
|
function DocxEditorDialogs({ findReplace, tableProperties, imagePosition, imageProperties, pageSetup, footnoteProperties }) {
|
|
7427
6592
|
return /* @__PURE__ */ jsxs(Suspense, {
|
|
7428
6593
|
fallback: null,
|
|
@@ -9115,7 +8280,7 @@ function useContextMenu({ pagedEditorRef }) {
|
|
|
9115
8280
|
* effects that drive a load, the original buffer ref, and re-binding the host
|
|
9116
8281
|
* callbacks each render.
|
|
9117
8282
|
*/
|
|
9118
|
-
const useDocumentLoader = ({ documentBuffer, initialDocument, history, onError, onCompatibilityChange, onReset, setDocumentLoadState }) => {
|
|
8283
|
+
const useDocumentLoader = ({ documentBuffer, initialDocument, password, history, onError, onCompatibilityChange, onReset, setDocumentLoadState }) => {
|
|
9119
8284
|
/** Original DOCX buffer kept for selective save / full repack. */
|
|
9120
8285
|
const originalBufferRef = useRef(null);
|
|
9121
8286
|
const [{ manager, api }] = useState(() => {
|
|
@@ -9152,15 +8317,20 @@ const useDocumentLoader = ({ documentBuffer, initialDocument, history, onError,
|
|
|
9152
8317
|
api.loadParsedDocument(source.document);
|
|
9153
8318
|
return;
|
|
9154
8319
|
}
|
|
9155
|
-
api.loadBuffer(source.buffer);
|
|
8320
|
+
api.loadBuffer(source.buffer, { password });
|
|
9156
8321
|
}, [
|
|
9157
8322
|
documentBuffer,
|
|
9158
8323
|
initialDocument,
|
|
8324
|
+
password,
|
|
9159
8325
|
api
|
|
9160
8326
|
]);
|
|
9161
8327
|
useEffect(() => {
|
|
9162
|
-
if (
|
|
9163
|
-
|
|
8328
|
+
if (history.state?.originalBuffer) {
|
|
8329
|
+
originalBufferRef.current = history.state.originalBuffer;
|
|
8330
|
+
return;
|
|
8331
|
+
}
|
|
8332
|
+
if (documentBuffer instanceof ArrayBuffer) originalBufferRef.current = documentBuffer;
|
|
8333
|
+
}, [history.state, documentBuffer]);
|
|
9164
8334
|
return {
|
|
9165
8335
|
loadBuffer: api.loadBuffer,
|
|
9166
8336
|
loadParsedDocument: api.loadParsedDocument,
|
|
@@ -10958,7 +10128,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
|
|
|
10958
10128
|
* - Error boundary
|
|
10959
10129
|
* - Loading states
|
|
10960
10130
|
*/
|
|
10961
|
-
const CommentsSidebar = lazy(() => import("./CommentsSidebar-
|
|
10131
|
+
const CommentsSidebar = lazy(() => import("./CommentsSidebar-_utmEkA9.js").then((m) => ({ default: m.CommentsSidebar })));
|
|
10962
10132
|
const TextContextMenu = lazy(() => import("./TextContextMenu-CG0V37wi.js").then((m) => ({ default: m.TextContextMenu })));
|
|
10963
10133
|
const loadAttemptSelectiveSave = async () => {
|
|
10964
10134
|
const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
|
|
@@ -11038,7 +10208,7 @@ function areActiveTrackedChangesEqual(a, b) {
|
|
|
11038
10208
|
/**
|
|
11039
10209
|
* DocxEditor - Complete DOCX editor component
|
|
11040
10210
|
*/
|
|
11041
|
-
const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, document: initialDocument, documentKey, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, showMarginGuides: _showMarginGuides = false, marginGuideColor: _marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy: _onCopy, onCut: _onCut, onPaste: _onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, featureFlags, onSelectiveSaveTripwire }, ref) {
|
|
10211
|
+
const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, documentKey, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, showMarginGuides: _showMarginGuides = false, marginGuideColor: _marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy: _onCopy, onCut: _onCut, onPaste: _onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, featureFlags, onSelectiveSaveTripwire }, ref) {
|
|
11042
10212
|
const t = useTranslations("folio");
|
|
11043
10213
|
useEffect(() => {
|
|
11044
10214
|
const onClipboardReadError = () => {
|
|
@@ -11356,6 +10526,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, document: in
|
|
|
11356
10526
|
const { loadBuffer, loadParsedDocument, originalBufferRef } = useDocumentLoader({
|
|
11357
10527
|
documentBuffer: documentBuffer ?? null,
|
|
11358
10528
|
initialDocument: initialDocument ?? null,
|
|
10529
|
+
password,
|
|
11359
10530
|
history,
|
|
11360
10531
|
onError,
|
|
11361
10532
|
onCompatibilityChange,
|
|
@@ -13557,4 +12728,4 @@ const renderAsync = (input, container, options = {}) => {
|
|
|
13557
12728
|
});
|
|
13558
12729
|
};
|
|
13559
12730
|
//#endregion
|
|
13560
|
-
export {
|
|
12731
|
+
export { formatZoom as a, FormattingBar as c, containedHandler as d, clampZoom as i, ZoomControl as l, DocxEditor as n, parseZoom as o, ZOOM_PRESETS as r, useWheelZoom as s, renderAsync as t, AutocompleteCaretOverlay as u };
|