@inshapardaz/likhari-react 0.1.47 → 0.1.48
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/components/Toolbar.d.ts +6 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +189 -56
- package/dist/i18n/strings.d.ts +19 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +39 -0
- package/dist/theme/editor.css +213 -0
- package/package.json +1 -1
|
@@ -7,6 +7,12 @@ import { type FontMode, type FontOption } from '../fonts/index.js';
|
|
|
7
7
|
import type { Locale } from '../i18n/strings.js';
|
|
8
8
|
/** Appearance of the toolbar. The accent colour comes from the editor's `accentColor`. */
|
|
9
9
|
export interface ToolbarStyle {
|
|
10
|
+
/**
|
|
11
|
+
* `classic` is the single row of command groups (UI spec §3.1); `ribbon` puts the same
|
|
12
|
+
* commands on tabs (Home, Insert, Tools, View) with Table, Poetry and Link tabs that
|
|
13
|
+
* appear while the caret is in that kind of content (UI spec §3.4). Default `classic`.
|
|
14
|
+
*/
|
|
15
|
+
layout?: 'classic' | 'ribbon';
|
|
10
16
|
/** Outline the toolbar and each button cluster. Default true. */
|
|
11
17
|
bordered?: boolean;
|
|
12
18
|
/** `light` tints the active button, `filled` fills it with the accent. Default `light`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA2CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAmDtF,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAkF,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAI1I,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA2CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAmDtF,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAkF,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAI1I,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AAklBvD,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gCAAgC;IAChC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,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;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gJAAgJ;IAChJ,kBAAkB,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;IAC5C,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B;AAED;iFACiF;AACjF,eAAO,MAAM,gBAAgB,8EAA8E,CAAC;AAE5G,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAqB,EAAE,eAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,QAAsB,EAAE,iBAAiB,EAAE,IAAU,EAAE,yBAAyB,EAAE,YAAY,EAAE,SAAiB,EAAE,MAAa,EAAE,kBAA2B,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,YAAY,+BAmkD3d"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { Fragment, forwardRef, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Menu, Select, Toolbar as MantineToolbar } from '@mantine/core';
|
|
4
4
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
5
5
|
import { $getSelection, $isRangeSelection, $isElementNode, $setSelection, $getRoot, $selectAll, $getNearestNodeFromDOMNode, $createTextNode, KEY_MODIFIER_COMMAND, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, UNDO_COMMAND, REDO_COMMAND, SELECTION_CHANGE_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, COMMAND_PRIORITY_LOW, } from 'lexical';
|
|
@@ -36,7 +36,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX, ZOOM_LEVELS_
|
|
|
36
36
|
import { setStyleProperty } from '../utils/style.js';
|
|
37
37
|
import { useStrings } from '../i18n/useStrings.js';
|
|
38
38
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
39
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconArrowsJoin, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHelpCircle, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconClipboard, IconCopy, IconCut, IconSearch, IconSelectAll, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconMinus, IconPlus, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
39
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconArrowsJoin, IconBold, IconClearFormatting, IconDeviceFloppy, IconChevronDown, IconChevronUp, IconDots, IconHelpCircle, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconClipboard, IconCopy, IconCut, IconSearch, IconSelectAll, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconMinus, IconPlus, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
40
40
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
41
41
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
42
42
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -172,27 +172,34 @@ function ToolbarSelect({ icon: Icon, label, value, data, width, disabled, placeh
|
|
|
172
172
|
function MoreMenuItem({ icon: Icon, label, active, onClick, }) {
|
|
173
173
|
return (_jsx(Menu.Item, { leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), "data-active": active ? 'true' : 'false', onMouseDown: (e) => e.preventDefault(), onClick: onClick, children: label }));
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
/** One command, as a menu item or as a ribbon button (the label becomes its tooltip and name). */
|
|
176
|
+
function CommandItem({ mode, icon: Icon, label, onClick, disabled, color, }) {
|
|
177
|
+
if (mode === 'ribbon') {
|
|
178
|
+
return _jsx(ToolbarButton, { icon: Icon, title: label, disabled: disabled, "data-danger": color === 'red' ? 'true' : undefined, onClick: onClick });
|
|
179
|
+
}
|
|
180
|
+
return (_jsx(Menu.Item, { color: color, disabled: disabled, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onClick, children: label }));
|
|
181
|
+
}
|
|
182
|
+
/** A group heading in a menu; the ribbon's tab already names the group, so it shows nothing there. */
|
|
183
|
+
const ItemLabel = ({ mode, children }) => (mode === 'ribbon' ? null : _jsx(Menu.Label, { children: children }));
|
|
184
|
+
const ItemDivider = ({ mode }) => (mode === 'ribbon' ? _jsx(MantineToolbar.Divider, {}) : _jsx(Menu.Divider, {}));
|
|
185
|
+
function LinkMenuItems({ url, onEdit, onRemove, strings, mode = 'menu' }) {
|
|
176
186
|
// Only offer the link as clickable if it's a URL the editor would have accepted.
|
|
177
187
|
const safeUrl = normalizeLinkUrl(url);
|
|
178
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
188
|
+
return (_jsxs(_Fragment, { children: [_jsx(ItemLabel, { mode: mode, children: strings.link.menuLabel }), mode === 'ribbon' ? (safeUrl && (_jsx(MantineToolbar.Toggle, { component: "a", href: safeUrl, target: "_blank", rel: "noopener noreferrer", "aria-label": url, title: url, children: _jsx(IconExternalLink, { size: ICON_SIZE, stroke: ICON_STROKE }) }))) : safeUrl ? (_jsx(Menu.Item, { component: "a", href: safeUrl, target: "_blank", rel: "noopener noreferrer", leftSection: _jsx(IconExternalLink, { size: ICON_SIZE, stroke: ICON_STROKE }), title: url, className: "likhari-link-menu-url", children: url })) : (
|
|
179
189
|
// Not a URL the editor would accept (e.g. loaded from a document): show it, don't make it clickable.
|
|
180
|
-
_jsx(Menu.Item, { disabled: true, title: url, className: "likhari-link-menu-url", children: url || strings.link.noUrl })), _jsx(
|
|
190
|
+
_jsx(Menu.Item, { disabled: true, title: url, className: "likhari-link-menu-url", children: url || strings.link.noUrl })), _jsx(CommandItem, { mode: mode, icon: IconPencil, label: strings.link.editLink, onClick: onEdit }), _jsx(CommandItem, { mode: mode, icon: IconLinkOff, label: strings.link.removeLink, onClick: onRemove, color: "red" })] }));
|
|
181
191
|
}
|
|
182
192
|
/** The table actions menu's contents — shared by the toolbar button and the
|
|
183
193
|
* right-click menu. Each acts on the selected cell, or on every row/column a
|
|
184
194
|
* multi-cell selection covers. */
|
|
185
|
-
function TableMenuItems({ strings, direction, rows, columns, canMergeCells, canUnmergeCell, onAction, }) {
|
|
195
|
+
function TableMenuItems({ strings, direction, rows, columns, canMergeCells, canUnmergeCell, onAction, mode = 'menu', }) {
|
|
186
196
|
const t = strings.tableMenu;
|
|
187
197
|
// "Before" is the start side, which is on the right in an RTL table.
|
|
188
198
|
const rtl = direction === 'rtl';
|
|
189
199
|
const manyRows = rows > 1;
|
|
190
200
|
const manyColumns = columns > 1;
|
|
191
|
-
const item = (icon, label, action, color) => {
|
|
192
|
-
|
|
193
|
-
return (_jsx(Menu.Item, { color: color, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
|
|
194
|
-
};
|
|
195
|
-
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)), (canMergeCells || canUnmergeCell) && _jsx(Menu.Divider, {}), canMergeCells && item(IconArrowMergeBoth, t.mergeCells, $mergeTableCells), canUnmergeCell && item(IconArrowsSplit2, t.unmergeCell, $unmergeTableCell), _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')] }));
|
|
201
|
+
const item = (icon, label, action, color) => (_jsx(CommandItem, { mode: mode, icon: icon, label: label, onClick: onAction(action), color: color }));
|
|
202
|
+
return (_jsxs(_Fragment, { children: [_jsx(ItemLabel, { mode: mode, 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)), (canMergeCells || canUnmergeCell) && _jsx(ItemDivider, { mode: mode }), canMergeCells && item(IconArrowMergeBoth, t.mergeCells, $mergeTableCells), canUnmergeCell && item(IconArrowsSplit2, t.unmergeCell, $unmergeTableCell), _jsx(ItemDivider, { mode: mode }), item(IconRowRemove, manyRows ? t.deleteRows : t.deleteRow, $deleteTableRows), item(IconColumnRemove, manyColumns ? t.deleteColumns : t.deleteColumn, $deleteTableColumns), item(IconTableMinus, t.deleteTable, $deleteTable, 'red')] }));
|
|
196
203
|
}
|
|
197
204
|
/** Whether a one-notch step from `value` stays on the scale — a step that
|
|
198
205
|
* would fall off either end is disabled rather than silently clamped. */
|
|
@@ -200,18 +207,15 @@ function canStep(scale, value, step) {
|
|
|
200
207
|
const next = scale.indexOf(value) + step;
|
|
201
208
|
return next >= 0 && next < scale.length;
|
|
202
209
|
}
|
|
203
|
-
function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
|
|
210
|
+
function PoetryMenuItems({ strings, layout, scale, centered, onAction, mode = 'menu', }) {
|
|
204
211
|
const t = strings.poetryMenu;
|
|
205
|
-
const item = (icon, label, action, active = false, color) => {
|
|
206
|
-
const Icon = icon;
|
|
207
|
-
return (_jsx(Menu.Item, { color: color, disabled: active, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
|
|
208
|
-
};
|
|
212
|
+
const item = (icon, label, action, active = false, color) => (_jsx(CommandItem, { mode: mode, icon: icon, label: label, onClick: onAction(action), disabled: active, color: color }));
|
|
209
213
|
const setLayout = (next) => () => {
|
|
210
214
|
const node = $getPoetryBlockFromSelection();
|
|
211
215
|
if (node)
|
|
212
216
|
$setPoetryLayout(node, next);
|
|
213
217
|
};
|
|
214
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
218
|
+
return (_jsxs(_Fragment, { children: [_jsx(ItemLabel, { mode: mode, children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(ItemDivider, { mode: mode }), _jsx(ItemDivider, { mode: mode }), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), centered && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCenter, () => $adjustPoetryCenterWidth(-1), !canStep(POETRY_CENTER_WIDTHS, scale.centerWidth, -1)), item(IconArrowsMaximize, t.widerCenter, () => $adjustPoetryCenterWidth(1), !canStep(POETRY_CENTER_WIDTHS, scale.centerWidth, 1))] })), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
|
|
215
219
|
}
|
|
216
220
|
/** `docs/markdown-dialect.md` at the repository's default branch — the Markdown
|
|
217
221
|
* format this editor reads and writes, including the poetry container syntax. */
|
|
@@ -220,6 +224,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
220
224
|
const bordered = toolbarStyle?.bordered ?? true;
|
|
221
225
|
const variant = toolbarStyle?.variant ?? 'light';
|
|
222
226
|
const overflowEnabled = toolbarStyle?.overflow ?? true;
|
|
227
|
+
const ribbon = toolbarStyle?.layout === 'ribbon';
|
|
223
228
|
const [editor] = useLexicalComposerContext();
|
|
224
229
|
const [state, setState] = useState(INITIAL_STATE);
|
|
225
230
|
const strings = useStrings(locale);
|
|
@@ -559,6 +564,34 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
559
564
|
editor.focus();
|
|
560
565
|
};
|
|
561
566
|
const [contextMenu, setContextMenu] = useState(null);
|
|
567
|
+
const [ribbonTab, setRibbonTab] = useState('home');
|
|
568
|
+
const ribbonId = useId();
|
|
569
|
+
// Collapsed: only the tabs show. Clicking a tab then "peeks" at its commands in a panel over the canvas.
|
|
570
|
+
const [ribbonCollapsed, setRibbonCollapsed] = useState(false);
|
|
571
|
+
const [ribbonPeek, setRibbonPeek] = useState(false);
|
|
572
|
+
const ribbonRootRef = useRef(null);
|
|
573
|
+
useEffect(() => {
|
|
574
|
+
if (!ribbonPeek)
|
|
575
|
+
return;
|
|
576
|
+
// A click outside the ribbon closes the peek, but not one in a menu or dropdown it opened: those
|
|
577
|
+
// render in the editor's portal anchor, outside the ribbon's own DOM.
|
|
578
|
+
const onPointerDown = (event) => {
|
|
579
|
+
const target = event.target;
|
|
580
|
+
if (target && (ribbonRootRef.current?.contains(target) || target.closest?.('.likhari-portal-target')))
|
|
581
|
+
return;
|
|
582
|
+
setRibbonPeek(false);
|
|
583
|
+
};
|
|
584
|
+
const onKeyDown = (event) => {
|
|
585
|
+
if (event.key === 'Escape')
|
|
586
|
+
setRibbonPeek(false);
|
|
587
|
+
};
|
|
588
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
589
|
+
document.addEventListener('keydown', onKeyDown);
|
|
590
|
+
return () => {
|
|
591
|
+
document.removeEventListener('pointerdown', onPointerDown, true);
|
|
592
|
+
document.removeEventListener('keydown', onKeyDown);
|
|
593
|
+
};
|
|
594
|
+
}, [ribbonPeek]);
|
|
562
595
|
useEffect(() => {
|
|
563
596
|
const onContextMenu = async (event) => {
|
|
564
597
|
event.preventDefault();
|
|
@@ -847,17 +880,22 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
847
880
|
editor.focus();
|
|
848
881
|
}
|
|
849
882
|
: withRefocus((v) => applyFont('font-family', v)) })), config.font.size && !uniform && (_jsx(ToolbarSelect, { icon: IconTextSize, label: strings.toolbar.fontSize, width: 84, value: FONT_SIZES_PX.some((px) => `${px}px` === shownFontSize) ? shownFontSize : null, placeholder: strings.toolbar.fontSizePlaceholder, data: FONT_SIZES_PX.map((px) => ({ value: `${px}px`, label: String(px) })), onMouseDown: snapshotSelection, onChange: withRefocus((v) => applyFont('font-size', v)) }))] }, "font"));
|
|
850
|
-
|
|
851
|
-
|
|
883
|
+
/** The insert commands. `contextual` also puts the link, table and poetry option menus among them (the classic
|
|
884
|
+
* toolbar); the ribbon shows those on their own tabs instead. */
|
|
885
|
+
const insertButtons = (contextual) => (_jsxs(_Fragment, { children: [config.links &&
|
|
886
|
+
(contextual && state.isLink ? (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.linkOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(LinkMenuItems, { url: state.linkUrl, onEdit: () => {
|
|
852
887
|
restoreSelection();
|
|
853
888
|
openLinkDialog();
|
|
854
|
-
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog }))), (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.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.tables && state.inTable && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconTableOptions, title: strings.toolbar.tableOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }) })] })), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.footnotes && (_jsx(ToolbarButton, { icon: IconNumber1Small, title: strings.toolbar.insertFootnote, onClick: () => editor.dispatchCommand(INSERT_FOOTNOTE_COMMAND, undefined) })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) })), config.poetry.enabled && state.inPoetry && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.poetryOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] }))] }
|
|
889
|
+
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog }))), (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.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), contextual && config.tables && state.inTable && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconTableOptions, title: strings.toolbar.tableOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }) })] })), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.footnotes && (_jsx(ToolbarButton, { icon: IconNumber1Small, title: strings.toolbar.insertFootnote, onClick: () => editor.dispatchCommand(INSERT_FOOTNOTE_COMMAND, undefined) })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) })), contextual && config.poetry.enabled && state.inPoetry && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.poetryOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] }))] }));
|
|
890
|
+
const insertSection = showInsertGroup && (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: insertButtons(true) }, "insert"));
|
|
855
891
|
const joinLines = () => {
|
|
856
892
|
editor.update(() => {
|
|
857
893
|
$joinSelectedLines();
|
|
858
894
|
}, { discrete: true });
|
|
859
895
|
editor.focus();
|
|
860
896
|
};
|
|
897
|
+
// The tools group is always built, even when every command in it is off, so the ribbon asks first.
|
|
898
|
+
const hasToolsGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck || config.joinLines;
|
|
861
899
|
const toolsSection = (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [config.language.autocorrect && (_jsx(ToolbarButton, { icon: IconWand, title: strings.toolbar.autocorrect, active: autoCorrectOpen, onClick: onToggleAutoCorrect })), config.language.textCleanup && (_jsx(ToolbarButton, { icon: IconSparkles, title: strings.autoCorrect.correctDocument, onClick: () => editor.dispatchCommand(CORRECT_DOCUMENT_COMMAND, undefined) })), config.language.spellCheck && (_jsx(ToolbarButton, { icon: IconAbc, title: strings.toolbar.spellChecker, active: spellOpen, onClick: onToggleSpell })), config.joinLines && (_jsx(ToolbarButton, { icon: IconArrowsJoin, title: strings.toolbar.joinLines, disabled: !state.canJoinLines, onClick: joinLines }))] }, "tools"));
|
|
862
900
|
// Uniform mode's zoom: [-] 100% [+], stepping through the preset levels; the
|
|
863
901
|
// percentage resets to 100%. Always laid out left-to-right, like a number.
|
|
@@ -866,13 +904,18 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
866
904
|
const zoomInTo = ZOOM_LEVELS_PERCENT.find((level) => level > zoom);
|
|
867
905
|
const hasEndUtilities = Boolean(drafts || config.findReplace || helpUrl !== false);
|
|
868
906
|
const zoomGroup = showZoom && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", role: "group", "aria-label": strings.toolbar.zoom, dir: "ltr", children: [_jsx(ToolbarButton, { icon: IconMinus, title: strings.toolbar.zoomOut, disabled: zoomOutTo === undefined, onClick: () => zoomOutTo !== undefined && onZoomChange?.(zoomOutTo) }), _jsxs(MantineToolbar.Toggle, { title: strings.toolbar.zoomReset, "aria-label": `${strings.toolbar.zoomReset} (${zoom}%)`, onMouseDown: (e) => e.preventDefault(), onClick: () => onZoomChange?.(100), style: { width: 'auto', minWidth: 52, padding: '0 6px', fontSize: 12 }, children: [zoom, "%"] }), _jsx(ToolbarButton, { icon: IconPlus, title: strings.toolbar.zoomIn, disabled: zoomInTo === undefined, onClick: () => zoomInTo !== undefined && onZoomChange?.(zoomInTo) })] }, "zoom"));
|
|
907
|
+
const draftsButton = drafts && _jsx(ToolbarButton, { icon: IconHistory, title: strings.toolbar.drafts, onClick: () => setDraftsOpen(true) });
|
|
908
|
+
const findButton = config.findReplace && (_jsx(ToolbarButton, { icon: IconSearch, title: strings.findReplace.toggle, active: findOpen, onClick: onToggleFind }));
|
|
909
|
+
const helpButton = helpUrl !== false && (_jsx(MantineToolbar.Toggle, { component: "a", href: helpUrl ?? DEFAULT_HELP_URL, target: "_blank", rel: "noopener noreferrer", "aria-label": strings.toolbar.help, title: strings.toolbar.help, children: _jsx(IconHelpCircle, { size: ICON_SIZE, stroke: ICON_STROKE }) }));
|
|
869
910
|
// Drafts, search and help: the far-end group (see `endMovable` below).
|
|
870
|
-
const utilitiesGroup = hasEndUtilities && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [
|
|
911
|
+
const utilitiesGroup = hasEndUtilities && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [draftsButton, findButton, helpButton] }, "end"));
|
|
912
|
+
const saveGroup = showSave && (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: _jsx(ToolbarButton, { icon: IconDeviceFloppy, title: strings.toolbar.save, dirty: Boolean(isDirty),
|
|
913
|
+
// Nothing to save until the content has changed since it was loaded or last saved.
|
|
914
|
+
disabled: !isDirty, onClick: onSave }) }, "save"));
|
|
915
|
+
const historyGroup = config.history && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [_jsx(ToolbarButton, { icon: IconArrowBackUp, title: strings.toolbar.undo, disabled: !state.canUndo, onClick: () => editor.dispatchCommand(UNDO_COMMAND, undefined) }), _jsx(ToolbarButton, { icon: IconArrowForwardUp, title: strings.toolbar.redo, disabled: !state.canRedo, onClick: () => editor.dispatchCommand(REDO_COMMAND, undefined) })] }, "history"));
|
|
871
916
|
const startSections = [
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
disabled: !isDirty, onClick: onSave }) }, "save")),
|
|
875
|
-
config.history && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [_jsx(ToolbarButton, { icon: IconArrowBackUp, title: strings.toolbar.undo, disabled: !state.canUndo, onClick: () => editor.dispatchCommand(UNDO_COMMAND, undefined) }), _jsx(ToolbarButton, { icon: IconArrowForwardUp, title: strings.toolbar.redo, disabled: !state.canRedo, onClick: () => editor.dispatchCommand(REDO_COMMAND, undefined) })] }, "history")),
|
|
917
|
+
saveGroup,
|
|
918
|
+
historyGroup,
|
|
876
919
|
formatSection,
|
|
877
920
|
alignSection,
|
|
878
921
|
];
|
|
@@ -942,35 +985,125 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
942
985
|
const visibleEnd = endMovable.filter(isVisible);
|
|
943
986
|
// Shown in the menu in toolbar order: the inline sections, then the far-end ones.
|
|
944
987
|
const hiddenMovable = [...mainMovable, ...endMovable].filter((section) => !isVisible(section));
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
988
|
+
// The right-click menu and the dialogs are the same in both layouts.
|
|
989
|
+
const contextMenuEl = (_jsxs(Menu, { opened: contextMenu !== null, onChange: (opened) => {
|
|
990
|
+
if (!opened)
|
|
991
|
+
setContextMenu(null);
|
|
992
|
+
}, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 260, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: contextMenu?.x ?? -9999, top: contextMenu?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsxs(Menu.Dropdown, { children: [contextMenu?.spelling && (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: strings.contextMenu.spelling }), contextMenu.spelling.suggestions.length === 0 && _jsx(Menu.Item, { disabled: true, children: strings.contextMenu.noSuggestions }), contextMenu.spelling.suggestions.map((suggestion) => (_jsx(Menu.Item, { onClick: () => {
|
|
993
|
+
const match = contextMenu.spelling.match;
|
|
994
|
+
editor.update(() => $replaceMatch(match, suggestion), { discrete: true });
|
|
995
|
+
editor.focus();
|
|
996
|
+
}, children: suggestion }, suggestion))), _jsx(Menu.Item, { onClick: () => {
|
|
997
|
+
ignoreWord(contextMenu.spelling.language, contextMenu.spelling.word);
|
|
998
|
+
setContextMenu(null);
|
|
999
|
+
}, children: strings.contextMenu.ignore }), _jsx(Menu.Item, { onClick: () => {
|
|
1000
|
+
const { language, word } = contextMenu.spelling;
|
|
1001
|
+
// Without a writable store, the word is ignored for this session instead.
|
|
1002
|
+
void addUserWord(dictionaryStores, language, word).then((added) => {
|
|
1003
|
+
if (!added)
|
|
1004
|
+
ignoreWord(language, word);
|
|
1005
|
+
});
|
|
1006
|
+
setContextMenu(null);
|
|
1007
|
+
}, children: strings.contextMenu.addToDictionary }), onAddAutoCorrect && config.language.autocorrect && (_jsx(Menu.Item, { onClick: () => {
|
|
1008
|
+
onAddAutoCorrect(contextMenu.spelling.word, contextMenu.spelling.language);
|
|
1009
|
+
setContextMenu(null);
|
|
1010
|
+
}, children: strings.contextMenu.addToAutoCorrect })), _jsx(Menu.Divider, {})] })), contextMenu?.thesaurus && (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: strings.thesaurus.synonyms }), contextMenu.thesaurus.items === undefined && _jsx(Menu.Item, { disabled: true, children: strings.thesaurus.loading }), contextMenu.thesaurus.items?.length === 0 && _jsx(Menu.Item, { disabled: true, children: strings.thesaurus.none }), contextMenu.thesaurus.items?.map((synonym) => (_jsx(Menu.Item, { onClick: () => {
|
|
1011
|
+
const match = contextMenu.thesaurus.match;
|
|
1012
|
+
editor.update(() => $replaceMatch(match, synonym), { discrete: true });
|
|
1013
|
+
editor.focus();
|
|
1014
|
+
}, children: synonym }, synonym))), _jsx(Menu.Divider, {})] })), contextMenu?.link !== undefined && (_jsxs(_Fragment, { children: [_jsx(LinkMenuItems, { url: contextMenu.link, onEdit: () => {
|
|
1015
|
+
restoreSelection();
|
|
1016
|
+
openLinkDialog();
|
|
1017
|
+
}, onRemove: removeLink, strings: strings }), _jsx(Menu.Divider, {})] })), contextMenu?.table && (_jsxs(_Fragment, { children: [_jsx(TableMenuItems, { strings: strings, direction: direction, rows: contextMenu.table.rows, columns: contextMenu.table.columns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), contextMenu?.poetry && (_jsxs(_Fragment, { children: [_jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), contextMenu?.text && (_jsxs(_Fragment, { children: [_jsx(Menu.Item, { leftSection: _jsx(IconArrowsJoin, { size: ICON_SIZE, stroke: ICON_STROKE }), disabled: !contextMenu.canJoin, onClick: runMenuAction(() => {
|
|
1018
|
+
$joinSelectedLines();
|
|
1019
|
+
}), children: strings.contextMenu.joinLines }), _jsx(Menu.Divider, {})] })), _jsx(Menu.Item, { leftSection: _jsx(IconCut, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(true)(), children: strings.contextMenu.cut }), _jsx(Menu.Item, { leftSection: _jsx(IconCopy, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(false)(), children: strings.contextMenu.copy }), _jsx(Menu.Item, { leftSection: _jsx(IconClipboard, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void paste(), children: strings.contextMenu.paste }), _jsx(Menu.Item, { leftSection: _jsx(IconSelectAll, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: runMenuAction(() => $selectAll()), children: strings.contextMenu.selectAll })] })] }));
|
|
1020
|
+
const dialogsEl = (_jsxs(_Fragment, { children: [(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.columns && _jsx(LayoutDialog, { opened: layoutDialogOpen, onSubmit: insertLayout, onClose: closeLayoutDialog }), 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 })] }));
|
|
1021
|
+
// The ribbon layout (UI spec §3.4): the same command groups as above, on tabs.
|
|
1022
|
+
if (ribbon) {
|
|
1023
|
+
const rt = strings.toolbar.ribbon;
|
|
1024
|
+
const cluster = (key, children) => (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: children }, key));
|
|
1025
|
+
const groupsByTab = {
|
|
1026
|
+
home: [formatSection, alignSection, fontSection],
|
|
1027
|
+
insert: [showInsertGroup && cluster('insert', insertButtons(false))],
|
|
1028
|
+
tools: [hasToolsGroup && toolsSection],
|
|
1029
|
+
table: [
|
|
1030
|
+
config.tables &&
|
|
1031
|
+
state.inTable &&
|
|
1032
|
+
cluster('table', _jsx(TableMenuItems, { mode: "ribbon", strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction })),
|
|
1033
|
+
],
|
|
1034
|
+
poetry: [
|
|
1035
|
+
config.poetry.enabled &&
|
|
1036
|
+
state.inPoetry &&
|
|
1037
|
+
cluster('poetry', _jsx(PoetryMenuItems, { mode: "ribbon", strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction })),
|
|
1038
|
+
],
|
|
1039
|
+
link: [
|
|
1040
|
+
config.links &&
|
|
1041
|
+
state.isLink &&
|
|
1042
|
+
cluster('link', _jsx(LinkMenuItems, { mode: "ribbon", url: state.linkUrl, onEdit: () => {
|
|
1043
|
+
restoreSelection();
|
|
1044
|
+
openLinkDialog();
|
|
1045
|
+
}, onRemove: removeLink, strings: strings })),
|
|
1046
|
+
],
|
|
1047
|
+
};
|
|
1048
|
+
const CONTEXTUAL = ['table', 'poetry', 'link'];
|
|
1049
|
+
// A tab with nothing to show (its features are off, or the caret is not in that content) is left out.
|
|
1050
|
+
const tabs = ['home', 'insert', 'tools', ...CONTEXTUAL]
|
|
1051
|
+
.map((id) => ({ id, label: rt[id], groups: groupsByTab[id].filter(Boolean) }))
|
|
1052
|
+
.filter((tab) => tab.groups.length > 0);
|
|
1053
|
+
const activeTab = tabs.find((tab) => tab.id === ribbonTab) ?? tabs[0];
|
|
1054
|
+
// A context tab that went away (the caret left the table) must not come back selected on its own later.
|
|
1055
|
+
if (activeTab && activeTab.id !== ribbonTab)
|
|
1056
|
+
setRibbonTab(activeTab.id);
|
|
1057
|
+
const panelVisible = !ribbonCollapsed || ribbonPeek;
|
|
1058
|
+
const toggleCollapsed = () => {
|
|
1059
|
+
setRibbonCollapsed((collapsed) => !collapsed);
|
|
1060
|
+
setRibbonPeek(false);
|
|
1061
|
+
};
|
|
1062
|
+
const tabDomId = (id) => `${ribbonId}-tab-${id}`;
|
|
1063
|
+
const onTabKeyDown = (event) => {
|
|
1064
|
+
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key) || tabs.length === 0)
|
|
1065
|
+
return;
|
|
1066
|
+
const index = Math.max(0, tabs.findIndex((tab) => tab.id === activeTab?.id));
|
|
1067
|
+
const forward = event.key === (direction === 'rtl' ? 'ArrowLeft' : 'ArrowRight');
|
|
1068
|
+
const next = event.key === 'Home' ? 0 : event.key === 'End' ? tabs.length - 1 : (index + (forward ? 1 : -1) + tabs.length) % tabs.length;
|
|
1069
|
+
event.preventDefault();
|
|
1070
|
+
setRibbonTab(tabs[next].id);
|
|
1071
|
+
event.currentTarget.querySelectorAll('[role="tab"]')[next]?.focus();
|
|
1072
|
+
};
|
|
1073
|
+
// Save, undo and redo come before the tabs; drafts, search and help come after them. Neither is on a tab,
|
|
1074
|
+
// so both stay in reach whichever tab is open (and when there are no tabs).
|
|
1075
|
+
const quickAccess = [saveGroup, historyGroup].filter(Boolean);
|
|
1076
|
+
const utilities = (draftsButton || findButton || helpButton) &&
|
|
1077
|
+
cluster('utilities', _jsxs(_Fragment, { children: [draftsButton, findButton, helpButton] }));
|
|
1078
|
+
// The collapse button belongs to the row, not to a tab, and is only offered when there are tabs to hide the commands of.
|
|
1079
|
+
const collapseGroup = tabs.length > 0 &&
|
|
1080
|
+
cluster('collapse', _jsx(ToolbarButton, { icon: ribbonCollapsed ? IconChevronDown : IconChevronUp, title: ribbonCollapsed ? rt.expand : rt.collapse, "aria-expanded": !ribbonCollapsed, onClick: toggleCollapsed }));
|
|
1081
|
+
// Zoom (uniform font mode) is a view setting, not a tab: it leads the document tools.
|
|
1082
|
+
const utilityBar = [zoomGroup, utilities, collapseGroup].filter(Boolean);
|
|
1083
|
+
return (_jsxs("div", { ref: ribbonRootRef, className: ['likhari-ribbon', bordered ? '' : 'likhari-ribbon--plain', ribbonCollapsed ? 'likhari-ribbon--collapsed' : ''].filter(Boolean).join(' '), onKeyDown: (event) => {
|
|
1084
|
+
// Ctrl+F1 collapses and expands the ribbon, as in office suites.
|
|
1085
|
+
if (event.key === 'F1' && event.ctrlKey && tabs.length > 0) {
|
|
1086
|
+
event.preventDefault();
|
|
1087
|
+
toggleCollapsed();
|
|
1088
|
+
}
|
|
1089
|
+
}, children: [_jsxs("div", { className: "likhari-ribbon-top", children: [quickAccess.length > 0 && (_jsx(MantineToolbar, { "aria-label": rt.quickAccess, className: "likhari-ribbon-quick", withBorder: false, variant: variant, color: "var(--editor-accent)", children: withDividers(quickAccess) })), tabs.length > 0 && (_jsx("div", { role: "tablist", "aria-label": rt.tabsLabel, className: "likhari-ribbon-tabs", onKeyDown: onTabKeyDown, children: tabs.map((tab) => {
|
|
1090
|
+
// While the ribbon is collapsed a tab only counts as selected when its panel is peeking open.
|
|
1091
|
+
const selected = panelVisible && tab.id === activeTab?.id;
|
|
1092
|
+
return (_jsx("button", { type: "button", role: "tab", id: tabDomId(tab.id), "aria-selected": selected, "aria-controls": selected ? `${ribbonId}-panel` : undefined, tabIndex: tab.id === activeTab?.id ? 0 : -1, className: "likhari-ribbon-tab", "data-contextual": CONTEXTUAL.includes(tab.id) ? 'true' : undefined,
|
|
1093
|
+
// Keep the editor's selection: a mousedown here would blur the canvas.
|
|
1094
|
+
onMouseDown: (e) => e.preventDefault(), onClick: () => {
|
|
1095
|
+
setRibbonTab(tab.id);
|
|
1096
|
+
// Collapsed: a tab opens its commands over the canvas, and clicking it again closes them.
|
|
1097
|
+
if (ribbonCollapsed)
|
|
1098
|
+
setRibbonPeek(!(ribbonPeek && tab.id === activeTab?.id));
|
|
1099
|
+
}, onDoubleClick: toggleCollapsed, children: tab.label }, tab.id));
|
|
1100
|
+
}) })), utilityBar.length > 0 && (_jsx(MantineToolbar, { "aria-label": rt.utilities, className: "likhari-ribbon-utilities", withBorder: false, variant: variant, color: "var(--editor-accent)", children: withDividers(utilityBar) }))] }), panelVisible && activeTab && (_jsx("div", { role: "tabpanel", id: `${ribbonId}-panel`, "aria-labelledby": tabDomId(activeTab.id), className: ribbonCollapsed ? 'likhari-ribbon-panel-wrap likhari-ribbon-panel-wrap--peek' : 'likhari-ribbon-panel-wrap', onClick: (event) => {
|
|
1101
|
+
// A command chosen from the peeking panel closes it, as in office suites. A button that opens a
|
|
1102
|
+
// menu (More formatting) keeps it open, so the menu is not pulled away from under the pointer.
|
|
1103
|
+
const button = event.target.closest('button, a');
|
|
1104
|
+
if (ribbonCollapsed && button && !button.hasAttribute('aria-haspopup'))
|
|
1105
|
+
setRibbonPeek(false);
|
|
1106
|
+
}, children: _jsx(MantineToolbar, { "aria-label": strings.toolbar.ariaLabel, className: bordered ? 'likhari-toolbar likhari-ribbon-panel' : 'likhari-toolbar likhari-toolbar--plain likhari-ribbon-panel', withBorder: bordered, variant: variant, color: "var(--editor-accent)", children: withDividers(activeTab.groups) }) })), contextMenuEl, dialogsEl] }));
|
|
1107
|
+
}
|
|
1108
|
+
return (_jsxs(MantineToolbar, { ref: toolbarContainerRef, "aria-label": strings.toolbar.ariaLabel, className: bordered ? 'likhari-toolbar' : 'likhari-toolbar likhari-toolbar--plain', withBorder: bordered, variant: variant, color: "var(--editor-accent)", children: [withDividers(startSections), visibleMovable.map((section) => (_jsxs(Fragment, { children: [_jsx(MantineToolbar.Divider, {}), section.node] }, section.key))), hiddenMovable.length > 0 && (_jsxs(_Fragment, { children: [_jsx(MantineToolbar.Divider, {}), _jsxs(Menu, { opened: overflowMenuOpen, onChange: handleOverflowMenuChange, position: "bottom-end", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: "max-content", closeOnItemClick: false, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconDots, title: strings.toolbar.moreFormatting }) }), _jsx(Menu.Dropdown, { p: 6, children: _jsx(MantineToolbar, { withBorder: false, variant: variant, color: "var(--editor-accent)", style: { maxWidth: 320 }, children: withDividers(hiddenMovable.map((section) => section.node)) }) })] })] })), _jsx("span", { "aria-hidden": "true", style: { flex: '1 1 auto' } }), visibleEnd.map((section) => section.node), contextMenuEl, overflowEnabled && (_jsxs(MantineToolbar, { "aria-hidden": "true", ref: toolbarMeasureRef, withBorder: bordered, variant: variant, color: "var(--editor-accent)", style: { position: 'absolute', visibility: 'hidden', pointerEvents: 'none', top: 0, left: 0, flexWrap: 'nowrap', width: 'max-content' }, children: [withDividers(startSections), movableSections.map((section) => (_jsxs(Fragment, { children: [_jsx(MantineToolbar.Divider, {}), _jsx("span", { "data-group-key": section.key, style: { display: 'inline-flex' }, children: section.node })] }, section.key)))] })), dialogsEl] }));
|
|
976
1109
|
}
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -74,6 +74,25 @@ export interface Strings {
|
|
|
74
74
|
clearFormatting: string;
|
|
75
75
|
outdent: string;
|
|
76
76
|
indent: string;
|
|
77
|
+
/** The ribbon layout (`toolbarStyle.layout: 'ribbon'`): its tab strip and tabs. */
|
|
78
|
+
ribbon: {
|
|
79
|
+
/** aria-label on the tab strip. */
|
|
80
|
+
tabsLabel: string;
|
|
81
|
+
/** aria-label on the group before the tabs that holds save, undo and redo. */
|
|
82
|
+
quickAccess: string;
|
|
83
|
+
/** aria-label on the group after the tabs that holds drafts, search and help. */
|
|
84
|
+
utilities: string;
|
|
85
|
+
/** The button that hides the command row, leaving only the tabs, and the one that brings it back. */
|
|
86
|
+
collapse: string;
|
|
87
|
+
expand: string;
|
|
88
|
+
home: string;
|
|
89
|
+
insert: string;
|
|
90
|
+
tools: string;
|
|
91
|
+
/** Contextual tabs, shown only while the caret is in that kind of content. */
|
|
92
|
+
table: string;
|
|
93
|
+
poetry: string;
|
|
94
|
+
link: string;
|
|
95
|
+
};
|
|
77
96
|
formattingOptions: {
|
|
78
97
|
paragraph: string;
|
|
79
98
|
heading: (level: number) => 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
|
@@ -62,6 +62,19 @@ const en = {
|
|
|
62
62
|
clearFormatting: 'Clear formatting',
|
|
63
63
|
outdent: 'Outdent',
|
|
64
64
|
indent: 'Indent',
|
|
65
|
+
ribbon: {
|
|
66
|
+
tabsLabel: 'Ribbon tabs',
|
|
67
|
+
quickAccess: 'Quick access',
|
|
68
|
+
utilities: 'Document tools',
|
|
69
|
+
collapse: 'Collapse the ribbon',
|
|
70
|
+
expand: 'Expand the ribbon',
|
|
71
|
+
home: 'Home',
|
|
72
|
+
insert: 'Insert',
|
|
73
|
+
tools: 'Tools',
|
|
74
|
+
table: 'Table',
|
|
75
|
+
poetry: 'Poetry',
|
|
76
|
+
link: 'Link',
|
|
77
|
+
},
|
|
65
78
|
formattingOptions: {
|
|
66
79
|
paragraph: 'Paragraph',
|
|
67
80
|
heading: (level) => `Heading ${level}`,
|
|
@@ -347,6 +360,19 @@ const ur = {
|
|
|
347
360
|
clearFormatting: 'فارمیٹنگ ختم کریں',
|
|
348
361
|
outdent: 'حاشیہ کم کریں',
|
|
349
362
|
indent: 'حاشیہ بڑھائیں',
|
|
363
|
+
ribbon: {
|
|
364
|
+
tabsLabel: 'ربن کے ٹیب',
|
|
365
|
+
quickAccess: 'فوری رسائی',
|
|
366
|
+
utilities: 'دستاویز کے اوزار',
|
|
367
|
+
collapse: 'ربن چھپائیں',
|
|
368
|
+
expand: 'ربن دکھائیں',
|
|
369
|
+
home: 'ہوم',
|
|
370
|
+
insert: 'شامل کریں',
|
|
371
|
+
tools: 'اوزار',
|
|
372
|
+
table: 'جدول',
|
|
373
|
+
poetry: 'شاعری',
|
|
374
|
+
link: 'لنک',
|
|
375
|
+
},
|
|
350
376
|
formattingOptions: {
|
|
351
377
|
paragraph: 'پیراگراف',
|
|
352
378
|
heading: (level) => `عنوان ${level}`,
|
|
@@ -632,6 +658,19 @@ const paShahmukhi = {
|
|
|
632
658
|
clearFormatting: 'فارمیٹنگ ہٹاؤ',
|
|
633
659
|
outdent: 'حاشیہ گھٹاؤ',
|
|
634
660
|
indent: 'حاشیہ ودھاؤ',
|
|
661
|
+
ribbon: {
|
|
662
|
+
tabsLabel: 'ربن دے ٹیب',
|
|
663
|
+
quickAccess: 'جھٹ رسائی',
|
|
664
|
+
utilities: 'دستاویز دے اوزار',
|
|
665
|
+
collapse: 'ربن لکو',
|
|
666
|
+
expand: 'ربن وکھاؤ',
|
|
667
|
+
home: 'ہوم',
|
|
668
|
+
insert: 'شامل کرو',
|
|
669
|
+
tools: 'اوزار',
|
|
670
|
+
table: 'جدول',
|
|
671
|
+
poetry: 'شاعری',
|
|
672
|
+
link: 'لنک',
|
|
673
|
+
},
|
|
635
674
|
formattingOptions: {
|
|
636
675
|
paragraph: 'پیراگراف',
|
|
637
676
|
heading: (level) => `سرلیکھ ${level}`,
|
package/dist/theme/editor.css
CHANGED
|
@@ -1119,3 +1119,216 @@
|
|
|
1119
1119
|
background: var(--editor-accent-soft);
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
|
+
|
|
1123
|
+
/* Ribbon layout (toolbarStyle.layout: 'ribbon', UI spec §3.4): a strip of tabs over one row of the active
|
|
1124
|
+
tab's command groups, with save, undo and redo before the tabs and drafts, search and help after them. */
|
|
1125
|
+
.likhari-ribbon {
|
|
1126
|
+
display: flex;
|
|
1127
|
+
flex-direction: column;
|
|
1128
|
+
flex-shrink: 0;
|
|
1129
|
+
/* The containing block, and a stacking level above the canvas, for the panel that peeks out when collapsed. */
|
|
1130
|
+
position: relative;
|
|
1131
|
+
z-index: 5;
|
|
1132
|
+
background: var(--editor-paper-dim);
|
|
1133
|
+
/* Lets the row below react to the editor's own width, not the window's. */
|
|
1134
|
+
container-type: inline-size;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
/* Collapsed: only the tab row stays, closed off with a line where the command row was. */
|
|
1138
|
+
.likhari-ribbon--collapsed .likhari-ribbon-top {
|
|
1139
|
+
padding-bottom: 2px;
|
|
1140
|
+
border-bottom: 1px solid var(--editor-line);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
/* In a narrow editor the save/undo group and the document tools take all the width and squeeze the tabs to
|
|
1144
|
+
nothing, so the tabs drop to a line of their own (scrolling sideways if need be). */
|
|
1145
|
+
@container (max-width: 560px) {
|
|
1146
|
+
.likhari-ribbon-top {
|
|
1147
|
+
flex-wrap: wrap;
|
|
1148
|
+
row-gap: 0;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
.likhari-ribbon-tabs {
|
|
1152
|
+
order: 3;
|
|
1153
|
+
flex: 1 1 100%;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/* A collapsed tab's commands open over the canvas instead of pushing it down, so the page does not jump. */
|
|
1158
|
+
.likhari-ribbon-panel-wrap--peek {
|
|
1159
|
+
position: absolute;
|
|
1160
|
+
inset-inline: 0;
|
|
1161
|
+
top: 100%;
|
|
1162
|
+
z-index: 30;
|
|
1163
|
+
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.16);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.likhari-ribbon-top {
|
|
1167
|
+
display: flex;
|
|
1168
|
+
align-items: center;
|
|
1169
|
+
justify-content: space-between;
|
|
1170
|
+
gap: 8px;
|
|
1171
|
+
padding: 2px 8px 0;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
.likhari-ribbon-tabs {
|
|
1175
|
+
display: flex;
|
|
1176
|
+
gap: 2px;
|
|
1177
|
+
min-width: 0;
|
|
1178
|
+
/* Narrow screens scroll the tabs sideways rather than wrapping them. */
|
|
1179
|
+
overflow-x: auto;
|
|
1180
|
+
scrollbar-width: none;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
.likhari-ribbon-tab {
|
|
1184
|
+
appearance: none;
|
|
1185
|
+
flex: 0 0 auto;
|
|
1186
|
+
margin: 0;
|
|
1187
|
+
padding: 6px 12px;
|
|
1188
|
+
border: 0;
|
|
1189
|
+
border-bottom: 2px solid transparent;
|
|
1190
|
+
border-radius: 4px 4px 0 0;
|
|
1191
|
+
background: transparent;
|
|
1192
|
+
color: var(--editor-ink-soft);
|
|
1193
|
+
font: inherit;
|
|
1194
|
+
font-size: 13px;
|
|
1195
|
+
line-height: 1.2;
|
|
1196
|
+
white-space: nowrap;
|
|
1197
|
+
cursor: pointer;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.likhari-ribbon-tab:hover {
|
|
1201
|
+
background: var(--editor-accent-soft);
|
|
1202
|
+
color: var(--editor-ink);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
.likhari-ribbon-tab[aria-selected='true'] {
|
|
1206
|
+
border-bottom-color: var(--editor-accent);
|
|
1207
|
+
color: var(--editor-accent);
|
|
1208
|
+
font-weight: 600;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/* A context tab (Table, Poetry, Link) is tinted so it reads as appearing because of where the caret is. */
|
|
1212
|
+
.likhari-ribbon-tab[data-contextual] {
|
|
1213
|
+
background: var(--editor-accent-soft);
|
|
1214
|
+
color: var(--editor-accent);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
.likhari-ribbon-tab:focus-visible {
|
|
1218
|
+
outline: 2px solid var(--editor-accent);
|
|
1219
|
+
outline-offset: -2px;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
.likhari-ribbon-quick,
|
|
1223
|
+
.likhari-ribbon-utilities {
|
|
1224
|
+
display: flex;
|
|
1225
|
+
flex: 0 0 auto;
|
|
1226
|
+
flex-wrap: nowrap;
|
|
1227
|
+
align-items: center;
|
|
1228
|
+
gap: 8px;
|
|
1229
|
+
min-height: 0;
|
|
1230
|
+
padding: 0;
|
|
1231
|
+
background: transparent;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/* Drafts, search and help at the end of the row, also when there are no tabs to push them there. */
|
|
1235
|
+
.likhari-ribbon-utilities {
|
|
1236
|
+
margin-inline-start: auto;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
/* The panel scrolls sideways when its groups do not fit, instead of wrapping onto a second row. */
|
|
1240
|
+
.likhari-ribbon-panel {
|
|
1241
|
+
flex-wrap: nowrap;
|
|
1242
|
+
overflow-x: auto;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
.likhari-ribbon-panel > * {
|
|
1246
|
+
flex: 0 0 auto;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/* A destructive command (delete table, delete couplet) on the ribbon, as red as it is in the menus. */
|
|
1250
|
+
.likhari-ribbon-panel [data-danger='true'] {
|
|
1251
|
+
color: var(--mantine-color-red-6, #e03131);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/* The buttons on the tab row, outside every tab (save, undo, redo; drafts, search, help): flat icons with no
|
|
1255
|
+
border or background at rest. Hover tints them; "on" and "unsaved" are shown by colour and a mark instead
|
|
1256
|
+
of a fill, so the row stays light next to the tabs. */
|
|
1257
|
+
.likhari-ribbon-quick .likhari-toolbar-cluster,
|
|
1258
|
+
.likhari-ribbon-utilities .likhari-toolbar-cluster {
|
|
1259
|
+
border: none;
|
|
1260
|
+
border-radius: 0;
|
|
1261
|
+
background: transparent;
|
|
1262
|
+
overflow: visible;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
.likhari-ribbon-quick [data-toolbar-toggle],
|
|
1266
|
+
.likhari-ribbon-utilities [data-toolbar-toggle] {
|
|
1267
|
+
position: relative;
|
|
1268
|
+
border: none;
|
|
1269
|
+
border-radius: 6px;
|
|
1270
|
+
background: transparent !important;
|
|
1271
|
+
color: var(--editor-ink-soft);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
.likhari-ribbon-quick .likhari-toolbar-cluster [data-toolbar-toggle] + [data-toolbar-toggle],
|
|
1275
|
+
.likhari-ribbon-utilities .likhari-toolbar-cluster [data-toolbar-toggle] + [data-toolbar-toggle] {
|
|
1276
|
+
border-inline-start: none;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
.likhari-ribbon-quick [data-toolbar-toggle]:hover:not(:disabled):not([data-disabled]),
|
|
1280
|
+
.likhari-ribbon-utilities [data-toolbar-toggle]:hover:not(:disabled):not([data-disabled]) {
|
|
1281
|
+
background: var(--editor-accent-soft) !important;
|
|
1282
|
+
color: var(--editor-ink);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
.likhari-ribbon-quick [data-toolbar-toggle]:disabled,
|
|
1286
|
+
.likhari-ribbon-quick [data-toolbar-toggle][data-disabled],
|
|
1287
|
+
.likhari-ribbon-utilities [data-toolbar-toggle]:disabled,
|
|
1288
|
+
.likhari-ribbon-utilities [data-toolbar-toggle][data-disabled] {
|
|
1289
|
+
color: var(--editor-ink-soft);
|
|
1290
|
+
opacity: 0.45;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/* A button that is on (find and replace open): accent icon with a short bar under it. */
|
|
1294
|
+
.likhari-ribbon-quick [data-toolbar-toggle][aria-pressed='true'],
|
|
1295
|
+
.likhari-ribbon-utilities [data-toolbar-toggle][aria-pressed='true'] {
|
|
1296
|
+
color: var(--editor-accent);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
.likhari-ribbon-quick [data-toolbar-toggle][aria-pressed='true']::after,
|
|
1300
|
+
.likhari-ribbon-utilities [data-toolbar-toggle][aria-pressed='true']::after {
|
|
1301
|
+
content: '';
|
|
1302
|
+
position: absolute;
|
|
1303
|
+
inset-inline: 7px;
|
|
1304
|
+
bottom: 2px;
|
|
1305
|
+
height: 2px;
|
|
1306
|
+
border-radius: 1px;
|
|
1307
|
+
background: var(--editor-accent);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
/* Save with unsaved changes: accent icon and a dot, not the filled button the classic toolbar uses. */
|
|
1311
|
+
.likhari-ribbon-quick [data-dirty='true'] {
|
|
1312
|
+
color: var(--editor-accent);
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
.likhari-ribbon-quick [data-dirty='true']::after {
|
|
1316
|
+
content: '';
|
|
1317
|
+
position: absolute;
|
|
1318
|
+
top: 4px;
|
|
1319
|
+
inset-inline-end: 4px;
|
|
1320
|
+
width: 7px;
|
|
1321
|
+
height: 7px;
|
|
1322
|
+
border-radius: 50%;
|
|
1323
|
+
background: var(--editor-accent);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
.likhari-ribbon-quick [data-dirty='true']:hover,
|
|
1327
|
+
.likhari-ribbon-quick [data-dirty='false'] {
|
|
1328
|
+
color: var(--editor-accent);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
.likhari-ribbon-quick [data-dirty='false']:disabled,
|
|
1332
|
+
.likhari-ribbon-quick [data-dirty='false'][data-disabled] {
|
|
1333
|
+
color: var(--editor-ink-soft);
|
|
1334
|
+
}
|