@stll/folio-react 0.25.2 → 0.26.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.
Files changed (26) hide show
  1. package/README.md +1 -1
  2. package/dist/{CommentsSidebar-IR9uTkkk.js → CommentsSidebar-C4IpXib8.js} +53 -33
  3. package/dist/{FindReplaceDialog-BUwFQWaq.js → FindReplaceDialog-LlVMe3EW.js} +148 -107
  4. package/dist/{FootnotePropertiesDialog-6XdO0zBH.js → FootnotePropertiesDialog-D73t3LNP.js} +1 -1
  5. package/dist/ImagePositionDialog-Cwt6R8iM.js +1039 -0
  6. package/dist/ImagePropertiesDialog-GNZLBFLB.js +607 -0
  7. package/dist/{InsertSymbolDialog-Cn_Nifhg.js → InsertSymbolDialog-CeEhkEvc.js} +1 -1
  8. package/dist/PageSetupDialog-DD6IEZAo.js +805 -0
  9. package/dist/SetNumberingValueDialog-CDQGDvP1.js +233 -0
  10. package/dist/TablePropertiesDialog-Vu0HXQz6.js +416 -0
  11. package/dist/{TextContextMenu-Bqth8itn.js → TextContextMenu-DZ3AUFKh.js} +4 -2
  12. package/dist/compat/eigenpal.js +1 -1
  13. package/dist/{dialogs-DZz6gVev.d.ts → dialogs-BENP66Ly.d.ts} +11 -11
  14. package/dist/{dialogs-Dzu4hqRp.js → dialogs-De-oslzU.js} +417 -394
  15. package/dist/dialogs.d.ts +1 -1
  16. package/dist/dialogs.js +8 -8
  17. package/dist/{folio-ui-DO95voaI.js → folio-ui-rCHqCEG6.js} +125 -35
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +10 -10
  20. package/dist/{renderAsync-C0_y_c9Y.js → renderAsync-T2p_qqNU.js} +2843 -2022
  21. package/package.json +4 -4
  22. package/dist/ImagePositionDialog-9q71ka9N.js +0 -1065
  23. package/dist/ImagePropertiesDialog-o79NCGk7.js +0 -613
  24. package/dist/PageSetupDialog-CMdVXCZ-.js +0 -820
  25. package/dist/SetNumberingValueDialog-DOsaSq7e.js +0 -237
  26. package/dist/TablePropertiesDialog-DwPiUj4m.js +0 -421
package/README.md CHANGED
@@ -48,7 +48,7 @@ layout engine, DOCX ↔ Markdown), depend on `@stll/folio-core` directly.
48
48
 
49
49
  ## Peer dependencies
50
50
 
51
- `react` ^18 or ^19 · `react-dom` ^18 or ^19 · `use-intl` >=4
51
+ `react` ^19.2 · `react-dom` ^19.2 · `use-intl` >=4
52
52
 
53
53
  ## Acknowledgements
54
54
 
