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

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.
@@ -283,7 +283,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
283
283
  const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
284
284
  return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, findOpen: findOpen, onToggleFind: () => setFindOpen((v) => !v), isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
285
285
  ? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
286
- : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && findOpen && _jsx(FindReplaceBar, { strings: strings, onClose: () => setFindOpen(false) }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
286
+ : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && findOpen && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setFindOpen(false) }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
287
287
  handleSave();
288
288
  settleLeave(true);
289
289
  }, onSaveDraft: () => {
@@ -5,8 +5,9 @@ import type { Strings } from '../i18n/strings.js';
5
5
  * only counts matches — the editor's selection moves to a match only when the
6
6
  * user asks (next, previous, replace), so typing keeps going into the bar.
7
7
  */
8
- export declare function FindReplaceBar({ strings, onClose }: {
8
+ export declare function FindReplaceBar({ strings, dir, onClose }: {
9
9
  strings: Strings;
10
+ dir: 'ltr' | 'rtl';
10
11
  onClose: () => void;
11
12
  }): import("react").JSX.Element;
12
13
  //# sourceMappingURL=FindReplaceBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FindReplaceBar.d.ts","sourceRoot":"","sources":["../../src/components/FindReplaceBar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BAyH7F"}
1
+ {"version":3,"file":"FindReplaceBar.d.ts","sourceRoot":"","sources":["../../src/components/FindReplaceBar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BA0HtH"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from 'react';
3
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
- import { IconChevronDown, IconChevronRight, IconX } from '@tabler/icons-react';
4
+ import { IconChevronDown, IconChevronRight, IconRepeat, IconReplace, IconX } from '@tabler/icons-react';
5
5
  import { $findMatches, $replaceAll, $replaceMatch, $selectMatch } from '../find/findReplaceActions.js';
6
6
  /**
7
7
  * A compact find widget, right-aligned above the canvas (VS Code style). The
@@ -9,7 +9,7 @@ import { $findMatches, $replaceAll, $replaceMatch, $selectMatch } from '../find/
9
9
  * only counts matches — the editor's selection moves to a match only when the
10
10
  * user asks (next, previous, replace), so typing keeps going into the bar.
11
11
  */
12
- export function FindReplaceBar({ strings, onClose }) {
12
+ export function FindReplaceBar({ strings, dir, onClose }) {
13
13
  const [editor] = useLexicalComposerContext();
14
14
  const t = strings.findReplace;
15
15
  const [query, setQuery] = useState('');
@@ -59,13 +59,13 @@ export function FindReplaceBar({ strings, onClose }) {
59
59
  });
60
60
  const status = query === '' ? '' : count === 0 ? t.noMatches : `${index + 1} / ${count}`;
61
61
  const Chevron = showReplace ? IconChevronDown : IconChevronRight;
62
- return (_jsxs("div", { className: "likhari-find-widget", role: "search", 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) => {
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
63
  if (e.key === 'Enter')
64
64
  step(e.shiftKey ? -1 : 1);
65
65
  if (e.key === 'Escape')
66
66
  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", { "aria-label": t.replace, placeholder: t.replacePlaceholder, value: replacement, onChange: (e) => setReplacement(e.target.value), onKeyDown: (e) => {
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
68
  if (e.key === 'Enter' && count > 0)
69
69
  replaceCurrent();
70
- } }), _jsx("button", { type: "button", onClick: replaceCurrent, disabled: count === 0, children: t.replaceOne }), _jsx("button", { type: "button", onClick: replaceEverything, disabled: count === 0, children: t.replaceAll })] }))] }));
70
+ } }), _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 }) })] }))] }));
71
71
  }
@@ -770,7 +770,7 @@
770
770
  position: absolute;
771
771
  z-index: 5;
772
772
  top: 8px;
773
- inset-inline-end: 16px;
773
+ right: 16px;
774
774
  display: flex;
775
775
  flex-direction: column;
776
776
  gap: 6px;
@@ -783,15 +783,36 @@
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
789
  .likhari-find-row {
787
- display: flex;
790
+ display: grid;
791
+ grid-template-columns: 24px 180px 56px 24px 24px 24px;
788
792
  align-items: center;
789
- justify-content: flex-end;
790
- gap: 4px;
793
+ column-gap: 4px;
794
+ }
795
+
796
+ .likhari-find-replace-input {
797
+ grid-column: 2;
798
+ }
799
+
800
+ .likhari-find-replace-one {
801
+ grid-column: 4;
802
+ }
803
+
804
+ .likhari-find-replace-all {
805
+ grid-column: 5;
806
+ }
807
+
808
+ .likhari-find-widget[dir='rtl'] {
809
+ right: auto;
810
+ left: 16px;
791
811
  }
792
812
 
793
813
  .likhari-find-widget input {
794
- width: 180px;
814
+ width: 100%;
815
+ min-width: 0;
795
816
  padding: 3px 6px;
796
817
  border: 1px solid var(--editor-line);
797
818
  border-radius: 4px;
@@ -825,9 +846,7 @@
825
846
  }
826
847
 
827
848
  .likhari-find-icon-spacer {
828
- display: inline-block;
829
- width: 24px;
830
- flex: 0 0 24px;
849
+ display: block;
831
850
  }
832
851
 
833
852
  .likhari-find-status {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.18-dev.169",
3
+ "version": "0.1.18-dev.173",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {