@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.
Files changed (87) hide show
  1. package/dist/bluepic-embed.iife.js +402 -178
  2. package/dist/bluepic-embed.umd.js +402 -178
  3. package/dist/components/AssetViewer/AssetViewer.vue.d.ts +71 -0
  4. package/dist/components/BxAudioPlayButton.vue.d.ts +24 -0
  5. package/dist/components/BxCard.vue.d.ts +35 -0
  6. package/dist/components/BxInput.vue.d.ts +7 -1
  7. package/dist/components/BxList.vue.d.ts +9 -0
  8. package/dist/components/BxListItem.vue.d.ts +13 -1
  9. package/dist/components/BxPopover.vue.d.ts +7 -0
  10. package/dist/components/BxPreviewLayer.vue.d.ts +18 -0
  11. package/dist/components/BxScrollbar.vue.d.ts +7 -0
  12. package/dist/components/BxSelect.vue.d.ts +16 -2
  13. package/dist/components/BxTable.vue.d.ts +109 -0
  14. package/dist/components/BxTabs.vue.d.ts +7 -0
  15. package/dist/components/BxWaveformThumb.vue.d.ts +27 -0
  16. package/dist/components/CollectionFieldPopup.vue.d.ts +4 -0
  17. package/dist/components/PopoverElement.vue.d.ts +10 -1
  18. package/dist/components/TemplateEditor/BatchCell.vue.d.ts +18 -0
  19. package/dist/components/TemplateEditor/BatchEditor.vue.d.ts +264 -0
  20. package/dist/components/TemplateEditor/BatchExportPopup.vue.d.ts +68 -0
  21. package/dist/components/TemplateEditor/BatchImportPopup.vue.d.ts +25 -0
  22. package/dist/components/TemplateEditor/BxLiveTemplate.vue.d.ts +8 -0
  23. package/dist/components/TemplateEditor/BxTemplateEditor.vue.d.ts +285 -16
  24. package/dist/components/TemplateEditor/FieldHintsLayer.vue.d.ts +86 -0
  25. package/dist/components/TemplateEditor/TemplateView.vue.d.ts +77 -2
  26. package/dist/components/User/UserInfo.vue.d.ts +12 -1
  27. package/dist/components/directives/usePopup.d.ts +5 -0
  28. package/dist/components/fields/Collection.vue.d.ts +3 -0
  29. package/dist/components/fields/Image.vue.d.ts +19 -5
  30. package/dist/components/fields/ImageEdit.vue.d.ts +6 -1
  31. package/dist/components/fields/Text.vue.d.ts +1 -1
  32. package/dist/embed/embed.d.ts +1024 -228
  33. package/dist/{index-CWm6zOv7.js → index-C99_zLhc.js} +9 -9
  34. package/dist/index-D8N6IfRw.cjs +1 -0
  35. package/dist/main.cjs +240 -162
  36. package/dist/main.d.ts +20 -0
  37. package/dist/main.mjs +79043 -68465
  38. package/dist/markdown-it-5-ieF6Bh.js +3790 -0
  39. package/dist/markdown-it-CLB5Jta6.cjs +16 -0
  40. package/dist/postal-mime-Df-WB8Vq.js +3337 -0
  41. package/dist/postal-mime-_7WF5UBe.cjs +28 -0
  42. package/dist/style.css +1 -1
  43. package/dist/theme/bridge.d.ts +14 -0
  44. package/dist/theme/color.d.ts +80 -0
  45. package/dist/theme/css.d.ts +8 -0
  46. package/dist/theme/index.d.ts +19 -0
  47. package/dist/theme/legacy.d.ts +3 -0
  48. package/dist/theme/resolve.d.ts +10 -0
  49. package/dist/theme/tokens.d.ts +129 -0
  50. package/dist/theme/types-contract.d.ts +13 -0
  51. package/dist/theme.cjs +1 -0
  52. package/dist/theme.mjs +1313 -0
  53. package/dist/util/assetAuth.d.ts +35 -0
  54. package/dist/util/audioPreview.d.ts +8 -0
  55. package/dist/util/batch/csv.d.ts +58 -0
  56. package/dist/util/batch/export.d.ts +92 -0
  57. package/dist/util/batch/fields.d.ts +22 -0
  58. package/dist/util/batch/parseCSV.d.ts +72 -0
  59. package/dist/util/batch/useBatchRows.d.ts +67 -0
  60. package/dist/util/cloneDeep.d.ts +5 -5
  61. package/dist/util/cloudflareImages.d.ts +8 -1
  62. package/dist/util/contextCapture.d.ts +19 -0
  63. package/dist/util/export.d.ts +65 -18
  64. package/dist/util/fieldHints/chipAction.d.ts +23 -0
  65. package/dist/util/fieldHints/fieldFocus.d.ts +81 -0
  66. package/dist/util/fieldHints/geometry.d.ts +52 -0
  67. package/dist/util/fieldHints/index.d.ts +20 -0
  68. package/dist/util/fieldHints/probe.d.ts +84 -0
  69. package/dist/util/fieldHints/resolve.d.ts +55 -0
  70. package/dist/util/fieldHints/textProbe.d.ts +71 -0
  71. package/dist/util/fieldHints/useCanvasTextEditing.d.ts +125 -0
  72. package/dist/util/fieldHints/useChipHighlight.d.ts +29 -0
  73. package/dist/util/fieldHints/useFieldHitboxes.d.ts +5601 -0
  74. package/dist/util/fieldHints/useHintReveal.d.ts +10 -0
  75. package/dist/util/fieldTree.d.ts +20 -0
  76. package/dist/util/fields.d.ts +1 -1
  77. package/dist/util/gallery.d.ts +78 -30
  78. package/dist/util/popoverArrow.d.ts +33 -0
  79. package/dist/util/popupHeaderTools.d.ts +26 -0
  80. package/dist/util/scrollPassthrough.d.ts +9 -0
  81. package/dist/util/useTheme.d.ts +36 -1
  82. package/dist/util/visualViewport.d.ts +47 -0
  83. package/dist/xlsx-BopDBbWb.js +24176 -0
  84. package/dist/xlsx-qn1xoUuv.cjs +105 -0
  85. package/package.json +18 -5
  86. package/dist/index-DFXQWOGQ.cjs +0 -1
  87. package/dist/util/backgroundRemoval.d.ts +0 -51
