editor: use strings from @notesnook/intl

This commit is contained in:
Abdullah Atta
2024-10-09 15:35:13 +05:00
committed by Abdullah Atta
parent 3e55492318
commit 8577c32c1f
25 changed files with 265 additions and 177 deletions

View File

@@ -11,6 +11,7 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
"@notesnook/ui": "file:../ui",
"@social-embed/lib": "^0.1.0-next.7",
@@ -180,6 +181,27 @@
"ws": "^8.13.0"
}
},
"../intl": {
"name": "@notesnook/intl",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"devDependencies": {
"@lingui/cli": "^4.11.4",
"@lingui/macro": "^4.11.4 ",
"@lingui/swc-plugin": "^4.0.10",
"@types/react": "^18.2.39",
"babel-plugin-macros": "^3.1.0",
"react": "18.2.0",
"typescript": "5.5.3",
"vite": "^5.4.8",
"vite-plugin-dts": "^4.2.3",
"vite-plugin-swc-transform": "^1.0.1"
},
"peerDependencies": {
"@lingui/macro": "*",
"react": ">=18"
}
},
"../theme": {
"name": "@notesnook/theme",
"version": "2.1.3",
@@ -981,6 +1003,10 @@
"resolved": "../common",
"link": true
},
"node_modules/@notesnook/intl": {
"resolved": "../intl",
"link": true
},
"node_modules/@notesnook/theme": {
"resolved": "../theme",
"link": true
@@ -1342,6 +1368,23 @@
"@styled-system/css": "^5.1.5"
}
},
"node_modules/@theme-ui/color-modes": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.16.2.tgz",
"integrity": "sha512-jWEWx53lxNgWCT38i/kwLV2rsvJz8lVZgi5oImnVwYba9VejXD23q1ckbNFJHosQ8KKXY87ht0KPC6BQFIiHtQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@theme-ui/core": "^0.16.2",
"@theme-ui/css": "^0.16.2",
"deepmerge": "^4.2.2"
},
"peerDependencies": {
"@emotion/react": "^11.11.1",
"react": ">=18"
}
},
"node_modules/@theme-ui/components": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@theme-ui/components/-/components-0.16.2.tgz",
@@ -1387,6 +1430,23 @@
"@emotion/react": "^11.11.1"
}
},
"node_modules/@theme-ui/theme-provider": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.16.2.tgz",
"integrity": "sha512-LRnVevODcGqO0JyLJ3wht+PV3ZoZcJ7XXLJAJWDoGeII4vZcPQKwVy4Lpz/juHsZppQxKcB3U+sQDGBnP25irQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@theme-ui/color-modes": "^0.16.2",
"@theme-ui/core": "^0.16.2",
"@theme-ui/css": "^0.16.2"
},
"peerDependencies": {
"@emotion/react": "^11.11.1",
"react": ">=18"
}
},
"node_modules/@tiptap/core": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.6.6.tgz",
@@ -2842,8 +2902,7 @@
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/jsesc": {
"version": "2.5.2",
@@ -2901,7 +2960,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dev": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -3466,7 +3524,6 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"dev": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -3487,7 +3544,6 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"dev": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -3638,7 +3694,6 @@
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"dev": true,
"dependencies": {
"loose-envify": "^1.1.0"
}

View File

@@ -50,6 +50,7 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
"@notesnook/ui": "file:../ui",
"@social-embed/lib": "^0.1.0-next.7",

View File

