@bluepic/embed 0.4.0-next.99 → 0.5.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/bluepic-embed.iife.js +402 -178
- package/dist/bluepic-embed.umd.js +402 -178
- package/dist/components/AssetViewer/AssetViewer.vue.d.ts +71 -0
- package/dist/components/BxAudioPlayButton.vue.d.ts +24 -0
- package/dist/components/BxCard.vue.d.ts +35 -0
- package/dist/components/BxInput.vue.d.ts +7 -1
- package/dist/components/BxList.vue.d.ts +9 -0
- package/dist/components/BxListItem.vue.d.ts +13 -1
- package/dist/components/BxPopover.vue.d.ts +7 -0
- package/dist/components/BxPreviewLayer.vue.d.ts +18 -0
- package/dist/components/BxScrollbar.vue.d.ts +7 -0
- package/dist/components/BxSelect.vue.d.ts +16 -2
- package/dist/components/BxTable.vue.d.ts +109 -0
- package/dist/components/BxTabs.vue.d.ts +7 -0
- package/dist/components/BxWaveformThumb.vue.d.ts +27 -0
- package/dist/components/CollectionFieldPopup.vue.d.ts +4 -0
- package/dist/components/PopoverElement.vue.d.ts +10 -1
- package/dist/components/TemplateEditor/BatchCell.vue.d.ts +18 -0
- package/dist/components/TemplateEditor/BatchEditor.vue.d.ts +264 -0
- package/dist/components/TemplateEditor/BatchExportPopup.vue.d.ts +68 -0
- package/dist/components/TemplateEditor/BatchImportPopup.vue.d.ts +25 -0
- package/dist/components/TemplateEditor/BxLiveTemplate.vue.d.ts +8 -0
- package/dist/components/TemplateEditor/BxTemplateEditor.vue.d.ts +285 -16
- package/dist/components/TemplateEditor/FieldHintsLayer.vue.d.ts +86 -0
- package/dist/components/TemplateEditor/TemplateView.vue.d.ts +77 -2
- package/dist/components/User/UserInfo.vue.d.ts +12 -1
- package/dist/components/directives/usePopup.d.ts +5 -0
- package/dist/components/fields/Collection.vue.d.ts +3 -0
- package/dist/components/fields/Image.vue.d.ts +19 -5
- package/dist/components/fields/ImageEdit.vue.d.ts +6 -1
- package/dist/components/fields/Text.vue.d.ts +1 -1
- package/dist/embed/embed.d.ts +1024 -228
- package/dist/{index-CWm6zOv7.js → index-C99_zLhc.js} +9 -9
- package/dist/index-D8N6IfRw.cjs +1 -0
- package/dist/main.cjs +240 -162
- package/dist/main.d.ts +20 -0
- package/dist/main.mjs +79043 -68465
- package/dist/markdown-it-5-ieF6Bh.js +3790 -0
- package/dist/markdown-it-CLB5Jta6.cjs +16 -0
- package/dist/postal-mime-Df-WB8Vq.js +3337 -0
- package/dist/postal-mime-_7WF5UBe.cjs +28 -0
- package/dist/style.css +1 -1
- package/dist/theme/bridge.d.ts +14 -0
- package/dist/theme/color.d.ts +80 -0
- package/dist/theme/css.d.ts +8 -0
- package/dist/theme/index.d.ts +19 -0
- package/dist/theme/legacy.d.ts +3 -0
- package/dist/theme/resolve.d.ts +10 -0
- package/dist/theme/tokens.d.ts +129 -0
- package/dist/theme/types-contract.d.ts +13 -0
- package/dist/theme.cjs +1 -0
- package/dist/theme.mjs +1313 -0
- package/dist/util/assetAuth.d.ts +35 -0
- package/dist/util/audioPreview.d.ts +8 -0
- package/dist/util/batch/csv.d.ts +58 -0
- package/dist/util/batch/export.d.ts +92 -0
- package/dist/util/batch/fields.d.ts +22 -0
- package/dist/util/batch/parseCSV.d.ts +72 -0
- package/dist/util/batch/useBatchRows.d.ts +67 -0
- package/dist/util/cloneDeep.d.ts +5 -5
- package/dist/util/cloudflareImages.d.ts +8 -1
- package/dist/util/contextCapture.d.ts +19 -0
- package/dist/util/export.d.ts +65 -18
- package/dist/util/fieldHints/chipAction.d.ts +23 -0
- package/dist/util/fieldHints/fieldFocus.d.ts +81 -0
- package/dist/util/fieldHints/geometry.d.ts +52 -0
- package/dist/util/fieldHints/index.d.ts +20 -0
- package/dist/util/fieldHints/probe.d.ts +84 -0
- package/dist/util/fieldHints/resolve.d.ts +55 -0
- package/dist/util/fieldHints/textProbe.d.ts +71 -0
- package/dist/util/fieldHints/useCanvasTextEditing.d.ts +125 -0
- package/dist/util/fieldHints/useChipHighlight.d.ts +29 -0
- package/dist/util/fieldHints/useFieldHitboxes.d.ts +5601 -0
- package/dist/util/fieldHints/useHintReveal.d.ts +10 -0
- package/dist/util/fieldTree.d.ts +20 -0
- package/dist/util/fields.d.ts +1 -1
- package/dist/util/gallery.d.ts +78 -30
- package/dist/util/popoverArrow.d.ts +33 -0
- package/dist/util/popupHeaderTools.d.ts +26 -0
- package/dist/util/scrollPassthrough.d.ts +9 -0
- package/dist/util/useTheme.d.ts +36 -1
- package/dist/util/visualViewport.d.ts +47 -0
- package/dist/xlsx-BopDBbWb.js +24176 -0
- package/dist/xlsx-qn1xoUuv.cjs +105 -0
- package/package.json +18 -5
- package/dist/index-DFXQWOGQ.cjs +0 -1
- package/dist/util/backgroundRemoval.d.ts +0 -51
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BluepicField } from '@bluepic/types';
|
|
2
|
+
import type { HintPoint, HintQuad } from './probe';
|
|
3
|
+
/**
|
|
4
|
+
* Geometry helpers over probe output. Everything here works in SERIAL
|
|
5
|
+
* coordinates — the overlay maps to screen space via zoompinch's
|
|
6
|
+
* `composePoint`, so nothing in this file needs to know about pan, zoom or
|
|
7
|
+
* viewport size.
|
|
8
|
+
*/
|
|
9
|
+
/** Shoelace area. Quads may be rotated or sheared, so no width×height shortcut. */
|
|
10
|
+
export declare function quadArea(quad: HintQuad): number;
|
|
11
|
+
export declare function quadCentroid(quad: HintQuad): HintPoint;
|
|
12
|
+
export declare function quadAABB(quad: HintQuad): {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Which frame a quad belongs to, in the 1-based numbering `field.frameIndex`
|
|
20
|
+
* already uses (`BxTemplateEditor` reads it as `field.frameIndex || 1` and
|
|
21
|
+
* derives `frameX = (frameIndex - 1) % frames.x`).
|
|
22
|
+
*
|
|
23
|
+
* Decided by the centroid, so an element straddling a frame boundary lands in
|
|
24
|
+
* the frame it mostly occupies rather than being duplicated or dropped.
|
|
25
|
+
*/
|
|
26
|
+
export declare function frameIndexOfPoint(point: HintPoint, serialWidth: number, serialHeight: number, frames: {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
} | undefined): number;
|
|
30
|
+
/**
|
|
31
|
+
* Stacking class for overlap resolution — lower sits ON TOP.
|
|
32
|
+
*
|
|
33
|
+
* Hitboxes overlap constantly (a logo inside a full-bleed background image), so
|
|
34
|
+
* the pointer has to go somewhere defensible. Content-bearing fields win over
|
|
35
|
+
* pickers, which win over the tweak-a-value controls.
|
|
36
|
+
*/
|
|
37
|
+
export declare function hintPriorityClass(fieldType: BluepicField['type']): number;
|
|
38
|
+
export type OrderableHitbox = {
|
|
39
|
+
fieldType: BluepicField['type'];
|
|
40
|
+
area: number;
|
|
41
|
+
/** Position of the element in the serial's depth-first order; later paints later. */
|
|
42
|
+
elementOrder: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Sorts hitboxes back-to-front, so the caller can render in array order and let
|
|
46
|
+
* DOM order do the stacking. The LAST entry is the topmost / most reachable.
|
|
47
|
+
*
|
|
48
|
+
* Smaller area on top is what keeps a logo sitting inside a full-bleed image
|
|
49
|
+
* clickable — without it the background would swallow every pointer event
|
|
50
|
+
* inside its own bounds.
|
|
51
|
+
*/
|
|
52
|
+
export declare function orderHitboxes<T extends OrderableHitbox>(hitboxes: T[]): T[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { fieldHitboxProbe } from './probe';
|
|
2
|
+
export type { HintPoint, HintQuad, ElementQuad, HitboxProbeResult } from './probe';
|
|
3
|
+
export { collectSerialElements, expandBindingClosure, fieldBindings, referencesIdentifier, resolveFieldElements, scoreElement, CANDIDATE_SCORE_RATIO, } from './resolve';
|
|
4
|
+
export type { FieldElementMatch } from './resolve';
|
|
5
|
+
export { frameIndexOfPoint, hintPriorityClass, orderHitboxes, quadAABB, quadArea, quadCentroid } from './geometry';
|
|
6
|
+
export type { OrderableHitbox } from './geometry';
|
|
7
|
+
export { useFieldHitboxes } from './useFieldHitboxes';
|
|
8
|
+
export type { FieldHitbox } from './useFieldHitboxes';
|
|
9
|
+
export { useHintReveal } from './useHintReveal';
|
|
10
|
+
export { useChipHighlight } from './useChipHighlight';
|
|
11
|
+
export { createFieldElementRegistry, provideFieldFocus, revealFieldElement, useFieldFocus, FIELD_FOCUS_KEY, FIELD_FOCUS_FLASH_CLASS, FIELD_HOVER_CLASS, } from './fieldFocus';
|
|
12
|
+
export type { FieldFocusController } from './fieldFocus';
|
|
13
|
+
export { chipActionFor, fieldHasChip, readFieldProp } from './chipAction';
|
|
14
|
+
export type { ChipAction } from './chipAction';
|
|
15
|
+
export { textGeometryProbe } from './textProbe';
|
|
16
|
+
export type { CaretGeometry, SelectionQuad, TextGeometryResult, TextIndexResult } from './textProbe';
|
|
17
|
+
export { useCanvasTextEditing } from './useCanvasTextEditing';
|
|
18
|
+
export type { CanvasTextState, SelectionHandle } from './useCanvasTextEditing';
|
|
19
|
+
export { useFieldActivator } from './fieldFocus';
|
|
20
|
+
export type { FieldActivator } from './fieldFocus';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sandbox-side geometry probe.
|
|
3
|
+
*
|
|
4
|
+
* Field hints need to know where each element ACTUALLY landed on the canvas —
|
|
5
|
+
* after every ancestor transform, layout-group flow shift, mask clip and text
|
|
6
|
+
* auto-fit. That composition already happened once, inside the sandbox iframe,
|
|
7
|
+
* and the browser is holding the result. So rather than re-deriving it in the
|
|
8
|
+
* parent (which would mean linking `@bluepic/core` into this package and
|
|
9
|
+
* pinning ONE engine version against sandboxes that deliberately freeze one
|
|
10
|
+
* engine per template), we ask the frame that drew the pixels.
|
|
11
|
+
*
|
|
12
|
+
* `getBBox()` gives an element's local geometry; `getScreenCTM()` gives its
|
|
13
|
+
* full transform chain — CSS `transform` included, which is how core applies
|
|
14
|
+
* per-element matrices. Composing the element's screen CTM with the INVERSE of
|
|
15
|
+
* the root SVG's screen CTM cancels out viewport sizing and `preserveAspectRatio`
|
|
16
|
+
* letterboxing, leaving a matrix straight into viewBox units — i.e. serial
|
|
17
|
+
* coordinates. Verified against a live sandbox (0.2.65) to 0.0000px for an
|
|
18
|
+
* identity rect, a 23°-rotated text element, a rotate+scale group, and a rect
|
|
19
|
+
* nested inside that group.
|
|
20
|
+
*
|
|
21
|
+
* Nothing here needs a core release or a sandbox redeploy: it travels as source
|
|
22
|
+
* text through the existing `EmbeddedController.evaluate()` channel.
|
|
23
|
+
*/
|
|
24
|
+
export type HintPoint = {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
/** Element corners in serial coordinates, clockwise from the local top-left. */
|
|
29
|
+
export type HintQuad = [HintPoint, HintPoint, HintPoint, HintPoint];
|
|
30
|
+
export type ElementQuad = {
|
|
31
|
+
/**
|
|
32
|
+
* The rendered instance's unique id (`data-id`). An element with an
|
|
33
|
+
* `iteration` renders once per item, so one serial element can yield several
|
|
34
|
+
* of these — `id__0`, `id__1`, … — all sharing one `data-orginal-id`.
|
|
35
|
+
*/
|
|
36
|
+
dataId: string;
|
|
37
|
+
quad: HintQuad;
|
|
38
|
+
/**
|
|
39
|
+
* Tighter box to POINT AT, when the element has one. Present only for text
|
|
40
|
+
* elements whose painted box is larger than the glyphs — i.e. text carrying a
|
|
41
|
+
* surface/background bar, where `quad` balloons out to the whole text frame.
|
|
42
|
+
*
|
|
43
|
+
* The hover region stays `quad` (generous, easy to hit); only the tooltip's
|
|
44
|
+
* anchor moves here, so a bubble describing a headline points at the words
|
|
45
|
+
* rather than at the far corner of the bar behind them. Absent whenever the
|
|
46
|
+
* two coincide, which is the common case.
|
|
47
|
+
*/
|
|
48
|
+
anchor?: HintQuad;
|
|
49
|
+
};
|
|
50
|
+
export type HitboxProbeResult = {
|
|
51
|
+
supported: false;
|
|
52
|
+
/**
|
|
53
|
+
* `no-root` — no `.serial-wrapper > svg` yet (not mounted, or a sandbox
|
|
54
|
+
* that structures its DOM differently).
|
|
55
|
+
* `no-element-identity` — rendered, but the engine predates per-element
|
|
56
|
+
* `data-id` attributes (roughly < core 0.1.400). Nothing to anchor to;
|
|
57
|
+
* hints stay off for this template forever, by design.
|
|
58
|
+
* `no-ctm` — the root SVG has no screen CTM (whole subtree hidden).
|
|
59
|
+
*/
|
|
60
|
+
reason: 'no-root' | 'no-element-identity' | 'no-ctm';
|
|
61
|
+
} | {
|
|
62
|
+
supported: true;
|
|
63
|
+
quads: {
|
|
64
|
+
[originalId: string]: ElementQuad[];
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* ⚠️ THIS FUNCTION IS SHIPPED AS SOURCE TEXT, NOT AS A CLOSURE.
|
|
69
|
+
*
|
|
70
|
+
* `EmbeddedController.evaluate()` does `func.toString()` here and `new Function(...)`
|
|
71
|
+
* inside the iframe, so the body executes in a scope where NOTHING from this
|
|
72
|
+
* bundle exists. Any reference to an import, a module-scope const, or a helper
|
|
73
|
+
* defined outside these braces typechecks, builds green, and then throws
|
|
74
|
+
* `ReferenceError` in the sandbox under a minified name that won't resemble the
|
|
75
|
+
* original.
|
|
76
|
+
*
|
|
77
|
+
* Rules, all enforced by `probe.test.ts`:
|
|
78
|
+
* - one self-contained function; no free variables beyond `document`
|
|
79
|
+
* - plain ES (`var`, `function`, no optional chaining) so no transpiler
|
|
80
|
+
* helper can be hoisted out of the body
|
|
81
|
+
* - arguments in as a JSON string, return value JSON-serialisable — flatten
|
|
82
|
+
* every `DOMMatrix`/`DOMRect` before returning
|
|
83
|
+
*/
|
|
84
|
+
export declare function fieldHitboxProbe(originalIdsJson: string): HitboxProbeResult;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BluepicField, Template } from '@bluepic/types';
|
|
2
|
+
/**
|
|
3
|
+
* Candidates scoring below this share of the winner are dropped. Keeps the
|
|
4
|
+
* legitimate multi-element cases — a headline plus the background bar bound to
|
|
5
|
+
* it, or one binding echoed across two frames — while cutting the long tail of
|
|
6
|
+
* weak style/visibility couplings that would otherwise blanket the canvas.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CANDIDATE_SCORE_RATIO = 0.6;
|
|
9
|
+
export type FieldElementMatch = {
|
|
10
|
+
/** Serial element id — matches the rendered `data-orginal-id`. */
|
|
11
|
+
elementId: string;
|
|
12
|
+
element: Template.Element;
|
|
13
|
+
score: number;
|
|
14
|
+
/** Property keys that produced the match, for debugging a surprising hitbox. */
|
|
15
|
+
matchedProperties: string[];
|
|
16
|
+
};
|
|
17
|
+
/** Depth-first walk over the serial tree, descending into group/mask slots. */
|
|
18
|
+
export declare function collectSerialElements(elements: Template.Element[]): Generator<Template.Element>;
|
|
19
|
+
/**
|
|
20
|
+
* Does `expression` reference `name` as a standalone identifier?
|
|
21
|
+
*
|
|
22
|
+
* Hand-rolled rather than a regex with a lookbehind: `(?<!…)` still throws at
|
|
23
|
+
* compile time on Safari below 16.4, and a template that renders fine
|
|
24
|
+
* everywhere else must not blank its hints on an older iPad. A preceding `.`
|
|
25
|
+
* is excluded so `other.headline` doesn't match `headline`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function referencesIdentifier(expression: string, name: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Every binding that carries this field's value, mapped to how many
|
|
30
|
+
* `computedBindings` hops away it is. A field may write `headline`, while the
|
|
31
|
+
* element actually reads `headlineUpper = UPPER(headline)`.
|
|
32
|
+
*
|
|
33
|
+
* Iterated to a fixpoint and guarded on improvement only, so a cyclic
|
|
34
|
+
* computed-binding definition terminates instead of spinning.
|
|
35
|
+
*/
|
|
36
|
+
export declare function expandBindingClosure(computedBindings: {
|
|
37
|
+
[k: string]: string;
|
|
38
|
+
} | undefined, roots: string[]): Map<string, number>;
|
|
39
|
+
/** The bindings a field writes. Group/Instruction fields have none. */
|
|
40
|
+
export declare function fieldBindings(field: BluepicField): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Score one element against one field. Returns `null` when nothing matched.
|
|
43
|
+
* The score is the STRONGEST single property match, not a sum — an element
|
|
44
|
+
* whose text is bound to the field shouldn't outrank a sibling merely by also
|
|
45
|
+
* borrowing the same value for its opacity.
|
|
46
|
+
*/
|
|
47
|
+
export declare function scoreElement(field: BluepicField, element: Template.Element, hopsByBinding: Map<string, number>): {
|
|
48
|
+
score: number;
|
|
49
|
+
matchedProperties: string[];
|
|
50
|
+
} | null;
|
|
51
|
+
/**
|
|
52
|
+
* The elements a field drives, best first, already cut to the candidates worth
|
|
53
|
+
* drawing a hitbox for.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveFieldElements(serial: Template.Serial, field: BluepicField): FieldElementMatch[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text geometry on the canvas: where the caret is, what the selection covers,
|
|
3
|
+
* and which character a point lands on.
|
|
4
|
+
*
|
|
5
|
+
* All three answers come from the glyphs the engine actually laid out, via
|
|
6
|
+
* `SVGTextContentElement`:
|
|
7
|
+
* `getStartPositionOfChar` / `getEndPositionOfChar` — caret and range edges
|
|
8
|
+
* `getExtentOfChar` — line height / em box
|
|
9
|
+
* `getCharNumAtPosition` — point → character
|
|
10
|
+
* plus the tspan's computed `fill` for colour. Verified against a live 0.2.65
|
|
11
|
+
* sandbox: hit-testing along a line returned the exact character at each
|
|
12
|
+
* position and −1 outside.
|
|
13
|
+
*
|
|
14
|
+
* ONE probe with an `op` rather than three: it ships as SOURCE TEXT (see the
|
|
15
|
+
* warning on `fieldHitboxProbe`), so helpers cannot be shared between separate
|
|
16
|
+
* probe functions — they would have to be duplicated inside each one. The line
|
|
17
|
+
* mapping below is subtle enough that having two copies drift apart is a real
|
|
18
|
+
* risk, so the ops share one body.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* A caret as a SEGMENT rather than a point plus a height.
|
|
22
|
+
*
|
|
23
|
+
* Both ends are computed in the line's local space and mapped out, so the
|
|
24
|
+
* segment carries the text's rotation, skew and scale intrinsically. Returning
|
|
25
|
+
* `{x, y, height}` instead forced the consumer to subtract the ascent in SERIAL
|
|
26
|
+
* y — which is only "up" for unrotated text, and left carets and handle stems
|
|
27
|
+
* standing vertically through slanted text.
|
|
28
|
+
*/
|
|
29
|
+
export type CaretGeometry = {
|
|
30
|
+
/** Top of the em box, in serial coordinates. */
|
|
31
|
+
top: {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
};
|
|
35
|
+
/** Bottom of the em box, in serial coordinates. */
|
|
36
|
+
bottom: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
};
|
|
40
|
+
/** Resolved text colour, so the caret matches the words it sits in. */
|
|
41
|
+
color: string;
|
|
42
|
+
lineIndex: number;
|
|
43
|
+
};
|
|
44
|
+
/** One selected run on one line, as a quad so rotated text still works. */
|
|
45
|
+
export type SelectionQuad = {
|
|
46
|
+
points: Array<{
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
}>;
|
|
50
|
+
lineIndex: number;
|
|
51
|
+
};
|
|
52
|
+
export type TextGeometryResult = {
|
|
53
|
+
found: false;
|
|
54
|
+
} | {
|
|
55
|
+
found: true;
|
|
56
|
+
/** Present only when the selection is collapsed — a caret, not a range. */
|
|
57
|
+
caret?: CaretGeometry;
|
|
58
|
+
selection: SelectionQuad[];
|
|
59
|
+
/** Range ends, for the mobile drag handles. Present when a range exists. */
|
|
60
|
+
startAnchor?: CaretGeometry;
|
|
61
|
+
endAnchor?: CaretGeometry;
|
|
62
|
+
};
|
|
63
|
+
export type TextIndexResult = {
|
|
64
|
+
index: number | null;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* ⚠️ SHIPPED AS SOURCE TEXT — no imports, no module-scope references, plain ES.
|
|
68
|
+
*
|
|
69
|
+
* @param argsJson `{ op, elementId, value, selectionStart, selectionEnd, x, y }`
|
|
70
|
+
*/
|
|
71
|
+
export declare function textGeometryProbe(argsJson: string): TextGeometryResult | TextIndexResult;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { BluepicField } from '@bluepic/types';
|
|
3
|
+
import { type CaretGeometry, type SelectionQuad } from './textProbe';
|
|
4
|
+
type EvaluateFn = (func: Function, ...args: string[]) => Promise<unknown>;
|
|
5
|
+
export type CanvasTextState = {
|
|
6
|
+
caret?: CaretGeometry;
|
|
7
|
+
selection: SelectionQuad[];
|
|
8
|
+
startAnchor?: CaretGeometry;
|
|
9
|
+
endAnchor?: CaretGeometry;
|
|
10
|
+
};
|
|
11
|
+
export type SelectionHandle = 'start' | 'end';
|
|
12
|
+
export declare function useCanvasTextEditing(options: {
|
|
13
|
+
evaluate: () => EvaluateFn | undefined;
|
|
14
|
+
data: Ref<{
|
|
15
|
+
[k: string]: unknown;
|
|
16
|
+
}>;
|
|
17
|
+
}): {
|
|
18
|
+
state: Ref<{
|
|
19
|
+
caret?: {
|
|
20
|
+
top: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
bottom: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
color: string;
|
|
29
|
+
lineIndex: number;
|
|
30
|
+
} | undefined;
|
|
31
|
+
selection: {
|
|
32
|
+
points: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
}[];
|
|
36
|
+
lineIndex: number;
|
|
37
|
+
}[];
|
|
38
|
+
startAnchor?: {
|
|
39
|
+
top: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
};
|
|
43
|
+
bottom: {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
};
|
|
47
|
+
color: string;
|
|
48
|
+
lineIndex: number;
|
|
49
|
+
} | undefined;
|
|
50
|
+
endAnchor?: {
|
|
51
|
+
top: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
};
|
|
55
|
+
bottom: {
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
};
|
|
59
|
+
color: string;
|
|
60
|
+
lineIndex: number;
|
|
61
|
+
} | undefined;
|
|
62
|
+
} | undefined, CanvasTextState | {
|
|
63
|
+
caret?: {
|
|
64
|
+
top: {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
};
|
|
68
|
+
bottom: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
color: string;
|
|
73
|
+
lineIndex: number;
|
|
74
|
+
} | undefined;
|
|
75
|
+
selection: {
|
|
76
|
+
points: {
|
|
77
|
+
x: number;
|
|
78
|
+
y: number;
|
|
79
|
+
}[];
|
|
80
|
+
lineIndex: number;
|
|
81
|
+
}[];
|
|
82
|
+
startAnchor?: {
|
|
83
|
+
top: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
};
|
|
87
|
+
bottom: {
|
|
88
|
+
x: number;
|
|
89
|
+
y: number;
|
|
90
|
+
};
|
|
91
|
+
color: string;
|
|
92
|
+
lineIndex: number;
|
|
93
|
+
} | undefined;
|
|
94
|
+
endAnchor?: {
|
|
95
|
+
top: {
|
|
96
|
+
x: number;
|
|
97
|
+
y: number;
|
|
98
|
+
};
|
|
99
|
+
bottom: {
|
|
100
|
+
x: number;
|
|
101
|
+
y: number;
|
|
102
|
+
};
|
|
103
|
+
color: string;
|
|
104
|
+
lineIndex: number;
|
|
105
|
+
} | undefined;
|
|
106
|
+
} | undefined>;
|
|
107
|
+
activeElementId: Ref<string | undefined, string | undefined>;
|
|
108
|
+
isActive: import("vue").ComputedRef<boolean>;
|
|
109
|
+
begin: (next: {
|
|
110
|
+
field: BluepicField;
|
|
111
|
+
elementId: string;
|
|
112
|
+
binding: string;
|
|
113
|
+
input: HTMLInputElement | HTMLTextAreaElement;
|
|
114
|
+
}) => void;
|
|
115
|
+
end: () => void;
|
|
116
|
+
beginSelectionAt: (x: number, y: number) => Promise<void>;
|
|
117
|
+
beginHandleDrag: (handle: SelectionHandle, point: {
|
|
118
|
+
x: number;
|
|
119
|
+
y: number;
|
|
120
|
+
}) => void;
|
|
121
|
+
extendSelectionTo: (x: number, y: number) => Promise<void>;
|
|
122
|
+
endSelectionDrag: () => void;
|
|
123
|
+
selectWordAt: (x: number, y: number) => Promise<void>;
|
|
124
|
+
};
|
|
125
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which hint is highlighted, and which chip is on screen — two answers, because
|
|
3
|
+
* they are not the same question.
|
|
4
|
+
*
|
|
5
|
+
* The OUTLINE follows the pointer exactly: whatever it is over is the element
|
|
6
|
+
* being asked about, and nothing else may be lit.
|
|
7
|
+
*
|
|
8
|
+
* The CHIP cannot, because of where it sits. It is centred on its picture, so
|
|
9
|
+
* reaching it means travelling ACROSS that picture — and pictures nest (a logo,
|
|
10
|
+
* a portrait, a badge over a background), so the trip regularly crosses another
|
|
11
|
+
* hitbox. Handing the chip straight over to whatever the pointer touched on the
|
|
12
|
+
* way pulled it out from under a pointer already aimed at it, and the click
|
|
13
|
+
* landed on the element underneath instead: the upload dialog simply never
|
|
14
|
+
* opened. A chip that has just lost the highlight therefore stays painted (and
|
|
15
|
+
* clickable) for a moment longer.
|
|
16
|
+
*
|
|
17
|
+
* That grace period is not a lifetime: arriving on the chip re-activates it
|
|
18
|
+
* (`activate` from the chip's own `pointerenter`), so it only ever has to
|
|
19
|
+
* outlast the trip.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useChipHighlight({ lingerMs }?: {
|
|
22
|
+
lingerMs?: number;
|
|
23
|
+
}): {
|
|
24
|
+
activeKey: import("vue").Ref<string | undefined, string | undefined>;
|
|
25
|
+
chipShown: (key: string) => boolean;
|
|
26
|
+
activate: (key: string) => void;
|
|
27
|
+
release: (key: string) => boolean;
|
|
28
|
+
reset: () => void;
|
|
29
|
+
};
|