@@ -1,5 +1,5 @@
1
- import { f as containedHandler, u as useDrawerFocus } from "./renderAsync-C0_y_c9Y.js";
2
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
1
+ import { f as containedHandler, u as useDrawerFocus } from "./renderAsync-T2p_qqNU.js";
2
+ import { useCallback, useEffect, useEffectEvent, useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import { CheckIcon, MoreVerticalIcon } from "lucide-react";
4
4
  import { useLocale, useTranslations } from "use-intl";
5
5
  import { scrollEditorTo } from "@stll/folio-core/paged-layout/editorScrollRoot";
@@ -105,12 +105,14 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
105
105
  const [replyingTo, setReplyingTo] = useState(null);
106
106
  const [replyText, setReplyText] = useState("");
107
107
  const [newCommentText, setNewCommentText] = useState("");
108
- const [expandedCard, setExpandedCard] = useState(null);
108
+ const [expandedCard, setExpandedCard] = useState(activeCommentId === null ? null : `comment-${activeCommentId}`);
109
109
  const [menuOpenFor, setMenuOpenFor] = useState(null);
110
- const [cardPositions, setCardPositions] = useState(/* @__PURE__ */ new Map());
110
+ const [{ positions: cardPositions, knownCards }, setCardGeometry] = useState(() => ({
111
+ positions: /* @__PURE__ */ new Map(),
112
+ knownCards: /* @__PURE__ */ new Set()
113
+ }));
111
114
  const [measuredLeft, setMeasuredLeft] = useState(null);
112
115
  const [initialPositionsDone, setInitialPositionsDone] = useState(false);
113
- const knownCardsRef = useRef(/* @__PURE__ */ new Set());
114
116
  const lastKnownCardPositionsRef = useRef(/* @__PURE__ */ new Map());
115
117
  const sidebarRef = useRef(null);
116
118
  const cardRefs = useRef(/* @__PURE__ */ new Map());
@@ -157,8 +159,13 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
157
159
  const maxVisibleLeft = Math.max(8, offsetParent.clientWidth - SIDEBAR_WIDTH - 8);
158
160
  setMeasuredLeft(Math.max(8, Math.min(rawLeft, maxVisibleLeft)));
159
161
  }, [editorContainerRef, isDrawer]);
162
+ const measureSidebarCommit = useEffectEvent((_layout, measure) => measure());
160
163
  useLayoutEffect(() => {
161
- updateSidebarLeft();
164
+ measureSidebarCommit({
165
+ pageWidth,
166
+ isAddingComment,
167
+ commentCount: comments.length
168
+ }, updateSidebarLeft);
162
169
  }, [
163
170
  updateSidebarLeft,
164
171
  pageWidth,
@@ -257,7 +264,15 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
257
264
  resolvedPositions.set(pos.id, y);
258
265
  lastBottom = y + pos.height;
259
266
  }
260
- setCardPositions((prev) => arePositionMapsEqual(prev, resolvedPositions) ? prev : resolvedPositions);
267
+ setCardGeometry((previous) => {
268
+ if (arePositionMapsEqual(previous.positions, resolvedPositions)) return previous;
269
+ const nextKnownCards = new Set(previous.knownCards);
270
+ for (const cardId_0 of previous.positions.keys()) nextKnownCards.add(cardId_0);
271
+ return {
272
+ positions: resolvedPositions,
273
+ knownCards: nextKnownCards
274
+ };
275
+ });
261
276
  const visiblePositionIds = new Set(resolvedPositions.keys());
262
277
  for (const key of lastKnownCardPositionsRef.current.keys()) if (!visiblePositionIds.has(key) && key !== "new-comment-input") lastKnownCardPositionsRef.current.delete(key);
263
278
  }, [
@@ -326,10 +341,14 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
326
341
  container_2.removeEventListener("scroll", scheduleUpdate);
327
342
  };
328
343
  }, [editorContainerRef, updateCardPositions]);