@@ -0,0 +1,10 @@
1
+ import { type Ref } from 'vue';
2
+ export declare function useHintReveal(enabled: Ref<boolean>): {
3
+ revealed: import("vue").ComputedRef<boolean>;
4
+ reveal: () => void;
5
+ onPointerEnter: (event: PointerEvent) => void;
6
+ onPointerMove: (event: PointerEvent) => void;
7
+ onPointerLeave: (event: PointerEvent) => void;
8
+ onPointerDown: (event: PointerEvent) => void;
9
+ onPointerUp: (event: PointerEvent) => void;
10
+ };
@@ -0,0 +1,20 @@
1
+ import type { BluepicField } from '@bluepic/types';
2
+ /**
3
+ * Pure field-tree walks, deliberately kept OUT of `./fields.ts`.
4
+ *
5
+ * `fields.ts` imports the per-type icon components, so importing anything from
6
+ * it drags a dozen Vue SFCs along — fine in the browser bundle, fatal for any
7
+ * consumer that runs outside Vite (Node tests, headless tooling). These
8
+ * functions are plain logic over the field tree and have no such need.
9
+ *
10
+ * `fields.ts` re-exports `flattenFieldTable` so existing imports keep working.
11
+ */
12
+ /**
13
+ * Every LEAF field, in document order. `Group` is pure presentation — it holds
14
+ * no binding of its own — so it is flattened away rather than returned.
15
+ *
16
+ * `Collection` is NOT descended into: its nested `props.fields` are the
17
+ * per-item template, not fields with live bindings, while the Collection field
18
+ * itself does carry a `modelValue`. So it is returned as the leaf it behaves as.
19
+ */
20
+ export declare function flattenFieldTable(fields: BluepicField[]): BluepicField[];
@@ -10,7 +10,7 @@ export declare function modelField(model: BluepicField['model'], data: Ref<{
10
10
  [x: string]: unknown;
11
11
  };
12
12
  export declare function flattenFields(fields: BluepicField[]): MobileFieldsSlide[];
13
- export declare function flattenFieldTable(fields: BluepicField[]): BluepicField[];
13
+ export { flattenFieldTable } from './fieldTree';
14
14
  export declare function useMobileFields(fields: Ref<BluepicField[]>): {
15
15
  mobileFields: import("vue").ComputedRef<{
16
16
  originalField: BluepicFieldGroup | undefined;
@@ -1,47 +1,95 @@
1
1
  import { Studio } from '@bluepic/types';
2
2
  import { z } from '@hono/zod-openapi';
3
+ /**
4
+ * A multi-canvas template (canvases v2) is ATOMIC in the gallery: its canvases
5
+ * ARE its format variants, so it never merges with same-named templates — and
6
+ * two multi-canvas templates sharing a name stay two cards. Single-format
7
+ * templates keep merging by name exactly as before.
8
+ */
9
+ export declare function isMultiCanvasTemplateDescriptor(td: Pick<z.infer<typeof Studio.publicTemplateDescriptor>, 'canvases'>): boolean;
3
10
  export declare function groupTemplatesByName(templates: {
4
11
  [k: string]: z.infer<typeof Studio.publicTemplateDescriptor>;
5
12
  }): {
6
13
  [k: string]: {
7
- [k: string]: z.infer<z.ZodObject<{
8
- serial: z.ZodNullable<z.ZodAny>;
9
- preview: z.ZodNullable<z.ZodString>;
10
- name: z.ZodString;
11
- width: z.ZodNumber;
12
- height: z.ZodNumber;
13
- category: z.ZodNullable<z.ZodString>;
14
- dpi: z.ZodOptional<z.ZodNumber>;
15
- }, z.core.$strip>>;
14
+ [k: string]: {
15
+ serial: any;
16
+ preview: string | null;
17
+ name: string;
18
+ width: number;
19
+ height: number;
20
+ dpi?: number | undefined;
21
+ canvases?: {
22
+ id: string;
23
+ width: number;
24
+ height: number;
25
+ label?: string | undefined;
26
+ preview?: string | null | undefined;
27
+ }[] | undefined;
28
+ };
16
29
  };
17
30
  };
31
+ export declare const OTHER_CATEGORY = "Other";
32
+ export type PortalAsset = z.infer<typeof Studio.publicCampaignAssetDescriptor>;
33
+ export type CampaignCategory = Studio.CampaignCategory;
18
34
  /**
19
- * A campaign-level template→category override map (`config.categories`), keyed
20
- * by TEMPLATE ID. When an entry exists for a template it wins over the
21
- * template's own `category`; templates with no entry fall back to their
22
- * descriptor category. `undefined`/empty categories collapse into "Other".
35
+ * The one ordering for portal assets — alphabetical by title, same as the
36
+ * campaign editor. Used both within a category bucket and for the flat,
37
+ * uncategorised list, so toggling "sort by categories" only changes GROUPING,
38
+ * never the relative order of two given assets.
23
39
  */
24
- export type CampaignCategories = {
25
- [templateId: string]: string;
26
- } | undefined;
27
- export declare function collectTemplatesCategories(templates: {
28
- [k: string]: z.infer<typeof Studio.publicTemplateDescriptor>;
29
- }, overrides?: CampaignCategories): string[];
30
- export declare function groupTemplatesByCategory(templates: {
40
+ export declare function sortPortalAssetsByTitle(assets: PortalAsset[]): PortalAsset[];
41
+ /**
42
+ * Group templates AND assets by the campaign's categories.
43
+ *
44
+ * Takes the CONVERTED category array — `Studio.convertCampaign` has already run
45
+ * at the boundary — so there is no shape-guessing here, no legacy record, and
46
+ * no separate order field: array position IS the order.
47
+ *
48
+ * Anything no category claims falls into "Other", which always renders last.
49
+ * Categories that end up empty are dropped: an empty category is legitimate
50
+ * while editing, but not something to render a tab for.
51
+ */
52
+ export declare function groupPortalItemsByCategory(templates: {
31
53
  [k: string]: z.infer<typeof Studio.publicTemplateDescriptor>;
32
- }, overrides?: CampaignCategories): {
54
+ }, assets: PortalAsset[] | undefined, categories: CampaignCategory[] | undefined): {
33
55
  category: string;
34
56
  templatesByName: {
35
57
  [k: string]: {
36
- [k: string]: z.infer<z.ZodObject<{
37
- serial: z.ZodNullable<z.ZodAny>;
38
- preview: z.ZodNullable<z.ZodString>;
39
- name: z.ZodString;
40
- width: z.ZodNumber;
41
- height: z.ZodNumber;
42
- category: z.ZodNullable<z.ZodString>;
43
- dpi: z.ZodOptional<z.ZodNumber>;
44
- }, z.core.$strip>>;
58
+ [k: string]: {
59
+ serial: any;
60
+ preview: string | null;
61
+ name: string;
62
+ width: number;
63
+ height: number;
64
+ dpi?: number | undefined;
65
+ canvases?: {
66
+ id: string;
67
+ width: number;
68
+ height: number;
69
+ label?: string | undefined;
70
+ preview?: string | null | undefined;
71
+ }[] | undefined;
72
+ };
45
73
  };
46
74
  };
75
+ assets: {
76
+ id: string;
77
+ kind: "image" | "file";
78
+ title: string;
79
+ description: string | null;
80
+ category: string | null;
81
+ mime: string;
82
+ size: number;
83
+ filename: string;
84
+ previewUrl: string | null;
85
+ downloadUrl: string;
86
+ width?: number | undefined;
87
+ height?: number | undefined;
88
+ pageCount?: number | undefined;
89
+ documentUrl?: string | undefined;
90
+ }[];
47
91
  }[];
92
+ /** The category strip: only labels that actually have something in them. */
93
+ export declare function collectPortalCategories(templates: {
94
+ [k: string]: z.infer<typeof Studio.publicTemplateDescriptor>;
95
+ }, assets: PortalAsset[] | undefined, categories: CampaignCategory[] | undefined): string[];
@@ -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 };
@@ -0,0 +1,26 @@
1
+ import { type InjectionKey, type Ref } from 'vue';
2
+ /**
3
+ * A channel for putting controls INTO the popup's own header.
4
+ *
5
+ * A popup owns its header — title, actions, close button — while the thing
6
+ * rendered inside it owns the state those actions act on. The asset viewer's
7
+ * Preview/Source switch is the case in point: it belongs visually beside the
8
+ * Download button, but the text it copies and the view it toggles live in the
9
+ * viewer, three levels down.
10
+ *
11
+ * Rather than lift that state into every host that opens a popup, the popup
12
+ * publishes the header's action container as an element ref and descendants
13
+ * TELEPORT into it. The control renders where it belongs while its state stays
14
+ * where it belongs.
15
+ *
16
+ * Null when there is no popup ancestor — a component using this must keep
17
+ * working standalone, so treat it as "no header available" and render inline.
18
+ */
19
+ export declare const popupHeaderToolsKey: InjectionKey<Ref<HTMLElement | null>>;
20
+ /** Called by the popup itself. Returns the ref to bind to the tools container. */
21
+ export declare function providePopupHeaderTools(): Ref<HTMLElement | null>;
22
+ /**
23
+ * Called by content inside a popup. The returned ref resolves after mount, so
24
+ * teleport with `v-if` on it rather than reading it during setup.
25
+ */
26
+ export declare function usePopupHeaderTools(): Ref<HTMLElement | null>;
@@ -0,0 +1,9 @@
1
+ import { type Ref } from 'vue';
2
+ /**
3
+ * Forward wheel/touch gestures that land on `wrapperRef`'s own backdrop to the
4
+ * app behind it. Gestures over the popover's content are left alone.
5
+ *
6
+ * @param wrapperRef the full-viewport popover wrapper
7
+ * @param enabled re-evaluated on every gesture, so a popover can flip modes
8
+ */
9
+ export declare function useScrollPassthrough(wrapperRef: Ref<HTMLElement | undefined>, enabled: () => boolean): void;
@@ -1,5 +1,40 @@
1
1
  import { z } from '@hono/zod-openapi';
2
2
  import { EmbedV2 } from '@bluepic/types';
3
+ import { Ref, type MaybeRefOrGetter } from 'vue';
4
+ import { type ResolvedTheme, type ThemeInput } from '../theme';
5
+ /**
6
+ * @deprecated Legacy engine. Parses a preset SCSS dump into a flat variable map. Kept only so
7
+ * campaigns without `config.theme` keep rendering exactly as before; new code should use
8
+ * `resolveTheme()` / `useThemeV2()` (theme system v2). Will be removed once no legacy campaigns remain.
9
+ */
3
10
  export declare function getThemeStyle(rawCSS: string): Record<string, string>;
11
+ /** @deprecated Legacy engine — see `getThemeStyle`. Use `resolveTheme({ version: 2, preset })` + `themeToCssText()` instead. */
4
12
  export declare function resolveThemeStyle(theme: 'light' | 'dark' | 'auto'): Record<string, string>;
5
- export declare function useTheme(bluepicAppWrapperSelector?: string, theme?: 'light' | 'dark' | 'auto', customThemeVars?: Partial<z.infer<typeof EmbedV2.customStyleSchema>>, interFontUrl?: string): any;
13
+ export type UseThemeV2Options = {
14
+ /** Selector of the app wrapper (default: GLOBAL_APP_WRAPPER_SELECTOR). */
15
+ wrapperSelector?: string;
16
+ /** Optional @import for the UI font (e.g. Inter). */
17
+ fontUrl?: string;
18
+ /**
19
+ * Legacy `customStyle` snapshot to fall back to when the input is empty — only its
20
+ * surface/primary/contrast are used (see themeInputFromLegacyCustomStyle).
21
+ */
22
+ legacyCustomStyle?: MaybeRefOrGetter<Record<string, string> | null | undefined>;
23
+ };
24
+ /**
25
+ * Reactive v2 theme binding. Re-resolves whenever the input changes and rewrites the SAME
26
+ * style element. Returns the resolved theme (tokens + contrast report) for hosts that want to
27
+ * show it (e.g. the Studio theme step).
28
+ */
29
+ export declare function useThemeV2(input: MaybeRefOrGetter<ThemeInput | null | undefined>, options?: UseThemeV2Options): {
30
+ theme: import("vue").ComputedRef<ResolvedTheme>;
31
+ uid: string;
32
+ };
33
+ /** Imperative one-shot application (no reactivity). */
34
+ export declare function applyTheme(theme: ResolvedTheme, options?: Omit<UseThemeV2Options, 'legacyCustomStyle'>): string;
35
+ /**
36
+ * Legacy API. `customThemeVars` may be a legacy customStyle record (preset snapshot + overrides)
37
+ * or, as of v2, a `ThemeInput` (`{ version: 2, surface, primary, … }`), in which case the new
38
+ * engine is used. The returned ref holds the emitted CSS variables.
39
+ */
40
+ export declare function useTheme(bluepicAppWrapperSelector?: string, theme?: 'light' | 'dark' | 'auto', customThemeVars?: Partial<z.infer<typeof EmbedV2.customStyleSchema>> | ThemeInput, interFontUrl?: string): Ref<Record<string, string>, Record<string, string>>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The on-screen keyboard, as iOS actually reports it.
3
+ *
4
+ * iOS Safari does NOT shrink the layout viewport when the keyboard opens:
5
+ * `window.innerHeight`, `100vh` and even `100dvh` stay exactly as they were
6
+ * (`dvh` tracks the URL bar collapsing, not the keyboard). The only thing that
7
+ * reports the covered space is `visualViewport` — so any layout that has to
8
+ * react to the keyboard has to be driven from JS. There is no CSS-only
9
+ * equivalent on iOS.
10
+ *
11
+ * Android Chrome behaves differently by default (it resizes the layout
12
+ * viewport), which this handles for free: the inset simply computes to ~0
13
+ * because `innerHeight` shrank along with the visual viewport.
14
+ */
15
+ export declare function useVisualViewport(): {
16
+ supported: boolean;
17
+ height: import("vue").Ref<number, number>;
18
+ offsetTop: import("vue").Ref<number, number>;
19
+ keyboardInset: import("vue").Ref<number, number>;
20
+ keyboardOpen: import("vue").Ref<boolean, boolean>;
21
+ };
22
+ /**
23
+ * Scroll the PAGE so `el`'s top edge meets the top of the visible band.
24
+ *
25
+ * Used on an element that has already been sized to FIT the band, so aligning
26
+ * its top is the whole job — there is no "scroll to the field" here. Scrolling
27
+ * to a target inside a box that is about to get shorter is what produced the
28
+ * drift: the scroll landed first and the content then shrank out from under it.
29
+ *
30
+ * Why not `scrollIntoView`: it scrolls every scrollable ancestor, and on the
31
+ * mobile layout one of those is swiper's track — which positions its slides by
32
+ * transform. Scrolling it leaves swiper's own offset wrong and the panel
33
+ * misaligned. Moving the page and nothing else is the whole job.
34
+ *
35
+ * Why not just `focus()` without `preventScroll`: same reason, plus iOS ignores
36
+ * it for a programmatic focus often enough to be useless — which is why the
37
+ * field only jumped into view once the user typed.
38
+ *
39
+ * The keyboard animates over ~250–400ms and fires several `resize` events on
40
+ * the way; we wait for a quiet moment rather than guessing a delay, with a hard
41
+ * stop for the case where no keyboard is coming at all (a hardware keyboard, a
42
+ * desktop browser, a field that opened no keyboard).
43
+ */
44
+ export declare function revealAboveKeyboard(el: HTMLElement | undefined, { margin, hardStopMs }?: {
45
+ margin?: number | undefined;
46
+ hardStopMs?: number | undefined;
47
+ }): void;