@agent-native/core 0.0.0-beta-20260819225910 → 0.0.0-beta-20260819231527

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/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 8479
34
+ - template files: 8480
@@ -60,6 +60,109 @@ type SelectionFillRange = {
60
60
  };
61
61
 
62
62
  type TextStyle = "paragraph" | 1 | 2 | 3 | 4 | 5 | 6;
63
+ type ColorAttribute = "color" | "bgColor";
64
+ type ColorName =
65
+ | "gray"
66
+ | "brown"
67
+ | "orange"
68
+ | "yellow"
69
+ | "green"
70
+ | "blue"
71
+ | "purple"
72
+ | "pink"
73
+ | "red";
74
+
75
+ const COLOR_NAMES: ColorName[] = [
76
+ "gray",
77
+ "brown",
78
+ "orange",
79
+ "yellow",
80
+ "green",
81
+ "blue",
82
+ "purple",
83
+ "pink",
84
+ "red",
85
+ ];
86
+
87
+ export function getSelectionNotionSpanAttribute(
88
+ editor: Editor,
89
+ attribute: ColorAttribute,
90
+ ): string | null | "mixed" {
91
+ const { from, to } = editor.state.selection;
92
+ const markType = editor.state.schema.marks.notionSpan;
93
+ if (!markType) return null;
94
+
95
+ let observed: string | null = null;
96
+ let hasObserved = false;
97
+ let mixed = false;
98
+
99
+ editor.state.doc.nodesBetween(from, to, (node, _position, parent) => {
100
+ if (!node.isText || !parent?.type.allowsMarkType(markType)) return;
101
+ const mark = node.marks.find((candidate) => candidate.type === markType);
102
+ const value = (mark?.attrs[attribute] as string | null | undefined) ?? null;
103
+ if (!hasObserved) {
104
+ observed = value;
105
+ hasObserved = true;
106
+ } else if (observed !== value) {
107
+ mixed = true;
108
+ }
109
+ });
110
+
111
+ return mixed ? "mixed" : observed;
112
+ }
113
+
114
+ export function selectionHasColorableText(
115
+ state: EditorState,
116
+ from: number,
117
+ to: number,
118
+ ) {
119
+ const markType = state.schema.marks.notionSpan;
120
+ if (!markType) return false;
121
+
122
+ let hasText = false;
123
+ state.doc.nodesBetween(from, to, (node, _position, parent) => {
124
+ if (node.isText && parent?.type.allowsMarkType(markType)) hasText = true;
125
+ return !hasText;
126
+ });
127
+ return hasText;
128
+ }
129
+
130
+ export function setSelectionNotionSpanAttribute(
131
+ editor: Editor,
132
+ attribute: ColorAttribute,
133
+ value: string | null,
134
+ ) {
135
+ const { state } = editor;
136
+ const { from, to } = state.selection;
137
+ const markType = state.schema.marks.notionSpan;
138
+ if (!markType || from === to) return false;
139
+
140
+ const transaction = state.tr;
141
+ state.doc.nodesBetween(from, to, (node, position, parent) => {
142
+ if (!node.isText || !parent?.type.allowsMarkType(markType)) return;
143
+ const start = Math.max(from, position);
144
+ const end = Math.min(to, position + node.nodeSize);
145
+ if (start >= end) return;
146
+
147
+ const existing = node.marks.find((mark) => mark.type === markType);
148
+ const attrs = { ...existing?.attrs, [attribute]: value };
149
+ transaction.removeMark(start, end, markType);
150
+ if (
151
+ attrs.color ||
152
+ attrs.bgColor ||
153
+ attrs.underline ||
154
+ attrs.href ||
155
+ (attrs.attrsJson && attrs.attrsJson !== "{}")
156
+ ) {
157
+ transaction.addMark(start, end, markType.create(attrs));
158
+ }
159
+ });
160
+
161
+ if (!transaction.docChanged) return false;
162
+ editor.view.dispatch(transaction);
163
+ editor.commands.focus();
164
+ return true;
165
+ }
63
166
 
64
167
  function activeTextStyle(editor: Editor): TextStyle {
65
168
  for (const level of [1, 2, 3, 4, 5, 6] as const) {
@@ -119,8 +222,16 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
119
222
  const [showLinkInput, setShowLinkInput] = useState(false);
120
223
  const [linkUrl, setLinkUrl] = useState("");
121
224
  const [textStyleOpen, setTextStyleOpen] = useState(false);
225
+ const [colorOpen, setColorOpen] = useState(false);
226
+ const [colorRevision, setColorRevision] = useState(0);
227
+ const [recentColor, setRecentColor] = useState<{
228
+ attribute: ColorAttribute;
229
+ value: string;
230
+ } | null>(null);
122
231
  const textStyleSelection = useRef<{ from: number; to: number } | null>(null);
232
+ const colorSelection = useRef<{ from: number; to: number } | null>(null);
123
233
  const textStyleApplied = useRef(false);
234
+ const colorApplied = useRef(false);
124
235
  const restoreEditorFocusOnClose = useRef(false);
125
236
  const [textStyle, setTextStyle] = useState<TextStyle>(() =>
126
237
  activeTextStyle(editor),
@@ -129,8 +240,12 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
129
240
  useEffect(() => {
130
241
  const syncTextStyle = () => {
131
242
  setTextStyle(activeTextStyle(editor));
243
+ setColorRevision((revision) => revision + 1);
132
244
  const { from, to } = editor.state.selection;
133
- if (from !== to) textStyleSelection.current = { from, to };
245
+ if (from !== to) {
246
+ textStyleSelection.current = { from, to };
247
+ colorSelection.current = { from, to };
248
+ }
134
249
  };
135
250
  editor.on("selectionUpdate", syncTextStyle);
136
251
  editor.on("transaction", syncTextStyle);
@@ -199,6 +314,82 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
199
314
  setTextStyleOpen(false);
200
315
  };
201
316
 
317
+ const applyColor = (attribute: ColorAttribute, value: string | null) => {
318
+ if (colorSelection.current) {
319
+ editor.commands.setTextSelection(colorSelection.current);
320
+ }
321
+ if (!setSelectionNotionSpanAttribute(editor, attribute, value)) return;
322
+ if (value) setRecentColor({ attribute, value });
323
+ colorApplied.current = true;
324
+ setColorOpen(false);
325
+ };
326
+
327
+ const activeTextColor = getSelectionNotionSpanAttribute(editor, "color");
328
+ const activeBackgroundColor = getSelectionNotionSpanAttribute(
329
+ editor,
330
+ "bgColor",
331
+ );
332
+ void colorRevision;
333
+
334
+ const renderColorChoice = (
335
+ attribute: ColorAttribute,
336
+ value: string | null,
337
+ ) => {
338
+ const sectionLabel = t(
339
+ attribute === "color" ? "editor.textColor" : "editor.backgroundColor",
340
+ );
341
+ const colorName = value?.replace(/_bg$/, "") as ColorName | undefined;
342
+ const choiceLabel = colorName
343
+ ? t(`editor.color.${colorName}`)
344
+ : t("editor.defaultColor");
345
+ const activeValue =
346
+ attribute === "color" ? activeTextColor : activeBackgroundColor;
347
+ const isActive = activeValue !== "mixed" && activeValue === value;
348
+
349
+ return (
350
+ <button
351
+ key={`${attribute}-${value ?? "default"}`}
352
+ type="button"
353
+ role="menuitemradio"
354
+ aria-checked={isActive}
355
+ aria-label={`${sectionLabel}: ${choiceLabel}`}
356
+ onPointerDown={(event) => {
357
+ event.preventDefault();
358
+ event.stopPropagation();
359
+ applyColor(attribute, value);
360
+ }}
361
+ onClick={(event) => {
362
+ if (event.detail === 0) applyColor(attribute, value);
363
+ }}
364
+ className={cn(
365
+ "relative flex size-8 items-center justify-center rounded-md border border-border bg-background text-sm font-semibold hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
366
+ isActive && "ring-2 ring-foreground",
367
+ )}
368
+ >
369
+ {attribute === "color" ? (
370
+ <span className={colorName ? `notion-block-color--${colorName}` : ""}>
371
+ A
372
+ </span>
373
+ ) : (
374
+ <span
375
+ className={cn(
376
+ "size-5 rounded border border-border",
377
+ colorName && `notion-block-bg--${colorName}`,
378
+ )}
379
+ />
380
+ )}
381
+ {isActive ? (
382
+ <IconCheck
383
+ aria-hidden="true"
384
+ className="absolute -end-1 -top-1 rounded-full bg-foreground p-0.5 text-background"
385
+ size={12}
386
+ strokeWidth={3}
387
+ />
388
+ ) : null}
389
+ </button>
390
+ );
391
+ };
392
+
202
393
  const openLinkInput = useCallback(() => {
203
394
  setLinkUrl(editor.getAttributes("link").href || "");
204
395
  setShowLinkInput(true);
@@ -318,6 +509,15 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
318
509
  };
319
510
 
320
511
  const items = [
512
+ { type: "text-style" as const },
513
+ ...(selectionHasColorableText(
514
+ editor.state,
515
+ editor.state.selection.from,
516
+ editor.state.selection.to,
517
+ )
518
+ ? [{ type: "color" as const }]
519
+ : []),
520
+ { type: "divider" as const },
321
521
  {
322
522
  icon: IconBold,
323
523
  title: t("editor.bold"),
@@ -343,8 +543,6 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
343
543
  isActive: () => editor.isActive("code"),
344
544
  },
345
545
  { type: "divider" as const },
346
- { type: "text-style" as const },
347
- { type: "divider" as const },
348
546
  {
349
547
  icon: IconLink,
350
548
  title: t("editor.link"),
@@ -529,6 +727,103 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
529
727
  </Popover>
530
728
  );
531
729
  }
730
+ if ("type" in item && item.type === "color") {
731
+ return (
732
+ <Popover
733
+ key="color"
734
+ open={colorOpen}
735
+ onOpenChange={(open) => {
736
+ if (open) {
737
+ colorApplied.current = false;
738
+ restoreEditorFocusOnClose.current = false;
739
+ const { from, to } = editor.state.selection;
740
+ if (from !== to) colorSelection.current = { from, to };
741
+ }
742
+ setColorOpen(open);
743
+ }}
744
+ >
745
+ <PopoverTrigger asChild>
746
+ <button
747
+ type="button"
748
+ aria-label={t("editor.color.label")}
749
+ className={cn(
750
+ "flex size-8 items-center justify-center rounded text-sm font-semibold text-popover-foreground/85 hover:bg-accent hover:text-accent-foreground",
751
+ colorOpen && "bg-accent text-accent-foreground",
752
+ )}
753
+ >
754
+ A
755
+ </button>
756
+ </PopoverTrigger>
757
+ <PopoverContent
758
+ portalled={false}
759
+ align="start"
760
+ sideOffset={24}
761
+ className="w-52 p-2"
762
+ onEscapeKeyDown={() => {
763
+ restoreEditorFocusOnClose.current = true;
764
+ window.setTimeout(() => editor.commands.focus(), 0);
765
+ }}
766
+ onCloseAutoFocus={(event) => {
767
+ if (
768
+ colorApplied.current ||
769
+ restoreEditorFocusOnClose.current
770
+ ) {
771
+ event.preventDefault();
772
+ }
773
+ if (restoreEditorFocusOnClose.current) {
774
+ editor.commands.focus();
775
+ }
776
+ colorApplied.current = false;
777
+ restoreEditorFocusOnClose.current = false;
778
+ }}
779
+ >
780
+ {recentColor ? (
781
+ <div className="mb-2">
782
+ <div className="mb-1 text-xs font-medium text-muted-foreground">
783
+ {t("editor.color.recentlyUsed")}
784
+ </div>
785
+ <div role="menu">
786
+ {renderColorChoice(
787
+ recentColor.attribute,
788
+ recentColor.value,
789
+ )}
790
+ </div>
791
+ </div>
792
+ ) : null}
793
+ <div className="mb-2">
794
+ <div className="mb-1 text-xs font-medium text-muted-foreground">
795
+ {t("editor.textColor")}
796
+ </div>
797
+ <div
798
+ role="menu"
799
+ aria-label={t("editor.textColor")}
800
+ className="grid grid-cols-5 gap-1"
801
+ >
802
+ {renderColorChoice("color", null)}
803
+ {COLOR_NAMES.map((name) =>
804
+ renderColorChoice("color", name),
805
+ )}
806
+ </div>
807
+ </div>
808
+ <div>
809
+ <div className="mb-1 text-xs font-medium text-muted-foreground">
810
+ {t("editor.backgroundColor")}
811
+ </div>
812
+ <div
813
+ role="menu"
814
+ aria-label={t("editor.backgroundColor")}
815
+ className="grid grid-cols-5 gap-1"
816
+ >
817
+ {renderColorChoice("bgColor", null)}
818
+ {COLOR_NAMES.map((name) =>
819
+ renderColorChoice("bgColor", `${name}_bg`),
820
+ )}
821
+ </div>
822
+ </div>
823
+ </PopoverContent>
824
+ </Popover>
825
+ );
826
+ }
532
827
  const {
533
828
  icon: Icon,
534
829
  title,
@@ -76,6 +76,7 @@ import {
76
76
  LocalMdxComponentNode,
77
77
  } from "./extensions/LocalMdxComponentNode";
78
78
  import {
79
+ CompatibleCode,
79
80
  createNotionEditorExtensions,
80
81
  focusMostRecentEmptyToggleSummary,
81
82
  type NotionPageLink,
@@ -1645,6 +1646,7 @@ export function createVisualEditorExtensions({
1645
1646
  },
1646
1647
  starterKit: {
1647
1648
  blockquote: false,
1649
+ code: false,
1648
1650
  paragraph: false,
1649
1651
  heading: { levels: [1, 2, 3, 4, 5, 6] },
1650
1652
  horizontalRule: {},
@@ -1653,6 +1655,7 @@ export function createVisualEditorExtensions({
1653
1655
  collab:
1654
1656
  ydoc || localAwareness ? { ydoc, awareness: localAwareness, user } : null,
1655
1657
  extraExtensions: [
1658
+ CompatibleCode,
1656
1659
  EmptyLineParagraph,
1657
1660
  NotionBlockquote,
1658
1661
  CodeBlock,
@@ -1,4 +1,5 @@
1
1
  import { findTrailingPlainInlineMath } from "@shared/inline-math";
2
+ import { NFM_COLORS } from "@shared/nfm";
2
3
  import {
3
4
  escapeHtml,
4
5
  indentMarkdown,
@@ -12,6 +13,7 @@ import {
12
13
  IconFileText,
13
14
  } from "@tabler/icons-react";
14
15
  import { InputRule, type Editor } from "@tiptap/core";
16
+ import { Code } from "@tiptap/extension-code";
15
17
  import type { Fragment, Node as ProseMirrorNode } from "@tiptap/pm/model";
16
18
  import { Selection } from "@tiptap/pm/state";
17
19
  import {
@@ -745,12 +747,19 @@ export const NotionSpanMark = Mark.create({
745
747
  renderHTML({ HTMLAttributes }) {
746
748
  const attrs = parseAttrsJson(HTMLAttributes.attrsJson as string);
747
749
  const style: string[] = [];
750
+ const classes: string[] = [];
748
751
 
749
- if (HTMLAttributes.color) {
750
- style.push(`color: ${HTMLAttributes.color}`);
752
+ if (
753
+ NFM_COLORS.has(HTMLAttributes.color) &&
754
+ !HTMLAttributes.color.endsWith("_bg")
755
+ ) {
756
+ classes.push(`notion-block-color--${HTMLAttributes.color}`);
751
757
  }
752
- if (HTMLAttributes.bgColor) {
753
- style.push(`background-color: ${HTMLAttributes.bgColor}`);
758
+ if (
759
+ NFM_COLORS.has(HTMLAttributes.bgColor) &&
760
+ HTMLAttributes.bgColor.endsWith("_bg")
761
+ ) {
762
+ classes.push(`notion-block-bg--${HTMLAttributes.bgColor.slice(0, -3)}`);
754
763
  }
755
764
  if (HTMLAttributes.underline === "true") {
756
765
  style.push("text-decoration: underline");
@@ -764,6 +773,7 @@ export const NotionSpanMark = Mark.create({
764
773
  bg_color: HTMLAttributes.bgColor || undefined,
765
774
  underline: HTMLAttributes.underline || undefined,
766
775
  href: HTMLAttributes.href || undefined,
776
+ class: classes.length ? classes.join(" ") : undefined,
767
777
  style: style.length ? style.join("; ") : undefined,
768
778
  }),
769
779
  0,
@@ -787,6 +797,10 @@ export const NotionSpanMark = Mark.create({
787
797
  },
788
798
  });
789
799
 
800
+ export const CompatibleCode = Code.extend({
801
+ excludes: "",
802
+ });
803
+
790
804
  export const NotionToggle = Node.create({
791
805
  name: "notionToggle",
792
806
  priority: 1000,
@@ -3137,6 +3137,22 @@ const enUS = {
3137
3137
  italic: "Italic",
3138
3138
  strikethrough: "Strikethrough",
3139
3139
  code: "Code",
3140
+ textColor: "Text color",
3141
+ backgroundColor: "Background color",
3142
+ defaultColor: "Default",
3143
+ color: {
3144
+ label: "Color",
3145
+ recentlyUsed: "Recently used",
3146
+ gray: "Gray",
3147
+ brown: "Brown",
3148
+ orange: "Orange",
3149
+ yellow: "Yellow",
3150
+ green: "Green",
3151
+ blue: "Blue",
3152
+ purple: "Purple",
3153
+ pink: "Pink",
3154
+ red: "Red",
3155
+ },
3140
3156
  heading1: "Heading 1",
3141
3157
  heading2: "Heading 2",
3142
3158
  heading3: "Heading 3",
@@ -5729,6 +5745,22 @@ const databaseExactEnglishMessagesByLocale = {
5729
5745
 
5730
5746
  const editorMessagesByLocale = {
5731
5747
  "zh-CN": {
5748
+ textColor: "文本颜色",
5749
+ backgroundColor: "背景颜色",
5750
+ defaultColor: "默认",
5751
+ color: {
5752
+ label: "颜色",
5753
+ recentlyUsed: "最近使用",
5754
+ gray: "灰色",
5755
+ brown: "棕色",
5756
+ orange: "橙色",
5757
+ yellow: "黄色",
5758
+ green: "绿色",
5759
+ blue: "蓝色",
5760
+ purple: "紫色",
5761
+ pink: "粉色",
5762
+ red: "红色",
5763
+ },
5732
5764
  noDocumentSelected: "未选择文档",
5733
5765
  blocksFieldRevisionConflict:
5734
5766
  "此 Blocks 字段已在其他位置更改。你的编辑未保存;现已显示最新版本。",
@@ -6078,6 +6110,22 @@ const editorMessagesByLocale = {
6078
6110
  },
6079
6111
  },
6080
6112
  "es-ES": {
6113
+ textColor: "Color de texto",
6114
+ backgroundColor: "Color de fondo",
6115
+ defaultColor: "Predeterminado",
6116
+ color: {
6117
+ label: "Color",
6118
+ recentlyUsed: "Usados recientemente",
6119
+ gray: "Gris",
6120
+ brown: "Marrón",
6121
+ orange: "Naranja",
6122
+ yellow: "Amarillo",
6123
+ green: "Verde",
6124
+ blue: "Azul",
6125
+ purple: "Morado",
6126
+ pink: "Rosa",
6127
+ red: "Rojo",
6128
+ },
6081
6129
  noDocumentSelected: "Ningún documento seleccionado",
6082
6130
  blocksFieldRevisionConflict:
6083
6131
  "Este campo de bloques cambió en otro lugar. Tu edición no se guardó; ahora se muestra la versión más reciente.",
@@ -6440,6 +6488,22 @@ const editorMessagesByLocale = {
6440
6488
  },
6441
6489
  },
6442
6490
  "fr-FR": {
6491
+ textColor: "Couleur du texte",
6492
+ backgroundColor: "Couleur d’arrière-plan",
6493
+ defaultColor: "Par défaut",
6494
+ color: {
6495
+ label: "Couleur",
6496
+ recentlyUsed: "Utilisées récemment",
6497
+ gray: "Gris",
6498
+ brown: "Marron",
6499
+ orange: "Orange",
6500
+ yellow: "Jaune",
6501
+ green: "Vert",
6502
+ blue: "Bleu",
6503
+ purple: "Violet",
6504
+ pink: "Rose",
6505
+ red: "Rouge",
6506
+ },
6443
6507
  noDocumentSelected: "Aucun document sélectionné",
6444
6508
  blocksFieldRevisionConflict:
6445
6509
  "Ce champ de blocs a été modifié ailleurs. Votre modification n’a pas été enregistrée ; la dernière version est maintenant affichée.",
@@ -6807,6 +6871,22 @@ const editorMessagesByLocale = {
6807
6871
  },
6808
6872
  },
6809
6873
  "de-DE": {
6874
+ textColor: "Textfarbe",
6875
+ backgroundColor: "Hintergrundfarbe",
6876
+ defaultColor: "Standard",
6877
+ color: {
6878
+ label: "Farbe",
6879
+ recentlyUsed: "Zuletzt verwendet",
6880
+ gray: "Grau",
6881
+ brown: "Braun",
6882
+ orange: "Orange",
6883
+ yellow: "Gelb",
6884
+ green: "Grün",
6885
+ blue: "Blau",
6886
+ purple: "Violett",
6887
+ pink: "Rosa",
6888
+ red: "Rot",
6889
+ },
6810
6890
  noDocumentSelected: "Kein Dokument ausgewählt",
6811
6891
  blocksFieldRevisionConflict:
6812
6892
  "Dieses Blocks-Feld wurde an anderer Stelle geändert. Deine Bearbeitung wurde nicht gespeichert; jetzt wird die neueste Version angezeigt.",
@@ -7177,6 +7257,22 @@ const editorMessagesByLocale = {
7177
7257
  },
7178
7258
  },
7179
7259
  "ja-JP": {
7260
+ textColor: "テキストの色",
7261
+ backgroundColor: "背景色",
7262
+ defaultColor: "デフォルト",
7263
+ color: {
7264
+ label: "色",
7265
+ recentlyUsed: "最近使用した色",
7266
+ gray: "灰色",
7267
+ brown: "茶色",
7268
+ orange: "オレンジ",
7269
+ yellow: "黄色",
7270
+ green: "緑",
7271
+ blue: "青",
7272
+ purple: "紫",
7273
+ pink: "ピンク",
7274
+ red: "赤",
7275
+ },
7180
7276
  noDocumentSelected: "ドキュメントが選択されていません",
7181
7277
  blocksFieldRevisionConflict:
7182
7278
  "このブロックフィールドは別の場所で変更されました。編集内容は保存されず、最新バージョンが表示されています。",
@@ -7536,6 +7632,22 @@ const editorMessagesByLocale = {
7536
7632
  },
7537
7633
  },
7538
7634
  "ko-KR": {
7635
+ textColor: "텍스트 색상",
7636
+ backgroundColor: "배경색",
7637
+ defaultColor: "기본값",
7638
+ color: {
7639
+ label: "색상",
7640
+ recentlyUsed: "최근 사용",
7641
+ gray: "회색",
7642
+ brown: "갈색",
7643
+ orange: "주황색",
7644
+ yellow: "노란색",
7645
+ green: "녹색",
7646
+ blue: "파란색",
7647
+ purple: "보라색",
7648
+ pink: "분홍색",
7649
+ red: "빨간색",
7650
+ },
7539
7651
  noDocumentSelected: "선택한 문서가 없습니다.",
7540
7652
  blocksFieldRevisionConflict:
7541
7653
  "이 블록 필드가 다른 곳에서 변경되었습니다. 편집 내용은 저장되지 않았으며 최신 버전이 표시됩니다.",
@@ -7894,6 +8006,22 @@ const editorMessagesByLocale = {
7894
8006
  },
7895
8007
  },
7896
8008
  "pt-BR": {
8009
+ textColor: "Cor do texto",
8010
+ backgroundColor: "Cor de fundo",
8011
+ defaultColor: "Padrão",
8012
+ color: {
8013
+ label: "Cor",
8014
+ recentlyUsed: "Usadas recentemente",
8015
+ gray: "Cinza",
8016
+ brown: "Marrom",
8017
+ orange: "Laranja",
8018
+ yellow: "Amarelo",
8019
+ green: "Verde",
8020
+ blue: "Azul",
8021
+ purple: "Roxo",
8022
+ pink: "Rosa",
8023
+ red: "Vermelho",
8024
+ },
7897
8025
  noDocumentSelected: "Nenhum documento selecionado",
7898
8026
  blocksFieldRevisionConflict:
7899
8027
  "Este campo de blocos foi alterado em outro lugar. Sua edição não foi salva; a versão mais recente agora está sendo exibida.",
@@ -8258,6 +8386,22 @@ const editorMessagesByLocale = {
8258
8386
  },
8259
8387
  },
8260
8388
  "hi-IN": {
8389
+ textColor: "टेक्स्ट का रंग",
8390
+ backgroundColor: "पृष्ठभूमि का रंग",
8391
+ defaultColor: "डिफ़ॉल्ट",
8392
+ color: {
8393
+ label: "रंग",
8394
+ recentlyUsed: "हाल में उपयोग किए गए",
8395
+ gray: "स्लेटी",
8396
+ brown: "भूरा",
8397
+ orange: "नारंगी",
8398
+ yellow: "पीला",
8399
+ green: "हरा",
8400
+ blue: "नीला",
8401
+ purple: "बैंगनी",
8402
+ pink: "गुलाबी",
8403
+ red: "लाल",
8404
+ },
8261
8405
  noDocumentSelected: "कोई दस्तावेज़ चयनित नहीं",
8262
8406
  blocksFieldRevisionConflict:
8263
8407
  "यह ब्लॉक फ़ील्ड कहीं और बदल गया है। आपका संपादन सहेजा नहीं गया; अब नवीनतम संस्करण दिखाया जा रहा है।",
@@ -8612,6 +8756,22 @@ const editorMessagesByLocale = {
8612
8756
  },
8613
8757
  },
8614
8758
  "ar-SA": {
8759
+ textColor: "لون النص",
8760
+ backgroundColor: "لون الخلفية",
8761
+ defaultColor: "افتراضي",
8762
+ color: {
8763
+ label: "اللون",
8764
+ recentlyUsed: "المستخدمة مؤخراً",
8765
+ gray: "رمادي",
8766
+ brown: "بني",
8767
+ orange: "برتقالي",
8768
+ yellow: "أصفر",
8769
+ green: "أخضر",
8770
+ blue: "أزرق",
8771
+ purple: "أرجواني",
8772
+ pink: "وردي",
8773
+ red: "أحمر",
8774
+ },
8615
8775
  noDocumentSelected: "لم يتم تحديد أي مستند",
8616
8776
  blocksFieldRevisionConflict:
8617
8777
  "تم تغيير حقل الكتل هذا في مكان آخر. لم يتم حفظ تعديلك؛ ويظهر الآن أحدث إصدار.",