@stll/folio-react 0.0.1-placeholder.0 → 0.1.1

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.
@@ -0,0 +1,358 @@
1
+ import { r as useFolioUI } from "./folio-ui-o_rftArH.js";
2
+ import "./useFindReplace-MZ8wi31A.js";
3
+ import React, { useCallback, useEffect, useRef, useState } from "react";
4
+ import { ChevronDownIcon, ChevronUpIcon, SearchIcon, XIcon } from "lucide-react";
5
+ import { useTranslations } from "use-intl";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import "@stll/folio-core/managers/FindReplaceManager";
8
+ //#region src/components/dialogs/findReplaceDialogBehavior.ts
9
+ const getFindDialogOpenBehavior = ({ isOpen, initialSearchText }) => {
10
+ if (!isOpen) return {
11
+ type: "closed",
12
+ shouldClearHighlights: true
13
+ };
14
+ return {
15
+ type: "open",
16
+ searchText: initialSearchText,
17
+ shouldFindInitialText: initialSearchText.length > 0
18
+ };
19
+ };
20
+ const shouldRefreshFindDialogSearch = ({ isOpen, searchText }) => isOpen && searchText.trim().length > 0;
21
+ //#endregion
22
+ //#region src/components/dialogs/findReplaceDialogLayout.ts
23
+ const FIND_REPLACE_DIALOG_TOP = "var(--folio-find-replace-top, 7rem)";
24
+ const FIND_REPLACE_DIALOG_LEFT = "var(--folio-find-replace-left, 5.5rem)";
25
+ const FIND_REPLACE_DIALOG_RIGHT = "var(--folio-find-replace-right, 0px)";
26
+ function getFindReplaceOverlayStyle(style) {
27
+ return {
28
+ top: FIND_REPLACE_DIALOG_TOP,
29
+ left: FIND_REPLACE_DIALOG_LEFT,
30
+ right: FIND_REPLACE_DIALOG_RIGHT,
31
+ ...style
32
+ };
33
+ }
34
+ //#endregion
35
+ //#region src/components/dialogs/findReplaceInteraction.ts
36
+ function getFindEnterAction({ searchText, result, shiftKey }) {
37
+ if (!searchText.trim() || !result || result.totalCount === 0) return "search";
38
+ return shiftKey ? "previous" : "next";
39
+ }
40
+ //#endregion
41
+ //#region src/components/dialogs/FindReplaceDialog.tsx
42
+ /**
43
+ * Find and Replace Dialog Component
44
+ *
45
+ * Modal dialog for searching and replacing text in the document.
46
+ * Supports find, find next/previous, replace, and replace all operations.
47
+ *
48
+ * Logic and utilities are in separate files:
49
+ * - findReplaceUtils.ts — Pure search/replace functions and types
50
+ * - useFindReplace.ts — React hook for dialog state management
51
+ */
52
+ /**
53
+ * FindReplaceDialog component - Modal for finding and replacing text
54
+ */
55
+ function FindReplaceDialog({ isOpen, onClose, onFind, onFindNext, onFindPrevious, onHighlightMatches, onClearHighlights, initialSearchText = "", currentResult, className, style }) {
56
+ const id = React.useId();
57
+ const t = useTranslations("folio");
58
+ const { Button, Input, Checkbox } = useFolioUI();
59
+ const [searchText, setSearchText] = useState("");
60
+ const [matchCase, setMatchCase] = useState(false);
61
+ const [matchWholeWord, setMatchWholeWord] = useState(false);
62
+ const [result, setResult] = useState(null);
63
+ const searchInputRef = useRef(null);
64
+ const latestFindCallbacksRef = useRef({
65
+ onFind,
66
+ onHighlightMatches,
67
+ onClearHighlights
68
+ });
69
+ latestFindCallbacksRef.current = {
70
+ onFind,
71
+ onHighlightMatches,
72
+ onClearHighlights
73
+ };
74
+ const latestFindOptionsRef = useRef({
75
+ matchCase,
76
+ matchWholeWord
77
+ });
78
+ latestFindOptionsRef.current = {
79
+ matchCase,
80
+ matchWholeWord
81
+ };
82
+ const latestSearchStateRef = useRef({
83
+ isOpen,
84
+ searchText
85
+ });
86
+ latestSearchStateRef.current = {
87
+ isOpen,
88
+ searchText
89
+ };
90
+ useEffect(() => {
91
+ if (currentResult !== void 0) setResult(currentResult);
92
+ }, [currentResult]);
93
+ useEffect(() => {
94
+ const behavior = getFindDialogOpenBehavior({
95
+ isOpen,
96
+ initialSearchText
97
+ });
98
+ if (behavior.type === "closed") {
99
+ latestFindCallbacksRef.current.onClearHighlights?.();
100
+ return;
101
+ }
102
+ setSearchText(behavior.searchText);
103
+ setResult(null);
104
+ setTimeout(() => {
105
+ searchInputRef.current?.focus();
106
+ searchInputRef.current?.select();
107
+ }, 100);
108
+ if (behavior.shouldFindInitialText) {
109
+ const callbacks = latestFindCallbacksRef.current;
110
+ const options = latestFindOptionsRef.current;
111
+ const searchResult = callbacks.onFind(behavior.searchText, {
112
+ matchCase: options.matchCase,
113
+ matchWholeWord: options.matchWholeWord
114
+ });
115
+ setResult(searchResult);
116
+ if (searchResult?.matches && callbacks.onHighlightMatches) callbacks.onHighlightMatches(searchResult.matches);
117
+ }
118
+ }, [isOpen, initialSearchText]);
119
+ const performSearch = useCallback(() => {
120
+ if (!searchText.trim()) {
121
+ setResult(null);
122
+ if (onClearHighlights) onClearHighlights();
123
+ return;
124
+ }
125
+ const searchResult = onFind(searchText, {
126
+ matchCase,
127
+ matchWholeWord
128
+ });
129
+ setResult(searchResult);
130
+ if (searchResult?.matches && onHighlightMatches) onHighlightMatches(searchResult.matches);
131
+ else if (onClearHighlights) onClearHighlights();
132
+ }, [
133
+ searchText,
134
+ matchCase,
135
+ matchWholeWord,
136
+ onFind,
137
+ onHighlightMatches,
138
+ onClearHighlights
139
+ ]);
140
+ const performSearchRef = useRef(performSearch);
141
+ performSearchRef.current = performSearch;
142
+ useEffect(() => {
143
+ if (shouldRefreshFindDialogSearch(latestSearchStateRef.current)) performSearchRef.current();
144
+ }, [matchCase, matchWholeWord]);
145
+ useEffect(() => {
146
+ if (!isOpen) return;
147
+ if (!searchText.trim()) {
148
+ setResult(null);
149
+ onClearHighlights?.();
150
+ return;
151
+ }
152
+ const timeout = setTimeout(performSearch, 120);
153
+ return () => clearTimeout(timeout);
154
+ }, [
155
+ isOpen,
156
+ searchText,
157
+ performSearch,
158
+ onClearHighlights
159
+ ]);
160
+ const handleSearchChange = useCallback((e) => {
161
+ setSearchText(e.target.value);
162
+ setResult(null);
163
+ }, []);
164
+ const handleFindNext = useCallback(() => {
165
+ if (!searchText.trim()) {
166
+ performSearch();
167
+ return;
168
+ }
169
+ if (!result || result.totalCount === 0) {
170
+ performSearch();
171
+ return;
172
+ }
173
+ if (onFindNext()) {
174
+ const newIndex = (result.currentIndex + 1) % result.totalCount;
175
+ setResult({
176
+ ...result,
177
+ currentIndex: newIndex
178
+ });
179
+ }
180
+ }, [
181
+ searchText,
182
+ result,
183
+ performSearch,
184
+ onFindNext
185
+ ]);
186
+ const handleFindPrevious = useCallback(() => {
187
+ if (!searchText.trim()) {
188
+ performSearch();
189
+ return;
190
+ }
191
+ if (!result || result.totalCount === 0) {
192
+ performSearch();
193
+ return;
194
+ }
195
+ if (onFindPrevious()) {
196
+ const newIndex = result.currentIndex === 0 ? result.totalCount - 1 : result.currentIndex - 1;
197
+ setResult({
198
+ ...result,
199
+ currentIndex: newIndex
200
+ });
201
+ }
202
+ }, [
203
+ searchText,
204
+ result,
205
+ performSearch,
206
+ onFindPrevious
207
+ ]);
208
+ const handleSearchKeyDown = useCallback((e) => {
209
+ if (e.key === "Enter") {
210
+ e.preventDefault();
211
+ const action = getFindEnterAction({
212
+ searchText,
213
+ result,
214
+ shiftKey: e.shiftKey
215
+ });
216
+ if (action === "search") {
217
+ performSearch();
218
+ return;
219
+ }
220
+ if (action === "previous") {
221
+ handleFindPrevious();
222
+ return;
223
+ }
224
+ handleFindNext();
225
+ } else if (e.key === "Escape") onClose();
226
+ }, [
227
+ searchText,
228
+ result,
229
+ performSearch,
230
+ handleFindPrevious,
231
+ handleFindNext,
232
+ onClose
233
+ ]);
234
+ const handleOverlayClick = useCallback((e) => {
235
+ if (e.target === e.currentTarget) {}
236
+ }, []);
237
+ const handleDialogKeyDown = useCallback((e) => {
238
+ if (e.key === "Escape") onClose();
239
+ }, [onClose]);
240
+ if (!isOpen) return null;
241
+ const hasMatches = result && result.totalCount > 0;
242
+ const noMatches = result && result.totalCount === 0 && searchText.trim();
243
+ const overlayStyle = getFindReplaceOverlayStyle(style);
244
+ const titleId = `${id}-find-replace-dialog-title`;
245
+ const findTextId = `${id}-find-text`;
246
+ return /* @__PURE__ */ jsx("div", {
247
+ role: "presentation",
248
+ className: `docx-find-replace-dialog-overlay pointer-events-none fixed end-0 bottom-0 z-[10002] flex items-start justify-end bg-transparent ${className || ""}`,
249
+ style: overlayStyle,
250
+ "data-slot": "folio-find-replace-overlay",
251
+ onClick: handleOverlayClick,
252
+ onKeyDown: handleDialogKeyDown,
253
+ children: /* @__PURE__ */ jsxs("div", {
254
+ className: "docx-find-replace-dialog bg-popover text-popover-foreground pointer-events-auto me-4 mt-3 w-[min(440px,calc(100vw-var(--folio-find-replace-left,5.5rem)-2rem))] rounded-lg border shadow-xl",
255
+ "data-testid": "find-replace-dialog",
256
+ role: "dialog",
257
+ "aria-modal": "false",
258
+ "aria-labelledby": titleId,
259
+ children: [/* @__PURE__ */ jsxs("div", {
260
+ className: "bg-muted/30 flex items-center justify-between gap-3 border-b px-3 py-2",
261
+ children: [/* @__PURE__ */ jsxs("h2", {
262
+ className: "flex min-w-0 items-center gap-2 text-sm font-medium",
263
+ id: titleId,
264
+ children: [/* @__PURE__ */ jsx(SearchIcon, { className: "text-muted-foreground size-4 shrink-0" }), /* @__PURE__ */ jsx("span", {
265
+ className: "truncate",
266
+ children: t("findReplace.find")
267
+ })]
268
+ }), /* @__PURE__ */ jsx(Button, {
269
+ onClick: onClose,
270
+ "aria-label": t("findReplace.close"),
271
+ size: "icon-xs",
272
+ title: t("findReplace.close"),
273
+ variant: "ghost",
274
+ children: /* @__PURE__ */ jsx(XIcon, {})
275
+ })]
276
+ }), /* @__PURE__ */ jsxs("div", {
277
+ className: "space-y-2 p-3",
278
+ children: [
279
+ /* @__PURE__ */ jsxs("div", {
280
+ className: "grid grid-cols-[4.5rem_minmax(0,1fr)_auto] items-center gap-2",
281
+ children: [
282
+ /* @__PURE__ */ jsx("label", {
283
+ className: "text-muted-foreground text-xs font-medium",
284
+ htmlFor: findTextId,
285
+ children: t("findReplace.find")
286
+ }),
287
+ /* @__PURE__ */ jsx(Input, {
288
+ ref: searchInputRef,
289
+ id: findTextId,
290
+ nativeInput: true,
291
+ type: "text",
292
+ className: "h-8",
293
+ size: "sm",
294
+ value: searchText,
295
+ onChange: handleSearchChange,
296
+ onKeyDown: handleSearchKeyDown,
297
+ onBlur: () => {
298
+ if (searchText.trim() && !result) performSearch();
299
+ },
300
+ placeholder: t("findReplace.findPlaceholder"),
301
+ "aria-label": t("findReplace.findText")
302
+ }),
303
+ /* @__PURE__ */ jsxs("div", {
304
+ className: "flex items-center gap-0.5",
305
+ children: [/* @__PURE__ */ jsx(Button, {
306
+ onClick: handleFindPrevious,
307
+ disabled: !hasMatches,
308
+ "aria-label": t("findReplace.previous"),
309
+ title: t("findReplace.previousShortcut"),
310
+ size: "icon-xs",
311
+ variant: "ghost",
312
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, {})
313
+ }), /* @__PURE__ */ jsx(Button, {
314
+ onClick: handleFindNext,
315
+ disabled: !hasMatches,
316
+ "aria-label": t("findReplace.next"),
317
+ title: t("findReplace.nextShortcut"),
318
+ size: "icon-xs",
319
+ variant: "ghost",
320
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
321
+ })]
322
+ })
323
+ ]
324
+ }),
325
+ hasMatches && /* @__PURE__ */ jsx("div", {
326
+ className: "text-muted-foreground ms-20 text-xs tabular-nums",
327
+ children: t("findReplace.matchCounter", {
328
+ current: String(result.currentIndex + 1),
329
+ total: String(result.totalCount)
330
+ })
331
+ }),
332
+ noMatches && /* @__PURE__ */ jsx("div", {
333
+ className: "text-destructive ms-20 text-xs",
334
+ children: t("findReplace.noResults")
335
+ }),
336
+ /* @__PURE__ */ jsxs("div", {
337
+ className: "ms-20 flex flex-wrap items-center gap-x-4 gap-y-2",
338
+ children: [/* @__PURE__ */ jsxs("label", {
339
+ className: "text-muted-foreground flex items-center gap-2 text-xs",
340
+ children: [/* @__PURE__ */ jsx(Checkbox, {
341
+ checked: matchCase,
342
+ onCheckedChange: setMatchCase
343
+ }), t("findReplace.matchCase")]
344
+ }), /* @__PURE__ */ jsxs("label", {
345
+ className: "text-muted-foreground flex items-center gap-2 text-xs",
346
+ children: [/* @__PURE__ */ jsx(Checkbox, {
347
+ checked: matchWholeWord,
348
+ onCheckedChange: setMatchWholeWord
349
+ }), t("findReplace.wholeWords")]
350
+ })]
351
+ })
352
+ ]
353
+ })]
354
+ })
355
+ });
356
+ }
357
+ //#endregion
358
+ export { FindReplaceDialog };
@@ -0,0 +1,265 @@
1
+ import { r as useFolioUI } from "./folio-ui-o_rftArH.js";
2
+ import { useId, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/dialogs/FootnotePropertiesDialog.tsx
5
+ /**
6
+ * Footnote & Endnote Properties Dialog
7
+ *
8
+ * Edits position, numbering format, start number, and restart rules.
9
+ */
10
+ const numberFormatOptions = [
11
+ {
12
+ value: "decimal",
13
+ label: "1, 2, 3, ..."
14
+ },
15
+ {
16
+ value: "lowerRoman",
17
+ label: "i, ii, iii, ..."
18
+ },
19
+ {
20
+ value: "upperRoman",
21
+ label: "I, II, III, ..."
22
+ },
23
+ {
24
+ value: "lowerLetter",
25
+ label: "a, b, c, ..."
26
+ },
27
+ {
28
+ value: "upperLetter",
29
+ label: "A, B, C, ..."
30
+ },
31
+ {
32
+ value: "chicago",
33
+ label: "*, †, ‡, ..."
34
+ }
35
+ ];
36
+ function FootnotePropertiesDialog({ isOpen, onClose, onApply, footnotePr, endnotePr }) {
37
+ const { Root: Dialog, Portal: DialogPortal, Backdrop: DialogBackdrop, Popup: DialogPopup, Title: DialogTitle, Close: DialogClose } = useFolioUI().Dialog;
38
+ const id = useId();
39
+ const [fnPosition, setFnPosition] = useState(footnotePr?.position ?? "pageBottom");
40
+ const [fnNumFmt, setFnNumFmt] = useState(footnotePr?.numFmt ?? "decimal");
41
+ const [fnNumStart, setFnNumStart] = useState(footnotePr?.numStart ?? 1);
42
+ const [fnRestart, setFnRestart] = useState(footnotePr?.numRestart ?? "continuous");
43
+ const [enPosition, setEnPosition] = useState(endnotePr?.position ?? "docEnd");
44
+ const [enNumFmt, setEnNumFmt] = useState(endnotePr?.numFmt ?? "lowerRoman");
45
+ const [enNumStart, setEnNumStart] = useState(endnotePr?.numStart ?? 1);
46
+ const [enRestart, setEnRestart] = useState(endnotePr?.numRestart ?? "continuous");
47
+ const handleApply = () => {
48
+ onApply({
49
+ position: fnPosition,
50
+ numFmt: fnNumFmt,
51
+ numStart: fnNumStart,
52
+ numRestart: fnRestart
53
+ }, {
54
+ position: enPosition,
55
+ numFmt: enNumFmt,
56
+ numStart: enNumStart,
57
+ numRestart: enRestart
58
+ });
59
+ onClose();
60
+ };
61
+ const labelCls = "block text-muted-foreground mb-1 text-xs";
62
+ const selectCls = "border-input bg-background text-foreground mb-2 w-full rounded border px-2 py-1 text-[13px] outline-none";
63
+ const inputCls = "border-input bg-background text-foreground w-[60px] rounded border px-2 py-1 text-[13px] outline-none";
64
+ const sectionCls = "mb-4 rounded border p-3";
65
+ const fieldIds = {
66
+ fnPosition: `${id}-fn-position`,
67
+ fnNumFmt: `${id}-fn-num-fmt`,
68
+ fnStartAt: `${id}-fn-start-at`,
69
+ fnNumbering: `${id}-fn-numbering`,
70
+ enPosition: `${id}-en-position`,
71
+ enNumFmt: `${id}-en-num-fmt`,
72
+ enStartAt: `${id}-en-start-at`,
73
+ enNumbering: `${id}-en-numbering`
74
+ };
75
+ return /* @__PURE__ */ jsx(Dialog, {
76
+ open: isOpen,
77
+ onOpenChange: (open) => {
78
+ if (!open) onClose();
79
+ },
80
+ children: /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogBackdrop, { className: "fixed inset-0 z-[10000] bg-black/50" }), /* @__PURE__ */ jsxs(DialogPopup, {
81
+ className: "bg-popover fixed start-1/2 top-1/2 z-[10001] w-full max-w-[500px] min-w-[400px] -translate-x-1/2 -translate-y-1/2 rounded-lg border shadow-xl",
82
+ children: [
83
+ /* @__PURE__ */ jsx(DialogTitle, {
84
+ className: "border-b px-5 py-3 text-base font-semibold",
85
+ children: "Footnote & Endnote Properties"
86
+ }),
87
+ /* @__PURE__ */ jsxs("div", {
88
+ className: "flex flex-col gap-3 px-5 py-4",
89
+ children: [/* @__PURE__ */ jsxs("div", {
90
+ className: sectionCls,
91
+ children: [
92
+ /* @__PURE__ */ jsx("h4", {
93
+ className: "mb-2 text-sm font-semibold",
94
+ children: "Footnotes"
95
+ }),
96
+ /* @__PURE__ */ jsx("label", {
97
+ htmlFor: fieldIds.fnPosition,
98
+ className: labelCls,
99
+ children: "Position"
100
+ }),
101
+ /* @__PURE__ */ jsxs("select", {
102
+ id: fieldIds.fnPosition,
103
+ className: selectCls,
104
+ value: fnPosition,
105
+ onChange: (e) => setFnPosition(e.target.value),
106
+ children: [/* @__PURE__ */ jsx("option", {
107
+ value: "pageBottom",
108
+ children: "Bottom of page"
109
+ }), /* @__PURE__ */ jsx("option", {
110
+ value: "beneathText",
111
+ children: "Below text"
112
+ })]
113
+ }),
114
+ /* @__PURE__ */ jsx("label", {
115
+ htmlFor: fieldIds.fnNumFmt,
116
+ className: labelCls,
117
+ children: "Number format"
118
+ }),
119
+ /* @__PURE__ */ jsx("select", {
120
+ id: fieldIds.fnNumFmt,
121
+ className: selectCls,
122
+ value: fnNumFmt,
123
+ onChange: (e) => setFnNumFmt(e.target.value),
124
+ children: numberFormatOptions.map((o) => /* @__PURE__ */ jsx("option", {
125
+ value: o.value,
126
+ children: o.label
127
+ }, o.value))
128
+ }),
129
+ /* @__PURE__ */ jsxs("div", {
130
+ className: "flex items-center gap-3",
131
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
132
+ htmlFor: fieldIds.fnStartAt,
133
+ className: labelCls,
134
+ children: "Start at"
135
+ }), /* @__PURE__ */ jsx("input", {
136
+ id: fieldIds.fnStartAt,
137
+ type: "number",
138
+ min: 1,
139
+ className: inputCls,
140
+ value: fnNumStart,
141
+ onChange: (e) => setFnNumStart(Number.parseInt(e.target.value, 10) || 1)
142
+ })] }), /* @__PURE__ */ jsxs("div", {
143
+ className: "flex-1",
144
+ children: [/* @__PURE__ */ jsx("label", {
145
+ htmlFor: fieldIds.fnNumbering,
146
+ className: labelCls,
147
+ children: "Numbering"
148
+ }), /* @__PURE__ */ jsxs("select", {
149
+ id: fieldIds.fnNumbering,
150
+ className: selectCls,
151
+ value: fnRestart,
152
+ onChange: (e) => setFnRestart(e.target.value),
153
+ children: [
154
+ /* @__PURE__ */ jsx("option", {
155
+ value: "continuous",
156
+ children: "Continuous"
157
+ }),
158
+ /* @__PURE__ */ jsx("option", {
159
+ value: "eachSect",
160
+ children: "Restart each section"
161
+ }),
162
+ /* @__PURE__ */ jsx("option", {
163
+ value: "eachPage",
164
+ children: "Restart each page"
165
+ })
166
+ ]
167
+ })]
168
+ })]
169
+ })
170
+ ]
171
+ }), /* @__PURE__ */ jsxs("div", {
172
+ className: sectionCls,
173
+ children: [
174
+ /* @__PURE__ */ jsx("h4", {
175
+ className: "mb-2 text-sm font-semibold",
176
+ children: "Endnotes"
177
+ }),
178
+ /* @__PURE__ */ jsx("label", {
179
+ htmlFor: fieldIds.enPosition,
180
+ className: labelCls,
181
+ children: "Position"
182
+ }),
183
+ /* @__PURE__ */ jsxs("select", {
184
+ id: fieldIds.enPosition,
185
+ className: selectCls,
186
+ value: enPosition,
187
+ onChange: (e) => setEnPosition(e.target.value),
188
+ children: [/* @__PURE__ */ jsx("option", {
189
+ value: "docEnd",
190
+ children: "End of document"
191
+ }), /* @__PURE__ */ jsx("option", {
192
+ value: "sectEnd",
193
+ children: "End of section"
194
+ })]
195
+ }),
196
+ /* @__PURE__ */ jsx("label", {
197
+ htmlFor: fieldIds.enNumFmt,
198
+ className: labelCls,
199
+ children: "Number format"
200
+ }),
201
+ /* @__PURE__ */ jsx("select", {
202
+ id: fieldIds.enNumFmt,
203
+ className: selectCls,
204
+ value: enNumFmt,
205
+ onChange: (e) => setEnNumFmt(e.target.value),
206
+ children: numberFormatOptions.map((o) => /* @__PURE__ */ jsx("option", {
207
+ value: o.value,
208
+ children: o.label
209
+ }, o.value))
210
+ }),
211
+ /* @__PURE__ */ jsxs("div", {
212
+ className: "flex items-center gap-3",
213
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
214
+ htmlFor: fieldIds.enStartAt,
215
+ className: labelCls,
216
+ children: "Start at"
217
+ }), /* @__PURE__ */ jsx("input", {
218
+ id: fieldIds.enStartAt,
219
+ type: "number",
220
+ min: 1,
221
+ className: inputCls,
222
+ value: enNumStart,
223
+ onChange: (e) => setEnNumStart(Number.parseInt(e.target.value, 10) || 1)
224
+ })] }), /* @__PURE__ */ jsxs("div", {
225
+ className: "flex-1",
226
+ children: [/* @__PURE__ */ jsx("label", {
227
+ htmlFor: fieldIds.enNumbering,
228
+ className: labelCls,
229
+ children: "Numbering"
230
+ }), /* @__PURE__ */ jsxs("select", {
231
+ id: fieldIds.enNumbering,
232
+ className: selectCls,
233
+ value: enRestart,
234
+ onChange: (e) => setEnRestart(e.target.value),
235
+ children: [/* @__PURE__ */ jsx("option", {
236
+ value: "continuous",
237
+ children: "Continuous"
238
+ }), /* @__PURE__ */ jsx("option", {
239
+ value: "eachSect",
240
+ children: "Restart each section"
241
+ })]
242
+ })]
243
+ })]
244
+ })
245
+ ]
246
+ })]
247
+ }),
248
+ /* @__PURE__ */ jsxs("div", {
249
+ className: "flex justify-end gap-2 border-t px-5 py-3",
250
+ children: [/* @__PURE__ */ jsx(DialogClose, {
251
+ className: "border-input rounded border px-4 py-1.5 text-[13px]",
252
+ children: "Cancel"
253
+ }), /* @__PURE__ */ jsx("button", {
254
+ className: "bg-primary text-primary-foreground rounded px-4 py-1.5 text-[13px] font-medium",
255
+ onClick: handleApply,
256
+ type: "button",
257
+ children: "Apply"
258
+ })]
259
+ })
260
+ ]
261
+ })] })
262
+ });
263
+ }
264
+ //#endregion
265
+ export { FootnotePropertiesDialog };