329
- useEffect(() => {
330
- const raf = requestAnimationFrame(updateCardPositions);
344
+ const measureCardsCommit = useEffectEvent((_layout_0, measure_0) => {
345
+ const raf = requestAnimationFrame(measure_0);
331
346
  return () => cancelAnimationFrame(raf);
332
- }, [
347
+ });
348
+ useEffect(() => measureCardsCommit({
349
+ expandedCard,
350
+ isAddingComment
351
+ }, updateCardPositions), [
333
352
  expandedCard,
334
353
  isAddingComment,
335
354
  updateCardPositions
@@ -359,20 +378,21 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
359
378
  if (onAddComment?.(newCommentText.trim()) !== false) setNewCommentText("");
360
379
  }
361
380
  };
362
- useEffect(() => {
363
- if (activeCommentId === null) return;
364
- setExpandedCard(`comment-${activeCommentId}`);
365
- }, [activeCommentId]);
366
- const handleCardClick = (cardId_0, commentId_0) => {
367
- const nextExpandedCard = expandedCard === cardId_0 ? null : cardId_0;
381
+ const [previousActiveCommentId, setPreviousActiveCommentId] = useState(activeCommentId);
382
+ if (previousActiveCommentId !== activeCommentId) {
383
+ setPreviousActiveCommentId(activeCommentId);
384
+ if (activeCommentId !== null) setExpandedCard(`comment-${activeCommentId}`);
385
+ }
386
+ const handleCardClick = (cardId_1, commentId_0) => {
387
+ const nextExpandedCard = expandedCard === cardId_1 ? null : cardId_1;
368
388
  setExpandedCard(nextExpandedCard);
369
389
  setMenuOpenFor(null);
370
390
  if (commentId_0 !== void 0) onCommentClick?.(nextExpandedCard === null && activeCommentId === commentId_0 ? null : commentId_0);
371
- if (isDrawer && commentId_0 !== void 0 && nextExpandedCard !== null) revealAnchor(cardId_0);
391
+ if (isDrawer && commentId_0 !== void 0 && nextExpandedCard !== null) revealAnchor(cardId_1);
372
392
  };
373
- const revealAnchor = (cardId_1) => {
393
+ const revealAnchor = (cardId_2) => {
374
394
  const scrollEl_1 = editorContainerRef?.current;
375
- const anchorY = lastKnownCardPositionsRef.current.get(cardId_1) ?? anchorPositions?.get(cardId_1);
395
+ const anchorY = lastKnownCardPositionsRef.current.get(cardId_2) ?? anchorPositions?.get(cardId_2);
376
396
  if (!scrollEl_1 || anchorY === void 0) return;
377
397
  scrollEditorTo(scrollEl_1, {
378
398
  top: Math.max(0, anchorY - scrollEl_1.clientHeight / 3),
@@ -405,10 +425,8 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
405
425
  fontWeight: 500,
406
426
  fontFamily: "inherit"
407
427
  });
408
- const cardContainerStyle = (cardId_2, isExpanded, yPos) => {
409
- const isKnown = knownCardsRef.current.has(cardId_2);
410
- if (yPos !== void 0) knownCardsRef.current.add(cardId_2);
411
- const isNewCard = !isKnown && yPos !== void 0;
428
+ const cardContainerStyle = (cardId_3, isExpanded, yPos) => {
429
+ const isNewCard = !knownCards.has(cardId_3) && yPos !== void 0;
412
430
  const noPosition = hasPositions && yPos === void 0;
413
431
  const positionStyle = (() => {
414
432
  if (!hasPositions) return { marginBottom: 6 };
@@ -593,24 +611,26 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
593
611
  });
594
612
  const renderCommentCard = (comment_0) => {
595
613
  const replies_0 = getReplies(comment_0.id);
596
- const cardId_3 = `comment-${comment_0.id}`;
597
- const isExpanded_1 = expandedCard === cardId_3;
614
+ const cardId_4 = `comment-${comment_0.id}`;
615
+ const isExpanded_1 = expandedCard === cardId_4;
598
616
  const isActive = activeCommentId === comment_0.id;
599
- const yPos_0 = cardPositions.get(cardId_3) ?? lastKnownCardPositionsRef.current.get(cardId_3);
617
+ const yPos_0 = cardPositions.get(cardId_4);
600
618
  return /* @__PURE__ */ jsxs("div", {
601
619
  ref: (el_3) => {
602
- if (el_3) cardRefs.current.set(cardId_3, el_3);
603
- else cardRefs.current.delete(cardId_3);
620
+ if (el_3) cardRefs.current.set(cardId_4, el_3);
621
+ else cardRefs.current.delete(cardId_4);
604
622
  },
605
623
  "data-comment-id": comment_0.id,
606
624
  className: "docx-comment-card",
607
- onClick: containedHandler(() => handleCardClick(cardId_3, comment_0.id)),
625
+ onClick: (event) => {
626
+ containedHandler(() => handleCardClick(cardId_4, comment_0.id))(event);
627
+ },
608
628
  onKeyDown: (e_9) => {
609
- if (e_9.key === "Enter" || e_9.key === " ") handleCardClick(cardId_3, comment_0.id);
629
+ if (e_9.key === "Enter" || e_9.key === " ") handleCardClick(cardId_4, comment_0.id);
610
630
  },
611
631
  onMouseDown: containedHandler((e_10) => e_10.stopPropagation()),
612
632
  style: {
613
- ...cardContainerStyle(cardId_3, isExpanded_1, yPos_0),
633
+ ...cardContainerStyle(cardId_4, isExpanded_1, yPos_0),
614
634
  opacity: comment_0.done ? .6 : 1,
615
635
  outline: isActive ? "2px solid var(--doc-primary, var(--primary))" : "none",
616
636
  outlineOffset: 2
@@ -669,13 +689,13 @@ const CommentsSidebar = ({ comments, onCommentClick, activeCommentId = null, onC
669
689
  type: "button",
670
690
  onClick: (e_12) => {
671
691
  e_12.stopPropagation();
672
- setMenuOpenFor(menuOpenFor === cardId_3 ? null : cardId_3);
692
+ setMenuOpenFor(menuOpenFor === cardId_4 ? null : cardId_4);
673
693
  },
674
694
  title: "More options",
675
695
  style: ICON_BUTTON_STYLE,
676
696
  children: /* @__PURE__ */ jsx(MoreVerticalIcon, { size: 16 })
677
697
  }),
678
- menuOpenFor === cardId_3 && /* @__PURE__ */ jsx("div", {
698
+ menuOpenFor === cardId_4 && /* @__PURE__ */ jsx("div", {
679
699
  onClick: (e_13) => e_13.stopPropagation(),
680
700
  onKeyDown: (e_14) => e_14.stopPropagation(),
681
701
  onMouseDown: (e_15) => e_15.stopPropagation(),
@@ -1,24 +1,11 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BBjsoOtd.js";
2
- import { r as useFolioUI } from "./folio-ui-DO95voaI.js";
3
- import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import { r as useFolioUI } from "./folio-ui-rCHqCEG6.js";
3
+ import { c } from "react-compiler-runtime";
4
+ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
4
5
  import { ChevronDownIcon, ChevronUpIcon, SearchIcon, XIcon } from "lucide-react";
5
6
  import { useTranslations } from "use-intl";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  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
9
  //#region src/components/dialogs/findReplaceDialogLayout.ts
23
10
  const FIND_REPLACE_DIALOG_TOP = "var(--folio-find-replace-top, 7rem)";
24
11
  const FIND_REPLACE_DIALOG_LEFT = "var(--folio-find-replace-left, 5.5rem)";
@@ -53,115 +40,157 @@ var FindReplaceDialog_exports = /* @__PURE__ */ __exportAll({ FindReplaceDialog:
53
40
  /**
54
41
  * FindReplaceDialog component - Modal for finding and replacing text
55
42
  */
56
- function FindReplaceDialog({ isOpen, onClose, onFind, onFindNext, onFindPrevious, onHighlightMatches, onClearHighlights, initialSearchText = "", currentResult, className, style }) {
43
+ function FindReplaceDialog(props) {
44
+ const $ = c(8);
45
+ const [matchCase, setMatchCase] = useState(false);
46
+ const [matchWholeWord, setMatchWholeWord] = useState(false);
47
+ const { isOpen, onClearHighlights } = props;
48
+ let t0;
49
+ let t1;
50
+ if ($[0] !== isOpen || $[1] !== onClearHighlights) {
51
+ t0 = () => {
52
+ if (!isOpen) onClearHighlights?.();
53
+ };
54
+ t1 = [isOpen, onClearHighlights];
55
+ $[0] = isOpen;
56
+ $[1] = onClearHighlights;
57
+ $[2] = t0;
58
+ $[3] = t1;
59
+ } else {
60
+ t0 = $[2];
61
+ t1 = $[3];
62
+ }
63
+ useEffect(t0, t1);
64
+ if (!isOpen) return null;
65
+ let t2;
66
+ if ($[4] !== matchCase || $[5] !== matchWholeWord || $[6] !== props) {
67
+ t2 = /* @__PURE__ */ jsx(FindReplaceDialogForm, {
68
+ ...props,
69
+ matchCase,
70
+ matchWholeWord,
71
+ onMatchCaseChange: setMatchCase,
72
+ onMatchWholeWordChange: setMatchWholeWord
73
+ }, props.initialSearchText);
74
+ $[4] = matchCase;
75
+ $[5] = matchWholeWord;
76
+ $[6] = props;
77
+ $[7] = t2;
78
+ } else t2 = $[7];
79
+ return t2;
80
+ }
81
+ const getFindQueryKey = (text, { matchCase, matchWholeWord }) => JSON.stringify([
82
+ text,
83
+ matchCase,
84
+ matchWholeWord
85
+ ]);
86
+ const getQueryResult = (state, queryKey) => {
87
+ switch (state.status) {
88
+ case "cleared": return null;
89
+ case "ready": return state.queryKey === queryKey ? state.result : null;
90
+ default: return state;
91
+ }
92
+ };
93
+ function FindReplaceDialogForm({ isOpen, onClose, onFind, onFindNext, onFindPrevious, onHighlightMatches, onClearHighlights, initialSearchText = "", currentResult, className, style, matchCase, matchWholeWord, onMatchCaseChange, onMatchWholeWordChange }) {
57
94
  const id = React.useId();
58
95
  const t = useTranslations("folio");
59
96
  const { Button, Input, Checkbox } = useFolioUI();
60
- const [searchText, setSearchText] = useState("");
61
- const [matchCase, setMatchCase] = useState(false);
62
- const [matchWholeWord, setMatchWholeWord] = useState(false);
63
- const [result, setResult] = useState(null);
64
- const searchInputRef = useRef(null);
65
- const latestFindCallbacksRef = useRef({
66
- onFind,
67
- onHighlightMatches,
68
- onClearHighlights
69
- });
70
- latestFindCallbacksRef.current = {
71
- onFind,
72
- onHighlightMatches,
73
- onClearHighlights
74
- };
75
- const latestFindOptionsRef = useRef({
76
- matchCase,
77
- matchWholeWord
78
- });
79
- latestFindOptionsRef.current = {
97
+ const [searchText, setSearchText] = useState(initialSearchText);
98
+ const queryKey = getFindQueryKey(searchText, {
80
99
  matchCase,
81
100
  matchWholeWord
82
- };
83
- const latestSearchStateRef = useRef({
84
- isOpen,
85
- searchText
86
101
  });
87
- latestSearchStateRef.current = {
88
- isOpen,
89
- searchText
90
- };
91
- useEffect(() => {
92
- if (currentResult !== void 0) setResult(currentResult);
93
- }, [currentResult]);
102
+ const [findResult, setFindResult] = useState({ status: "cleared" });
103
+ const [previousCurrentResult, setPreviousCurrentResult] = useState(currentResult);
104
+ if (currentResult !== previousCurrentResult) {
105
+ setPreviousCurrentResult(currentResult);
106
+ if (findResult.status === "ready" && findResult.queryKey === queryKey && currentResult !== void 0) setFindResult(currentResult ? {
107
+ status: "ready",
108
+ queryKey,
109
+ result: currentResult
110
+ } : { status: "cleared" });
111
+ }
112
+ const result = getQueryResult(findResult, queryKey);
113
+ const searchInputRef = useRef(null);
94
114
  useEffect(() => {
95
- const behavior = getFindDialogOpenBehavior({
96
- isOpen,
97
- initialSearchText
98
- });
99
- if (behavior.type === "closed") {
100
- latestFindCallbacksRef.current.onClearHighlights?.();
101
- return;
102
- }
103
- setSearchText(behavior.searchText);
104
- setResult(null);
105
- setTimeout(() => {
115
+ const timeout = setTimeout(() => {
106
116
  searchInputRef.current?.focus();
107
117
  searchInputRef.current?.select();
108
118
  }, 100);
109
- if (behavior.shouldFindInitialText) {
110
- const callbacks = latestFindCallbacksRef.current;
111
- const options = latestFindOptionsRef.current;
112
- const searchResult = callbacks.onFind(behavior.searchText, {
113
- matchCase: options.matchCase,
114
- matchWholeWord: options.matchWholeWord
115
- });
116
- setResult(searchResult);
117
- if (searchResult?.matches && callbacks.onHighlightMatches) callbacks.onHighlightMatches(searchResult.matches);
118
- }
119
- }, [isOpen, initialSearchText]);
120
- const performSearch = useCallback(() => {
121
- if (!searchText.trim()) {
122
- setResult(null);
123
- if (onClearHighlights) onClearHighlights();
119
+ return () => clearTimeout(timeout);
120
+ }, []);
121
+ const performSearch = useCallback((text = searchText, options = {
122
+ matchCase,
123
+ matchWholeWord
124
+ }) => {
125
+ if (!text.trim()) {
126
+ setFindResult({ status: "cleared" });
127
+ onClearHighlights?.();
124
128
  return;
125
129
  }
126
- const searchResult_0 = onFind(searchText, {
127
- matchCase,
128
- matchWholeWord
129
- });
130
- setResult(searchResult_0);
131
- if (searchResult_0?.matches && onHighlightMatches) onHighlightMatches(searchResult_0.matches);
132
- else if (onClearHighlights) onClearHighlights();
130
+ const searchResult = onFind(text, options);
131
+ setFindResult(searchResult ? {
132
+ status: "ready",
133
+ queryKey: getFindQueryKey(text, options),
134
+ result: searchResult
135
+ } : { status: "cleared" });
136
+ if (searchResult?.matches && onHighlightMatches) onHighlightMatches(searchResult.matches);
137
+ else onClearHighlights?.();
133
138
  }, [
134
139
  searchText,
135
140
  matchCase,
136
141
  matchWholeWord,
137
142
  onFind,
138
143
  onHighlightMatches,
139
- onClearHighlights
144
+ onClearHighlights,
145
+ setFindResult
140
146
  ]);
141
147
  const performSearchRef = useRef(performSearch);
142
- performSearchRef.current = performSearch;
148
+ const clearHighlightsRef = useRef(onClearHighlights);
149
+ useLayoutEffect(() => {
150
+ performSearchRef.current = performSearch;
151
+ clearHighlightsRef.current = onClearHighlights;
152
+ }, [performSearch, onClearHighlights]);
143
153
  useEffect(() => {
144
- if (shouldRefreshFindDialogSearch(latestSearchStateRef.current)) performSearchRef.current();
145
- }, [matchCase, matchWholeWord]);
146
- useEffect(() => {
147
- if (!isOpen) return;
148
154
  if (!searchText.trim()) {
149
- setResult(null);
150
- onClearHighlights?.();
155
+ clearHighlightsRef.current?.();
151
156
  return;
152
157
  }
153
- const timeout = setTimeout(performSearch, 120);
154
- return () => clearTimeout(timeout);
158
+ const timeout_0 = setTimeout(() => performSearchRef.current(searchText, {
159
+ matchCase,
160
+ matchWholeWord
161
+ }), 120);
162
+ return () => clearTimeout(timeout_0);
155
163
  }, [
156
- isOpen,
157
164
  searchText,
158
- performSearch,
159
- onClearHighlights
165
+ matchCase,
166
+ matchWholeWord
160
167
  ]);
168
+ const handleMatchCaseChange = useCallback((value) => {
169
+ setFindResult({ status: "cleared" });
170
+ onMatchCaseChange(value);
171
+ }, [onMatchCaseChange, setFindResult]);
172
+ const handleMatchWholeWordChange = useCallback((value_0) => {
173
+ setFindResult({ status: "cleared" });
174
+ onMatchWholeWordChange(value_0);
175
+ }, [onMatchWholeWordChange, setFindResult]);
161
176
  const handleSearchChange = useCallback((e) => {
162
- setSearchText(e.target.value);
163
- setResult(null);
164
- }, []);
177
+ const text_0 = e.target.value;
178
+ setSearchText(text_0);
179
+ setFindResult({ status: "cleared" });
180
+ if (!text_0.trim()) {
181
+ onFind(text_0, {
182
+ matchCase,
183
+ matchWholeWord
184
+ });
185
+ onClearHighlights?.();
186
+ }
187
+ }, [
188
+ onFind,
189
+ matchCase,
190
+ matchWholeWord,
191
+ onClearHighlights,
192
+ setFindResult
193
+ ]);
165
194
  const handleFindNext = useCallback(() => {
166
195
  if (!searchText.trim()) {
167
196
  performSearch();
@@ -173,16 +202,22 @@ function FindReplaceDialog({ isOpen, onClose, onFind, onFindNext, onFindPrevious
173
202
  }
174
203
  if (onFindNext()) {
175
204
  const newIndex = (result.currentIndex + 1) % result.totalCount;
176
- setResult({
177
- ...result,
178
- currentIndex: newIndex
205
+ setFindResult({
206
+ status: "ready",
207
+ queryKey,
208
+ result: {
209
+ ...result,
210
+ currentIndex: newIndex
211
+ }
179
212
  });
180
213
  }
181
214
  }, [
182
215
  searchText,
183
216
  result,
217
+ queryKey,
184
218
  performSearch,
185
- onFindNext
219
+ onFindNext,
220
+ setFindResult
186
221
  ]);
187
222
  const handleFindPrevious = useCallback(() => {
188
223
  if (!searchText.trim()) {
@@ -195,16 +230,22 @@ function FindReplaceDialog({ isOpen, onClose, onFind, onFindNext, onFindPrevious
195
230
  }
196
231
  if (onFindPrevious()) {
197
232
  const newIndex_0 = result.currentIndex === 0 ? result.totalCount - 1 : result.currentIndex - 1;
198
- setResult({
199
- ...result,
200
- currentIndex: newIndex_0
233
+ setFindResult({
234
+ status: "ready",
235
+ queryKey,
236
+ result: {
237
+ ...result,
238
+ currentIndex: newIndex_0
239
+ }
201
240
  });
202
241
  }
203
242
  }, [
204
243
  searchText,
205
244
  result,
245
+ queryKey,
206
246
  performSearch,
207
- onFindPrevious
247
+ onFindPrevious,
248
+ setFindResult
208
249
  ]);
209
250
  const handleSearchKeyDown = useCallback((e_0) => {
210
251
  if (e_0.key === "Enter") {
@@ -345,13 +386,13 @@ function FindReplaceDialog({ isOpen, onClose, onFind, onFindNext, onFindPrevious
345
386
  className: "text-muted-foreground flex items-center gap-2 text-xs",
346
387
  children: [/* @__PURE__ */ jsx(Checkbox, {
347
388
  checked: matchCase,
348
- onCheckedChange: setMatchCase
389
+ onCheckedChange: handleMatchCaseChange
349
390
  }), t("findReplace.matchCase")]
350
391
  }), /* @__PURE__ */ jsxs("label", {
351
392
  className: "text-muted-foreground flex items-center gap-2 text-xs",
352
393
  children: [/* @__PURE__ */ jsx(Checkbox, {
353
394
  checked: matchWholeWord,
354
- onCheckedChange: setMatchWholeWord
395
+ onCheckedChange: handleMatchWholeWordChange
355
396
  }), t("findReplace.wholeWords")]
356
397
  })]
357
398
  })
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BBjsoOtd.js";
2
- import { r as useFolioUI } from "./folio-ui-DO95voaI.js";
2
+ import { r as useFolioUI } from "./folio-ui-rCHqCEG6.js";
3
3
  import { u as useCloseOnDialogOpenChange } from "./dialogChrome-BoGYPgeu.js";
4
4
  import { c } from "react-compiler-runtime";
5
5
  import { useId, useState } from "react";