@inshapardaz/likhari-react 0.1.49 → 0.1.51-dev.407

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 (33) hide show
  1. package/dist/autocorrect/AutoCorrectPlugin.d.ts.map +1 -1
  2. package/dist/autocorrect/AutoCorrectPlugin.js +25 -5
  3. package/dist/autocorrect/autoCorrectActions.d.ts.map +1 -1
  4. package/dist/autocorrect/autoCorrectActions.js +5 -3
  5. package/dist/autocorrect/autoCorrectStores.d.ts +17 -1
  6. package/dist/autocorrect/autoCorrectStores.d.ts.map +1 -1
  7. package/dist/autocorrect/autoCorrectStores.js +68 -12
  8. package/dist/autocorrect/punctuationRules.d.ts +8 -0
  9. package/dist/autocorrect/punctuationRules.d.ts.map +1 -1
  10. package/dist/autocorrect/punctuationRules.js +13 -2
  11. package/dist/cleanup/textCleanupActions.d.ts +3 -2
  12. package/dist/cleanup/textCleanupActions.d.ts.map +1 -1
  13. package/dist/cleanup/textCleanupActions.js +21 -3
  14. package/dist/components/AutoCorrectPanel.d.ts.map +1 -1
  15. package/dist/components/AutoCorrectPanel.js +3 -2
  16. package/dist/components/Toolbar.d.ts.map +1 -1
  17. package/dist/components/Toolbar.js +111 -35
  18. package/dist/components/ToolbarSettingsPanel.d.ts +17 -0
  19. package/dist/components/ToolbarSettingsPanel.d.ts.map +1 -0
  20. package/dist/components/ToolbarSettingsPanel.js +12 -0
  21. package/dist/i18n/strings.d.ts +18 -0
  22. package/dist/i18n/strings.d.ts.map +1 -1
  23. package/dist/i18n/strings.js +48 -0
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/join/joinLinesActions.d.ts.map +1 -1
  28. package/dist/join/joinLinesActions.js +12 -14
  29. package/dist/theme/editor.css +54 -0
  30. package/dist/toolbar/toolbarVisibility.d.ts +23 -0
  31. package/dist/toolbar/toolbarVisibility.d.ts.map +1 -0
  32. package/dist/toolbar/toolbarVisibility.js +40 -0
  33. package/package.json +1 -1
@@ -28,11 +28,10 @@ export function $canJoinLines() {
28
28
  return selection.getNodes().some($isLineBreakNode) || $textNodesWithNewlines(selection).length > 0;
29
29
  }
30
30
  /** Replaces the newlines in the selected part of a text node, each by one space (none if one is already there). */
31
- function $replaceNewlinesInText(node, selection) {
32
- const [start, end] = selection.getStartEndPoints() ?? [];
31
+ function $replaceNewlinesInText(node, start, end) {
33
32
  const text = node.getTextContent();
34
- const from = start && start.key === node.getKey() ? start.offset : 0;
35
- const to = end && end.key === node.getKey() ? end.offset : text.length;
33
+ const from = start.key === node.getKey() ? start.offset : 0;
34
+ const to = end.key === node.getKey() ? end.offset : text.length;
36
35
  const joined = text.slice(from, to).replace(/[ \t]*\r?\n[ \t]*/g, ' ');
37
36
  node.setTextContent(text.slice(0, from) + joined + text.slice(to));
38
37
  }
@@ -126,27 +125,26 @@ export function $joinSelectedLines() {
126
125
  const textsWithNewlines = $textNodesWithNewlines(selection);
127
126
  if (paragraphs.length < 2 && lineBreaks.length === 0 && textsWithNewlines.length === 0)
128
127
  return false;
129
- const [start, end] = selection.getStartEndPoints() ?? [];
128
+ // RangeSelection's anchor/focus track drag direction, not document order (and
129
+ // getStartEndPoints() returns them as-is, anchor first) — reorder them so "start"/"end"
130
+ // below always mean "earlier"/"later" in the document, regardless of which way the user
131
+ // dragged, or Shift+arrow'd, the selection. Getting this wrong silently skips the tail
132
+ // split below (sweeping unselected content into the join) for any backward selection.
133
+ const [start, end] = selection.isBackward() ? [selection.focus, selection.anchor] : [selection.anchor, selection.focus];
130
134
  for (const lineBreak of lineBreaks)
131
135
  $replaceBreakWithSpace(lineBreak);
132
136
  for (const textNode of textsWithNewlines)
133
- $replaceNewlinesInText(textNode, selection);
137
+ $replaceNewlinesInText(textNode, start, end);
134
138
  const [target, ...rest] = paragraphs;
135
139
  if (!target)
136
140
  return false;
137
141
  const lastParagraph = paragraphs[paragraphs.length - 1];
138
- if (end)
139
- $splitUnselectedTail(lastParagraph, end);
142
+ $splitUnselectedTail(lastParagraph, end);
140
143
  for (const paragraph of rest)
141
144
  $appendParagraph(target, paragraph);
142
145
  // Keep the caret where the selection began, rather than at the end of everything
143
146
  // just joined — useful on its own, and essential when many lines were joined at
144
147
  // once, where "the end" could otherwise land far past where the user was working.
145
- if (start) {
146
- start.getNode().select(start.offset, start.offset);
147
- }
148
- else {
149
- target.selectEnd();
150
- }
148
+ start.getNode().select(start.offset, start.offset);
151
149
  return true;
152
150
  }
@@ -1076,6 +1076,16 @@
1076
1076
  color: inherit;
1077
1077
  }
