@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.
- package/dist/_pkgs/affine-block-data-view/configs/tooltips.js +1 -1
- package/dist/_pkgs/affine-block-database/configs/tooltips.js +1 -1
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +4 -2
- package/dist/_pkgs/affine-block-embed/common/iframe-sandbox.d.ts +39 -0
- package/dist/_pkgs/affine-block-embed/common/iframe-sandbox.js +39 -0
- package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.js +2 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-error-card.d.ts +14 -1
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-error-card.js +21 -2
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.d.ts +0 -2
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.js +2 -5
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.d.ts +1 -1
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +14 -6
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/types.d.ts +16 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/types.js +17 -1
- package/dist/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.js +2 -0
- package/dist/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.js +2 -0
- package/dist/_pkgs/affine-block-embed/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-embed/index.js +1 -0
- package/dist/_pkgs/affine-block-embed/translations.d.ts +8 -0
- package/dist/_pkgs/affine-block-embed/translations.js +28 -0
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.js +4 -2
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +2 -2
- package/dist/_pkgs/affine-block-frame/frame-manager.js +5 -2
- package/dist/_pkgs/affine-block-list/utils/get-list-icon.js +3 -1
- package/dist/_pkgs/affine-block-note/configs/tooltips.js +1 -1
- package/dist/_pkgs/affine-block-root/adapters/html.js +2 -2
- package/dist/_pkgs/affine-block-root/commands/copy-link-commands.d.ts +2 -0
- package/dist/_pkgs/affine-block-root/commands/copy-link-commands.js +155 -0
- package/dist/_pkgs/affine-block-root/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-root/index.js +1 -0
- package/dist/_pkgs/affine-block-root/view.js +2 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +13 -1
- package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +8 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend.js +59 -3
- package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.js +4 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.d.ts +3 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch-translations.js +23 -0
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +1 -1
- package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +12 -4
- package/dist/_pkgs/affine-block-surface/framework-background/background-view.js +1 -1
- package/dist/_pkgs/affine-block-surface/framework-background/fit.d.ts +36 -0
- package/dist/_pkgs/affine-block-surface/framework-background/fit.js +30 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.js +2 -7
- package/dist/_pkgs/affine-block-surface-ref/configs/tooltips.js +2 -2
- package/dist/_pkgs/affine-components/color-picker/palette-carousel.js +5 -0
- package/dist/_pkgs/affine-components/color-picker/styles.js +1 -1
- package/dist/_pkgs/affine-components/context-menu/button.js +3 -1
- package/dist/_pkgs/affine-components/icons/ai.js +3 -3
- package/dist/_pkgs/affine-components/icons/list.js +7 -1
- package/dist/_pkgs/affine-components/size-dropdown-menu/dropdown-menu.js +6 -1
- package/dist/_pkgs/affine-components/toolbar/index.d.ts +1 -1
- package/dist/_pkgs/affine-components/toolbar/index.js +1 -1
- package/dist/_pkgs/affine-components/toolbar/menu-button.d.ts +7 -0
- package/dist/_pkgs/affine-components/toolbar/menu-button.js +30 -0
- package/dist/_pkgs/affine-components/toolbar/picker-menu.d.ts +16 -1
- package/dist/_pkgs/affine-components/toolbar/picker-menu.js +2 -2
- package/dist/_pkgs/affine-components/toolbar/toolbar.d.ts +1 -0
- package/dist/_pkgs/affine-components/toolbar/toolbar.js +67 -0
- package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title-editor.js +1 -1
- package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.js +1 -1
- package/dist/_pkgs/affine-gfx-brush/toolbar/components/eraser/icons.js +1 -1
- package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.d.ts +11 -2
- package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +11 -2
- package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +3 -2
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +23 -7
- package/dist/_pkgs/affine-gfx-connector/translations.d.ts +3 -0
- package/dist/_pkgs/affine-gfx-connector/translations.js +23 -0
- package/dist/_pkgs/affine-gfx-mindmap/indicator-overlay/index.js +6 -2
- package/dist/_pkgs/affine-gfx-mindmap/toolbar/config.js +4 -2
- package/dist/_pkgs/affine-gfx-mindmap/translations.d.ts +6 -0
- package/dist/_pkgs/affine-gfx-mindmap/translations.js +10 -0
- package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +4 -2
- package/dist/_pkgs/affine-gfx-shape/translations.d.ts +7 -0
- package/dist/_pkgs/affine-gfx-shape/translations.js +11 -0
- package/dist/_pkgs/affine-gfx-template/builtin/other.js +13 -7
- package/dist/_pkgs/affine-gfx-template/toolbar/template-loading.js +1 -1
- package/dist/_pkgs/affine-gfx-template/translations.d.ts +5 -0
- package/dist/_pkgs/affine-gfx-template/translations.js +38 -0
- package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +3 -2
- package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +3 -1
- package/dist/_pkgs/affine-gfx-text/translations.d.ts +8 -0
- package/dist/_pkgs/affine-gfx-text/translations.js +12 -0
- package/dist/_pkgs/affine-inline-latex/latex-node/latex-editor-menu.js +2 -1
- package/dist/_pkgs/affine-model/consts/text.d.ts +15 -2
- package/dist/_pkgs/affine-model/consts/text.js +25 -1
- package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +13 -2
- package/dist/_pkgs/affine-shared/services/font-loader/config.js +43 -54
- package/dist/_pkgs/affine-shared/services/theme-service.d.ts +19 -0
- package/dist/_pkgs/affine-shared/services/theme-service.js +24 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +20 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +81 -0
- package/dist/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.js +2 -2
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.js +5 -1
- package/dist/_pkgs/affine-widget-edgeless-toolbar/config/types.d.ts +15 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/config/utils.d.ts +1 -1
- package/dist/_pkgs/affine-widget-edgeless-toolbar/config/utils.js +7 -2
- package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-family-panel.d.ts +18 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-family-panel.js +52 -6
- package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.d.ts +6 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/translations.js +10 -0
- package/dist/_pkgs/affine-widget-frame-title/edgeless-frame-title-editor.js +2 -1
- package/dist/_pkgs/affine-widget-slash-menu/translations.d.ts +16 -0
- package/dist/_pkgs/affine-widget-slash-menu/translations.js +23 -1
- package/dist/_pkgs/affine-widget-toolbar/utils.js +57 -14
- package/dist/_pkgs/data-view/core/detail/field.js +2 -1
- package/dist/_pkgs/data-view/core/filter/literal/define.js +3 -1
- package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +1 -1
- package/dist/_pkgs/data-view/property-presets/checkbox/cell-renderer.js +8 -2
- package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +1 -1
- package/dist/_pkgs/data-view/view-presets/kanban/pc/controller/drag.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/controller/drag.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/controller/selection.js +1 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/header/vertical-indicator.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/row/row-select-checkbox.js +3 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/drag.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/selection.js +1 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/vertical-indicator.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/row-header.js +3 -1
- package/dist/_pkgs/std/gfx/model/surface/role.d.ts +10 -5
- package/dist/commands.js +2 -1
- package/dist/translations.js +5 -0
- 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'
|
|
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'
|
|
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
|
-
|
|
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="${
|
|
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
|
-
|
|
78
|
-
|
|
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=${
|
|
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
|
-
${
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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({
|
|
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
|
|
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:
|
|
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
|
|
129
|
+
? CheckBoxCheckSolidIcon({ style: `color:var(--affine-primary-color)` })
|
|
124
130
|
: CheckBoxUnIcon();
|
|
125
131
|
return html ` <div class="affine-database-checkbox-container">
|
|
126
132
|
<div
|