@@ -29,6 +29,7 @@ import { ReactNodeViewProps } from "../react/types.js";
import { CodeBlockAttributes } from "./code-block.js";
import Languages from "./languages.json";
import { useThemeEngineStore } from "@notesnook/theme";
import { strings } from "@notesnook/intl";
export function CodeblockComponent(
props: ReactNodeViewProps<CodeBlockAttributes>
@@ -108,9 +109,9 @@ export function CodeblockComponent(
>
{caretPosition ? (
<Text variant={"subBody"} sx={{ mr: 1, mt: "2px" }}>
Line {caretPosition.line}, Column {caretPosition.column}{" "}
{strings.lineColumn(caretPosition.line, caretPosition.column)}{" "}
{caretPosition.selected
? `(${caretPosition.selected} selected)`
? `(${strings.selectedCode(caretPosition.selected)})`
: ""}
</Text>
) : null}
@@ -121,7 +122,7 @@ export function CodeblockComponent(
p: 1,
opacity: "1 !important"
}}
title="Toggle indentation mode"
title={strings.toggleIndentationMode()}
disabled={!editor.isEditable}
onClick={() => {
if (!editor.isEditable) return;
@@ -132,7 +133,8 @@ export function CodeblockComponent(
}}
>
<Text variant={"subBody"}>
{indentType === "space" ? "Spaces" : "Tabs"}: {indentLength}
{indentType === "space" ? strings.spaces() : strings.tabs()}:{" "}
{indentLength}
</Text>
</Button>
@@ -150,7 +152,7 @@ export function CodeblockComponent(
setIsOpen(true);
}}
title="Change language"
title={strings.changeLanguage()}
>
<Text variant={"subBody"} spellCheck={false}>
{languageDefinition?.title || "Plaintext"}
@@ -173,14 +175,14 @@ export function CodeblockComponent(
);
start();
}}
title="Copy to clipboard"
title={strings.copyToClipboard()}
>
<Text
variant={"subBody"}
spellCheck={false}
sx={{ color: "codeFg" }}
>
{enabled ? "Copied!" : "Copy"}
{enabled ? strings.copied() : strings.copy()}
</Text>
</Button>
) : null}
@@ -208,7 +210,7 @@ export function CodeblockComponent(
location: "top",
yOffset: 5
}}
title="Select language"
title={strings.selectLanguage()}
>
<LanguageSelector
selectedLanguage={languageDefinition?.filename || "Plaintext"}
@@ -247,7 +249,7 @@ function LanguageSelector(props: LanguageSelectorProps) {
>
<Input
autoFocus
placeholder="Search languages"
placeholder={strings.searchLanguages()}
sx={{
width: "auto",
bg: "background",

View File

@@ -39,6 +39,7 @@ import {
} from "../../utils/prosemirror.js";
import { DesktopOnly } from "../../components/responsive/index.js";
import { TextDirections } from "../text-direction/index.js";
import { strings } from "@notesnook/intl";
export function TableComponent(props: ReactNodeViewProps) {
const { editor, node, forwardRef } = props;
@@ -262,7 +263,7 @@ function TableColumnToolbar(props: TableToolbarProps) {
>
<TableProperties
editor={editor}
title="Table properties"
title={strings.tableSettings()}
icon="more"
variant={"small"}
/>

View File

@@ -28,6 +28,7 @@ import { useIsMobile } from "../../toolbar/stores/toolbar-store.js";
import { isiOS } from "../../utils/platform.js";
import { DesktopOnly } from "../../components/responsive/index.js";
import TaskItem from "@tiptap/extension-task-item";
import { strings } from "@notesnook/intl";
export function TaskItemComponent(
props: ReactNodeViewProps<TaskItemAttributes>
@@ -146,7 +147,7 @@ export function TaskItemComponent(
{editor.isEditable && (
<Icon
className="deleleTaskItem"
title="Delete this task item"
title={strings.delete()}
path={Icons.close}
size={18}
sx={{

View File

@@ -29,6 +29,7 @@ import TaskItem from "@tiptap/extension-task-item";
import { useIsMobile } from "../../toolbar/stores/toolbar-store.js";
import { Icons } from "../../toolbar/icons.js";
import { Icon } from "@notesnook/ui";
import { strings } from "@notesnook/intl";
export function TaskListComponent(
props: ReactNodeViewProps<TaskListAttributes>
@@ -123,7 +124,7 @@ export function TaskListComponent(
fontSize: "inherit",
fontFamily: "inherit"
}}
placeholder="Untitled"
placeholder={strings.untitled()}
onChange={(e) => {
e.target.value = replaceDateTime(
e.target.value,
@@ -140,7 +141,7 @@ export function TaskListComponent(
<>
<ToolButton
toggled={false}
title="Make tasklist readonly"
title={strings.readonlyTaskList()}
icon={readonly ? "readonlyOn" : "readonlyOff"}
variant="small"
sx={{
@@ -171,7 +172,7 @@ export function TaskListComponent(
/>
<ToolButton
toggled={false}
title="Move all checked tasks to bottom"
title={strings.sortTaskList()}
icon="sortTaskList"
variant="small"
sx={{
@@ -190,7 +191,7 @@ export function TaskListComponent(
/>
<ToolButton
toggled={false}
title="Clear completed tasks"
title={strings.clearCompletedTasks()}
icon="clear"
variant="small"
sx={{

View File

@@ -84,6 +84,7 @@ import BlockId from "./extensions/block-id/index.js";
import { useEditorSearchStore } from "./toolbar/stores/search-store.js";
import { DiffHighlighter } from "./extensions/diff-highlighter/index.js";
import { getChangedNodes } from "./utils/prosemirror.js";
import { strings } from "@notesnook/intl";
interface TiptapStorage {
dateFormat?: DateTimeOptions["dateFormat"];
@@ -291,7 +292,7 @@ const useTiptap = (
defaultAlignment: "left"
}),
Placeholder.configure({
placeholder: options.placeholder || "Start writing your note..."
placeholder: options.placeholder || strings.startWritingNote()
}),
ImageNode.configure({ allowBase64: true }),
EmbedNode,

View File

@@ -21,6 +21,7 @@ import React from "react";
import { Flex, Text } from "@theme-ui/components";
import { ToolButton } from "./tool-button.js";
import { useIsMobile } from "../stores/toolbar-store.js";
import { strings } from "@notesnook/intl";
export type CounterProps = {
title: string;
@@ -47,11 +48,11 @@ function _Counter(props: CounterProps) {
}
}}
onClick={disabled ? undefined : onReset}
title={disabled ? "" : `Click to reset ${title}`}
title={disabled ? "" : strings.clickToReset(title)}
>
<ToolButton
toggled={false}
title={`Decrease ${title}`}
title={strings.decrease(title)}
icon="minus"
variant={"small"}
disabled={disabled}
@@ -80,7 +81,7 @@ function _Counter(props: CounterProps) {
<ToolButton
toggled={false}
title={`Increase ${title}`}
title={strings.increase(title)}
icon="plus"
variant={"small"}
disabled={disabled}

View File

@@ -23,6 +23,7 @@ import { Flex, FlexProps } from "@theme-ui/components";
import { Editor } from "../../types.js";
import { MoreTools } from "./more-tools.js";
import { getToolDefinition } from "../tool-definitions.js";
import { strings } from "@notesnook/intl";
export type ToolbarGroupProps = FlexProps & {
tools: ToolbarGroupDefinition;
@@ -51,7 +52,7 @@ export function ToolbarGroup(props: ToolbarGroupProps) {
<MoreTools
parentGroup={groupId}
key={"more-tools"}
title="More"
title={strings.more()}
icon="more"
popupId={toolId.join("")}
tools={toolId}

View File

@@ -25,18 +25,19 @@ import { Icon } from "@notesnook/ui";
import { Popup } from "../components/popup.js";
import { Icons } from "../icons.js";
import { ColorPicker } from "./color-picker.js";
import { strings } from "@notesnook/intl";
type CellPropertiesProps = { editor: Editor; onClose: () => void };
export function CellProperties(props: CellPropertiesProps) {
const { editor, onClose } = props;
const attributes = editor.getAttributes("tableCell");
return (
<Popup title="Cell properties" onClose={onClose}>
<Popup title={strings.cellProperties()} onClose={onClose}>
<Tabs activeIndex={0}>
<Tab
title={
<Icon
title="Cell background color"
title={strings.cellBackgroundColor()}
path={Icons.backgroundColor}
size={16}
/>
@@ -57,7 +58,11 @@ export function CellProperties(props: CellPropertiesProps) {
</Tab>
<Tab
title={
<Icon title="Cell text color" path={Icons.textColor} size={16} />
<Icon
title={strings.cellTextColor()}
path={Icons.textColor}
size={16}
/>
}
>
<Box mt={2} />
@@ -74,7 +79,7 @@ export function CellProperties(props: CellPropertiesProps) {
<Tab
title={
<Icon
title="Cell border color"
title={strings.cellBorderColor()}
path={Icons.cellBorderColor}
size={16}
/>

View File

@@ -29,6 +29,7 @@ import { debounce } from "../../utils/debounce.js";
import { Popup } from "../components/popup.js";
import { SchemeColors } from "@notesnook/theme";
import { Editor } from "../../types.js";
import { strings } from "@notesnook/intl";
type ColorPickerProps = {
editor: Editor;
@@ -162,7 +163,7 @@ export function ColorPicker(props: ColorPickerProps) {
icon={Icons.save}
iconSize={18}
onClick={() => onSave(currentColor)}
title="Save color"
title={strings.save()}
/>
)}
</Flex>
@@ -183,7 +184,7 @@ export function ColorPicker(props: ColorPickerProps) {
<PaletteButton
icon={Icons.colorClear}
onClick={onClear}
title="Clear color"
title={strings.clear()}
iconSize={15}
/>
)}
@@ -192,11 +193,7 @@ export function ColorPicker(props: ColorPickerProps) {
iconColor={deleteMode ? "var(--icon-error)" : "icon"}
bg={deleteMode ? "var(--background-error)" : "transparent"}
onClick={() => setDeleteMode((s) => !s)}
title={
deleteMode
? "Disable delete mode"
: "Enable delete mode for deleting custom colors"
}
title={strings.deleteMode()}
iconSize={18}
/>
{!deleteMode && (
@@ -217,7 +214,7 @@ export function ColorPicker(props: ColorPickerProps) {
return !s;
});
}}
title="Choose custom color"
title={strings.chooseCustomColor()}
iconSize={18}
bg={currentColor}
/>
@@ -225,7 +222,7 @@ export function ColorPicker(props: ColorPickerProps) {
{allColors.map((colorItem) => (
<PaletteButton
key={colorItem}
title={deleteMode ? "Click to delete this color" : colorItem}
title={deleteMode ? strings.clickToRemove() : colorItem}
bg={colorItem}
iconSize={15}
iconColor={"white"}

View File

@@ -25,6 +25,7 @@ import { Embed, EmbedSizeOptions } from "../../extensions/embed/index.js";
import { convertUrlToEmbedUrl } from "@social-embed/lib";
import { InlineInput } from "../../components/inline-input/index.js";
import { Tabs, Tab } from "../../components/tabs/index.js";
import { strings } from "@notesnook/intl";
type EmbedSource = "url" | "code";
export type EmbedPopupProps = {
@@ -71,7 +72,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
title={title}
onClose={() => onClose()}
action={{
title: "Save",
title: strings.save(),
onClick: () => {
setError(null);
let _src = src;
@@ -127,9 +128,9 @@ export function EmbedPopup(props: EmbedPopupProps) {
containerProps={{ sx: { mx: 1, flexDirection: "column" } }}
onTabChanged={(index) => setEmbedSource(index === 0 ? "url" : "code")}
>
<Tab title="From URL">
<Tab title={strings.fromURL()}>
<Input
placeholder="Enter embed source URL"
placeholder={strings.enterEmbedSourceURL()}
value={src}
autoFocus
onChange={(e) => setSrc(e.target.value)}
@@ -141,7 +142,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
containerProps={{ sx: { mr: 1 } }}
label="width"
type="number"
placeholder="Width"
placeholder={strings.width()}
value={width}
sx={{
mr: 1,
@@ -152,7 +153,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
<InlineInput
label="height"
type="number"
placeholder="Height"
placeholder={strings.height()}
value={height}
sx={{ fontSize: "body" }}
onChange={(e) =>
@@ -161,7 +162,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
/>
</Flex>
</Tab>
<Tab title="From code">
<Tab title={strings.fromCode()}>
<Textarea
autoFocus
variant={"forms.input"}
@@ -171,7 +172,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
minHeight: [200, 100]
}}
onChange={(e) => setSrc(e.target.value)}
placeholder="Paste embed code here. Only iframes are supported."
placeholder={strings.pasteEmbedCode()}
/>
</Tab>
</Tabs>

View File

@@ -23,6 +23,7 @@ import { ImageAttributes } from "../../extensions/image/index.js";
import { Editor } from "../../types.js";
import { InlineInput } from "../../components/inline-input/index.js";
import { findSelectedNode } from "../../utils/prosemirror.js";
import { strings } from "@notesnook/intl";
export type ImagePropertiesProps = {
editor: Editor;
@@ -37,7 +38,7 @@ export function ImageProperties(props: ImagePropertiesProps) {
const { width, height, aspectRatio } = image.attrs as ImageAttributes;
return (
<Popup title="Image properties" onClose={onClose}>
<Popup title={strings.imageProperties()} onClose={onClose}>
<Flex sx={{ width: ["auto", 300], alignItems: "center", p: 1 }}>
<InlineInput
label="width"

View File

@@ -24,6 +24,7 @@ import { ImageAttributes } from "../../extensions/image/index.js";
import { Popup } from "../components/popup.js";
import { downloadImage, toDataURL } from "../../utils/downloader.js";
import { useToolbarStore } from "../stores/toolbar-store.js";
import { strings } from "@notesnook/intl";
export type ImageUploadPopupProps = {
onInsert: (image: Partial<ImageAttributes>) => void;
@@ -38,11 +39,11 @@ export function ImageUploadPopup(props: ImageUploadPopupProps) {
return (
<Popup
title="Insert image from URL"
title={strings.attachImageFromURL()}
onClose={onClose}
action={{
loading: isDownloading,
title: "Insert image",
title: strings.insert(),
disabled: !url,
onClick: async () => {
setIsDownloading(true);
@@ -65,7 +66,7 @@ export function ImageUploadPopup(props: ImageUploadPopupProps) {
<Input
type="url"
autoFocus
placeholder="Paste Image URL here"
placeholder={strings.pasteImageURL()}
value={url}
onChange={(e) => {
setUrl(e.target.value);

View File

@@ -27,6 +27,7 @@ import Link, { LinkAttributes } from "../../extensions/link/index.js";
import { ImageNode } from "../../extensions/image/index.js";
import { findMark, selectionToOffset } from "../../utils/prosemirror.js";
import { Editor, getMarkAttributes } from "@tiptap/core";
import { strings } from "@notesnook/intl";
export type LinkPopupProps = {
link?: LinkDefinition;
@@ -47,10 +48,10 @@ export function LinkPopup(props: LinkPopupProps) {
return (
<Popup
title={isEditing ? "Edit link" : "Insert link"}
title={isEditing ? strings.editLink() : strings.insertLink()}
onClose={onClose}
action={{
title: isEditing ? "Save edits" : "Insert link",
title: isEditing ? strings.save() : strings.insert(),
onClick: () => onDone(link.current)
}}
>
@@ -65,7 +66,7 @@ export function LinkPopup(props: LinkPopupProps) {
{!isImageActive && (
<Input
type="text"
placeholder="Link text"
placeholder={strings.linkText()}
defaultValue={link.current?.title}
sx={{ mb: 1 }}
onChange={(e) =>

View File

@@ -24,6 +24,7 @@ import { SearchStorage } from "../../extensions/search-replace/index.js";
import { ToolButton } from "../components/tool-button.js";
import { Editor } from "../../types.js";
import { useEditorSearchStore } from "../stores/search-store.js";
import { strings } from "@notesnook/intl";
export type SearchReplacePopupProps = { editor: Editor };
export function SearchReplacePopup(props: SearchReplacePopupProps) {
@@ -89,7 +90,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
variant={"clean"}
ref={searchInputRef}
autoFocus
placeholder="Find"
placeholder={strings.search()}
sx={{ p: 0, fontFamily: "monospace" }}
value={searchTerm}
onChange={(e) => {
@@ -115,7 +116,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
mr: 0
}}
toggled={isExpanded}
title="Expand"
title={strings.expand()}
id="expand"
icon={isExpanded ? "chevronRight" : "chevronLeft"}
onClick={() =>
@@ -130,7 +131,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
mr: 0
}}
toggled={matchCase}
title="Match case"
title={strings.matchCase()}
id="matchCase"
icon="caseSensitive"
onClick={() => {
@@ -144,7 +145,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
mr: 0
}}
toggled={matchWholeWord}
title="Match whole word"
title={strings.matchWholeWord()}
id="matchWholeWord"
icon="wholeWord"
onClick={() => {
@@ -160,7 +161,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
mr: 0
}}
toggled={enableRegex}
title="Enable regex"
title={strings.enableRegex()}
id="enableRegex"
icon="regex"
onClick={() => {
@@ -191,7 +192,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
{isReplacing && (
<Input
sx={{ mt: 1, p: "7px", fontFamily: "monospace" }}
placeholder="Replace"
placeholder={strings.replace()}
value={replaceTerm}
onChange={(e) =>
useEditorSearchStore.setState({ replaceTerm: e.target.value })
@@ -204,7 +205,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
{editor.isEditable && (
<ToolButton
toggled={isReplacing}
title="Toggle replace"
title={strings.toggleReplace()}
id="toggleReplace"
icon="replace"
onClick={() =>
@@ -218,7 +219,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
)}
<ToolButton
toggled={false}
title="Previous match"
title={strings.previousMatch()}
id="previousMatch"
icon="previousMatch"
onClick={() => editor.commands.moveToPreviousResult()}
@@ -227,7 +228,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
/>
<ToolButton
toggled={false}
title="Next match"
title={strings.nextMatch()}
id="nextMatch"
icon="nextMatch"
onClick={() => editor.commands.moveToNextResult()}
@@ -236,7 +237,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
/>
<ToolButton
toggled={false}
title="Close"
title={strings.close()}
id="close"
icon="close"
onClick={() => editor.chain().focus().endSearch().run()}
@@ -248,7 +249,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
<Flex sx={{ alignItems: "center", height: "33.2px", mt: 1 }}>
<ToolButton
toggled={false}
title="Replace"
title={strings.replace()}
id="replace"
icon="replaceOne"
onClick={() =>
@@ -261,7 +262,7 @@ export function SearchReplacePopup(props: SearchReplacePopupProps) {
/>
<ToolButton
toggled={false}
title="Replace all"
title={strings.replaceAll()}
id="replaceAll"
icon="replaceAll"
onClick={() =>

View File

@@ -22,6 +22,7 @@ import { useEffect, useState } from "react";
import { Popup } from "../components/popup.js";
import { useIsMobile } from "../stores/toolbar-store.js";
import { InlineInput } from "../../components/inline-input/index.js";
import { strings } from "@notesnook/intl";
const MAX_COLUMNS = 20;
const MAX_ROWS = 20;
@@ -76,8 +77,8 @@ export function TablePopup(props: TablePopupProps) {
action={{
title:
!cellLocation.column || !cellLocation.row
? "Please set a table size"
: `Insert a ${cellLocation.column} x ${cellLocation.row} table`,
? strings.setTableSizeNotice()
: strings.insertTableOfSize(cellLocation.row, cellLocation.column),
disabled: !cellLocation.column || !cellLocation.row,
onClick: () =>
onInsertTable({

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { ToolbarDefinition, ToolDefinition } from "./types.js";
import { ToolId } from "./tools/index.js";
import { strings } from "@notesnook/intl";
const tools: Record<ToolId, ToolDefinition> = {
none: {
@@ -27,332 +28,332 @@ const tools: Record<ToolId, ToolDefinition> = {
},
bold: {
icon: "bold",
title: "Bold"
title: strings.bold()
},
italic: {
icon: "italic",
title: "Italic"
title: strings.italic()
},
underline: {
icon: "underline",
title: "Underline"
title: strings.underline()
},
strikethrough: {
icon: "strikethrough",
title: "Strikethrough"
title: strings.strikethrough()
},
addInternalLink: {
icon: "noteLink",
title: "Add bi-directional note link"
title: strings.noteLink()
},
addLink: {
icon: "link",
title: "Link"
title: strings.link()
},
editLink: {
icon: "linkEdit",
title: "Edit link",
title: strings.linkEdit(),
conditional: true
},
removeLink: {
icon: "linkRemove",
title: "Remove link",
title: strings.linkRemove(),
conditional: true
},
openLink: {
icon: "openLink",
title: "Open link",
title: strings.openLink(),
conditional: true
},
copyLink: {
icon: "copyLink",
title: "Copy link",
title: strings.copyLink(),
conditional: true
},
linkSettings: {
icon: "linkSettings",
title: "Link settings",
title: strings.linkSettings(),
conditional: true
},
code: {
icon: "code",
title: "Code"
title: strings.code()
},
codeRemove: {
icon: "codeRemove",
title: "Code",
title: strings.codeRemove(),
conditional: true
},
clearformatting: {
icon: "formatClear",
title: "Clear all formatting"
title: strings.formatClear()
},
subscript: {
icon: "subscript",
title: "Subscript"
title: strings.subscript()
},
superscript: {
icon: "superscript",
title: "Superscript"
title: strings.superscript()
},
insertBlock: {
icon: "plus",
title: "Insert",
title: strings.insert(),
conditional: true
},
bulletList: {
icon: "bulletList",
title: "Bullet list"
title: strings.bulletList()
},
numberedList: {
icon: "numberedList",
title: "Numbered list"
title: strings.numberedList()
},
checkList: {
icon: "checklist",
title: "Checklist"
title: strings.checklist()
},
fontFamily: {
icon: "fontFamily",
title: "Font family"
title: strings.fontFamily()
},
fontSize: {
icon: "fontSize",
title: "Font size"
title: strings.fontSize()
},
headings: {
icon: "heading",
title: "Headings"
title: strings.headings()
},
alignment: {
icon: "alignCenter",
title: "Alignment"
title: strings.alignCenter()
},
textDirection: {
icon: "ltr",
title: "Text direction"
title: strings.ltr()
},
highlight: {
icon: "highlight",
title: "Highlight"
title: strings.highlight()
},
textColor: {
icon: "textColor",
title: "Text color"
title: strings.textColor()
},
math: {
icon: "math",
title: "Math (inline)"
title: strings.mathInline()
},
tableSettings: {
icon: "tableSettings",
title: "Table settings",
title: strings.tableSettings(),
conditional: true
},
columnProperties: {
icon: "columnProperties",
title: "Column properties",
title: strings.columnProperties(),
conditional: true
},
rowProperties: {
icon: "rowProperties",
title: "Row properties",
title: strings.rowProperties(),
conditional: true
},
cellProperties: {
icon: "cellProperties",
title: "Cell properties",
title: strings.cellProperties(),
conditional: true
},
insertColumnLeft: {
icon: "insertColumnLeft",
title: "Insert column left",
title: strings.insertColumnLeft(),
conditional: true
},
insertColumnRight: {
icon: "insertColumnRight",
title: "Insert column right",
title: strings.insertColumnRight(),
conditional: true
},
moveColumnLeft: {
icon: "moveColumnLeft",
title: "Move column left",
title: strings.moveColumnLeft(),
conditional: true
},
moveColumnRight: {
icon: "moveColumnRight",
title: "Move column right",
title: strings.moveColumnRight(),
conditional: true
},
deleteColumn: {
icon: "deleteColumn",
title: "Delete column",
title: strings.deleteColumn(),
conditional: true
},
splitCells: {
icon: "splitCells",
title: "Split cells",
title: strings.splitCells(),
conditional: true
},
mergeCells: {
icon: "mergeCells",
title: "Merge cells",
title: strings.mergeCells(),
conditional: true
},
insertRowAbove: {
icon: "insertRowAbove",
title: "Insert row above",
title: strings.insertRowAbove(),
conditional: true
},
insertRowBelow: {
icon: "insertRowBelow",
title: "Insert row below",
title: strings.insertRowBelow(),
conditional: true
},
moveRowUp: {
icon: "moveRowUp",
title: "Move row up",
title: strings.moveRowUp(),
conditional: true
},
moveRowDown: {
icon: "moveRowDown",
title: "Move row down",
title: strings.moveRowDown(),
conditional: true
},
deleteRow: {
icon: "deleteRow",
title: "Delete row",
title: strings.deleteRow(),
conditional: true
},
deleteTable: {
icon: "deleteTable",
title: "Delete table",
title: strings.deleteTable(),
conditional: true
},
cellBackgroundColor: {
icon: "backgroundColor",
title: "Cell background color",
title: strings.cellBackgroundColor(),
conditional: true
},
cellBorderColor: {
icon: "cellBorderColor",
title: "Cell border color",
title: strings.cellBorderColor(),
conditional: true
},
cellTextColor: {
icon: "textColor",
title: "Cell text color",
title: strings.textColor(),
conditional: true
},
cellBorderWidth: {
icon: "none",
title: "Cell border width",
title: strings.none(),
conditional: true
},
imageSettings: {
icon: "imageSettings",
title: "Image settings",
title: strings.imageSettings(),
conditional: true
},
imageAlignCenter: {
icon: "alignCenter",
title: "Align center",
title: strings.alignCenter(),
conditional: true
},
imageAlignLeft: {
icon: "alignLeft",
title: "Align left",
title: strings.alignLeft(),
conditional: true
},
imageAlignRight: {
icon: "alignRight",
title: "Align right",
title: strings.alignRight(),
conditional: true
},
imageFloat: {
icon: "imageFloat",
title: "Float image",
title: strings.imageFloat(),
conditional: true
},
imageProperties: {
icon: "more",
title: "Image properties",
title: strings.imageProperties(),
conditional: true
},
previewAttachment: {
icon: "previewAttachment",
title: "Preview attachment",
title: strings.previewAttachment(),
conditional: true
},
attachmentSettings: {
icon: "attachmentSettings",
title: "Attachment settings",
title: strings.attachmentSettings(),
conditional: true
},
downloadAttachment: {
icon: "download",
title: "Download attachment",
title: strings.downloadAttachment(),
conditional: true
},
removeAttachment: {
icon: "delete",
title: "Remove attachment",
title: strings.delete(),
conditional: true
},
embedSettings: {
icon: "embedSettings",
title: "Embed settings",
title: strings.embedSettings(),
conditional: true
},
embedAlignCenter: {
icon: "alignCenter",
title: "Align center",
title: strings.alignCenter(),
conditional: true
},
embedAlignLeft: {
icon: "alignLeft",
title: "Align left",
title: strings.alignLeft(),
conditional: true
},
embedAlignRight: {
icon: "alignRight",
title: "Align right",
title: strings.alignRight(),
conditional: true
},
embedProperties: {
icon: "more",
title: "Embed properties",
title: strings.embedProperties(),
conditional: true
},
webclipSettings: {
icon: "webclipSettings",
title: "Web clip settings",
title: strings.webclipSettings(),
conditional: true
},
webclipFullScreen: {
icon: "fullscreen",
title: "Full screen",
title: strings.fullscreen(),
conditional: true
},
webclipOpenExternal: {
icon: "openLink",
title: "Open in new tab",
title: strings.openLink(),
conditional: true
},
webclipOpenSource: {
icon: "openSource",
title: "Open source",
title: strings.openSource(),
conditional: true
},
outdent: {
icon: "outdent",
title: "Lift list item",
title: strings.outdent(),
conditional: true
},
indent: {
icon: "indent",
title: "Sink list item",
title: strings.indent(),
conditional: true
}
};

View File

@@ -29,6 +29,7 @@ import { ResponsivePresenter } from "../../components/responsive/index.js";
import { showPopup } from "../../components/popup-presenter/index.js";
import { ImageUploadPopup } from "../popups/image-upload.js";
import { Button } from "../../components/button.js";
import { strings } from "@notesnook/intl";
export function InsertBlock(props: ToolProps) {
const { editor } = props;
@@ -82,7 +83,7 @@ export function InsertBlock(props: ToolProps) {
<ResponsivePresenter
desktop="menu"
mobile="sheet"
title="Choose a block to insert"
title={strings.chooseBlockToInsert()}
isOpen={isOpen}
items={menuItems}
onClose={() => setIsOpen(false)}
@@ -100,7 +101,7 @@ export function InsertBlock(props: ToolProps) {
const horizontalRule = (editor: Editor): MenuItem => ({
key: "hr",
type: "button",
title: "Horizontal rule",
title: strings.horizontalRule(),
icon: Icons.horizontalRule,
isChecked: editor.isActive("horizontalRule"),
onClick: () => editor.chain().focus().setHorizontalRule().run()
@@ -109,7 +110,7 @@ const horizontalRule = (editor: Editor): MenuItem => ({
const codeblock = (editor: Editor): MenuItem => ({
key: "codeblock",
type: "button",
title: "Code block",
title: strings.codeBlock(),
icon: Icons.codeblock,
isChecked: editor.isActive("codeBlock"),
onClick: () => editor.chain().focus().toggleCodeBlock().run(),
@@ -119,7 +120,7 @@ const codeblock = (editor: Editor): MenuItem => ({
const blockquote = (editor: Editor): MenuItem => ({
key: "blockquote",
type: "button",
title: "Quote",
title: strings.quote(),
icon: Icons.blockquote,
isChecked: editor.isActive("blockQuote"),
onClick: () => editor.chain().focus().toggleBlockquote().run(),
@@ -129,7 +130,7 @@ const blockquote = (editor: Editor): MenuItem => ({
const mathblock = (editor: Editor): MenuItem => ({
key: "math",
type: "button",
title: "Math & formulas",
title: strings.mathAndFormulas(),
icon: Icons.mathBlock,
isChecked: editor.isActive("mathBlock"),
onClick: () => editor.chain().focus().insertMathBlock().run(),
@@ -139,7 +140,7 @@ const mathblock = (editor: Editor): MenuItem => ({
const callout = (editor: Editor): MenuItem => ({
key: "callout",
type: "button",
title: "Callout",
title: strings.callout(),
icon: Icons.callout,
menu: {
items: [
@@ -169,15 +170,15 @@ const callout = (editor: Editor): MenuItem => ({
const image = (editor: Editor, isMobile: boolean): MenuItem => ({
key: "image",
type: "button",
title: "Image",
title: strings.image(),
icon: Icons.image,
menu: {
title: "Insert an image",
title: strings.insertImage(),
items: [
{
key: "upload-from-disk",
type: "button",
title: "Upload from disk",
title: strings.uploadFromDisk(),
icon: Icons.upload,
onClick: () => editor.storage.openAttachmentPicker?.("image"),
modifier: "Mod-Shift-I"
@@ -185,7 +186,7 @@ const image = (editor: Editor, isMobile: boolean): MenuItem => ({
{
key: "camera",
type: "button",
title: "Take a photo using camera",
title: strings.takePhotoUsingCamera(),
icon: Icons.camera,
isHidden: !isMobile,
onClick: () => editor.storage.openAttachmentPicker?.("camera")
@@ -198,10 +199,10 @@ const image = (editor: Editor, isMobile: boolean): MenuItem => ({
const table = (editor: Editor): MenuItem => ({
key: "table",
type: "button",
title: "Table",
title: strings.table(),
icon: Icons.table,
menu: {
title: "Insert a table",
title: strings.insertTable(),
items: [
{
key: "table-size-selector",
@@ -229,10 +230,10 @@ const table = (editor: Editor): MenuItem => ({
const embedMobile = (editor: Editor): MenuItem => ({
key: "embed",
type: "button",
title: "Embed",
title: strings.embed(),
icon: Icons.embed,
menu: {
title: "Insert an embed",
title: strings.insertEmbed(),
items: [
{
key: "embed-popup",
@@ -240,7 +241,7 @@ const embedMobile = (editor: Editor): MenuItem => ({
component: function ({ onClick }) {
return (
<EmbedPopup
title="Insert embed"
title={strings.insertEmbed()}
onClose={(embed) => {
if (!embed) return onClick?.();
editor.chain().insertEmbed(embed).run();
@@ -257,14 +258,14 @@ const embedMobile = (editor: Editor): MenuItem => ({
const embedDesktop = (editor: Editor): MenuItem => ({
key: "embed",
type: "button",
title: "Embed",
title: strings.embed(),
icon: Icons.embed,
onClick: () => {
if (!editor) return;
showPopup({
popup: (hide) => (
<EmbedPopup
title="Insert embed"
title={strings.insertEmbed()}
onClose={(embed) => {
if (!embed) return hide();
editor.chain().insertEmbed(embed).run();
@@ -279,7 +280,7 @@ const embedDesktop = (editor: Editor): MenuItem => ({
const attachment = (editor: Editor): MenuItem => ({
key: "attachment",
type: "button",
title: "Attachment",
title: strings.attachment(),
icon: Icons.attachment,
isChecked: editor.isActive("attachment"),
onClick: () => editor.storage.openAttachmentPicker?.("file"),
@@ -289,7 +290,7 @@ const attachment = (editor: Editor): MenuItem => ({
const tasklist = (editor: Editor): MenuItem => ({
key: "tasklist",
type: "button",
title: "Task list",
title: strings.taskList(),
icon: Icons.checkbox,
isChecked: editor.isActive("taskList"),
onClick: () => editor.chain().focus().toggleTaskList().run(),
@@ -299,7 +300,7 @@ const tasklist = (editor: Editor): MenuItem => ({
const outlinelist = (editor: Editor): MenuItem => ({
key: "outlinelist",
type: "button",
title: "Outline list",
title: strings.outlineList(),
icon: Icons.outlineList,
isChecked: editor.isActive("outlineList"),
onClick: () => editor.chain().focus().toggleOutlineList().run(),
@@ -309,10 +310,10 @@ const outlinelist = (editor: Editor): MenuItem => ({
const uploadImageFromURLMobile = (editor: Editor): MenuItem => ({
key: "upload-from-url",
type: "button",
title: "Attach from URL",
title: strings.attachImageFromURL(),
icon: Icons.link,
menu: {
title: "Attach image from URL",
title: strings.attachImageFromURL(),
items: [
{
key: "attach-image",
@@ -341,7 +342,7 @@ const uploadImageFromURLMobile = (editor: Editor): MenuItem => ({
const uploadImageFromURL = (editor: Editor): MenuItem => ({
key: "upload-from-url",
type: "button",
title: "Attach from URL",
title: strings.attachImageFromURL(),
icon: Icons.link,
onClick: () => {
showPopup({

View File

@@ -23,10 +23,14 @@ import { PopupWrapper } from "../../components/popup-presenter/index.js";
import { config } from "../../utils/config.js";
import { SplitButton } from "../components/split-button.js";
import { ColorPicker } from "../popups/color-picker.js";
import { usePopupManager, useToolbarLocation } from "../stores/toolbar-store.js";
import {
usePopupManager,
useToolbarLocation
} from "../stores/toolbar-store.js";
import { ToolProps } from "../types.js";
import { getEditorToolbarPopup } from "../utils/dom.js";
import { PositionOptions } from "@notesnook/ui";
import { strings } from "@notesnook/intl";
type ColorType = "background" | "text" | "border";
type ColorToolProps = ToolProps & {
@@ -193,7 +197,7 @@ export function Highlight(props: ToolProps) {
{...props}
cacheKey="highlight"
activeColor={editor.getAttributes("textStyle").backgroundColor}
title={"Background color"}
title={strings.backgroundColor()}
type="background"
onColorChange={(color) =>
color
@@ -211,7 +215,7 @@ export function TextColor(props: ToolProps) {
{...props}
cacheKey={"textColor"}
activeColor={editor.getAttributes("textStyle").color}
title="Text color"
title={strings.textColor()}
type="text"
onColorChange={(color) =>
color

View File

@@ -26,6 +26,7 @@ import { useToolbarLocation } from "../stores/toolbar-store.js";
import { findSelectedNode } from "../../utils/prosemirror.js";
import { Embed } from "../../extensions/embed/index.js";
import { EmbedPopup } from "../popups/embed-popup.js";
import { strings } from "@notesnook/intl";
export function EmbedSettings(props: ToolProps) {
const { editor } = props;
@@ -121,7 +122,7 @@ export function EmbedProperties(props: ToolProps) {
}}
>
<EmbedPopup
title="Embed properties"
title={strings.embedProperties()}
onClose={(newEmbed) => {
if (!newEmbed) {
editor.commands.setEmbedSize(embed);

View File

@@ -27,6 +27,7 @@ import { useRefValue } from "../../hooks/use-ref-value.js";
import { useToolbarStore } from "../stores/toolbar-store.js";
import { getFontById, getFontIds, getFonts } from "../../utils/font.js";
import { CodeBlock } from "../../extensions/code-block/index.js";
import { strings } from "@notesnook/intl";
export function FontSize(props: ToolProps) {
const { editor } = props;
@@ -46,7 +47,7 @@ export function FontSize(props: ToolProps) {
return (
<Counter
title="Font size"
title={strings.fontSize()}
disabled={editor.isActive(CodeBlock.name)}
onDecrease={() =>
editor.chain().focus().setFontSize(`${decreaseFontSize()}px`).run()

View File

@@ -21,9 +21,13 @@ import { ToolProps } from "../types.js";
import { Editor } from "../../types.js";
import { Dropdown } from "../components/dropdown.js";
import { MenuItem } from "@notesnook/ui";
import { ToolbarLocation, useToolbarLocation } from "../stores/toolbar-store.js";
import {
ToolbarLocation,
useToolbarLocation
} from "../stores/toolbar-store.js";
import { useMemo } from "react";
import { CodeBlock } from "../../extensions/code-block/index.js";
import { strings } from "@notesnook/intl";
const defaultLevels = [1, 2, 3, 4, 5, 6] as const;
@@ -45,7 +49,9 @@ export function Headings(props: ToolProps) {
id="headings"
group="headings"
selectedItem={
currentHeadingLevel ? `Heading ${currentHeadingLevel}` : "Paragraph"
currentHeadingLevel
? strings.heading(currentHeadingLevel)
: strings.paragraph()
}
items={items}
menuWidth={130}
@@ -62,7 +68,7 @@ function toMenuItems(
const menuItems: MenuItem[] = defaultLevels.map((level) => ({
type: "button",
key: `heading-${level}`,
title: toolbarLocation === "bottom" ? `H${level}` : `Heading ${level}`,
title: toolbarLocation === "bottom" ? `H${level}` : strings.heading(level),
isChecked: level === currentHeadingLevel,
modifier: `Mod-Alt-${level}`,
onClick: () =>
@@ -76,7 +82,7 @@ function toMenuItems(
const paragraph: MenuItem = {
key: "paragraph",
type: "button",
title: "Paragraph",
title: strings.paragraph(),
isChecked: !currentHeadingLevel,
modifier: `Mod-Alt-0`,
onClick: () => editor.chain().focus().setParagraph().run()

View File

@@ -31,6 +31,7 @@ import { ImageNode } from "../../extensions/image/index.js";
import { Link as LinkNode } from "../../extensions/link/index.js";
import { getMarkAttributes } from "@tiptap/core";
import { useHoverPopupContext } from "../floating-menus/hover-popup/context.js";
import { strings } from "@notesnook/intl";
export function LinkSettings(props: ToolProps) {
const { editor } = props;
@@ -291,7 +292,7 @@ function LinkTool(props: LinkToolProps) {
align: "center",
yOffset: 5
}}
title={isEditing ? "Edit link" : "Insert link"}
title={isEditing ? strings.editLink() : strings.insertLink()}
isOpen={isOpen}
items={[]}
onClose={() => {

View File

@@ -38,6 +38,7 @@ import { Counter } from "../components/counter.js";
import { useToolbarLocation } from "../stores/toolbar-store.js";
import { showPopup } from "../../components/popup-presenter/index.js";
import { useRefValue } from "../../hooks/use-ref-value.js";
import { strings } from "@notesnook/intl";
export function TableSettings(props: ToolProps) {
const { editor } = props;
@@ -89,7 +90,7 @@ export function RowProperties(props: ToolProps) {
onClick={() => setIsMenuOpen(true)}
/>
<ResponsivePresenter
title="Row properties"
title={strings.rowProperties()}
mobile="sheet"
desktop="menu"
isOpen={isMenuOpen}
@@ -132,7 +133,7 @@ export function ColumnProperties(props: ToolProps) {
onClick={() => setIsMenuOpen(true)}
/>
<ResponsivePresenter
title="Column properties"
title={strings.columnProperties()}
mobile="sheet"
desktop="menu"
isOpen={isMenuOpen}
@@ -181,7 +182,7 @@ export function TableProperties(props: ToolProps) {
onClick={() => setIsMenuOpen(true)}
/>
<ResponsivePresenter
title="Table properties"
title={strings.tableSettings()}
mobile="sheet"
desktop="menu"
isOpen={isMenuOpen}
@@ -229,7 +230,7 @@ export function CellBackgroundColor(props: ToolProps) {
{...props}
cacheKey="cellBackgroundColor"
activeColor={editor.getAttributes("tableCell").backgroundColor}
title={"Cell background color"}
title={strings.cellBackgroundColor()}
type="background"
onColorChange={(color) =>
editor.chain().setCellAttribute("backgroundColor", color).run()
@@ -247,7 +248,7 @@ export function CellTextColor(props: ToolProps) {
cacheKey="cellTextColor"
type="text"
activeColor={editor.getAttributes("tableCell").color}
title={"Cell text color"}
title={strings.cellTextColor()}
onColorChange={(color) =>
editor.chain().focus().setCellAttribute("color", color).run()
}
@@ -264,7 +265,7 @@ export function CellBorderColor(props: ToolProps) {
cacheKey="cellBorderColor"
activeColor={editor.getAttributes("tableCell").borderColor}
type="border"
title={"Cell border color"}
title={strings.cellBorderColor()}
onColorChange={(color) =>
editor.chain().focus().setCellAttribute("borderColor", color).run()
}
@@ -292,7 +293,7 @@ export function CellBorderWidth(props: ToolProps) {
return (
<Counter
title="cell border width"
title={strings.cellBorderWidth()}
onDecrease={() =>
editor.commands.setCellAttribute("borderWidth", decreaseBorderWidth())
}