@bluepic/embed 0.4.0-next.146 → 0.4.0-next.148
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 +163 -155
- package/dist/bluepic-embed.umd.js +163 -155
- package/dist/components/TemplateEditor/BxTemplateEditor.vue.d.ts +134 -0
- package/dist/components/TemplateEditor/FieldHintsLayer.vue.d.ts +49 -0
- package/dist/components/TemplateEditor/TemplateView.vue.d.ts +47 -0
- package/dist/embed/embed.d.ts +402 -0
- package/dist/main.cjs +91 -83
- package/dist/main.mjs +25034 -24533
- package/dist/style.css +1 -1
- package/dist/util/fieldHints/chipAction.d.ts +23 -0
- package/dist/util/fieldHints/fieldFocus.d.ts +1 -1
- package/dist/util/fieldHints/index.d.ts +8 -2
- package/dist/util/fieldHints/placement.d.ts +15 -0
- package/dist/util/fieldHints/textProbe.d.ts +71 -0
- package/dist/util/fieldHints/useCanvasTextEditing.d.ts +125 -0
- package/dist/util/fieldHints/useFieldHitboxes.d.ts +1 -152
- package/dist/util/fields.d.ts +0 -16
- package/package.json +2 -2
- package/dist/util/fieldHints/interact.d.ts +0 -21
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BluepicField } from '@bluepic/types';
|
|
2
|
+
/**
|
|
3
|
+
* What clicking a hint chip does.
|
|
4
|
+
*
|
|
5
|
+
* There is no per-field hint MODE any more — hints are simply on or off for the
|
|
6
|
+
* whole campaign (`config.hints.enabled`). What a chip does is inferred from the
|
|
7
|
+
* field itself:
|
|
8
|
+
*
|
|
9
|
+
* - `upload` — an image field that accepts a device upload. Clicking goes
|
|
10
|
+
* straight to its own upload flow, which is the only thing anyone wants from
|
|
11
|
+
* an image chip.
|
|
12
|
+
* - `focus` — everything else, including image fields restricted to libraries.
|
|
13
|
+
* The chip scrolls the field into view and focuses its control, so the next
|
|
14
|
+
* keystroke already types into it.
|
|
15
|
+
*/
|
|
16
|
+
export type ChipAction = 'upload' | 'focus';
|
|
17
|
+
/**
|
|
18
|
+
* `field.props` entries may be author expressions (functions) rather than
|
|
19
|
+
* literals, so a prop can only be read through the host's evaluator — the same
|
|
20
|
+
* `wrapFieldProps` treatment `FieldsList` gives every field component.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readFieldProp<T>(value: T | (() => T), evaluate?: (fn: Function) => unknown): T | undefined;
|
|
23
|
+
export declare function chipActionFor(field: BluepicField, evaluate?: (fn: Function) => unknown): ChipAction;
|
|
@@ -49,7 +49,7 @@ export declare const FIELD_FOCUS_FLASH_CLASS = "bx-field-hint-target";
|
|
|
49
49
|
* container, and centering yanks the whole list even when the target was
|
|
50
50
|
* already comfortably visible.
|
|
51
51
|
*/
|
|
52
|
-
export declare function revealFieldElement(el: HTMLElement | null | undefined):
|
|
52
|
+
export declare function revealFieldElement(el: HTMLElement | null | undefined): HTMLElement | undefined;
|
|
53
53
|
/**
|
|
54
54
|
* Creates the desktop half: a registry keyed by the field object itself.
|
|
55
55
|
*
|
|
@@ -9,7 +9,13 @@ export type { FieldHitbox } from './useFieldHitboxes';
|
|
|
9
9
|
export { useHintReveal } from './useHintReveal';
|
|
10
10
|
export { createFieldElementRegistry, provideFieldFocus, revealFieldElement, useFieldFocus, FIELD_FOCUS_KEY, FIELD_FOCUS_FLASH_CLASS, } from './fieldFocus';
|
|
11
11
|
export type { FieldFocusController } from './fieldFocus';
|
|
12
|
-
export {
|
|
13
|
-
export type {
|
|
12
|
+
export { chipActionFor, readFieldProp } from './chipAction';
|
|
13
|
+
export type { ChipAction } from './chipAction';
|
|
14
|
+
export { textGeometryProbe } from './textProbe';
|
|
15
|
+
export type { CaretGeometry, SelectionQuad, TextGeometryResult, TextIndexResult } from './textProbe';
|
|
16
|
+
export { useCanvasTextEditing } from './useCanvasTextEditing';
|
|
17
|
+
export type { CanvasTextState, SelectionHandle } from './useCanvasTextEditing';
|
|
18
|
+
export { chooseChipPlacement, chipIsCentered, estimateChipWidth, arrowRotationForSide } from './placement';
|
|
19
|
+
export type { ChipSide, PlacementResult } from './placement';
|
|
14
20
|
export { useFieldActivator } from './fieldFocus';
|
|
15
21
|
export type { FieldActivator } from './fieldFocus';
|
|
@@ -55,3 +55,18 @@ export declare function chooseChipPlacement(input: PlacementInput): PlacementRes
|
|
|
55
55
|
* guess here would place the first paint visibly wrong.
|
|
56
56
|
*/
|
|
57
57
|
export declare function estimateChipWidth(label: string, max?: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* The arrow artwork points RIGHT at rest — the path's tip is authored on the
|
|
60
|
+
* left, but `popoverArrow`'s outer `matrix(-1,0,-0,-1,...)` flips it. Verified
|
|
61
|
+
* by rasterising the mask: the left edge is ~97% covered (the flat base) and
|
|
62
|
+
* the right edge ~4% (the point).
|
|
63
|
+
*/
|
|
64
|
+
export declare const ARROW_NATIVE_DIRECTION: {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Degrees to rotate the arrow so it points from the chip back at its hitbox.
|
|
70
|
+
* CSS rotation is clockwise with y pointing down.
|
|
71
|
+
*/
|
|
72
|
+
export declare function arrowRotationForSide(side: ChipSide): number;
|
|
@@ -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 {};
|