@bluepic/embed 0.4.0-next.145 → 0.4.0-next.146

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.
@@ -0,0 +1,57 @@
1
+ import type { BluepicField } from '@bluepic/types';
2
+ /**
3
+ * Where a hint chip sits relative to its hitbox.
4
+ *
5
+ * Deliberately a small synchronous solver rather than `@floating-ui`, which
6
+ * this package already depends on: hints re-project on EVERY pan/zoom frame,
7
+ * and floating-ui's `computePosition` is async and DOM-measuring. Running one
8
+ * per hint per frame would lag the overlay behind the canvas it is annotating.
9
+ * A pure function over numbers also means the placement rules can be tested
10
+ * without a DOM.
11
+ */
12
+ export type ChipSide = 'top' | 'bottom' | 'left' | 'right';
13
+ export type Rect = {
14
+ x: number;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ };
19
+ export type PlacementInput = {
20
+ /** Hitbox AABB in overlay pixels. */
21
+ box: Rect;
22
+ /** Measured (or estimated) chip size. */
23
+ chip: {
24
+ width: number;
25
+ height: number;
26
+ };
27
+ /** Visible overlay area. */
28
+ viewport: {
29
+ width: number;
30
+ height: number;
31
+ };
32
+ /** Distance from the hitbox edge to the chip edge — room for the arrow. */
33
+ gap: number;
34
+ /** Keep-inside-the-viewport padding. */
35
+ margin: number;
36
+ };
37
+ export type PlacementResult = {
38
+ side: ChipSide;
39
+ /** Chip top-left in overlay pixels. */
40
+ x: number;
41
+ y: number;
42
+ /**
43
+ * Arrow tip anchor, RELATIVE to the chip's top-left. Tracks the hitbox centre
44
+ * even after the chip has been shifted to stay on screen — otherwise a
45
+ * clamped chip would point at empty space.
46
+ */
47
+ arrowX: number;
48
+ arrowY: number;
49
+ };
50
+ export declare function chipIsCentered(fieldType: BluepicField['type']): boolean;
51
+ export declare function chooseChipPlacement(input: PlacementInput): PlacementResult;
52
+ /**
53
+ * Chip width before the real element has been measured. Only used for the very
54
+ * first frame — the layer measures the rendered chip and re-solves — but a wild
55
+ * guess here would place the first paint visibly wrong.
56
+ */
57
+ export declare function estimateChipWidth(label: string, max?: number): number;
@@ -35,6 +35,17 @@ export type ElementQuad = {
35
35
  */
36
36
  dataId: string;
37
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;
38
49
  };
