@inshapardaz/likhari-react 0.1.18-dev.173 → 0.1.18-dev.179

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.
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
4
  import { IconChevronDown, IconChevronRight, IconRepeat, IconReplace, IconX } from '@tabler/icons-react';
5
5
  import { $findMatches, $replaceAll, $replaceMatch, $selectMatch } from '../find/findReplaceActions.js';
@@ -17,7 +17,6 @@ export function FindReplaceBar({ strings, dir, onClose }) {
17
17
  const [showReplace, setShowReplace] = useState(false);
18
18
  const [index, setIndex] = useState(0);
19
19
  const [count, setCount] = useState(0);
20
- const findInput = useRef(null);
21
20
  // Runs `action` against the current matches inside a committed update, then
22
21
  // syncs the count and index. Selecting a match is up to the action, so
23
22
  // typing never moves the editor's selection.
@@ -33,8 +32,10 @@ export function FindReplaceBar({ strings, dir, onClose }) {
33
32
  setIndex(result.nextIndex);
34
33
  const match = result.matches[result.nextIndex];
35
34
  if (result.select && match) {
35
+ // Lexical only draws the selection while the editor has focus, so focus it
36
+ // here; the match stays selected and visible.
36
37
  editor.getElementByKey(match.anchorKey)?.scrollIntoView({ block: 'center' });
37
- findInput.current?.focus();
38
+ editor.focus();
38
39
  }
39
40
  };
40
41
  useEffect(() => {
@@ -59,12 +60,12 @@ export function FindReplaceBar({ strings, dir, onClose }) {
59
60
  });
60
61
  const status = query === '' ? '' : count === 0 ? t.noMatches : `${index + 1} / ${count}`;
61
62
  const Chevron = showReplace ? IconChevronDown : IconChevronRight;
62
- return (_jsxs("div", { className: "likhari-find-widget", role: "search", dir: dir, children: [_jsxs("div", { className: "likhari-find-row", children: [_jsx("button", { type: "button", className: "likhari-find-icon", onClick: () => setShowReplace((v) => !v), "aria-label": t.replace, "aria-expanded": showReplace, title: t.replace, children: _jsx(Chevron, { size: 14, stroke: 1.75 }) }), _jsx("input", { ref: findInput, "aria-label": t.find, placeholder: t.findPlaceholder, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: (e) => {
63
+ return (_jsxs("div", { className: "likhari-find-widget", role: "search", dir: dir, children: [_jsxs("div", { className: "likhari-find-row", children: [_jsx("button", { type: "button", className: "likhari-find-icon", onClick: () => setShowReplace((v) => !v), "aria-label": t.replace, "aria-expanded": showReplace, title: t.replace, children: _jsx(Chevron, { size: 14, stroke: 1.75 }) }), _jsx("input", { "aria-label": t.find, placeholder: t.findPlaceholder, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: (e) => {
63
64
  if (e.key === 'Enter')
64
65
  step(e.shiftKey ? -1 : 1);
65
66
  if (e.key === 'Escape')
66
67
  onClose();
67
- }, autoFocus: true }), _jsx("span", { className: "likhari-find-status", "aria-live": "polite", children: status }), _jsx("button", { type: "button", className: "likhari-find-icon", onClick: () => step(-1), disabled: count === 0, "aria-label": t.previous, title: t.previous, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75, style: { transform: 'rotate(180deg)' } }) }), _jsx("button", { type: "button", className: "likhari-find-icon", onClick: () => step(1), disabled: count === 0, "aria-label": t.next, title: t.next, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75 }) }), _jsx("button", { type: "button", className: "likhari-find-icon", onClick: onClose, "aria-label": t.close, title: t.close, children: _jsx(IconX, { size: 14, stroke: 1.75 }) })] }), showReplace && (_jsxs("div", { className: "likhari-find-row", children: [_jsx("span", { className: "likhari-find-icon-spacer", "aria-hidden": "true" }), _jsx("input", { className: "likhari-find-replace-input", "aria-label": t.replace, placeholder: t.replacePlaceholder, value: replacement, onChange: (e) => setReplacement(e.target.value), onKeyDown: (e) => {
68
+ }, autoFocus: true }), _jsx("span", { className: "likhari-find-status", "aria-live": "polite", children: status }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-prev", onClick: () => step(-1), disabled: count === 0, "aria-label": t.previous, title: t.previous, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75, style: { transform: 'rotate(180deg)' } }) }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-next", onClick: () => step(1), disabled: count === 0, "aria-label": t.next, title: t.next, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75 }) }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-close", onClick: onClose, "aria-label": t.close, title: t.close, children: _jsx(IconX, { size: 14, stroke: 1.75 }) })] }), showReplace && (_jsxs("div", { className: "likhari-find-row", children: [_jsx("span", { className: "likhari-find-icon-spacer", "aria-hidden": "true" }), _jsx("input", { className: "likhari-find-replace-input", "aria-label": t.replace, placeholder: t.replacePlaceholder, value: replacement, onChange: (e) => setReplacement(e.target.value), onKeyDown: (e) => {
68
69
  if (e.key === 'Enter' && count > 0)
69
70
  replaceCurrent();
70
71
  } }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-replace-one", onClick: replaceCurrent, disabled: count === 0, "aria-label": t.replaceOne, title: t.replaceOne, children: _jsx(IconReplace, { size: 14, stroke: 1.75 }) }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-replace-all", onClick: replaceEverything, disabled: count === 0, "aria-label": t.replaceAll, title: t.replaceAll, children: _jsx(IconRepeat, { size: 14, stroke: 1.75 }) })] }))] }));
@@ -783,12 +783,12 @@
783
783
  font-size: 13px;
784
784
  }
785
785
 
786
- /* Both rows share one grid so the replace controls sit directly under the
787
- search controls they belong with: input under input, buttons under the
788
- previous/next pair. Columns are chevron, input, status, prev, next, close. */
786
+ /* Both rows share one grid. Columns: chevron, input, then two narrow tracks
787
+ that hold either the match count (search row) or the two replace buttons
788
+ (replace row), then prev, next and close. */
789
789
  .likhari-find-row {
790
790
  display: grid;
791
- grid-template-columns: 24px 180px 56px 24px 24px 24px;
791
+ grid-template-columns: 24px 180px 24px 24px 24px 24px 24px;
792
792
  align-items: center;
793
793
  column-gap: 4px;
794
794
  }
@@ -797,12 +797,28 @@
797
797
  grid-column: 2;
798
798
  }
799
799
 
800
+ .likhari-find-status {
801
+ grid-column: 3 / span 2;
802
+ }
803
+
804
+ .likhari-find-prev {
805
+ grid-column: 5;
806
+ }
807
+
808
+ .likhari-find-next {
809
+ grid-column: 6;
810
+ }
811
+
812
+ .likhari-find-close {
813
+ grid-column: 7;
814
+ }
815
+
800
816
  .likhari-find-replace-one {
801
- grid-column: 4;
817
+ grid-column: 3;
802
818
  }
803
819
 
804
820
  .likhari-find-replace-all {
805
- grid-column: 5;
821
+ grid-column: 4;
806
822
  }
807
823
 
808
824
  .likhari-find-widget[dir='rtl'] {
@@ -850,7 +866,7 @@
850
866
  }
851
867
 
852
868
  .likhari-find-status {
853
- min-width: 56px;
854
869
  text-align: end;
855
870
  opacity: 0.8;
871
+ white-space: nowrap;
856
872
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.18-dev.173",
3
+ "version": "0.1.18-dev.179",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {