@formicoidea/labre-core 0.42.0 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/_pkgs/affine-block-data-view/configs/tooltips.js +1 -1
  2. package/dist/_pkgs/affine-block-database/configs/tooltips.js +1 -1
  3. package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +4 -2
  4. package/dist/_pkgs/affine-block-embed/common/iframe-sandbox.d.ts +39 -0
  5. package/dist/_pkgs/affine-block-embed/common/iframe-sandbox.js +39 -0
  6. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.js +2 -0
  7. package/dist/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-error-card.d.ts +14 -1
  8. package/dist/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-error-card.js +21 -2
  9. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.d.ts +0 -2
  10. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.js +2 -5
  11. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.d.ts +1 -1
  12. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +14 -6
  13. package/dist/_pkgs/affine-block-embed/embed-iframe-block/types.d.ts +16 -0
  14. package/dist/_pkgs/affine-block-embed/embed-iframe-block/types.js +17 -1
  15. package/dist/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.js +2 -0
  16. package/dist/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.js +2 -0
  17. package/dist/_pkgs/affine-block-embed/index.d.ts +1 -0
  18. package/dist/_pkgs/affine-block-embed/index.js +1 -0
  19. package/dist/_pkgs/affine-block-embed/translations.d.ts +8 -0
  20. package/dist/_pkgs/affine-block-embed/translations.js +28 -0
  21. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.js +4 -2
  22. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +2 -2
  23. package/dist/_pkgs/affine-block-frame/frame-manager.js +5 -2
  24. package/dist/_pkgs/affine-block-list/utils/get-list-icon.js +3 -1
  25. package/dist/_pkgs/affine-block-note/configs/tooltips.js +1 -1
  26. package/dist/_pkgs/affine-block-root/adapters/html.js +2 -2
  27. package/dist/_pkgs/affine-block-root/commands/copy-link-commands.d.ts +2 -0
  28. package/dist/_pkgs/affine-block-root/commands/copy-link-commands.js +155 -0
  29. package/dist/_pkgs/affine-block-root/index.d.ts +1 -0
  30. package/dist/_pkgs/affine-block-root/index.js +1 -0
  31. package/dist/_pkgs/affine-block-root/view.js +2 -0
  32. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +13 -1
  33. package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +8 -0
  34. package/dist/_pkgs/affine-block-surface/extensions/legend.js +59 -3
  35. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.js +4 -0
  36. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.d.ts +3 -0
  37. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.js +23 -0
  38. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +1 -1
  39. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +12 -4
  40. package/dist/_pkgs/affine-block-surface/framework-background/background-view.js +1 -1
  41. package/dist/_pkgs/affine-block-surface/framework-background/fit.d.ts +36 -0
  42. package/dist/_pkgs/affine-block-surface/framework-background/fit.js +30 -0
  43. package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
  44. package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
  45. package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.js +2 -7
  46. package/dist/_pkgs/affine-block-surface-ref/configs/tooltips.js +2 -2
  47. package/dist/_pkgs/affine-components/color-picker/palette-carousel.js +5 -0
  48. package/dist/_pkgs/affine-components/color-picker/styles.js +1 -1
  49. package/dist/_pkgs/affine-components/context-menu/button.js +3 -1
  50. package/dist/_pkgs/affine-components/icons/ai.js +3 -3
  51. package/dist/_pkgs/affine-components/icons/list.js +7 -1
  52. package/dist/_pkgs/affine-components/size-dropdown-menu/dropdown-menu.js +6 -1
  53. package/dist/_pkgs/affine-components/toolbar/index.d.ts +1 -1
  54. package/dist/_pkgs/affine-components/toolbar/index.js +1 -1
  55. package/dist/_pkgs/affine-components/toolbar/menu-button.d.ts +7 -0
  56. package/dist/_pkgs/affine-components/toolbar/menu-button.js +30 -0
  57. package/dist/_pkgs/affine-components/toolbar/picker-menu.d.ts +16 -1
  58. package/dist/_pkgs/affine-components/toolbar/picker-menu.js +2 -2
  59. package/dist/_pkgs/affine-components/toolbar/toolbar.d.ts +1 -0
  60. package/dist/_pkgs/affine-components/toolbar/toolbar.js +67 -0
  61. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title-editor.js +1 -1
  62. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.js +1 -1
  63. package/dist/_pkgs/affine-gfx-brush/toolbar/components/eraser/icons.js +1 -1
  64. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.d.ts +11 -2
  65. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +11 -2
  66. package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +3 -2
  67. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +23 -7
  68. package/dist/_pkgs/affine-gfx-connector/translations.d.ts +3 -0
  69. package/dist/_pkgs/affine-gfx-connector/translations.js +23 -0
  70. package/dist/_pkgs/affine-gfx-mindmap/indicator-overlay/index.js +6 -2
  71. package/dist/_pkgs/affine-gfx-mindmap/toolbar/config.js +4 -2
  72. package/dist/_pkgs/affine-gfx-mindmap/translations.d.ts +6 -0
  73. package/dist/_pkgs/affine-gfx-mindmap/translations.js +10 -0
  74. package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +4 -2
  75. package/dist/_pkgs/affine-gfx-shape/translations.d.ts +7 -0
  76. package/dist/_pkgs/affine-gfx-shape/translations.js +11 -0
  77. package/dist/_pkgs/affine-gfx-template/builtin/other.js +13 -7
  78. package/dist/_pkgs/affine-gfx-template/toolbar/template-loading.js +1 -1
  79. package/dist/_pkgs/affine-gfx-template/translations.d.ts +5 -0
  80. package/dist/_pkgs/affine-gfx-template/translations.js +38 -0
  81. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +3 -2
  82. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +3 -1
  83. package/dist/_pkgs/affine-gfx-text/translations.d.ts +8 -0
  84. package/dist/_pkgs/affine-gfx-text/translations.js +12 -0
  85. package/dist/_pkgs/affine-inline-latex/latex-node/latex-editor-menu.js +2 -1
  86. package/dist/_pkgs/affine-model/consts/text.d.ts +15 -2
  87. package/dist/_pkgs/affine-model/consts/text.js +25 -1
  88. package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +13 -2
  89. package/dist/_pkgs/affine-shared/services/font-loader/config.js +43 -54
  90. package/dist/_pkgs/affine-shared/services/theme-service.d.ts +19 -0
  91. package/dist/_pkgs/affine-shared/services/theme-service.js +24 -0
  92. package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +20 -0
  93. package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +81 -0
  94. package/dist/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.js +2 -2
  95. package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.js +5 -1
  96. package/dist/_pkgs/affine-widget-edgeless-toolbar/config/types.d.ts +15 -0
  97. package/dist/_pkgs/affine-widget-edgeless-toolbar/config/utils.d.ts +1 -1
  98. package/dist/_pkgs/affine-widget-edgeless-toolbar/config/utils.js +7 -2
  99. package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-family-panel.d.ts +18 -0
  100. package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-family-panel.js +52 -6
  101. package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.d.ts +6 -0
  102. package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.js +10 -0
  103. package/dist/_pkgs/affine-widget-frame-title/edgeless-frame-title-editor.js +2 -1
  104. package/dist/_pkgs/affine-widget-slash-menu/translations.d.ts +16 -0
  105. package/dist/_pkgs/affine-widget-slash-menu/translations.js +23 -1
  106. package/dist/_pkgs/affine-widget-toolbar/utils.js +57 -14
  107. package/dist/_pkgs/data-view/core/detail/field.js +2 -1
  108. package/dist/_pkgs/data-view/core/filter/literal/define.js +3 -1
  109. package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +1 -1
  110. package/dist/_pkgs/data-view/property-presets/checkbox/cell-renderer.js +8 -2
  111. package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +1 -1
  112. package/dist/_pkgs/data-view/view-presets/kanban/pc/controller/drag.js +2 -1
  113. package/dist/_pkgs/data-view/view-presets/table/pc/controller/drag.js +2 -1
  114. package/dist/_pkgs/data-view/view-presets/table/pc/controller/selection.js +1 -1
  115. package/dist/_pkgs/data-view/view-presets/table/pc/header/vertical-indicator.js +2 -1
  116. package/dist/_pkgs/data-view/view-presets/table/pc/row/row-select-checkbox.js +3 -1
  117. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/drag.js +2 -1
  118. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/selection.js +1 -1
  119. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/vertical-indicator.js +2 -1
  120. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/row-header.js +3 -1
  121. package/dist/_pkgs/std/gfx/model/surface/role.d.ts +10 -5
  122. package/dist/commands.js +2 -1
  123. package/dist/translations.js +5 -0
  124. package/package.json +5 -1
@@ -52,6 +52,21 @@ export const TOAST_NO_LINK_FOUND = [
52
52
  'com.labre.toast.no-link-found',
53
53
  'No link found',
54
54
  ];
55
+ /**
56
+ * What the `doc.copyLink` command says once the document's URL is on the
57
+ * clipboard.
58
+ *
59
+ * Its own wording rather than {@link TOAST_COPIED_TO_CLIPBOARD}: that one
60
+ * reports a SLICE copy (blocks, elements, an image) and this one reports a
61
+ * link, and the two are told apart by nothing else on screen. Its own wording
62
+ * rather than the inline link toolbar's "Copied link to clipboard" too — that
63
+ * key belongs to `@labre/affine-inline-link` and names the `href` a delta
64
+ * already carried, not a document address the host just generated.
65
+ */
66
+ export const TOAST_LINK_COPIED = [
67
+ 'com.labre.toast.link-copied',
68
+ 'Link copied',
69
+ ];
55
70
  /* ── Toolbars and menus ───────────────────────────────────────────────── */
56
71
  export const TOOLBAR_BRING_TO_FRONT = [
57
72
  'com.labre.toolbar.bring-to-front',
@@ -739,6 +754,40 @@ export const PALETTE_NAME_MEDIUM_GREY = [
739
754
  'com.labre.palette-name.medium-grey',
740
755
  'MediumGrey',
741
756
  ];
757
+ /*
758
+ * The `Heavy` row (`DefaultTheme.Palettes`, seven colours and no grey). It was
759
+ * missing from the table until #390 — the row rendered its raw `Palette.key`
760
+ * next to translated neighbours. The exhaustiveness test in
761
+ * `packages/affine/all` now compares this table to the theme.
762
+ */
763
+ export const PALETTE_NAME_HEAVY_RED = [
764
+ 'com.labre.palette-name.heavy-red',
765
+ 'HeavyRed',
766
+ ];
767
+ export const PALETTE_NAME_HEAVY_ORANGE = [
768
+ 'com.labre.palette-name.heavy-orange',
769
+ 'HeavyOrange',
770
+ ];
771
+ export const PALETTE_NAME_HEAVY_YELLOW = [
772
+ 'com.labre.palette-name.heavy-yellow',
773
+ 'HeavyYellow',
774
+ ];
775
+ export const PALETTE_NAME_HEAVY_GREEN = [
776
+ 'com.labre.palette-name.heavy-green',
777
+ 'HeavyGreen',
778
+ ];
779
+ export const PALETTE_NAME_HEAVY_BLUE = [
780
+ 'com.labre.palette-name.heavy-blue',
781
+ 'HeavyBlue',
782
+ ];
783
+ export const PALETTE_NAME_HEAVY_PURPLE = [
784
+ 'com.labre.palette-name.heavy-purple',
785
+ 'HeavyPurple',
786
+ ];
787
+ export const PALETTE_NAME_HEAVY_MAGENTA = [
788
+ 'com.labre.palette-name.heavy-magenta',
789
+ 'HeavyMagenta',
790
+ ];
742
791
  /**
743
792
  * Keyed by the exact `Palette.key` string the default theme's tables produce
744
793
  * (`buildPalettes`, `packages/affine/model/src/themes/{default,utils}.ts`) —
@@ -773,7 +822,30 @@ export const PALETTE_NAME_WORDINGS = {
773
822
  MediumPurple: PALETTE_NAME_MEDIUM_PURPLE,
774
823
  MediumMagenta: PALETTE_NAME_MEDIUM_MAGENTA,
775
824
  MediumGrey: PALETTE_NAME_MEDIUM_GREY,
825
+ HeavyRed: PALETTE_NAME_HEAVY_RED,
826
+ HeavyOrange: PALETTE_NAME_HEAVY_ORANGE,
827
+ HeavyYellow: PALETTE_NAME_HEAVY_YELLOW,
828
+ HeavyGreen: PALETTE_NAME_HEAVY_GREEN,
829
+ HeavyBlue: PALETTE_NAME_HEAVY_BLUE,
830
+ HeavyPurple: PALETTE_NAME_HEAVY_PURPLE,
831
+ HeavyMagenta: PALETTE_NAME_HEAVY_MAGENTA,
776
832
  };
833
+ /* ── Menu shells' accessible names (#390) ─────────────────────────────────
834
+ *
835
+ * The `aria-label` of an `editor-menu-button` is a wording of its OWN, never
836
+ * `` `${translatedLabel}-menu` `` — sewing a suffix onto a translated word
837
+ * gave "changer le type de forme-menu" to a French host. The precedent is
838
+ * `ROOT_ALIGNMENT_MENU_ARIA` (`blocks/root`). The fallbacks are the exact
839
+ * identifiers the composition produced in English, so a catalogue-less
840
+ * playground reads what it always read.
841
+ *
842
+ * This one is HERE and not in a package because three toolbars draw a menu
843
+ * called "Style" (shape, mindmap, connector) — one shared word, one key.
844
+ */
845
+ export const MENU_ARIA_STYLE = [
846
+ 'com.labre.menu-aria.style',
847
+ 'style-menu',
848
+ ];
777
849
  /* ── Clipboard size-limit toasts (adapters/clipboard/utils.ts) ────────── */
778
850
  export const CHROME_CLIPBOARD_FILE_TOO_LARGE = [
779
851
  'com.labre.clipboard.file-too-large',
@@ -1089,6 +1161,7 @@ export const CHROME_WORDINGS = [
1089
1161
  TOAST_NOTE_REMOVED_FROM_PAGE,
1090
1162
  TOAST_FRAME_INSERTED_INTO_PAGE,
1091
1163
  TOAST_NO_LINK_FOUND,
1164
+ TOAST_LINK_COPIED,
1092
1165
  TOOLBAR_BRING_TO_FRONT,
1093
1166
  TOOLBAR_SEND_TO_BACK,
1094
1167
  TOOLBAR_COPY,
@@ -1240,4 +1313,12 @@ export const CHROME_WORDINGS = [
1240
1313
  PALETTE_NAME_MEDIUM_PURPLE,
1241
1314
  PALETTE_NAME_MEDIUM_MAGENTA,
1242
1315
  PALETTE_NAME_MEDIUM_GREY,
1316
+ PALETTE_NAME_HEAVY_RED,
1317
+ PALETTE_NAME_HEAVY_ORANGE,
1318
+ PALETTE_NAME_HEAVY_YELLOW,
1319
+ PALETTE_NAME_HEAVY_GREEN,
1320
+ PALETTE_NAME_HEAVY_BLUE,
1321
+ PALETTE_NAME_HEAVY_PURPLE,
1322
+ PALETTE_NAME_HEAVY_MAGENTA,
1323
+ MENU_ARIA_STYLE,
1243
1324
  ];
@@ -10,11 +10,11 @@ export class EdgelessDraggingAreaRectWidget extends WidgetComponent {
10
10
  static { this.styles = css `
11
11
  .affine-edgeless-dragging-area {
12
12
  position: absolute;
13
- background: ${unsafeCSS(cssVarV2('edgeless/selection/selectionMarqueeBackground', '#1E96EB14'))};
13
+ background: ${unsafeCSS(cssVarV2('edgeless/selection/selectionMarqueeBackground'))};
14
14
  box-sizing: border-box;
15
15
  border-width: 1px;
16
16
  border-style: solid;
17
- border-color: ${unsafeCSS(cssVarV2('edgeless/selection/selectionMarqueeBorder', '#1E96EB'))};
17
+ border-color: ${unsafeCSS(cssVarV2('edgeless/selection/selectionMarqueeBorder'))};
18
18
 
19
19
  z-index: 1;
20
20
  pointer-events: none;
@@ -1,6 +1,7 @@
1
1
  import { EdgelessCRUDIdentifier, isNoteBlock, Overlay, } from '../affine-block-surface/index.js';
2
2
  import { ShapeFactory } from '../affine-gfx-shape/index.js';
3
3
  import { getShapeRadius, getShapeType, GroupElementModel, ShapeElementModel, } from '../affine-model/index.js';
4
+ import { getChromeAccentColor } from '../affine-shared/services/index.js';
4
5
  import { BlockSuiteError, ErrorCode } from '../global/exceptions/index.js';
5
6
  import { Bound, normalizeDegAngle } from '../global/gfx/index.js';
6
7
  import { assertType } from '../global/utils/index.js';
@@ -33,7 +34,10 @@ export class AutoCompleteTextOverlay extends AutoCompleteTargetOverlay {
33
34
  render(ctx, _rc) {
34
35
  const [x, y, w, h] = this.xywh;
35
36
  ctx.globalAlpha = 0.4;
36
- ctx.strokeStyle = '#1e96eb';
37
+ // The accent read from the theme, not a literal: a canvas context cannot
38
+ // take a `var(…)`, so the token is resolved here (DESIGN.md, The Borrowed
39
+ // Blue Rule).
40
+ ctx.strokeStyle = getChromeAccentColor(this.gfx.std);
37
41
  ctx.lineWidth = 1;
38
42
  ctx.strokeRect(x, y, w, h);
39
43
  // fill text placeholder
@@ -25,6 +25,21 @@ export type Menu<T> = {
25
25
  tooltip?: string;
26
26
  /** {@link tooltip}, for the translation seam. */
27
27
  tooltipWording?: ChromeWording;
28
+ /**
29
+ * The accessible name of the MENU shell (`aria-label` on
30
+ * `editor-menu-button`) — its own key, never a composition (#390).
31
+ *
32
+ * Before this field the shell's name was sewn together as
33
+ * `` `${resolvedLabel.toLowerCase()}-menu` ``, which was a stable
34
+ * identifier while `label` was English and became half-translated
35
+ * ("changer le type de forme-menu") the day `label` joined the seam. The
36
+ * precedent is `ROOT_ALIGNMENT_MENU_ARIA` (`blocks/root`): a menu's aria is
37
+ * a wording of its own.
38
+ *
39
+ * Left out, the name is composed from the ENGLISH {@link label}, so a
40
+ * caller that declares nothing keeps exactly the identifier it had.
41
+ */
42
+ menuAriaWording?: ChromeWording;
28
43
  items: MenuItem<T>[];
29
44
  currentValue: T;
30
45
  onPick: (value: T) => void;
@@ -7,6 +7,6 @@ export declare function renderCurrentMenuItemWith<T, F extends keyof MenuItem<T>
7
7
  * resolved through `std` when the caller has one, else its `key` literal.
8
8
  */
9
9
  export declare function resolveMenuItemLabel<T>(items: MenuItem<T>[], currentValue: T, std?: BlockStdScope): string | undefined;
10
- export declare function renderMenu<T>({ label, labelWording, tooltip, tooltipWording, icon, items, currentValue, onPick, std, }: Menu<T>): import("lit-html").TemplateResult<1>;
10
+ export declare function renderMenu<T>({ label, labelWording, tooltip, tooltipWording, menuAriaWording, icon, items, currentValue, onPick, std, }: Menu<T>): import("lit-html").TemplateResult<1>;
11
11
  export declare function renderMenuItems<T>(items: MenuItem<T>[], currentValue: T, onPick: (value: T) => void, std?: BlockStdScope): unknown;
12
12
  export declare function getRootBlock(ctx: ToolbarContext): BlockComponent | null;
@@ -18,14 +18,19 @@ export function resolveMenuItemLabel(items, currentValue, std) {
18
18
  ? translateKey(std, ...item.keyWording)
19
19
  : item.key;
20
20
  }
21
- export function renderMenu({ label, labelWording, tooltip, tooltipWording, icon, items, currentValue, onPick, std, }) {
21
+ export function renderMenu({ label, labelWording, tooltip, tooltipWording, menuAriaWording, icon, items, currentValue, onPick, std, }) {
22
22
  const resolvedLabel = labelWording && std ? translateKey(std, ...labelWording) : label;
23
23
  const resolvedTooltip = tooltipWording && std
24
24
  ? translateKey(std, ...tooltipWording)
25
25
  : (tooltip ?? resolvedLabel);
26
+ // Composed from the ENGLISH `label`, never `resolvedLabel` (#390): sewing
27
+ // `-menu` onto a translated word produced "changer le type de forme-menu".
28
+ const menuAria = menuAriaWording && std
29
+ ? translateKey(std, ...menuAriaWording)
30
+ : `${label.toLowerCase()}-menu`;
26
31
  return html `
27
32
  <editor-menu-button
28
- aria-label="${`${resolvedLabel.toLowerCase()}-menu`}"
33
+ aria-label="${menuAria}"
29
34
  .button=${html `
30
35
  <editor-icon-button
31
36
  aria-label="${resolvedLabel}"
@@ -1,9 +1,27 @@
1
1
  import { FontFamily } from '../../affine-model/index.js';
2
+ import type { BlockStdScope } from '../../std/index.js';
2
3
  import { LitElement } from 'lit';
3
4
  export declare class EdgelessFontFamilyPanel extends LitElement {
4
5
  static styles: import("lit").CSSResult;
6
+ /**
7
+ * The families the host configured: those with at least one face in its
8
+ * `FontConfig` (#396). Read from the config itself rather than from
9
+ * `document.fonts`, which the font loader fills a few seconds late for every
10
+ * non-critical family.
11
+ *
12
+ * `null` when no config is registered (the seam is absent, or empty, which
13
+ * the font loader also treats as absent): every family is offered, as before
14
+ * the seam narrowed the list. None of them has a file then, so each paints
15
+ * with the same fallback anyway.
16
+ */
17
+ private _configuredFamilies;
5
18
  private _onSelect;
19
+ private _unavailableLabel;
6
20
  render(): unknown;
7
21
  accessor onSelect: ((value: FontFamily) => void) | undefined;
22
+ /** Set by the caller that has one (`gfx/text`'s `createTextActions`): it
23
+ * carries the host's `FontConfig` and translations. Optional, so the panel
24
+ * still renders (every family, in English) when created with none. */
25
+ accessor std: BlockStdScope | undefined;
8
26
  accessor value: FontFamily;
9
27
  }
@@ -34,15 +34,20 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
34
34
  };
35
35
  import { TextUtils } from '../../affine-block-surface/index.js';
36
36
  import { FontFamily, FontFamilyList } from '../../affine-model/index.js';
37
+ import { fillPlaceholders, FontConfigIdentifier, translateKey, } from '../../affine-shared/services/index.js';
37
38
  import { DoneIcon } from '@blocksuite/icons/lit';
38
39
  import { css, html, LitElement, nothing } from 'lit';
39
40
  import { property } from 'lit/decorators.js';
40
41
  import { repeat } from 'lit/directives/repeat.js';
42
+ import { EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE } from '../translations.js';
41
43
  let EdgelessFontFamilyPanel = (() => {
42
44
  let _classSuper = LitElement;
43
45
  let _onSelect_decorators;
44
46
  let _onSelect_initializers = [];
45
47
  let _onSelect_extraInitializers = [];
48
+ let _std_decorators;
49
+ let _std_initializers = [];
50
+ let _std_extraInitializers = [];
46
51
  let _value_decorators;
47
52
  let _value_initializers = [];
48
53
  let _value_extraInitializers = [];
@@ -50,8 +55,10 @@ let EdgelessFontFamilyPanel = (() => {
50
55
  static {
51
56
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
52
57
  _onSelect_decorators = [property({ attribute: false })];
58
+ _std_decorators = [property({ attribute: false })];
53
59
  _value_decorators = [property({ attribute: false })];
54
60
  __esDecorate(this, null, _onSelect_decorators, { kind: "accessor", name: "onSelect", static: false, private: false, access: { has: obj => "onSelect" in obj, get: obj => obj.onSelect, set: (obj, value) => { obj.onSelect = value; } }, metadata: _metadata }, _onSelect_initializers, _onSelect_extraInitializers);
61
+ __esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
55
62
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
56
63
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
57
64
  }
@@ -67,26 +74,59 @@ let EdgelessFontFamilyPanel = (() => {
67
74
  width: 100%;
68
75
  }
69
76
  `; }
77
+ /**
78
+ * The families the host configured: those with at least one face in its
79
+ * `FontConfig` (#396). Read from the config itself rather than from
80
+ * `document.fonts`, which the font loader fills a few seconds late for every
81
+ * non-critical family.
82
+ *
83
+ * `null` when no config is registered (the seam is absent, or empty, which
84
+ * the font loader also treats as absent): every family is offered, as before
85
+ * the seam narrowed the list. None of them has a file then, so each paints
86
+ * with the same fallback anyway.
87
+ */
88
+ _configuredFamilies() {
89
+ const config = this.std?.getOptional(FontConfigIdentifier);
90
+ if (!config || config.length === 0)
91
+ return null;
92
+ return new Set(config.map(face => face.font));
93
+ }
70
94
  _onSelect(value) {
71
95
  this.value = value;
72
96
  if (this.onSelect) {
73
97
  this.onSelect(value);
74
98
  }
75
99
  }
100
+ _unavailableLabel(name) {
101
+ return this.std
102
+ ? translateKey(this.std, ...EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE, {
103
+ name,
104
+ })
105
+ : fillPlaceholders(EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE[1], { name });
106
+ }
76
107
  render() {
77
- return repeat(FontFamilyList, item => item[0], ([font, name]) => {
78
- const active = this.value === font;
108
+ const configured = this._configuredFamilies();
109
+ // The current family stays listed even when the host no longer ships it:
110
+ // the element keeps it (and paints the fallback), so the picker names it
111
+ // rather than pretend the text has none. Greyed and never picked from
112
+ // here, so nothing rewrites the stored value behind the user's back.
113
+ const families = FontFamilyList.filter(([font]) => !configured || configured.has(font) || font === this.value);
114
+ return repeat(families, item => item[0], ([font, name]) => {
115
+ const unavailable = !!configured && !configured.has(font);
116
+ const current = this.value === font;
79
117
  return html `
80
118
  <edgeless-tool-icon-button
81
119
  data-font="${name}"
82
120
  style="font-family: ${TextUtils.wrapFontFamily(font)}"
83
121
  .iconContainerPadding=${[4, 8]}
84
122
  .justify=${'space-between'}
85
- .active=${active}
123
+ .active=${current && !unavailable}
124
+ .disabled=${unavailable}
86
125
  .iconSize=${'20px'}
87
- @click=${() => this._onSelect(font)}
126
+ @click=${unavailable ? nothing : () => this._onSelect(font)}
88
127
  >
89
- ${name} ${active ? DoneIcon() : nothing}
128
+ ${unavailable ? this._unavailableLabel(name) : name}
129
+ ${current ? DoneIcon() : nothing}
90
130
  </edgeless-tool-icon-button>
91
131
  `;
92
132
  });
@@ -94,7 +134,13 @@ let EdgelessFontFamilyPanel = (() => {
94
134
  #onSelect_accessor_storage = __runInitializers(this, _onSelect_initializers, undefined);
95
135
  get onSelect() { return this.#onSelect_accessor_storage; }
96
136
  set onSelect(value) { this.#onSelect_accessor_storage = value; }
97
- #value_accessor_storage = (__runInitializers(this, _onSelect_extraInitializers), __runInitializers(this, _value_initializers, FontFamily.Inter));
137
+ #std_accessor_storage = (__runInitializers(this, _onSelect_extraInitializers), __runInitializers(this, _std_initializers, undefined));
138
+ /** Set by the caller that has one (`gfx/text`'s `createTextActions`): it
139
+ * carries the host's `FontConfig` and translations. Optional, so the panel
140
+ * still renders (every family, in English) when created with none. */
141
+ get std() { return this.#std_accessor_storage; }
142
+ set std(value) { this.#std_accessor_storage = value; }
143
+ #value_accessor_storage = (__runInitializers(this, _std_extraInitializers), __runInitializers(this, _value_initializers, FontFamily.Inter));
98
144
  get value() { return this.#value_accessor_storage; }
99
145
  set value(value) { this.#value_accessor_storage = value; }
100
146
  constructor() {
@@ -11,5 +11,11 @@ import { type ChromeWording } from '../affine-shared/services/index.js';
11
11
  */
12
12
  export declare const EDGELESS_TOOLBAR_COMING_SOON: ChromeWording;
13
13
  export declare const EDGELESS_TOOLBAR_MORE_TOOLS: ChromeWording;
14
+ /**
15
+ * A family the element still carries but the host no longer configures
16
+ * (#396): the font picker keeps its name, greyed, with this mark. `{{name}}`
17
+ * is the family name, a proper name the host does not translate.
18
+ */
19
+ export declare const EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE: ChromeWording;
14
20
  /** Every wording this package declares, in the order it renders them. */
15
21
  export declare const EDGELESS_TOOLBAR_WORDINGS: readonly ChromeWording[];
@@ -14,7 +14,17 @@ export const EDGELESS_TOOLBAR_MORE_TOOLS = [
14
14
  'com.labre.edgeless-toolbar.more-tools',
15
15
  'More Tools',
16
16
  ];
17
+ /**
18
+ * A family the element still carries but the host no longer configures
19
+ * (#396): the font picker keeps its name, greyed, with this mark. `{{name}}`
20
+ * is the family name, a proper name the host does not translate.
21
+ */
22
+ export const EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE = [
23
+ 'com.labre.edgeless-toolbar.font-family-unavailable',
24
+ '{{name}} (unavailable)',
25
+ ];
17
26
  /** Every wording this package declares, in the order it renders them. */
18
27
  export const EDGELESS_TOOLBAR_WORDINGS = [
19
28
  EDGELESS_TOOLBAR_MORE_TOOLS,
29
+ EDGELESS_TOOLBAR_FONT_FAMILY_UNAVAILABLE,
20
30
  ];
@@ -78,7 +78,8 @@ let EdgelessFrameTitleEditor = (() => {
78
78
  outline: none;
79
79
  z-index: 1;
80
80
  border: 1px solid var(--affine-primary-color);
81
- box-shadow: 0px 0px 0px 2px rgba(30, 150, 235, 0.3);
81
+ box-shadow: 0px 0px 0px 2px
82
+ color-mix(in srgb, var(--affine-primary-color) 30%, transparent);
82
83
  overflow: hidden;
83
84
  font-family: var(--affine-font-family);
84
85
  }
@@ -53,12 +53,19 @@ export declare const SLASH_MENU_DELETE_DESCRIPTION: ChromeWording;
53
53
  * '<n>_<Name>@<i>'`, the `<Name>` between `_` and `@`):
54
54
  *
55
55
  * - `Basic` — callout, latex, note (paragraph/heading/list/quote/divider).
56
+ * - `List`, `Style` — note again, but written as TEMPLATE literals
57
+ * (`` `1_List@${index++}` ``, `` `2_Style@${index++}` ``,
58
+ * `blocks/note/src/configs/slash-menu.ts`), which is why the first
59
+ * inventory — a grep for `group: '` — missed both (#390).
56
60
  * - `Content & Media` — attachment, bookmark, image, latex, the generic embed
57
61
  * (iframe) block, and (postponed, `blocks/table`) table.
58
62
  * - `Page` — the linked-doc embed block.
59
63
  * - `Edgeless Element` — surface-ref.
60
64
  * - `Date`, `Actions` — this package's own groups (`./config.ts`).
61
65
  *
66
+ * The inventory covers template literals too: the `<Name>` is read between the
67
+ * `_` and the `@`, whichever way the group string was built.
68
+ *
62
69
  * NOT included: `Database`, used only by the postponed `blocks/database` and
63
70
  * `blocks/data-view` — the PO's decision excludes those surfaces, and
64
71
  * `Database` has no other user today. A framework or a later lot that adds a
@@ -67,6 +74,15 @@ export declare const SLASH_MENU_DELETE_DESCRIPTION: ChromeWording;
67
74
  * of this existed.
68
75
  */
69
76
  export declare const SLASH_MENU_GROUP_BASIC: ChromeWording;
77
+ export declare const SLASH_MENU_GROUP_LIST: ChromeWording;
78
+ /**
79
+ * An ALIAS, not a new key: `STYLE_MENU_LABEL` already carries the word
80
+ * `Style` in the chrome table, and a second key with the same fallback would
81
+ * fail the "un mot chrome, une clé" test. Listed in the group table below,
82
+ * NOT in `SLASH_MENU_WORDINGS` — an alias is walked once, from
83
+ * `CHROME_WORDINGS`, exactly like `SLASH_MENU_COPY` / `_DUPLICATE`.
84
+ */
85
+ export declare const SLASH_MENU_GROUP_STYLE: ChromeWording;
70
86
  export declare const SLASH_MENU_GROUP_CONTENT_MEDIA: ChromeWording;
71
87
  export declare const SLASH_MENU_GROUP_PAGE: ChromeWording;
72
88
  export declare const SLASH_MENU_GROUP_EDGELESS_ELEMENT: ChromeWording;
@@ -1,4 +1,4 @@
1
- import { TOOLBAR_COPY, TOOLBAR_DELETE, TOOLBAR_DUPLICATE, TOOLBAR_MOVE_DOWN, TOOLBAR_MOVE_UP, } from '../affine-shared/services/index.js';
1
+ import { STYLE_MENU_LABEL, TOOLBAR_COPY, TOOLBAR_DELETE, TOOLBAR_DUPLICATE, TOOLBAR_MOVE_DOWN, TOOLBAR_MOVE_UP, } from '../affine-shared/services/index.js';
2
2
  /**
3
3
  * The slash menu's own wordings — one `ChromeWording` per static config
4
4
  * literal (`name`, `description`, a tooltip's `caption`) that
@@ -91,12 +91,19 @@ export const SLASH_MENU_DELETE_DESCRIPTION = [
91
91
  * '<n>_<Name>@<i>'`, the `<Name>` between `_` and `@`):
92
92
  *
93
93
  * - `Basic` — callout, latex, note (paragraph/heading/list/quote/divider).
94
+ * - `List`, `Style` — note again, but written as TEMPLATE literals
95
+ * (`` `1_List@${index++}` ``, `` `2_Style@${index++}` ``,
96
+ * `blocks/note/src/configs/slash-menu.ts`), which is why the first
97
+ * inventory — a grep for `group: '` — missed both (#390).
94
98
  * - `Content & Media` — attachment, bookmark, image, latex, the generic embed
95
99
  * (iframe) block, and (postponed, `blocks/table`) table.
96
100
  * - `Page` — the linked-doc embed block.
97
101
  * - `Edgeless Element` — surface-ref.
98
102
  * - `Date`, `Actions` — this package's own groups (`./config.ts`).
99
103
  *
104
+ * The inventory covers template literals too: the `<Name>` is read between the
105
+ * `_` and the `@`, whichever way the group string was built.
106
+ *
100
107
  * NOT included: `Database`, used only by the postponed `blocks/database` and
101
108
  * `blocks/data-view` — the PO's decision excludes those surfaces, and
102
109
  * `Database` has no other user today. A framework or a later lot that adds a
@@ -108,6 +115,18 @@ export const SLASH_MENU_GROUP_BASIC = [
108
115
  'com.labre.slash-menu.group.basic',
109
116
  'Basic',
110
117
  ];
118
+ export const SLASH_MENU_GROUP_LIST = [
119
+ 'com.labre.slash-menu.group.list',
120
+ 'List',
121
+ ];
122
+ /**
123
+ * An ALIAS, not a new key: `STYLE_MENU_LABEL` already carries the word
124
+ * `Style` in the chrome table, and a second key with the same fallback would
125
+ * fail the "un mot chrome, une clé" test. Listed in the group table below,
126
+ * NOT in `SLASH_MENU_WORDINGS` — an alias is walked once, from
127
+ * `CHROME_WORDINGS`, exactly like `SLASH_MENU_COPY` / `_DUPLICATE`.
128
+ */
129
+ export const SLASH_MENU_GROUP_STYLE = STYLE_MENU_LABEL;
111
130
  export const SLASH_MENU_GROUP_CONTENT_MEDIA = [
112
131
  'com.labre.slash-menu.group.content-media',
113
132
  'Content & Media',
@@ -131,6 +150,8 @@ export const SLASH_MENU_GROUP_ACTIONS = [
131
150
  /** The group table, keyed by the raw group name `parseGroup` extracts. */
132
151
  const SLASH_MENU_GROUP_WORDINGS = {
133
152
  Basic: SLASH_MENU_GROUP_BASIC,
153
+ List: SLASH_MENU_GROUP_LIST,
154
+ Style: SLASH_MENU_GROUP_STYLE,
134
155
  'Content & Media': SLASH_MENU_GROUP_CONTENT_MEDIA,
135
156
  Page: SLASH_MENU_GROUP_PAGE,
136
157
  'Edgeless Element': SLASH_MENU_GROUP_EDGELESS_ELEMENT,
@@ -167,6 +188,7 @@ export const SLASH_MENU_WORDINGS = [
167
188
  SLASH_MENU_COPY_DUPLICATE_CAPTION,
168
189
  SLASH_MENU_DELETE_DESCRIPTION,
169
190
  SLASH_MENU_GROUP_BASIC,
191
+ SLASH_MENU_GROUP_LIST,
170
192
  SLASH_MENU_GROUP_CONTENT_MEDIA,
171
193
  SLASH_MENU_GROUP_PAGE,
172
194
  SLASH_MENU_GROUP_EDGELESS_ELEMENT,
@@ -23,6 +23,21 @@ export const sideMap = new Map([
23
23
  // has only one shape element
24
24
  ['affine:surface:shape', { top: 26, bottom: -26 }],
25
25
  ]);
26
+ /**
27
+ * The narrowest room the row is ever told it has.
28
+ *
29
+ * A cap is a `max-width`: below the width of what the row cannot give up, it
30
+ * stops being an instruction and becomes a guillotine — the entries past it are
31
+ * painted outside the row's own background, over the document. A floor keeps
32
+ * that from ever happening on a number nobody meant.
33
+ *
34
+ * 120px is a minimal row, drawn: three icon buttons — the "⋮" plus the two
35
+ * entries a menu is worth opening for — at {@link MENU_BUTTON_WIDTH} each, the
36
+ * two 8px gaps between them, one separator and its gap, and the row's own 6px
37
+ * of padding on either side. 109px, rounded up to leave the border its half
38
+ * pixel and the eye a little air.
39
+ */
40
+ const MIN_TOOLBAR_WIDTH = 120;
26
41
  export function autoUpdatePosition(signal, toolbar, referenceElement, flavour, placement, sideOptions, options = { elementResize: false },
27
42
  /**
28
43
  * Called whenever the room the row has just changed. This is the only place
@@ -51,22 +66,32 @@ onAvailableWidth) {
51
66
  }
52
67
  : {
53
68
  placement,
69
+ // ORDER MATTERS, and `size` comes LAST of the four — after `inline`,
70
+ // after `shift`, after `flip` — which is the order floating-ui
71
+ // documents for it and the order this row needs.
72
+ //
73
+ // `size` asks the question "how much room is there", and it has two
74
+ // different answers depending on whether a `shift` has already run:
75
+ //
76
+ // - **after `shift`** (`middlewareData.shift.enabled.x`): the room is
77
+ // `maximumClippingWidth` — the clipping box, less the padding. Which
78
+ // is the truth: it is where the row may be drawn, and `shift` will
79
+ // slide the row to fit inside it.
80
+ // - **before `shift`**, on an UNALIGNED placement (`'top'`, which is
81
+ // what a text selection's row uses), floating-ui falls back to
82
+ // `width - 2 × overflow` — the row's own width, less twice what a
83
+ // row CENTRED on the selection would stick out by. That number is
84
+ // not room at all. It is fine while the centred row fits, and the
85
+ // moment it would stick out by one pixel it collapses below the
86
+ // row's width and the entries start leaving for the "⋮" — with 900px
87
+ // of empty editor next to them, because `shift` was about to slide
88
+ // the row back in anyway. Worse, it is computed from a width `size`
89
+ // itself has just capped, so each `reset` makes it smaller: the
90
+ // format bar measured 75px of "room" inside a 420px window.
91
+ //
92
+ // See the cap's only reader, `availableWidthOf`.
54
93
  middleware: [
55
94
  offset(10 + offsetY),
56
- size({
57
- padding: 10,
58
- apply: ({ elements, availableWidth }) => {
59
- elements.floating.style.width = 'fit-content';
60
- // The room the row has. The toolbar never wraps and never
61
- // scrolls: past this width its entries give way, in the order
62
- // they declared, into the "⋮" menu — see `ToolbarFitter`.
63
- const capped = `${availableWidth}px`;
64
- if (elements.floating.style.maxWidth !== capped) {
65
- elements.floating.style.maxWidth = capped;
66
- onAvailableWidth?.();
67
- }
68
- },
69
- }),
70
95
  isInline ? inline() : undefined,
71
96
  shift(state => ({
72
97
  padding: {
@@ -88,6 +113,20 @@ onAvailableWidth) {
88
113
  // 25/08/2026, third video: the map background's row). Horizontal
89
114
  // placement belongs to `shift`, which slides — it never teleports.
90
115
  flip({ padding: 10, crossAxis: false, flipAlignment: false }),
116
+ size({
117
+ padding: 10,
118
+ apply: ({ elements, availableWidth }) => {
119
+ elements.floating.style.width = 'fit-content';
120
+ // The room the row has. The toolbar never wraps and never
121
+ // scrolls: past this width its entries give way, in the order
122
+ // they declared, into the "⋮" menu — see `ToolbarFitter`.
123
+ const capped = `${Math.max(availableWidth, MIN_TOOLBAR_WIDTH)}px`;
124
+ if (elements.floating.style.maxWidth !== capped) {
125
+ elements.floating.style.maxWidth = capped;
126
+ onAvailableWidth?.();
127
+ }
128
+ },
129
+ }),
91
130
  hide(),
92
131
  ],
93
132
  };
@@ -599,6 +638,10 @@ const MAX_FIT_ROUNDS = 3;
599
638
  * keeps its natural width under it, while an `inner` toolbar is pinned to the
600
639
  * exact width of the block it sits on. Anything else — a row nothing has
601
640
  * positioned yet — has all the room in the world and collapses nothing.
641
+ *
642
+ * The cap is the clipping box less its padding, never the row's own width: see
643
+ * the middleware order in {@link autoUpdatePosition}. It is floored at
644
+ * {@link MIN_TOOLBAR_WIDTH}.
602
645
  */
603
646
  function availableWidthOf(toolbar) {
604
647
  const max = Number.parseFloat(toolbar.style.maxWidth);
@@ -129,7 +129,8 @@ let RecordField = (() => {
129
129
  }
130
130
 
131
131
  .field-content.is-editing {
132
- box-shadow: 0px 0px 0px 2px rgba(30, 150, 235, 0.3);
132
+ box-shadow: 0px 0px 0px 2px
133
+ color-mix(in srgb, var(--affine-primary-color) 30%, transparent);
133
134
  }
134
135
 
135
136
  .field-content.is-focus {
@@ -83,7 +83,9 @@ export const allLiteralConfig = [
83
83
  items: type.element.data?.map(tag => {
84
84
  const selected = set.has(tag.id);
85
85
  const prefix = selected
86
- ? CheckBoxCheckSolidIcon({ style: `color:#1E96EB` })
86
+ ? CheckBoxCheckSolidIcon({
87
+ style: `color:var(--affine-primary-color)`,
88
+ })
87
89
  : CheckBoxUnIcon();
88
90
  return menu.action({
89
91
  name: tag.value,
@@ -15,7 +15,7 @@ export class BooleanGroupView extends BaseGroup {
15
15
  render() {
16
16
  return html ` <div class="data-view-group-title-boolean-view">
17
17
  ${this.value
18
- ? CheckBoxCheckSolidIcon({ style: `color:#1E96EB` })
18
+ ? CheckBoxCheckSolidIcon({ style: `color:var(--affine-primary-color)` })
19
19
  : CheckBoxUnIcon()}
20
20
  </div>`;
21
21
  }
@@ -40,6 +40,12 @@ import { BaseCellRenderer } from '../../core/property/index.js';
40
40
  import { createFromBaseCellRenderer } from '../../core/property/renderer.js';
41
41
  import { createIcon } from '../../core/utils/uni-icon.js';
42
42
  import { checkboxPropertyModelConfig } from './define.js';
43
+ /**
44
+ * The chrome accent, reached through its token rather than written as a hex:
45
+ * the six-dot burst is chrome, so it has to follow the host's theme (DESIGN.md,
46
+ * The Borrowed Blue Rule).
47
+ */
48
+ const ACCENT = 'var(--affine-primary-color)';
43
49
  const playCheckAnimation = async (refElement, { left = 0, size = 20 } = {}) => {
44
50
  const sparkingEl = document.createElement('div');
45
51
  sparkingEl.classList.add('affine-check-animation');
@@ -56,7 +62,7 @@ const playCheckAnimation = async (refElement, { left = 0, size = 20 } = {}) => {
56
62
  refElement.append(sparkingEl);
57
63
  await sparkingEl.animate([
58
64
  {
59
- boxShadow: '0 -18px 0 -8px #1e96eb, 16px -8px 0 -8px #1e96eb, 16px 8px 0 -8px #1e96eb, 0 18px 0 -8px #1e96eb, -16px 8px 0 -8px #1e96eb, -16px -8px 0 -8px #1e96eb',
65
+ boxShadow: `0 -18px 0 -8px ${ACCENT}, 16px -8px 0 -8px ${ACCENT}, 16px 8px 0 -8px ${ACCENT}, 0 18px 0 -8px ${ACCENT}, -16px 8px 0 -8px ${ACCENT}, -16px -8px 0 -8px ${ACCENT}`,
60
66
  },
61
67
  ], { duration: 240, easing: 'ease', fill: 'forwards' }).finished;
62
68
  await sparkingEl.animate([
@@ -120,7 +126,7 @@ let CheckboxCell = (() => {
120
126
  render() {
121
127
  const checked = this.value ?? false;
122
128
  const icon = checked
123
- ? CheckBoxCheckSolidIcon({ style: `color:#1E96EB` })
129
+ ? CheckBoxCheckSolidIcon({ style: `color:var(--affine-primary-color)` })
124
130
  : CheckBoxUnIcon();
125
131
  return html ` <div class="affine-database-checkbox-container">
126
132
  <div