39
50
  export type HitboxProbeResult = {
40
51
  supported: false;
@@ -23,6 +23,18 @@ export type FieldHitbox = {
23
23
  width: number;
24
24
  height: number;
25
25
  };
26
+ /**
27
+ * What a tooltip should POINT AT — the text's own glyph box when the painted
28
+ * box is larger (text with a surface bar), otherwise identical to `aabb`.
29
+ * The hover region stays `quad`; only the anchor tightens.
30
+ */
31
+ anchorQuad: HintQuad;
32
+ anchorAABB: {
33
+ x: number;
34
+ y: number;
35
+ width: number;
36
+ height: number;
37
+ };
26
38
  /** 1-based, matching the `field.frameIndex` convention. */
27
39
  frameIndex: number;
28
40
  score: number;
@@ -2859,6 +2871,25 @@ export declare function useFieldHitboxes(options: {
2859
2871
  width: number;
2860
2872
  height: number;
2861
2873
  };
2874
+ anchorQuad: [{
2875
+ x: number;
2876
+ y: number;
2877
+ }, {
2878
+ x: number;
2879
+ y: number;
2880
+ }, {
2881
+ x: number;
2882
+ y: number;
2883
+ }, {
2884
+ x: number;
2885
+ y: number;
2886
+ }];
2887
+ anchorAABB: {
2888
+ x: number;
2889
+ y: number;
2890
+ width: number;
2891
+ height: number;
2892
+ };
2862
2893
  frameIndex: number;
2863
2894
  score: number;
2864
2895
  elementOrder: number;
@@ -5681,6 +5712,25 @@ export declare function useFieldHitboxes(options: {
5681
5712
  width: number;
5682
5713
  height: number;
5683
5714
  };
5715
+ anchorQuad: [{
5716
+ x: number;
5717
+ y: number;
5718
+ }, {
5719
+ x: number;
5720
+ y: number;
5721
+ }, {
5722
+ x: number;
5723
+ y: number;
5724
+ }, {
5725
+ x: number;
5726
+ y: number;
5727
+ }];
5728
+ anchorAABB: {
5729
+ x: number;
5730
+ y: number;
5731
+ width: number;
5732
+ height: number;
5733
+ };
5684
5734
  frameIndex: number;
5685
5735
  score: number;
5686
5736
  elementOrder: number;
@@ -1,6 +1,6 @@
1
1
  import { type Ref } from 'vue';
2
2
  export declare function useHintReveal(enabled: Ref<boolean>): {
3
- revealed: Ref<boolean, boolean>;
3
+ revealed: import("vue").ComputedRef<boolean>;
4
4
  hide: () => void;
5
5
  onPointerEnter: (event: PointerEvent) => void;
6
6
  onPointerLeave: (event: PointerEvent) => void;
@@ -20,9 +20,9 @@ export declare function groupTemplatesByName(templates: {
20
20
  dpi?: number | undefined;
21
21
  canvases?: {
22
22
  id: string;
23
- label: string;
24
23
  width: number;
25
24
  height: number;
25
+ label?: string | undefined;
26
26
  preview?: string | null | undefined;
27
27
  }[] | undefined;
28
28
  };
@@ -57,9 +57,9 @@ export declare function groupPortalItemsByCategory(templates: {
57
57
  dpi?: number | undefined;
58
58
  canvases?: {
59
59
  id: string;
60
- label: string;
61
60
  width: number;
62
61
  height: number;
62
+ label?: string | undefined;
63
63
  preview?: string | null | undefined;
64
64
  }[] | undefined;
65
65
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The popover/tooltip arrow artwork, shared by everything that needs to point
3
+ * at something.
4
+ *
5
+ * The arrow isn't a CSS triangle: it has a rounded tip and flared sides, drawn
6
+ * as an SVG path, and it renders as TWO masked layers — a fill layer tinted
7
+ * with the surface colour, and a border layer tinted with the border colour,
8
+ * built from an outline-only mask so the arrow's outline continues the
9
+ * bubble's. That's what makes it read as part of the bubble rather than a
10
+ * triangle stuck to it.
11
+ *
12
+ * The shape is authored pointing LEFT. Every other direction is a CSS rotation
13
+ * of the same mask at the call site, so there is one source of truth for the
14
+ * geometry and callers only own their placement.
15
+ *
16
+ * Extracted from `PopoverElement.vue` so the field-hint overlay can reuse the
17
+ * same arrow instead of growing a second, subtly different one.
18
+ */
19
+ declare const ARROW_VIEWBOX: readonly [0, 0, 540, 810];
20
+ /** Outer silhouette — the arrow as the reader sees it. */
21
+ declare const ARROW_SHAPE = "\n<g transform=\"matrix(-1,0,-0,-1,539.059,810)\">\n <path d=\"M11.046,422.072C-6.191,410.25 -0.941,397.5 11.046,387.928L539.059,0L539.059,810L11.046,422.072Z\"/>\n</g>\n";
22
+ /**
23
+ * Slightly inset copy of the silhouette. Subtracting it from the outer shape
24
+ * leaves a constant-width outline — the border layer. A plain stroke would
25
+ * thicken unevenly around the curved tip.
26
+ */
27
+ declare const ARROW_INNER_SHAPE = "\n<g transform=\"matrix(-0.926069,0,-0,-0.926069,499.205868,780.057974)\">\n <path d=\"M0.498,414.688C-13.575,404.976 -4.105,398.555 4.717,392.147L539.059,0L539.059,810L0.498,414.688Z\"/>\n</g>\n";
28
+ declare const ARROW_STROKE_WIDTH = 100;
29
+ /** `mask-image` value for the arrow's filled body. */
30
+ export declare function popoverArrowMaskImage(): string;
31
+ /** `mask-image` value for the arrow's outline. */
32
+ export declare function popoverArrowBorderMaskImage(): string;
33
+ export { ARROW_VIEWBOX, ARROW_SHAPE, ARROW_INNER_SHAPE, ARROW_STROKE_WIDTH };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluepic/embed",
3
- "version": "0.4.0-next.145",
3
+ "version": "0.4.0-next.146",
4
4
  "description": "Bluepic embed sdk",
5
5
  "type": "module",
6
6
  "sideEffects": false,