@inshapardaz/likhari-react 0.1.9 → 0.1.10
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.
- package/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +2 -1
- package/dist/components/TableDialog.d.ts +17 -0
- package/dist/components/TableDialog.d.ts.map +1 -0
- package/dist/components/TableDialog.js +33 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +105 -5
- package/dist/i18n/strings.d.ts +27 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +72 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +4 -0
- package/dist/table/tableActions.d.ts +21 -0
- package/dist/table/tableActions.d.ts.map +1 -0
- package/dist/table/tableActions.js +71 -0
- package/dist/theme/editor.css +37 -0
- package/dist/theme/editorTheme.d.ts.map +1 -1
- package/dist/theme/editorTheme.js +5 -0
- package/package.json +2 -1
package/dist/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -7,6 +7,7 @@ import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
|
|
|
7
7
|
import { ListPlugin } from '@lexical/react/LexicalListPlugin';
|
|
8
8
|
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
|
|
9
9
|
import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
10
|
+
import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
|
|
10
11
|
import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';
|
|
11
12
|
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
|
|
12
13
|
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
|
@@ -266,7 +267,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
266
267
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
267
268
|
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, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
268
269
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
269
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _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.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
270
|
+
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _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.tables && _jsx(TablePlugin, { hasCellMerge: false, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
270
271
|
handleSave();
|
|
271
272
|
settleLeave(true);
|
|
272
273
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface TableDialogValue {
|
|
2
|
+
rows: number;
|
|
3
|
+
columns: number;
|
|
4
|
+
headerRow: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface TableDialogProps {
|
|
7
|
+
opened: boolean;
|
|
8
|
+
onSubmit: (value: TableDialogValue) => void;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Insert-table dialog: rows x columns and an optional header row. Cell
|
|
13
|
+
* merge/split is intentionally not offered anywhere in this dialog or the
|
|
14
|
+
* table it creates — see the comment on `TablePlugin` in `EditorRoot.tsx`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function TableDialog({ opened, onSubmit, onClose }: TableDialogProps): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=TableDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableDialog.d.ts","sourceRoot":"","sources":["../../src/components/TableDialog.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAOD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,gBAAgB,+BAiD1E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Button, Checkbox, Group, Modal, NumberInput } from '@mantine/core';
|
|
4
|
+
import { useUiStrings } from '../i18n/useStrings.js';
|
|
5
|
+
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
6
|
+
const MIN_DIMENSION = 1;
|
|
7
|
+
const MAX_DIMENSION = 20;
|
|
8
|
+
const DEFAULT_ROWS = 3;
|
|
9
|
+
const DEFAULT_COLUMNS = 3;
|
|
10
|
+
/**
|
|
11
|
+
* Insert-table dialog: rows x columns and an optional header row. Cell
|
|
12
|
+
* merge/split is intentionally not offered anywhere in this dialog or the
|
|
13
|
+
* table it creates — see the comment on `TablePlugin` in `EditorRoot.tsx`.
|
|
14
|
+
*/
|
|
15
|
+
export function TableDialog({ opened, onSubmit, onClose }) {
|
|
16
|
+
const strings = useUiStrings();
|
|
17
|
+
const portalTarget = usePortalTarget();
|
|
18
|
+
const [rows, setRows] = useState(DEFAULT_ROWS);
|
|
19
|
+
const [columns, setColumns] = useState(DEFAULT_COLUMNS);
|
|
20
|
+
const [headerRow, setHeaderRow] = useState(true);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!opened)
|
|
23
|
+
return;
|
|
24
|
+
setRows(DEFAULT_ROWS);
|
|
25
|
+
setColumns(DEFAULT_COLUMNS);
|
|
26
|
+
setHeaderRow(true);
|
|
27
|
+
}, [opened]);
|
|
28
|
+
const handleSubmit = (e) => {
|
|
29
|
+
e.preventDefault();
|
|
30
|
+
onSubmit({ rows, columns, headerRow });
|
|
31
|
+
};
|
|
32
|
+
return (_jsx(Modal, { opened: opened, onClose: onClose, title: strings.tableDialog.title, centered: true, size: "sm", portalProps: { target: portalTarget }, children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsxs(Group, { grow: true, align: "flex-end", children: [_jsx(NumberInput, { label: strings.tableDialog.rows, min: MIN_DIMENSION, max: MAX_DIMENSION, value: rows, onChange: (v) => setRows(typeof v === 'number' ? v : DEFAULT_ROWS), "data-autofocus": true }), _jsx(NumberInput, { label: strings.tableDialog.columns, min: MIN_DIMENSION, max: MAX_DIMENSION, value: columns, onChange: (v) => setColumns(typeof v === 'number' ? v : DEFAULT_COLUMNS) })] }), _jsx(Checkbox, { mt: "sm", label: strings.tableDialog.headerRow, checked: headerRow, onChange: (e) => setHeaderRow(e.currentTarget.checked) }), _jsxs(Group, { justify: "flex-end", gap: "xs", mt: "md", children: [_jsx(Button, { variant: "default", onClick: onClose, children: strings.common.cancel }), _jsx(Button, { type: "submit", children: strings.common.insert })] })] }) }));
|
|
33
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAsDA,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA8YvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAo6BxJ"}
|
|
@@ -11,6 +11,9 @@ import { $findMatchingParent, $insertNodeToNearestRoot } from '@lexical/utils';
|
|
|
11
11
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
12
12
|
import { ImageDialog } from '../image/ImageDialog.js';
|
|
13
13
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
14
|
+
import { TableDialog } from './TableDialog.js';
|
|
15
|
+
import { $getTableCellNodeFromLexicalNode, $isTableSelection, INSERT_TABLE_COMMAND } from '@lexical/table';
|
|
16
|
+
import { $deleteTable, $deleteTableColumns, $deleteTableRows, $getTableSelectionSize, $insertTableColumns, $insertTableRows, } from '../table/tableActions.js';
|
|
14
17
|
import { $createLinkNode, $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
|
|
15
18
|
import { LinkDialog } from './LinkDialog.js';
|
|
16
19
|
import { DraftsDialog } from './DraftsDialog.js';
|
|
@@ -19,7 +22,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
19
22
|
import { setStyleProperty } from '../utils/style.js';
|
|
20
23
|
import { useStrings } from '../i18n/useStrings.js';
|
|
21
24
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
22
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
25
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
23
26
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
24
27
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
25
28
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -33,6 +36,9 @@ const INITIAL_STATE = {
|
|
|
33
36
|
fontSize: UNSET_STYLE,
|
|
34
37
|
isLink: false,
|
|
35
38
|
linkUrl: '',
|
|
39
|
+
inTable: false,
|
|
40
|
+
tableRows: 1,
|
|
41
|
+
tableColumns: 1,
|
|
36
42
|
canUndo: false,
|
|
37
43
|
canRedo: false,
|
|
38
44
|
};
|
|
@@ -121,6 +127,21 @@ function LinkMenuItems({ url, onEdit, onRemove, strings }) {
|
|
|
121
127
|
// Not a URL the editor would accept (e.g. loaded from a document): show it, don't make it clickable.
|
|
122
128
|
_jsx(Menu.Item, { disabled: true, title: url, className: "likhari-link-menu-url", children: url || strings.link.noUrl })), _jsx(Menu.Item, { leftSection: _jsx(IconPencil, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onEdit, children: strings.link.editLink }), _jsx(Menu.Item, { color: "red", leftSection: _jsx(IconLinkOff, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onRemove, children: strings.link.removeLink })] }));
|
|
123
129
|
}
|
|
130
|
+
/** The table actions menu's contents — shared by the toolbar button and the
|
|
131
|
+
* right-click menu. Each acts on the selected cell, or on every row/column a
|
|
132
|
+
* multi-cell selection covers. */
|
|
133
|
+
function TableMenuItems({ strings, direction, rows, columns, onAction, }) {
|
|
134
|
+
const t = strings.tableMenu;
|
|
135
|
+
// "Before" is the start side, which is on the right in an RTL table.
|
|
136
|
+
const rtl = direction === 'rtl';
|
|
137
|
+
const manyRows = rows > 1;
|
|
138
|
+
const manyColumns = columns > 1;
|
|
139
|
+
const item = (icon, label, action, color) => {
|
|
140
|
+
const Icon = icon;
|
|
141
|
+
return (_jsx(Menu.Item, { color: color, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
|
|
142
|
+
};
|
|
143
|
+
return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconRowInsertTop, manyRows ? t.insertRowsBefore : t.insertRowBefore, () => $insertTableRows(false)), item(IconRowInsertBottom, manyRows ? t.insertRowsAfter : t.insertRowAfter, () => $insertTableRows(true)), item(rtl ? IconColumnInsertRight : IconColumnInsertLeft, manyColumns ? t.insertColumnsBefore : t.insertColumnBefore, () => $insertTableColumns(false)), item(rtl ? IconColumnInsertLeft : IconColumnInsertRight, manyColumns ? t.insertColumnsAfter : t.insertColumnAfter, () => $insertTableColumns(true)), _jsx(Menu.Divider, {}), item(IconRowRemove, manyRows ? t.deleteRows : t.deleteRow, $deleteTableRows), item(IconColumnRemove, manyColumns ? t.deleteColumns : t.deleteColumn, $deleteTableColumns), item(IconTableMinus, t.deleteTable, $deleteTable, 'red')] }));
|
|
144
|
+
}
|
|
124
145
|
export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
125
146
|
const [editor] = useLexicalComposerContext();
|
|
126
147
|
const [state, setState] = useState(INITIAL_STATE);
|
|
@@ -139,9 +160,17 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
139
160
|
const updateToolbar = useCallback(() => {
|
|
140
161
|
editor.getEditorState().read(() => {
|
|
141
162
|
const selection = $getSelection();
|
|
163
|
+
// A selection of several table cells isn't a range selection.
|
|
164
|
+
if ($isTableSelection(selection)) {
|
|
165
|
+
const { rows, columns } = $getTableSelectionSize();
|
|
166
|
+
setState((s) => ({ ...s, inTable: true, tableRows: rows, tableColumns: columns }));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
142
169
|
if (!$isRangeSelection(selection))
|
|
143
170
|
return;
|
|
144
171
|
const anchorNode = selection.anchor.getNode();
|
|
172
|
+
const inTable = $getTableCellNodeFromLexicalNode(anchorNode) !== null;
|
|
173
|
+
const tableSize = inTable ? $getTableSelectionSize() : { rows: 1, columns: 1 };
|
|
145
174
|
const element = anchorNode.getKey() === 'root' ? anchorNode : (anchorNode.getTopLevelElement() ?? anchorNode);
|
|
146
175
|
const listParent = $findMatchingParent(anchorNode, $isListNode);
|
|
147
176
|
const listType = listParent && $isListNode(listParent) ? listParent.getListType() : null;
|
|
@@ -177,6 +206,9 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
177
206
|
fontSize,
|
|
178
207
|
isLink,
|
|
179
208
|
linkUrl,
|
|
209
|
+
inTable,
|
|
210
|
+
tableRows: tableSize.rows,
|
|
211
|
+
tableColumns: tableSize.columns,
|
|
180
212
|
}));
|
|
181
213
|
});
|
|
182
214
|
}, [editor]);
|
|
@@ -276,6 +308,26 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
276
308
|
});
|
|
277
309
|
closeImageDialog();
|
|
278
310
|
};
|
|
311
|
+
const [tableDialogOpen, setTableDialogOpen] = useState(false);
|
|
312
|
+
const openTableDialog = () => {
|
|
313
|
+
snapshotSelection();
|
|
314
|
+
setTableDialogOpen(true);
|
|
315
|
+
};
|
|
316
|
+
const closeTableDialog = () => {
|
|
317
|
+
setTableDialogOpen(false);
|
|
318
|
+
editor.focus();
|
|
319
|
+
};
|
|
320
|
+
const insertTable = ({ rows, columns, headerRow }) => {
|
|
321
|
+
const saved = menuSelectionRef.current;
|
|
322
|
+
if (saved)
|
|
323
|
+
editor.update(() => $setSelection(saved.clone()), { discrete: true });
|
|
324
|
+
editor.dispatchCommand(INSERT_TABLE_COMMAND, {
|
|
325
|
+
rows: String(rows),
|
|
326
|
+
columns: String(columns),
|
|
327
|
+
includeHeaders: { rows: headerRow, columns: false },
|
|
328
|
+
});
|
|
329
|
+
closeTableDialog();
|
|
330
|
+
};
|
|
279
331
|
/** Applies a font property per `config.font.scope`: to the selection, to
|
|
280
332
|
* every text node in the document, or (for 'both') to the selection when
|
|
281
333
|
* there is a range and to the whole document when there isn't. */
|
|
@@ -369,6 +421,50 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
369
421
|
root?.addEventListener('contextmenu', onContextMenu);
|
|
370
422
|
});
|
|
371
423
|
}, [editor, config.links]);
|
|
424
|
+
// Table actions. The menu takes focus, so the selection is snapshotted when it
|
|
425
|
+
// opens and restored before an action runs.
|
|
426
|
+
const runTableAction = (action) => () => {
|
|
427
|
+
restoreSelection();
|
|
428
|
+
editor.update(action);
|
|
429
|
+
editor.focus();
|
|
430
|
+
};
|
|
431
|
+
// Right-clicking a table cell opens the same actions at the pointer.
|
|
432
|
+
const [tableContext, setTableContext] = useState(null);
|
|
433
|
+
useEffect(() => {
|
|
434
|
+
if (!config.tables)
|
|
435
|
+
return;
|
|
436
|
+
const onContextMenu = (event) => {
|
|
437
|
+
if (event.defaultPrevented)
|
|
438
|
+
return; // a link inside the cell already took it
|
|
439
|
+
const cellElement = event.target?.closest?.('td, th');
|
|
440
|
+
if (!cellElement)
|
|
441
|
+
return;
|
|
442
|
+
let handled = false;
|
|
443
|
+
editor.update(() => {
|
|
444
|
+
const node = $getNearestNodeFromDOMNode(cellElement);
|
|
445
|
+
const cell = node ? $getTableCellNodeFromLexicalNode(node) : null;
|
|
446
|
+
if (!cell)
|
|
447
|
+
return;
|
|
448
|
+
handled = true;
|
|
449
|
+
const selection = $getSelection();
|
|
450
|
+
// Keep a multi-cell selection that includes this cell, so "insert
|
|
451
|
+
// rows" / "delete columns" act on everything selected.
|
|
452
|
+
const insideSelection = $isTableSelection(selection) && selection.getNodes().some((n) => n.getKey() === cell.getKey());
|
|
453
|
+
if (!insideSelection)
|
|
454
|
+
cell.selectEnd();
|
|
455
|
+
}, { discrete: true });
|
|
456
|
+
if (!handled)
|
|
457
|
+
return;
|
|
458
|
+
event.preventDefault();
|
|
459
|
+
snapshotSelectionRef.current();
|
|
460
|
+
const size = editor.getEditorState().read($getTableSelectionSize);
|
|
461
|
+
setTableContext({ x: event.clientX, y: event.clientY, rows: size.rows, columns: size.columns });
|
|
462
|
+
};
|
|
463
|
+
return editor.registerRootListener((root, previous) => {
|
|
464
|
+
previous?.removeEventListener('contextmenu', onContextMenu);
|
|
465
|
+
root?.addEventListener('contextmenu', onContextMenu);
|
|
466
|
+
});
|
|
467
|
+
}, [editor, config.tables]);
|
|
372
468
|
// Ctrl/Cmd+K opens the link dialog.
|
|
373
469
|
useEffect(() => {
|
|
374
470
|
if (!config.links)
|
|
@@ -429,7 +525,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
429
525
|
const showFormattingGroup = headingLevels.length > 0 || config.lists.bullet || config.lists.numbered || config.lists.check || config.blocks.quote;
|
|
430
526
|
const showInlineGroup = fmt.bold || fmt.italic || fmt.underline;
|
|
431
527
|
const showAlignGroup = config.alignment.start || config.alignment.center || config.alignment.justify || config.alignment.left || config.alignment.right;
|
|
432
|
-
const showStubInsertGroup = config.images.linked || config.images.embedded || config.blocks.horizontalRule || config.poetry.enabled;
|
|
528
|
+
const showStubInsertGroup = config.images.linked || config.images.embedded || config.tables || config.blocks.horizontalRule || config.poetry.enabled;
|
|
433
529
|
const showLanguageGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck;
|
|
434
530
|
// The "script & cleanup" and "indent/outdent" groups (UI spec §3.3) render
|
|
435
531
|
// as normal inline toolbar groups whenever there's room, and only move
|
|
@@ -599,7 +695,8 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
599
695
|
restoreSelection();
|
|
600
696
|
openLinkDialog();
|
|
601
697
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog })) }, "link")),
|
|
602
|
-
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
698
|
+
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
699
|
+
config.tables && state.inTable && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "data-active": "true", "aria-pressed": "true", "aria-haspopup": "menu", "aria-label": strings.toolbar.tableOptions, title: strings.toolbar.tableOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconTableOptions, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, onAction: runTableAction }) })] }) }, "tableActions")),
|
|
603
700
|
showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && _jsx(StubButton, { icon: IconWand, title: strings.toolbar.autocorrect, comingSoon: strings.toolbar.comingSoon }), config.language.textCleanup && _jsx(StubButton, { icon: IconSparkles, title: strings.toolbar.textCleanup, comingSoon: strings.toolbar.comingSoon }), config.language.spellCheck && _jsx(StubButton, { icon: IconAbc, title: strings.toolbar.spellChecker, comingSoon: strings.toolbar.comingSoon })] }, "language")),
|
|
604
701
|
];
|
|
605
702
|
return (_jsxs("div", { className: "likhari-toolbar", role: "toolbar", "aria-label": strings.toolbar.ariaLabel, ref: toolbarContainerRef, children: [fixedGroups, movableGroups
|
|
@@ -612,7 +709,10 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
612
709
|
}, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: linkContext?.x ?? -9999, top: linkContext?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsx(Menu.Dropdown, { children: _jsx(LinkMenuItems, { url: linkContext?.url ?? '', onEdit: () => {
|
|
613
710
|
restoreSelection();
|
|
614
711
|
openLinkDialog();
|
|
615
|
-
}, onRemove: removeLink, strings: strings }) })] })), _jsxs(
|
|
712
|
+
}, onRemove: removeLink, strings: strings }) })] })), config.tables && (_jsxs(Menu, { opened: tableContext !== null, onChange: (opened) => {
|
|
713
|
+
if (!opened)
|
|
714
|
+
setTableContext(null);
|
|
715
|
+
}, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: tableContext?.x ?? -9999, top: tableContext?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: tableContext?.rows ?? 1, columns: tableContext?.columns ?? 1, onAction: runTableAction }) })] })), _jsxs("div", { "aria-hidden": "true", ref: toolbarMeasureRef, style: {
|
|
616
716
|
position: 'absolute',
|
|
617
717
|
visibility: 'hidden',
|
|
618
718
|
pointerEvents: 'none',
|
|
@@ -621,5 +721,5 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
621
721
|
display: 'flex',
|
|
622
722
|
flexWrap: 'nowrap',
|
|
623
723
|
gap: 8,
|
|
624
|
-
}, children: [fixedGroups, movableGroups.map((group) => (_jsx(MovableGroupButtons, { group: group }, group.key)))] }), (config.images.linked || config.images.embedded) && (_jsx(ImageDialog, { mode: "insert", opened: imageDialogOpen, onSubmit: insertImage, onClose: closeImageDialog })), config.links && (_jsx(LinkDialog, { opened: linkDialogOpen, initialUrl: state.linkUrl, showTextField: linkNeedsText, onSubmit: applyLink, onRemove: state.isLink ? removeLink : undefined, onClose: closeLinkDialog })), drafts && _jsx(DraftsDialog, { opened: draftsOpen, locale: locale, onClose: () => setDraftsOpen(false), ...drafts })] }));
|
|
724
|
+
}, children: [fixedGroups, movableGroups.map((group) => (_jsx(MovableGroupButtons, { group: group }, group.key)))] }), (config.images.linked || config.images.embedded) && (_jsx(ImageDialog, { mode: "insert", opened: imageDialogOpen, onSubmit: insertImage, onClose: closeImageDialog })), config.tables && _jsx(TableDialog, { opened: tableDialogOpen, onSubmit: insertTable, onClose: closeTableDialog }), config.links && (_jsx(LinkDialog, { opened: linkDialogOpen, initialUrl: state.linkUrl, showTextField: linkNeedsText, onSubmit: applyLink, onRemove: state.isLink ? removeLink : undefined, onClose: closeLinkDialog })), drafts && _jsx(DraftsDialog, { opened: draftsOpen, locale: locale, onClose: () => setDraftsOpen(false), ...drafts })] }));
|
|
625
725
|
}
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -38,8 +38,11 @@ export interface Strings {
|
|
|
38
38
|
noMatch: string;
|
|
39
39
|
alignment: string;
|
|
40
40
|
linkOptions: string;
|
|
41
|
+
/** Toolbar button (shown while the caret is in a table) that opens the table actions menu. */
|
|
42
|
+
tableOptions: string;
|
|
41
43
|
insertLink: string;
|
|
42
44
|
insertImage: string;
|
|
45
|
+
insertTable: string;
|
|
43
46
|
insertHorizontalRule: string;
|
|
44
47
|
poetryBlocks: string;
|
|
45
48
|
comingSoon: (label: string) => string;
|
|
@@ -108,6 +111,24 @@ export interface Strings {
|
|
|
108
111
|
delete: string;
|
|
109
112
|
close: string;
|
|
110
113
|
};
|
|
114
|
+
/** The table actions menu (toolbar button and right-click on a cell). */
|
|
115
|
+
tableMenu: {
|
|
116
|
+
menuLabel: string;
|
|
117
|
+
insertRowBefore: string;
|
|
118
|
+
insertRowAfter: string;
|
|
119
|
+
insertColumnBefore: string;
|
|
120
|
+
insertColumnAfter: string;
|
|
121
|
+
deleteRow: string;
|
|
122
|
+
deleteColumn: string;
|
|
123
|
+
deleteTable: string;
|
|
124
|
+
/** Plural forms, used when the selection spans several rows or columns. */
|
|
125
|
+
insertRowsBefore: string;
|
|
126
|
+
insertRowsAfter: string;
|
|
127
|
+
insertColumnsBefore: string;
|
|
128
|
+
insertColumnsAfter: string;
|
|
129
|
+
deleteRows: string;
|
|
130
|
+
deleteColumns: string;
|
|
131
|
+
};
|
|
111
132
|
link: {
|
|
112
133
|
menuLabel: string;
|
|
113
134
|
noUrl: string;
|
|
@@ -124,6 +145,12 @@ export interface Strings {
|
|
|
124
145
|
invalidUrl: string;
|
|
125
146
|
apply: string;
|
|
126
147
|
};
|
|
148
|
+
tableDialog: {
|
|
149
|
+
title: string;
|
|
150
|
+
rows: string;
|
|
151
|
+
columns: string;
|
|
152
|
+
headerRow: string;
|
|
153
|
+
};
|
|
127
154
|
imageDialog: {
|
|
128
155
|
titleInsert: string;
|
|
129
156
|
titleEdit: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -31,8 +31,10 @@ const en = {
|
|
|
31
31
|
noMatch: 'No match',
|
|
32
32
|
alignment: 'Alignment',
|
|
33
33
|
linkOptions: 'Link options',
|
|
34
|
+
tableOptions: 'Table options',
|
|
34
35
|
insertLink: 'Insert link (Ctrl+K)',
|
|
35
36
|
insertImage: 'Insert image',
|
|
37
|
+
insertTable: 'Insert table',
|
|
36
38
|
insertHorizontalRule: 'Insert horizontal rule',
|
|
37
39
|
poetryBlocks: 'Poetry blocks',
|
|
38
40
|
comingSoon: (label) => `${label} (coming soon)`,
|
|
@@ -96,6 +98,22 @@ const en = {
|
|
|
96
98
|
delete: 'Delete',
|
|
97
99
|
close: 'Close',
|
|
98
100
|
},
|
|
101
|
+
tableMenu: {
|
|
102
|
+
menuLabel: 'Table',
|
|
103
|
+
insertRowBefore: 'Insert row before',
|
|
104
|
+
insertRowAfter: 'Insert row after',
|
|
105
|
+
insertColumnBefore: 'Insert column before',
|
|
106
|
+
insertColumnAfter: 'Insert column after',
|
|
107
|
+
deleteRow: 'Delete row',
|
|
108
|
+
deleteColumn: 'Delete column',
|
|
109
|
+
deleteTable: 'Delete table',
|
|
110
|
+
insertRowsBefore: 'Insert rows before',
|
|
111
|
+
insertRowsAfter: 'Insert rows after',
|
|
112
|
+
insertColumnsBefore: 'Insert columns before',
|
|
113
|
+
insertColumnsAfter: 'Insert columns after',
|
|
114
|
+
deleteRows: 'Delete rows',
|
|
115
|
+
deleteColumns: 'Delete columns',
|
|
116
|
+
},
|
|
99
117
|
link: {
|
|
100
118
|
menuLabel: 'Link',
|
|
101
119
|
noUrl: '(no URL)',
|
|
@@ -112,6 +130,12 @@ const en = {
|
|
|
112
130
|
invalidUrl: 'Enter a valid http(s), mailto, tel or relative URL',
|
|
113
131
|
apply: 'Apply',
|
|
114
132
|
},
|
|
133
|
+
tableDialog: {
|
|
134
|
+
title: 'Insert table',
|
|
135
|
+
rows: 'Rows',
|
|
136
|
+
columns: 'Columns',
|
|
137
|
+
headerRow: 'Header row',
|
|
138
|
+
},
|
|
115
139
|
imageDialog: {
|
|
116
140
|
titleInsert: 'Insert image',
|
|
117
141
|
titleEdit: 'Edit image',
|
|
@@ -198,8 +222,10 @@ const ur = {
|
|
|
198
222
|
noMatch: 'کوئی مماثلت نہیں',
|
|
199
223
|
alignment: 'سیدھ',
|
|
200
224
|
linkOptions: 'لنک کے اختیارات',
|
|
225
|
+
tableOptions: 'جدول کے اختیارات',
|
|
201
226
|
insertLink: 'لنک شامل کریں (Ctrl+K)',
|
|
202
227
|
insertImage: 'تصویر شامل کریں',
|
|
228
|
+
insertTable: 'جدول شامل کریں',
|
|
203
229
|
insertHorizontalRule: 'افقی لکیر شامل کریں',
|
|
204
230
|
poetryBlocks: 'شاعری کے بلاکس',
|
|
205
231
|
comingSoon: (label) => `${label} (جلد آ رہا ہے)`,
|
|
@@ -263,6 +289,22 @@ const ur = {
|
|
|
263
289
|
delete: 'حذف کریں',
|
|
264
290
|
close: 'بند کریں',
|
|
265
291
|
},
|
|
292
|
+
tableMenu: {
|
|
293
|
+
menuLabel: 'جدول',
|
|
294
|
+
insertRowBefore: 'پہلے قطار شامل کریں',
|
|
295
|
+
insertRowAfter: 'بعد میں قطار شامل کریں',
|
|
296
|
+
insertColumnBefore: 'پہلے کالم شامل کریں',
|
|
297
|
+
insertColumnAfter: 'بعد میں کالم شامل کریں',
|
|
298
|
+
deleteRow: 'قطار حذف کریں',
|
|
299
|
+
deleteColumn: 'کالم حذف کریں',
|
|
300
|
+
deleteTable: 'جدول حذف کریں',
|
|
301
|
+
insertRowsBefore: 'پہلے قطاریں شامل کریں',
|
|
302
|
+
insertRowsAfter: 'بعد میں قطاریں شامل کریں',
|
|
303
|
+
insertColumnsBefore: 'پہلے کالمز شامل کریں',
|
|
304
|
+
insertColumnsAfter: 'بعد میں کالمز شامل کریں',
|
|
305
|
+
deleteRows: 'قطاریں حذف کریں',
|
|
306
|
+
deleteColumns: 'کالمز حذف کریں',
|
|
307
|
+
},
|
|
266
308
|
link: {
|
|
267
309
|
menuLabel: 'لنک',
|
|
268
310
|
noUrl: '(کوئی یو آر ایل نہیں)',
|
|
@@ -279,6 +321,12 @@ const ur = {
|
|
|
279
321
|
invalidUrl: 'براہِ کرم ایک درست http(s)، mailto، tel یا رشتہ دار یو آر ایل درج کریں',
|
|
280
322
|
apply: 'لاگو کریں',
|
|
281
323
|
},
|
|
324
|
+
tableDialog: {
|
|
325
|
+
title: 'جدول شامل کریں',
|
|
326
|
+
rows: 'قطاریں',
|
|
327
|
+
columns: 'کالم',
|
|
328
|
+
headerRow: 'سرِ فہرست قطار',
|
|
329
|
+
},
|
|
282
330
|
imageDialog: {
|
|
283
331
|
titleInsert: 'تصویر شامل کریں',
|
|
284
332
|
titleEdit: 'تصویر میں ترمیم کریں',
|
|
@@ -365,8 +413,10 @@ const paShahmukhi = {
|
|
|
365
413
|
noMatch: 'کوئی نئیں ملیا',
|
|
366
414
|
alignment: 'سیدھ',
|
|
367
415
|
linkOptions: 'لنک دے اختیار',
|
|
416
|
+
tableOptions: 'ٹیبل دے اختیار',
|
|
368
417
|
insertLink: 'لنک پاؤ (Ctrl+K)',
|
|
369
418
|
insertImage: 'تصویر پاؤ',
|
|
419
|
+
insertTable: 'ٹیبل پاؤ',
|
|
370
420
|
insertHorizontalRule: 'لیٹی لکیر پاؤ',
|
|
371
421
|
poetryBlocks: 'شاعری بلاک',
|
|
372
422
|
comingSoon: (label) => `${label} (چھیتی آ رہا اے)`,
|
|
@@ -430,6 +480,22 @@ const paShahmukhi = {
|
|
|
430
480
|
delete: 'مٹاؤ',
|
|
431
481
|
close: 'بند کرو',
|
|
432
482
|
},
|
|
483
|
+
tableMenu: {
|
|
484
|
+
menuLabel: 'ٹیبل',
|
|
485
|
+
insertRowBefore: 'پہلاں قطار پاؤ',
|
|
486
|
+
insertRowAfter: 'بعد وچ قطار پاؤ',
|
|
487
|
+
insertColumnBefore: 'پہلاں کالم پاؤ',
|
|
488
|
+
insertColumnAfter: 'بعد وچ کالم پاؤ',
|
|
489
|
+
deleteRow: 'قطار مٹاؤ',
|
|
490
|
+
deleteColumn: 'کالم مٹاؤ',
|
|
491
|
+
deleteTable: 'ٹیبل مٹاؤ',
|
|
492
|
+
insertRowsBefore: 'پہلاں قطاراں پاؤ',
|
|
493
|
+
insertRowsAfter: 'بعد وچ قطاراں پاؤ',
|
|
494
|
+
insertColumnsBefore: 'پہلاں کالماں پاؤ',
|
|
495
|
+
insertColumnsAfter: 'بعد وچ کالماں پاؤ',
|
|
496
|
+
deleteRows: 'قطاراں مٹاؤ',
|
|
497
|
+
deleteColumns: 'کالماں مٹاؤ',
|
|
498
|
+
},
|
|
433
499
|
link: {
|
|
434
500
|
menuLabel: 'لنک',
|
|
435
501
|
noUrl: '(کوئی یو آر ایل نئیں)',
|
|
@@ -446,6 +512,12 @@ const paShahmukhi = {
|
|
|
446
512
|
invalidUrl: 'کِرپا کر کے صحیح http(s)، mailto، tel یا نسبتی یو آر ایل پاؤ',
|
|
447
513
|
apply: 'لاگو کرو',
|
|
448
514
|
},
|
|
515
|
+
tableDialog: {
|
|
516
|
+
title: 'ٹیبل پاؤ',
|
|
517
|
+
rows: 'قطاراں',
|
|
518
|
+
columns: 'کالم',
|
|
519
|
+
headerRow: 'سرکڑی قطار',
|
|
520
|
+
},
|
|
449
521
|
imageDialog: {
|
|
450
522
|
titleInsert: 'تصویر پاؤ',
|
|
451
523
|
titleEdit: 'تصویر وچ تبدیلی کرو',
|
package/dist/nodes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQlD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAW5C,CAAC"}
|
package/dist/nodes.js
CHANGED
|
@@ -2,6 +2,7 @@ import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
|
|
2
2
|
import { ListItemNode, ListNode } from '@lexical/list';
|
|
3
3
|
import { LinkNode } from '@lexical/link';
|
|
4
4
|
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
5
|
+
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
5
6
|
import { ImageNode } from './image/ImageNode.js';
|
|
6
7
|
/**
|
|
7
8
|
* Node types registered on the editor at construction time. Per
|
|
@@ -19,5 +20,8 @@ export const EDITOR_NODES = [
|
|
|
19
20
|
ListItemNode,
|
|
20
21
|
LinkNode,
|
|
21
22
|
HorizontalRuleNode,
|
|
23
|
+
TableNode,
|
|
24
|
+
TableRowNode,
|
|
25
|
+
TableCellNode,
|
|
22
26
|
ImageNode,
|
|
23
27
|
];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** How many rows and columns the selection spans (1 × 1 for a caret in a cell, 0 × 0 outside a table). */
|
|
2
|
+
export declare function $getTableSelectionSize(): {
|
|
3
|
+
rows: number;
|
|
4
|
+
columns: number;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Inserts as many rows as the selection spans, before its first row or after
|
|
8
|
+
* its last. Lexical's own insert works from the selection's focus cell and adds
|
|
9
|
+
* one row, so with several rows selected it would land mid-selection.
|
|
10
|
+
*/
|
|
11
|
+
export declare function $insertTableRows(insertAfter: boolean): void;
|
|
12
|
+
/** Like $insertTableRows, for columns. "Before" is the column index below the
|
|
13
|
+
* first selected one (the right-hand side in a right-to-left table). */
|
|
14
|
+
export declare function $insertTableColumns(insertAfter: boolean): void;
|
|
15
|
+
/** Deletes every row the selection touches (Lexical handles a multi-cell selection). */
|
|
16
|
+
export declare function $deleteTableRows(): void;
|
|
17
|
+
/** Deletes every column the selection touches. */
|
|
18
|
+
export declare function $deleteTableColumns(): void;
|
|
19
|
+
/** Removes the whole table the selection is in. */
|
|
20
|
+
export declare function $deleteTable(): void;
|
|
21
|
+
//# sourceMappingURL=tableActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableActions.d.ts","sourceRoot":"","sources":["../../src/table/tableActions.ts"],"names":[],"mappings":"AA2BA,0GAA0G;AAC1G,wBAAgB,sBAAsB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAS1E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAS3D;AAED;wEACwE;AACxE,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAQ9D;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,kDAAkD;AAClD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,mDAAmD;AACnD,wBAAgB,YAAY,IAAI,IAAI,CAInC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { $deleteTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $getTableCellNodeFromLexicalNode, $getTableColumnIndexFromTableCellNode, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $insertTableColumn__EXPERIMENTAL, $insertTableRow__EXPERIMENTAL, $isTableCellNode, $isTableSelection, } from '@lexical/table';
|
|
2
|
+
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
3
|
+
/** Table cells the selection covers: the caret's own cell, or every cell of a
|
|
4
|
+
* multi-cell selection. Empty when the selection isn't in a table. */
|
|
5
|
+
function $selectedCells() {
|
|
6
|
+
const selection = $getSelection();
|
|
7
|
+
if ($isTableSelection(selection))
|
|
8
|
+
return selection.getNodes().filter($isTableCellNode);
|
|
9
|
+
if ($isRangeSelection(selection)) {
|
|
10
|
+
const cell = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());
|
|
11
|
+
return cell ? [cell] : [];
|
|
12
|
+
}
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
/** How many rows and columns the selection spans (1 × 1 for a caret in a cell, 0 × 0 outside a table). */
|
|
16
|
+
export function $getTableSelectionSize() {
|
|
17
|
+
const cells = $selectedCells();
|
|
18
|
+
if (cells.length === 0)
|
|
19
|
+
return { rows: 0, columns: 0 };
|
|
20
|
+
const rows = cells.map($getTableRowIndexFromTableCellNode);
|
|
21
|
+
const columns = cells.map($getTableColumnIndexFromTableCellNode);
|
|
22
|
+
return {
|
|
23
|
+
rows: Math.max(...rows) - Math.min(...rows) + 1,
|
|
24
|
+
columns: Math.max(...columns) - Math.min(...columns) + 1,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Inserts as many rows as the selection spans, before its first row or after
|
|
29
|
+
* its last. Lexical's own insert works from the selection's focus cell and adds
|
|
30
|
+
* one row, so with several rows selected it would land mid-selection.
|
|
31
|
+
*/
|
|
32
|
+
export function $insertTableRows(insertAfter) {
|
|
33
|
+
const cells = $selectedCells();
|
|
34
|
+
if (cells.length === 0)
|
|
35
|
+
return;
|
|
36
|
+
const rows = cells.map($getTableRowIndexFromTableCellNode);
|
|
37
|
+
const first = Math.min(...rows);
|
|
38
|
+
const last = Math.max(...rows);
|
|
39
|
+
// Park the caret in a cell on the edge row; every insert then lands right next to it.
|
|
40
|
+
cells[rows.indexOf(insertAfter ? last : first)].selectEnd();
|
|
41
|
+
for (let i = 0; i <= last - first; i++)
|
|
42
|
+
$insertTableRow__EXPERIMENTAL(insertAfter);
|
|
43
|
+
}
|
|
44
|
+
/** Like $insertTableRows, for columns. "Before" is the column index below the
|
|
45
|
+
* first selected one (the right-hand side in a right-to-left table). */
|
|
46
|
+
export function $insertTableColumns(insertAfter) {
|
|
47
|
+
const cells = $selectedCells();
|
|
48
|
+
if (cells.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
const columns = cells.map($getTableColumnIndexFromTableCellNode);
|
|
51
|
+
const first = Math.min(...columns);
|
|
52
|
+
const last = Math.max(...columns);
|
|
53
|
+
cells[columns.indexOf(insertAfter ? last : first)].selectEnd();
|
|
54
|
+
for (let i = 0; i <= last - first; i++)
|
|
55
|
+
$insertTableColumn__EXPERIMENTAL(insertAfter);
|
|
56
|
+
}
|
|
57
|
+
/** Deletes every row the selection touches (Lexical handles a multi-cell selection). */
|
|
58
|
+
export function $deleteTableRows() {
|
|
59
|
+
$deleteTableRow__EXPERIMENTAL();
|
|
60
|
+
}
|
|
61
|
+
/** Deletes every column the selection touches. */
|
|
62
|
+
export function $deleteTableColumns() {
|
|
63
|
+
$deleteTableColumn__EXPERIMENTAL();
|
|
64
|
+
}
|
|
65
|
+
/** Removes the whole table the selection is in. */
|
|
66
|
+
export function $deleteTable() {
|
|
67
|
+
const selection = $getSelection();
|
|
68
|
+
const anchor = $isRangeSelection(selection) || $isTableSelection(selection) ? selection.anchor.getNode() : null;
|
|
69
|
+
if (anchor)
|
|
70
|
+
$getTableNodeFromLexicalNodeOrThrow(anchor).remove();
|
|
71
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -51,6 +51,12 @@
|
|
|
51
51
|
pointer-events: none;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/* pointer-events is inherited, so without this every menu, dropdown and dialog
|
|
55
|
+
portaled into the (pointer-transparent) anchor would be unclickable. */
|
|
56
|
+
.likhari-portal-target > * {
|
|
57
|
+
pointer-events: auto;
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
.likhari-toolbar-group {
|
|
55
61
|
display: flex;
|
|
56
62
|
align-items: center;
|
|
@@ -253,6 +259,37 @@
|
|
|
253
259
|
margin: 1.5em 0;
|
|
254
260
|
}
|
|
255
261
|
|
|
262
|
+
/* Tables — cell merge/split is deliberately out of scope for now (a flagged
|
|
263
|
+
open risk, lexical-editor-spec.md §12 item 3, needing its own scope
|
|
264
|
+
decision); TablePlugin is configured with hasCellMerge={false} to keep
|
|
265
|
+
every table a plain grid until that's resolved. */
|
|
266
|
+
.likhari-table {
|
|
267
|
+
border-collapse: collapse;
|
|
268
|
+
margin: 1em 0;
|
|
269
|
+
width: 100%;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.likhari-table-row {
|
|
273
|
+
border-bottom: 1px solid var(--editor-line);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.likhari-table-cell {
|
|
277
|
+
border: 1px solid var(--editor-line);
|
|
278
|
+
padding: 6px 10px;
|
|
279
|
+
min-width: 72px;
|
|
280
|
+
vertical-align: top;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.likhari-table-cell-header {
|
|
284
|
+
background: var(--editor-paper-dim);
|
|
285
|
+
font-weight: 600;
|
|
286
|
+
text-align: start;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.likhari-table-cell-selected {
|
|
290
|
+
background: var(--editor-accent-soft);
|
|
291
|
+
}
|
|
292
|
+
|
|
256
293
|
/* Images — block-level figure; the caption is static text (edited in the
|
|
257
294
|
image's dialog), and a selected image gets a corner resize handle. */
|
|
258
295
|
.likhari-image-block {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,kBAmCzB,CAAC"}
|
|
@@ -33,4 +33,9 @@ export const editorTheme = {
|
|
|
33
33
|
},
|
|
34
34
|
hr: 'likhari-hr',
|
|
35
35
|
image: 'likhari-image-block',
|
|
36
|
+
table: 'likhari-table',
|
|
37
|
+
tableRow: 'likhari-table-row',
|
|
38
|
+
tableCell: 'likhari-table-cell',
|
|
39
|
+
tableCellHeader: 'likhari-table-cell-header',
|
|
40
|
+
tableCellSelected: 'likhari-table-cell-selected',
|
|
36
41
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inshapardaz/likhari-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "React implementation of the Likhari editor, built on @lexical/react.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@lexical/react": "^0.20.0",
|
|
39
39
|
"@lexical/rich-text": "^0.20.0",
|
|
40
40
|
"@lexical/selection": "^0.20.0",
|
|
41
|
+
"@lexical/table": "^0.20.0",
|
|
41
42
|
"@lexical/utils": "^0.20.0",
|
|
42
43
|
"@inshapardaz/likhari-converters": "^0.1.0",
|
|
43
44
|
"@inshapardaz/likhari-core": "^0.1.0",
|