@inshapardaz/likhari-react 0.1.18-dev.175 → 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. The replace input sits under the search input and
787
- its two buttons follow it directly. Columns are chevron, input, status, prev,
788
- 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,14 +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
817
  grid-column: 3;
802
- justify-self: start;
803
818
  }
804
819
 
805
820
  .likhari-find-replace-all {
806
821
  grid-column: 4;
807
- justify-self: start;
808
822
  }
809
823
 
810
824
  .likhari-find-widget[dir='rtl'] {
@@ -852,7 +866,7 @@
852
866
  }
853
867
 
854
868
  .likhari-find-status {
855
- min-width: 56px;
856
869
  text-align: end;
857
870
  opacity: 0.8;
871
+ white-space: nowrap;
858
872
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.18-dev.175",
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": {