1078
1078
 
1079
+ .likhari-autocorrect-checkbox {
1080
+ flex-direction: row;
1081
+ align-items: center;
1082
+ gap: 6px;
1083
+ }
1084
+
1085
+ .likhari-autocorrect-checkbox input {
1086
+ width: auto;
1087
+ }
1088
+
1079
1089
  .likhari-autocorrect-actions {
1080
1090
  display: flex;
1081
1091
  flex-direction: column;
@@ -1097,6 +1107,50 @@
1097
1107
  cursor: default;
1098
1108
  }
1099
1109
 
1110
+ /* Toolbar settings panel: a Mantine Popover dropdown anchored on the gear button. */
1111
+ .likhari-toolbar-settings-panel {
1112
+ width: 280px;
1113
+ max-height: min(70vh, 480px);
1114
+ overflow-y: auto;
1115
+ padding: 8px;
1116
+ font-size: 13px;
1117
+ background: var(--editor-paper-dim);
1118
+ color: inherit;
1119
+ }
1120
+
1121
+ .likhari-toolbar-settings-groups {
1122
+ display: flex;
1123
+ flex-direction: column;
1124
+ gap: 10px;
1125
+ }
1126
+
1127
+ .likhari-toolbar-settings-group {
1128
+ border: 1px solid var(--editor-line);
1129
+ border-radius: 6px;
1130
+ padding: 6px 8px;
1131
+ margin: 0;
1132
+ }
1133
+
1134
+ .likhari-toolbar-settings-group legend {
1135
+ padding: 0 4px;
1136
+ font-size: 11px;
1137
+ text-transform: uppercase;
1138
+ letter-spacing: 0.02em;
1139
+ opacity: 0.7;
1140
+ }
1141
+
1142
+ .likhari-toolbar-settings-item {
1143
+ display: flex;
1144
+ align-items: center;
1145
+ gap: 6px;
1146
+ padding: 3px 2px;
1147
+ cursor: pointer;
1148
+ }
1149
+
1150
+ .likhari-toolbar-settings-item input {
1151
+ width: auto;
1152
+ }
1153
+
1100
1154
  /* Autocomplete suggestions, shown under the caret while typing. */
1101
1155
  .likhari-autocomplete {
1102
1156
  z-index: 20;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Which toolbar items the user has chosen to hide, kept in localStorage so the
3
+ * choice survives a reload. A feature a host turned off (`EditorFeatureConfig`)
4
+ * is never offered here and is unaffected by it — this only lets the user declutter
5
+ * what the host already made available, it does not re-gate availability.
6
+ */
7
+ export declare function useToolbarItemVisibility(): {
8
+ hidden: ReadonlySet<string>;
9
+ isHidden: (id: string) => boolean;
10
+ toggle: (id: string) => void;
11
+ };
12
+ /** One toggleable row in the toolbar settings panel. */
13
+ export interface ToolbarVisibilityItem {
14
+ id: string;
15
+ label: string;
16
+ }
17
+ /** A labelled group of toggleable rows, as shown in the toolbar settings panel. */
18
+ export interface ToolbarVisibilityGroup {
19
+ id: string;
20
+ label: string;
21
+ items: ToolbarVisibilityItem[];
22
+ }
23
+ //# sourceMappingURL=toolbarVisibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbarVisibility.d.ts","sourceRoot":"","sources":["../../src/toolbar/toolbarVisibility.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI;IAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAc3I;AAED,wDAAwD;AACxD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAChC"}
@@ -0,0 +1,40 @@
1
+ import { useState } from 'react';
2
+ const STORAGE_KEY = 'likhari-toolbar-hidden-items';
3
+ function readHidden() {
4
+ try {
5
+ const parsed = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '[]');
6
+ return new Set(Array.isArray(parsed) ? parsed.filter((id) => typeof id === 'string') : []);
7
+ }
8
+ catch {
9
+ return new Set();
10
+ }
11
+ }
12
+ function writeHidden(hidden) {
13
+ try {
14
+ localStorage.setItem(STORAGE_KEY, JSON.stringify([...hidden]));
15
+ }
16
+ catch {
17
+ // Storage disabled or full: the choice applies for this session only.
18
+ }
19
+ }
20
+ /**
21
+ * Which toolbar items the user has chosen to hide, kept in localStorage so the
22
+ * choice survives a reload. A feature a host turned off (`EditorFeatureConfig`)
23
+ * is never offered here and is unaffected by it — this only lets the user declutter
24
+ * what the host already made available, it does not re-gate availability.
25
+ */
26
+ export function useToolbarItemVisibility() {
27
+ const [hidden, setHidden] = useState(() => (typeof localStorage === 'undefined' ? new Set() : readHidden()));
28
+ const toggle = (id) => {
29
+ setHidden((prev) => {
30
+ const next = new Set(prev);
31
+ if (next.has(id))
32
+ next.delete(id);
33
+ else
34
+ next.add(id);
35
+ writeHidden(next);
36
+ return next;
37
+ });
38
+ };
39
+ return { hidden, isHidden: (id) => hidden.has(id), toggle };
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.49",
3
+ "version": "0.1.51-dev.407",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {