@formicoidea/labre-core 0.33.0 → 0.34.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-attachment/attachment-block.js +2 -2
- package/dist/_pkgs/affine-block-attachment/configs/toolbar.d.ts +2 -2
- package/dist/_pkgs/affine-block-attachment/configs/toolbar.js +9 -7
- package/dist/_pkgs/affine-block-bookmark/configs/toolbar.js +12 -12
- package/dist/_pkgs/affine-block-code/code-block.js +2 -2
- package/dist/_pkgs/affine-block-code/code-toolbar/config.js +6 -0
- package/dist/_pkgs/affine-block-database/database-block.js +2 -2
- package/dist/_pkgs/affine-block-embed/common/render-linked-doc.js +3 -3
- package/dist/_pkgs/affine-block-embed/configs/toolbar.js +11 -11
- package/dist/_pkgs/affine-block-embed/embed-html-block/configs/toolbar.js +5 -5
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.d.ts +7 -7
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +12 -12
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +2 -2
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +9 -9
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.js +4 -4
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/components/embed-synced-doc-card.js +5 -4
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +9 -9
- package/dist/_pkgs/affine-block-frame/frame-toolbar.js +2 -2
- package/dist/_pkgs/affine-block-image/configs/toolbar.js +4 -4
- package/dist/_pkgs/affine-block-note/configs/toolbar.js +2 -2
- package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +6 -4
- package/dist/_pkgs/affine-block-root/configs/toolbar.js +6 -6
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/misc.d.ts +10 -10
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/misc.js +4 -4
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.d.ts +7 -7
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +8 -8
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +3 -1
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +15 -4
- package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +17 -0
- package/dist/_pkgs/affine-block-surface/extensions/spotlight.d.ts +21 -0
- package/dist/_pkgs/affine-block-surface/extensions/spotlight.js +17 -3
- package/dist/_pkgs/affine-block-surface/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.d.ts +17 -0
- package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.js +66 -0
- package/dist/_pkgs/affine-block-surface/view.js +5 -0
- package/dist/_pkgs/affine-block-surface-ref/configs/toolbar.js +4 -4
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
- package/dist/_pkgs/affine-components/icons/text.js +426 -426
- package/dist/_pkgs/affine-components/open-doc-dropdown-menu/dropdown-menu.d.ts +2 -0
- package/dist/_pkgs/affine-components/resource/resource.js +2 -0
- package/dist/_pkgs/affine-components/view-dropdown-menu/dropdown-menu.js +27 -14
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.d.ts +4 -4
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.js +6 -6
- package/dist/_pkgs/affine-inline-reference/reference-node/configs/toolbar.d.ts +4 -4
- package/dist/_pkgs/affine-inline-reference/reference-node/configs/toolbar.js +6 -6
- package/dist/_pkgs/affine-model/elements/bpmn/pool.d.ts +61 -0
- package/dist/_pkgs/affine-model/elements/bpmn/pool.js +93 -0
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +7 -2
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +9 -4
- package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +7 -2
- package/dist/_pkgs/affine-model/elements/edgy/board.js +9 -4
- package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +20 -3
- package/dist/_pkgs/affine-model/elements/edgy/facets.js +13 -4
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +7 -2
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +9 -4
- package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +7 -2
- package/dist/_pkgs/affine-model/elements/framework-background/background.js +9 -4
- package/dist/_pkgs/affine-model/elements/framework-background/hit-test.d.ts +48 -0
- package/dist/_pkgs/affine-model/elements/framework-background/hit-test.js +55 -0
- package/dist/_pkgs/affine-model/elements/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.d.ts +11 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.js +15 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/action.d.ts +32 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/action.js +16 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/flags.d.ts +10 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/flags.js +32 -1
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +106 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +201 -0
- package/dist/_pkgs/affine-shared/services/translation-service/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/translation-service/index.js +1 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.d.ts +11 -16
- package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.js +11 -28
- package/dist/_pkgs/affine-widget-keyboard-toolbar/config.js +2 -1
- package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
- package/dist/_pkgs/affine-widget-slash-menu/config.js +2 -1
- package/dist/_pkgs/affine-widget-toolbar/toolbar.js +5 -0
- package/dist/_pkgs/affine-widget-toolbar/utils.d.ts +19 -2
- package/dist/_pkgs/affine-widget-toolbar/utils.js +22 -7
- package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +11 -11
- package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +18 -18
- package/dist/_pkgs/std/extension/command-registry.d.ts +36 -0
- package/dist/_pkgs/std/extension/command-registry.js +16 -0
- package/dist/_pkgs/std/extension/translation-manifest.d.ts +46 -1
- package/dist/_pkgs/std/extension/translation-manifest.js +58 -0
- package/dist/_pkgs/std/gfx/highlight.d.ts +84 -0
- package/dist/_pkgs/std/gfx/highlight.js +112 -0
- package/dist/_pkgs/std/gfx/index.d.ts +1 -0
- package/dist/_pkgs/std/gfx/index.js +1 -0
- package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +17 -3
- package/dist/_pkgs/std/scope/std-scope.d.ts +2 -1
- package/dist/_pkgs/std/scope/std-scope.js +2 -0
- package/dist/_pkgs/std/utils/gfx.js +2 -0
- package/dist/shortcuts.d.ts +20 -6
- package/dist/shortcuts.js +7 -9
- package/dist/translations.js +25 -18
- package/package.json +13 -1
|
@@ -32,8 +32,9 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects,
|
|
35
|
+
import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
|
|
36
36
|
import { field, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
|
|
37
|
+
import { backgroundIncludesPoint } from '../framework-background/index.js';
|
|
37
38
|
/**
|
|
38
39
|
* A static "Estuarine framework" map: the 2D energy (e, vertical, double-headed)
|
|
39
40
|
* / time (t, horizontal) space with the three reference curves — Liminal (green),
|
|
@@ -101,9 +102,13 @@ let EstuarineElementModel = (() => {
|
|
|
101
102
|
getNearestPoint(point) {
|
|
102
103
|
return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Picked by its BORDER band — see {@link backgroundIncludesPoint}. The map is
|
|
107
|
+
* a space constraint nodes are dropped into, so the clicks inside it are
|
|
108
|
+
* theirs.
|
|
109
|
+
*/
|
|
110
|
+
includesPoint(x, y, options) {
|
|
111
|
+
return backgroundIncludesPoint(this, x, y, options);
|
|
107
112
|
}
|
|
108
113
|
#resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
|
|
109
114
|
get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IVec } from '../../../global/gfx/index.js';
|
|
2
2
|
import { Bound } from '../../../global/gfx/index.js';
|
|
3
|
-
import type { BaseElementProps } from '../../../std/gfx/index.js';
|
|
3
|
+
import type { BaseElementProps, PointTestOptions } from '../../../std/gfx/index.js';
|
|
4
4
|
import { GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
|
|
5
5
|
/**
|
|
6
6
|
* The props every framework background carries, whatever it draws.
|
|
@@ -38,5 +38,10 @@ export declare abstract class FrameworkBackgroundElementModel<Props extends Base
|
|
|
38
38
|
containsBound(bounds: Bound): boolean;
|
|
39
39
|
getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
|
|
40
40
|
getNearestPoint(point: IVec): IVec;
|
|
41
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Picked by its BORDER band, not by its whole area — see
|
|
43
|
+
* {@link backgroundIncludesPoint} for the why and for what a caller asking
|
|
44
|
+
* about the visible extent (`ignoreTransparent: false`) still gets.
|
|
45
|
+
*/
|
|
46
|
+
includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
|
|
42
47
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects,
|
|
1
|
+
import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
|
|
2
2
|
import { GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
|
|
3
|
+
import { backgroundIncludesPoint } from './hit-test.js';
|
|
3
4
|
/**
|
|
4
5
|
* The MODEL half of the framework-background primitive (PF2.1).
|
|
5
6
|
*
|
|
@@ -35,8 +36,12 @@ export class FrameworkBackgroundElementModel extends GfxPrimitiveElementModel {
|
|
|
35
36
|
getNearestPoint(point) {
|
|
36
37
|
return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Picked by its BORDER band, not by its whole area — see
|
|
41
|
+
* {@link backgroundIncludesPoint} for the why and for what a caller asking
|
|
42
|
+
* about the visible extent (`ignoreTransparent: false`) still gets.
|
|
43
|
+
*/
|
|
44
|
+
includesPoint(x, y, options) {
|
|
45
|
+
return backgroundIncludesPoint(this, x, y, options);
|
|
41
46
|
}
|
|
42
47
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { IBound } from '../../../global/gfx/index.js';
|
|
2
|
+
import type { PointTestOptions } from '../../../std/gfx/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The width of the band a background is picked by, in SCREEN pixels.
|
|
5
|
+
*
|
|
6
|
+
* Ten is what every caller on the picking path already asks for
|
|
7
|
+
* (`getElementByPoint`, the default tool, the gfx view event handler all pass
|
|
8
|
+
* `hitThreshold: 10`); naming it here gives the one caller that passes nothing
|
|
9
|
+
* — the frame manager, which calls `includesPoint(x, y, {})` — the same band
|
|
10
|
+
* instead of a shape's 1-pixel default.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BACKGROUND_BORDER_HIT_THRESHOLD = 10;
|
|
13
|
+
/**
|
|
14
|
+
* Whether a point picks a framework background — THE hit test every background
|
|
15
|
+
* in the library shares.
|
|
16
|
+
*
|
|
17
|
+
* ## A background is picked by its border, not by its area
|
|
18
|
+
*
|
|
19
|
+
* A background is a passive canvas: the user drops nodes onto it and works on
|
|
20
|
+
* THEM. A hit test over the whole rectangle makes the backdrop compete with its
|
|
21
|
+
* own content for every click — it wins outright when it sits above in the
|
|
22
|
+
* paint order (`getElementByPoint` keeps the topmost hit), and it fills every
|
|
23
|
+
* gap when it sits below (the interior of an unfilled shape, the space beside a
|
|
24
|
+
* small node). Both were reported from the same recette (issue #194).
|
|
25
|
+
*
|
|
26
|
+
* So the band IS the affordance: within `hitThreshold` screen pixels of the
|
|
27
|
+
* (rotated) outline, and nowhere else. The threshold is divided by the zoom for
|
|
28
|
+
* the reason every shape divides it — a border band has to stay the same width
|
|
29
|
+
* under the pointer whatever the viewport is doing.
|
|
30
|
+
*
|
|
31
|
+
* ## The interior still answers "is the pointer on this element"
|
|
32
|
+
*
|
|
33
|
+
* `ignoreTransparent: false` is the existing way a caller says it is asking
|
|
34
|
+
* about the element's visible EXTENT rather than about what a click would pick
|
|
35
|
+
* — an unfilled shape answers the same two ways for the same reason
|
|
36
|
+
* (`rect.includesPoint`). Exactly two callers pass it: the default tool, which
|
|
37
|
+
* uses it to decide whether a press on an ALREADY-SELECTED element starts a
|
|
38
|
+
* move, and the connector manager, which never sees a background at all
|
|
39
|
+
* (`connectable` is false). So a selected background keeps being dragged from
|
|
40
|
+
* anywhere inside it, and only picking changed.
|
|
41
|
+
*
|
|
42
|
+
* ## What did NOT change
|
|
43
|
+
*
|
|
44
|
+
* `containsBound` / `intersectsBound` (the lasso), `getNearestPoint` and
|
|
45
|
+
* `getLineIntersections` are untouched: a rubber band that had to graze the
|
|
46
|
+
* outline would be a second regression dressed as a fix.
|
|
47
|
+
*/
|
|
48
|
+
export declare function backgroundIncludesPoint(bounds: IBound, x: number, y: number, options?: PointTestOptions): boolean;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getPointsFromBoundWithRotation, pointInPolygon, pointOnPolygonStoke, } from '../../../global/gfx/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The width of the band a background is picked by, in SCREEN pixels.
|
|
4
|
+
*
|
|
5
|
+
* Ten is what every caller on the picking path already asks for
|
|
6
|
+
* (`getElementByPoint`, the default tool, the gfx view event handler all pass
|
|
7
|
+
* `hitThreshold: 10`); naming it here gives the one caller that passes nothing
|
|
8
|
+
* — the frame manager, which calls `includesPoint(x, y, {})` — the same band
|
|
9
|
+
* instead of a shape's 1-pixel default.
|
|
10
|
+
*/
|
|
11
|
+
export const BACKGROUND_BORDER_HIT_THRESHOLD = 10;
|
|
12
|
+
/**
|
|
13
|
+
* Whether a point picks a framework background — THE hit test every background
|
|
14
|
+
* in the library shares.
|
|
15
|
+
*
|
|
16
|
+
* ## A background is picked by its border, not by its area
|
|
17
|
+
*
|
|
18
|
+
* A background is a passive canvas: the user drops nodes onto it and works on
|
|
19
|
+
* THEM. A hit test over the whole rectangle makes the backdrop compete with its
|
|
20
|
+
* own content for every click — it wins outright when it sits above in the
|
|
21
|
+
* paint order (`getElementByPoint` keeps the topmost hit), and it fills every
|
|
22
|
+
* gap when it sits below (the interior of an unfilled shape, the space beside a
|
|
23
|
+
* small node). Both were reported from the same recette (issue #194).
|
|
24
|
+
*
|
|
25
|
+
* So the band IS the affordance: within `hitThreshold` screen pixels of the
|
|
26
|
+
* (rotated) outline, and nowhere else. The threshold is divided by the zoom for
|
|
27
|
+
* the reason every shape divides it — a border band has to stay the same width
|
|
28
|
+
* under the pointer whatever the viewport is doing.
|
|
29
|
+
*
|
|
30
|
+
* ## The interior still answers "is the pointer on this element"
|
|
31
|
+
*
|
|
32
|
+
* `ignoreTransparent: false` is the existing way a caller says it is asking
|
|
33
|
+
* about the element's visible EXTENT rather than about what a click would pick
|
|
34
|
+
* — an unfilled shape answers the same two ways for the same reason
|
|
35
|
+
* (`rect.includesPoint`). Exactly two callers pass it: the default tool, which
|
|
36
|
+
* uses it to decide whether a press on an ALREADY-SELECTED element starts a
|
|
37
|
+
* move, and the connector manager, which never sees a background at all
|
|
38
|
+
* (`connectable` is false). So a selected background keeps being dragged from
|
|
39
|
+
* anywhere inside it, and only picking changed.
|
|
40
|
+
*
|
|
41
|
+
* ## What did NOT change
|
|
42
|
+
*
|
|
43
|
+
* `containsBound` / `intersectsBound` (the lasso), `getNearestPoint` and
|
|
44
|
+
* `getLineIntersections` are untouched: a rubber band that had to graze the
|
|
45
|
+
* outline would be a second regression dressed as a fix.
|
|
46
|
+
*/
|
|
47
|
+
export function backgroundIncludesPoint(bounds, x, y, options) {
|
|
48
|
+
const point = [x, y];
|
|
49
|
+
const points = getPointsFromBoundWithRotation(bounds);
|
|
50
|
+
const threshold = (options?.hitThreshold ?? BACKGROUND_BORDER_HIT_THRESHOLD) /
|
|
51
|
+
(options?.zoom ?? 1);
|
|
52
|
+
if (pointOnPolygonStoke(point, points, threshold))
|
|
53
|
+
return true;
|
|
54
|
+
return options?.ignoreTransparent === false && pointInPolygon(point, points);
|
|
55
|
+
}
|
|
@@ -405,6 +405,17 @@ export declare class EditPropsStore extends LifeCycleWatcher {
|
|
|
405
405
|
dispose(): void;
|
|
406
406
|
getStorage<T extends StoragePropsKey>(key: T): StorageProps[T] | null;
|
|
407
407
|
recordLastProps(key: LastPropsKey, props: Partial<LastProps[LastPropsKey]>): void;
|
|
408
|
+
/**
|
|
409
|
+
* Remember the edgeless viewport of the current editing session, so the next
|
|
410
|
+
* mount of this doc reopens where the user left it.
|
|
411
|
+
*
|
|
412
|
+
* The storage key is shared by every mount of the same doc, so a read-only
|
|
413
|
+
* mount — an embedded preview, a mini map — must not overwrite what the full
|
|
414
|
+
* editor remembered: a preview is not an editing session. Readonly is read
|
|
415
|
+
* here, at save time (the edgeless root block saves on unmount), so a
|
|
416
|
+
* session that turns read-only before unmounting stops writing too.
|
|
417
|
+
*/
|
|
418
|
+
saveViewport(viewport: StorageProps['viewport']): void;
|
|
408
419
|
setStorage<T extends StoragePropsKey>(key: T, value: StorageProps[T]): void;
|
|
409
420
|
unmounted(): void;
|
|
410
421
|
}
|
|
@@ -156,6 +156,21 @@ export class EditPropsStore extends LifeCycleWatcher {
|
|
|
156
156
|
const nextProps = mergeWith(clonedeep(innerProps), { [key]: overrideProps }, customizer);
|
|
157
157
|
this.innerProps$.value = OptionalPropsSchema.parse(nextProps);
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Remember the edgeless viewport of the current editing session, so the next
|
|
161
|
+
* mount of this doc reopens where the user left it.
|
|
162
|
+
*
|
|
163
|
+
* The storage key is shared by every mount of the same doc, so a read-only
|
|
164
|
+
* mount — an embedded preview, a mini map — must not overwrite what the full
|
|
165
|
+
* editor remembered: a preview is not an editing session. Readonly is read
|
|
166
|
+
* here, at save time (the edgeless root block saves on unmount), so a
|
|
167
|
+
* session that turns read-only before unmounting stops writing too.
|
|
168
|
+
*/
|
|
169
|
+
saveViewport(viewport) {
|
|
170
|
+
if (this.std.store.readonly)
|
|
171
|
+
return;
|
|
172
|
+
this.setStorage('viewport', viewport);
|
|
173
|
+
}
|
|
159
174
|
setStorage(key, value) {
|
|
160
175
|
const oldValue = this.getStorage(key);
|
|
161
176
|
this._getStorage(key).setItem(this._getStorageKey(key), JSON.stringify(value));
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { BlockStdScope } from '../../../std/index.js';
|
|
1
2
|
import type { TemplateResult } from 'lit';
|
|
3
|
+
import { type ChromeWording } from '../translation-service/index.js';
|
|
2
4
|
import type { ToolbarContext } from './context.js';
|
|
3
5
|
export declare enum ActionPlacement {
|
|
4
6
|
Start = 0,
|
|
@@ -25,9 +27,28 @@ type ActionBase = {
|
|
|
25
27
|
};
|
|
26
28
|
export type ToolbarAction = ActionBase & {
|
|
27
29
|
label?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The same word as {@link label}, said as an i18n key with its English
|
|
32
|
+
* default — resolved against the host's catalogue when the row is built, and
|
|
33
|
+
* written over `label` there (`combine`, in the toolbar widget).
|
|
34
|
+
*
|
|
35
|
+
* It exists because `label` is a VALUE and the translation seam needs `std`:
|
|
36
|
+
* a literal here is the one wording a host cannot override, which is what
|
|
37
|
+
* left a fully translated editor saying "Duplicate" and "Card view" in
|
|
38
|
+
* English (#183). Declaring the pair keeps a call site one line — the shape a
|
|
39
|
+
* static label already had — instead of pushing every entry that has words
|
|
40
|
+
* into a `generate`.
|
|
41
|
+
*
|
|
42
|
+
* Wordings are declared once in `@labre/affine-shared/services`
|
|
43
|
+
* (`CHROME_WORDINGS`), which is also what the key manifest walks — a pair
|
|
44
|
+
* spelt inline at a call site would be a key no host is ever offered.
|
|
45
|
+
*/
|
|
46
|
+
labelWording?: ChromeWording;
|
|
28
47
|
showLabel?: boolean;
|
|
29
48
|
icon?: TemplateResult;
|
|
30
49
|
tooltip?: string | TemplateResult;
|
|
50
|
+
/** {@link labelWording}, for the tooltip. Written over `tooltip`. */
|
|
51
|
+
tooltipWording?: ChromeWording;
|
|
31
52
|
variant?: 'destructive';
|
|
32
53
|
disabled?: ((cx: ToolbarContext) => boolean) | boolean;
|
|
33
54
|
content?: ((cx: ToolbarContext) => TemplateResult | null) | (TemplateResult | null);
|
|
@@ -45,4 +66,15 @@ export type ToolbarActionGroupGenerator = ActionBase & {
|
|
|
45
66
|
};
|
|
46
67
|
export type ToolbarGenericAction = ToolbarAction | ToolbarActionGenerator | ToolbarActionGroup | ToolbarActionGroupGenerator;
|
|
47
68
|
export type ToolbarActions<T extends ActionBase = ToolbarGenericAction> = T[];
|
|
69
|
+
/**
|
|
70
|
+
* What an entry SAYS, whether it declared a wording or a literal label.
|
|
71
|
+
*
|
|
72
|
+
* The row itself never needs this — `combine` resolves `labelWording` onto
|
|
73
|
+
* `label` before anything is drawn. It exists for the entries a widget renders
|
|
74
|
+
* ITSELF out of the raw declarations, which is exactly what the view switcher
|
|
75
|
+
* does: `content(ctx)` hands its own children to `affine-view-dropdown-menu`,
|
|
76
|
+
* so those never pass through `combine` and would otherwise be the one control
|
|
77
|
+
* in the editor left saying "Card view" in English (#183).
|
|
78
|
+
*/
|
|
79
|
+
export declare function toolbarActionLabel(std: BlockStdScope, action: ToolbarAction): string;
|
|
48
80
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { translateKey } from '../translation-service/index.js';
|
|
1
2
|
export var ActionPlacement;
|
|
2
3
|
(function (ActionPlacement) {
|
|
3
4
|
ActionPlacement[ActionPlacement["Start"] = 0] = "Start";
|
|
@@ -5,3 +6,18 @@ export var ActionPlacement;
|
|
|
5
6
|
ActionPlacement[ActionPlacement["End"] = 2] = "End";
|
|
6
7
|
ActionPlacement[ActionPlacement["More"] = 4] = "More";
|
|
7
8
|
})(ActionPlacement || (ActionPlacement = {}));
|
|
9
|
+
/**
|
|
10
|
+
* What an entry SAYS, whether it declared a wording or a literal label.
|
|
11
|
+
*
|
|
12
|
+
* The row itself never needs this — `combine` resolves `labelWording` onto
|
|
13
|
+
* `label` before anything is drawn. It exists for the entries a widget renders
|
|
14
|
+
* ITSELF out of the raw declarations, which is exactly what the view switcher
|
|
15
|
+
* does: `content(ctx)` hands its own children to `affine-view-dropdown-menu`,
|
|
16
|
+
* so those never pass through `combine` and would otherwise be the one control
|
|
17
|
+
* in the editor left saying "Card view" in English (#183).
|
|
18
|
+
*/
|
|
19
|
+
export function toolbarActionLabel(std, action) {
|
|
20
|
+
return action.labelWording
|
|
21
|
+
? translateKey(std, ...action.labelWording)
|
|
22
|
+
: (action.label ?? '');
|
|
23
|
+
}
|
|
@@ -9,11 +9,21 @@ export declare enum Flag {
|
|
|
9
9
|
Accepting = 64
|
|
10
10
|
}
|
|
11
11
|
export declare class Flags {
|
|
12
|
+
#private;
|
|
12
13
|
value$: import("@preact/signals-core").Signal<Flag>;
|
|
14
|
+
get revision(): number;
|
|
15
|
+
get revision$(): import("@preact/signals-core").Signal<number>;
|
|
13
16
|
get value(): Flag;
|
|
14
17
|
toggle(flag: Flag, activated: boolean): void;
|
|
15
18
|
check(flag: Flag, value?: Flag): boolean;
|
|
16
19
|
contains(flag: number, value?: Flag): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Forces subscribers to re-run while keeping `flag` activated.
|
|
22
|
+
*
|
|
23
|
+
* The revision bump is what actually notifies; the batch keeps both writes
|
|
24
|
+
* in a single notification so the toolbar never sees a transient
|
|
25
|
+
* {@link Flag.None} frame.
|
|
26
|
+
*/
|
|
17
27
|
refresh(flag: Flag): void;
|
|
18
28
|
reset(): void;
|
|
19
29
|
hide(): void;
|
|
@@ -16,6 +16,30 @@ export var Flag;
|
|
|
16
16
|
export class Flags {
|
|
17
17
|
constructor() {
|
|
18
18
|
this.value$ = signal(Flag.None);
|
|
19
|
+
/**
|
|
20
|
+
* Bumped on every {@link Flags.refresh} call.
|
|
21
|
+
*
|
|
22
|
+
* `refresh` intentionally leaves `value$` unchanged, so it cannot be used as
|
|
23
|
+
* a repaint channel on its own: since `@preact/signals-core` 1.14 a `batch`
|
|
24
|
+
* that ends on its initial value notifies nobody. Subscribers that must
|
|
25
|
+
* re-run on a forced refresh have to read this revision counter as well.
|
|
26
|
+
*/
|
|
27
|
+
this.#revision$ = signal(0);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Bumped on every {@link Flags.refresh} call.
|
|
31
|
+
*
|
|
32
|
+
* `refresh` intentionally leaves `value$` unchanged, so it cannot be used as
|
|
33
|
+
* a repaint channel on its own: since `@preact/signals-core` 1.14 a `batch`
|
|
34
|
+
* that ends on its initial value notifies nobody. Subscribers that must
|
|
35
|
+
* re-run on a forced refresh have to read this revision counter as well.
|
|
36
|
+
*/
|
|
37
|
+
#revision$;
|
|
38
|
+
get revision() {
|
|
39
|
+
return this.#revision$.peek();
|
|
40
|
+
}
|
|
41
|
+
get revision$() {
|
|
42
|
+
return this.#revision$;
|
|
19
43
|
}
|
|
20
44
|
get value() {
|
|
21
45
|
return this.value$.peek();
|
|
@@ -33,10 +57,17 @@ export class Flags {
|
|
|
33
57
|
contains(flag, value = this.value) {
|
|
34
58
|
return (flag & value) !== Flag.None;
|
|
35
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Forces subscribers to re-run while keeping `flag` activated.
|
|
62
|
+
*
|
|
63
|
+
* The revision bump is what actually notifies; the batch keeps both writes
|
|
64
|
+
* in a single notification so the toolbar never sees a transient
|
|
65
|
+
* {@link Flag.None} frame.
|
|
66
|
+
*/
|
|
36
67
|
refresh(flag) {
|
|
37
68
|
batch(() => {
|
|
38
|
-
this.toggle(flag, false);
|
|
39
69
|
this.toggle(flag, true);
|
|
70
|
+
this.#revision$.value++;
|
|
40
71
|
});
|
|
41
72
|
}
|
|
42
73
|
reset() {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor's own chrome wordings, as `[key, fallback]` pairs.
|
|
3
|
+
*
|
|
4
|
+
* ## Why they are a table and not forty literals
|
|
5
|
+
*
|
|
6
|
+
* "Copy", "Delete", "Card view" are the SAME word on a dozen toolbars — the
|
|
7
|
+
* bookmark's, the image's, the embed's, the linked doc's — and a literal per
|
|
8
|
+
* call site is a wording a host has to translate a dozen times and can get
|
|
9
|
+
* twelve different answers for. One pair per word, imported where it is
|
|
10
|
+
* rendered, is what makes the manifest's promise ("every key the library can
|
|
11
|
+
* ask for") describe a list a human can actually word.
|
|
12
|
+
*
|
|
13
|
+
* ## The tuple shape is load-bearing
|
|
14
|
+
*
|
|
15
|
+
* `translateKey(std, ...COPY)` spreads into `(std, key, fallback)`, so a call
|
|
16
|
+
* site names the wording once and cannot pair the wrong fallback with the right
|
|
17
|
+
* key. It is also what
|
|
18
|
+
* `packages/affine/all/src/__tests__/translations/manifest.unit.spec.ts` reads:
|
|
19
|
+
* the two adjacent literals below are the pair its drift check confirms the
|
|
20
|
+
* manifest against, which is why the wordings live in literals here rather than
|
|
21
|
+
* being derived from anything.
|
|
22
|
+
*
|
|
23
|
+
* Chrome, so every one of them ships an English default: a standalone
|
|
24
|
+
* playground with no `TranslationProvider` registered must read exactly as it
|
|
25
|
+
* did before these keys existed.
|
|
26
|
+
*/
|
|
27
|
+
/** A wording the library can ask the host for: its key, and its English default. */
|
|
28
|
+
export type ChromeWording = readonly [key: string, fallback: string];
|
|
29
|
+
/**
|
|
30
|
+
* The transient messages the editor puts on screen after a gesture.
|
|
31
|
+
*
|
|
32
|
+
* They were the last English strings left in a fully translated host (#182):
|
|
33
|
+
* silent while nobody injected a `NotificationProvider`, and English in the
|
|
34
|
+
* middle of a French UI the moment somebody did.
|
|
35
|
+
*/
|
|
36
|
+
export declare const TOAST_COPIED_TO_CLIPBOARD: ChromeWording;
|
|
37
|
+
export declare const TOAST_LINKED_DOC_CREATED: ChromeWording;
|
|
38
|
+
export declare const TOAST_NOTE_REMOVED_FROM_PAGE: ChromeWording;
|
|
39
|
+
export declare const TOAST_FRAME_INSERTED_INTO_PAGE: ChromeWording;
|
|
40
|
+
export declare const TOAST_NO_LINK_FOUND: ChromeWording;
|
|
41
|
+
export declare const TOOLBAR_BRING_TO_FRONT: ChromeWording;
|
|
42
|
+
export declare const TOOLBAR_SEND_TO_BACK: ChromeWording;
|
|
43
|
+
export declare const TOOLBAR_COPY: ChromeWording;
|
|
44
|
+
export declare const TOOLBAR_DUPLICATE: ChromeWording;
|
|
45
|
+
export declare const TOOLBAR_DELETE: ChromeWording;
|
|
46
|
+
export declare const TOOLBAR_LOCK: ChromeWording;
|
|
47
|
+
export declare const TOOLBAR_MORE: ChromeWording;
|
|
48
|
+
export declare const TOOLBAR_LINK: ChromeWording;
|
|
49
|
+
export declare const TOOLBAR_CREATE_LINKED_DOC: ChromeWording;
|
|
50
|
+
export declare const TOOLBAR_DRAW_CONNECTOR: ChromeWording;
|
|
51
|
+
/**
|
|
52
|
+
* The four wordings of the view switcher — the control that decides whether a
|
|
53
|
+
* link is drawn as words, as a card or as the document itself.
|
|
54
|
+
*
|
|
55
|
+
* One set for every block that offers it (bookmark, attachment, embed, linked
|
|
56
|
+
* doc, synced doc, iframe, the inline link and the inline reference): they are
|
|
57
|
+
* one control with one vocabulary, and a host that had to word "Card view"
|
|
58
|
+
* eight times would end up with eight wordings of it.
|
|
59
|
+
*/
|
|
60
|
+
export declare const TOOLBAR_SWITCH_VIEW: ChromeWording;
|
|
61
|
+
export declare const TOOLBAR_INLINE_VIEW: ChromeWording;
|
|
62
|
+
export declare const TOOLBAR_CARD_VIEW: ChromeWording;
|
|
63
|
+
export declare const TOOLBAR_EMBED_VIEW: ChromeWording;
|
|
64
|
+
/**
|
|
65
|
+
* The four states a linked-doc card can be in with nothing to show: deleted,
|
|
66
|
+
* unreadable, empty, and — for the SYNCED card, which frames a page rather
|
|
67
|
+
* than a doc — empty in its own words.
|
|
68
|
+
*
|
|
69
|
+
* All four and not only the two the recette caught (#183): they are one
|
|
70
|
+
* sentence rendered by one ternary, and translating half of it would leave a
|
|
71
|
+
* card that changes language when the document it points at goes missing.
|
|
72
|
+
*/
|
|
73
|
+
export declare const LINKED_DOC_DELETED: ChromeWording;
|
|
74
|
+
export declare const LINKED_DOC_FAILED: ChromeWording;
|
|
75
|
+
export declare const LINKED_DOC_EMPTY_PREVIEW: ChromeWording;
|
|
76
|
+
export declare const SYNCED_DOC_EMPTY_PREVIEW: ChromeWording;
|
|
77
|
+
/**
|
|
78
|
+
* The resize toggle, which is the one entry EVERY framework board carries —
|
|
79
|
+
* Wardley, BPMN, C4, EDGY, Cynefin, Estuarine and the two DDD boards all
|
|
80
|
+
* register the same always-on button (`docs/adr/0009`: a stored board must stay
|
|
81
|
+
* usable with its framework switched off).
|
|
82
|
+
*
|
|
83
|
+
* Declared here rather than once per framework because it is not a framework's
|
|
84
|
+
* own word: it names a behaviour of the generic frame primitive, and eight
|
|
85
|
+
* copies of it in eight manifests would be eight keys for one tooltip.
|
|
86
|
+
*/
|
|
87
|
+
export declare const BOARD_RESIZE_TOGGLE: ChromeWording;
|
|
88
|
+
/**
|
|
89
|
+
* The legend button, in the two wordings the boards actually use: the notation
|
|
90
|
+
* boards say "notation", Wardley says "components".
|
|
91
|
+
*
|
|
92
|
+
* Two keys and not one interpolated sentence, for the reason the interchange
|
|
93
|
+
* counts already ran on — the seam has no interpolation, so the smallest honest
|
|
94
|
+
* unit is the whole sentence.
|
|
95
|
+
*/
|
|
96
|
+
export declare const BOARD_LEGEND_NOTATION: ChromeWording;
|
|
97
|
+
export declare const BOARD_LEGEND_COMPONENTS: ChromeWording;
|
|
98
|
+
/**
|
|
99
|
+
* Every wording declared above, in declaration order.
|
|
100
|
+
*
|
|
101
|
+
* The manifest (`@labre/affine/translations`) walks this instead of restating
|
|
102
|
+
* the pairs, so a wording added here reaches a host's catalogue with no second
|
|
103
|
+
* edit — the same "declared data, not restated data" rule the roles, the rules
|
|
104
|
+
* and the commands already follow.
|
|
105
|
+
*/
|
|
106
|
+
export declare const CHROME_WORDINGS: readonly ChromeWording[];
|