@magicpages/kalotyp-ui 0.1.0

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 (110) hide show
  1. package/dist/canvas/position-handles.d.ts +18 -0
  2. package/dist/canvas/position-handles.d.ts.map +1 -0
  3. package/dist/canvas/preview-canvas.d.ts +21 -0
  4. package/dist/canvas/preview-canvas.d.ts.map +1 -0
  5. package/dist/canvas/render-image.d.ts +4 -0
  6. package/dist/canvas/render-image.d.ts.map +1 -0
  7. package/dist/canvas/render-overlay.d.ts +4 -0
  8. package/dist/canvas/render-overlay.d.ts.map +1 -0
  9. package/dist/canvas/stage-gestures.d.ts +12 -0
  10. package/dist/canvas/stage-gestures.d.ts.map +1 -0
  11. package/dist/cheatsheet/modal.d.ts +10 -0
  12. package/dist/cheatsheet/modal.d.ts.map +1 -0
  13. package/dist/dom/build-preset-row.d.ts +10 -0
  14. package/dist/dom/build-preset-row.d.ts.map +1 -0
  15. package/dist/dom/build-shell-dom.d.ts +39 -0
  16. package/dist/dom/build-shell-dom.d.ts.map +1 -0
  17. package/dist/dom/build-stage.d.ts +19 -0
  18. package/dist/dom/build-stage.d.ts.map +1 -0
  19. package/dist/dom/build-util-nav.d.ts +18 -0
  20. package/dist/dom/build-util-nav.d.ts.map +1 -0
  21. package/dist/dom/focus-trap.d.ts +21 -0
  22. package/dist/dom/focus-trap.d.ts.map +1 -0
  23. package/dist/dom/nested-modal.d.ts +25 -0
  24. package/dist/dom/nested-modal.d.ts.map +1 -0
  25. package/dist/icons.d.ts +13 -0
  26. package/dist/icons.d.ts.map +1 -0
  27. package/dist/index.d.ts +61 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +5198 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/keyboard-shortcuts.d.ts +15 -0
  32. package/dist/keyboard-shortcuts.d.ts.map +1 -0
  33. package/dist/output/popover.d.ts +21 -0
  34. package/dist/output/popover.d.ts.map +1 -0
  35. package/dist/plugins/annotate/coord-inputs.d.ts +72 -0
  36. package/dist/plugins/annotate/coord-inputs.d.ts.map +1 -0
  37. package/dist/plugins/annotate/mount.d.ts +40 -0
  38. package/dist/plugins/annotate/mount.d.ts.map +1 -0
  39. package/dist/plugins/annotate/panel.d.ts +43 -0
  40. package/dist/plugins/annotate/panel.d.ts.map +1 -0
  41. package/dist/plugins/annotate/plugin.d.ts +20 -0
  42. package/dist/plugins/annotate/plugin.d.ts.map +1 -0
  43. package/dist/plugins/annotate/pointer-drag.d.ts +41 -0
  44. package/dist/plugins/annotate/pointer-drag.d.ts.map +1 -0
  45. package/dist/plugins/annotate/render.d.ts +46 -0
  46. package/dist/plugins/annotate/render.d.ts.map +1 -0
  47. package/dist/plugins/annotate/selection.d.ts +43 -0
  48. package/dist/plugins/annotate/selection.d.ts.map +1 -0
  49. package/dist/plugins/annotate/stage.d.ts +29 -0
  50. package/dist/plugins/annotate/stage.d.ts.map +1 -0
  51. package/dist/plugins/annotate/text-editor.d.ts +34 -0
  52. package/dist/plugins/annotate/text-editor.d.ts.map +1 -0
  53. package/dist/plugins/annotate/tools.d.ts +46 -0
  54. package/dist/plugins/annotate/tools.d.ts.map +1 -0
  55. package/dist/plugins/crop/interaction.d.ts +17 -0
  56. package/dist/plugins/crop/interaction.d.ts.map +1 -0
  57. package/dist/plugins/crop/mount.d.ts +19 -0
  58. package/dist/plugins/crop/mount.d.ts.map +1 -0
  59. package/dist/plugins/crop/plugin.d.ts +11 -0
  60. package/dist/plugins/crop/plugin.d.ts.map +1 -0
  61. package/dist/plugins/filter/mount.d.ts +16 -0
  62. package/dist/plugins/filter/mount.d.ts.map +1 -0
  63. package/dist/plugins/filter/plugin.d.ts +10 -0
  64. package/dist/plugins/filter/plugin.d.ts.map +1 -0
  65. package/dist/plugins/filter/thumbnails.d.ts +32 -0
  66. package/dist/plugins/filter/thumbnails.d.ts.map +1 -0
  67. package/dist/plugins/finetune/mount.d.ts +16 -0
  68. package/dist/plugins/finetune/mount.d.ts.map +1 -0
  69. package/dist/plugins/finetune/plugin.d.ts +6 -0
  70. package/dist/plugins/finetune/plugin.d.ts.map +1 -0
  71. package/dist/plugins/finetune/preview.d.ts +16 -0
  72. package/dist/plugins/finetune/preview.d.ts.map +1 -0
  73. package/dist/plugins/flip/mount.d.ts +14 -0
  74. package/dist/plugins/flip/mount.d.ts.map +1 -0
  75. package/dist/plugins/flip/plugin.d.ts +6 -0
  76. package/dist/plugins/flip/plugin.d.ts.map +1 -0
  77. package/dist/plugins/frame/mount.d.ts +33 -0
  78. package/dist/plugins/frame/mount.d.ts.map +1 -0
  79. package/dist/plugins/frame/plugin.d.ts +15 -0
  80. package/dist/plugins/frame/plugin.d.ts.map +1 -0
  81. package/dist/plugins/redact/coord-inputs.d.ts +18 -0
  82. package/dist/plugins/redact/coord-inputs.d.ts.map +1 -0
  83. package/dist/plugins/redact/mount.d.ts +26 -0
  84. package/dist/plugins/redact/mount.d.ts.map +1 -0
  85. package/dist/plugins/redact/panel.d.ts +34 -0
  86. package/dist/plugins/redact/panel.d.ts.map +1 -0
  87. package/dist/plugins/redact/plugin.d.ts +14 -0
  88. package/dist/plugins/redact/plugin.d.ts.map +1 -0
  89. package/dist/plugins/redact/render.d.ts +57 -0
  90. package/dist/plugins/redact/render.d.ts.map +1 -0
  91. package/dist/plugins/redact/selection.d.ts +30 -0
  92. package/dist/plugins/redact/selection.d.ts.map +1 -0
  93. package/dist/plugins/redact/stage.d.ts +19 -0
  94. package/dist/plugins/redact/stage.d.ts.map +1 -0
  95. package/dist/plugins/resize/mount.d.ts +21 -0
  96. package/dist/plugins/resize/mount.d.ts.map +1 -0
  97. package/dist/plugins/resize/plugin.d.ts +6 -0
  98. package/dist/plugins/resize/plugin.d.ts.map +1 -0
  99. package/dist/plugins/rotate/mount.d.ts +16 -0
  100. package/dist/plugins/rotate/mount.d.ts.map +1 -0
  101. package/dist/plugins/rotate/plugin.d.ts +6 -0
  102. package/dist/plugins/rotate/plugin.d.ts.map +1 -0
  103. package/dist/preferences/modal.d.ts +24 -0
  104. package/dist/preferences/modal.d.ts.map +1 -0
  105. package/dist/preferences/storage.d.ts +77 -0
  106. package/dist/preferences/storage.d.ts.map +1 -0
  107. package/dist/shell.d.ts +27 -0
  108. package/dist/shell.d.ts.map +1 -0
  109. package/dist/styles.css +1 -0
  110. package/package.json +58 -0
@@ -0,0 +1,18 @@
1
+ import { type CornerHandle, type EdgeHandle, type Rect, type Viewport } from '@magicpages/kalotyp-core';
2
+ /**
3
+ * Position corner anchors, edge handles, and body hit-area to match the crop rect.
4
+ *
5
+ * Corner buttons aren't positioned directly: they live inside an anchor that sits at the
6
+ * corner point, and host CSS (Ghost's `pintura.css` or our `crop.css`) shifts the button
7
+ * by `-20px` so its 20×20 bracket pseudo-element aligns with the corner. Edges are inset
8
+ * by 12px on each end so they don't overlap the corner brackets.
9
+ */
10
+ export interface PositionHandlesInput {
11
+ readonly cropRectImage: Rect;
12
+ readonly viewport: Viewport;
13
+ readonly cornerAnchors: Readonly<Record<CornerHandle, HTMLElement>>;
14
+ readonly edgeHandles: Readonly<Record<EdgeHandle, HTMLElement>>;
15
+ readonly bodyHitArea: HTMLElement;
16
+ }
17
+ export declare function positionHandles(input: PositionHandlesInput): void;
18
+ //# sourceMappingURL=position-handles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-handles.d.ts","sourceRoot":"","sources":["../../src/canvas/position-handles.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CACnC;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CA+BjE"}
@@ -0,0 +1,21 @@
1
+ import { type SourceImage, type Viewport, type ViewportController } from '@magicpages/kalotyp-core';
2
+ declare const STAGE_PADDING_PX = 32;
3
+ export interface PreviewCanvas {
4
+ readonly container: HTMLDivElement;
5
+ readonly canvas: HTMLCanvasElement;
6
+ }
7
+ export declare function buildPreviewCanvas(): PreviewCanvas;
8
+ /** Compute the letterboxed viewport for a preview. Returns `undefined` if the container has no laid-out size yet. */
9
+ export declare function previewViewportFor(container: HTMLElement, intrinsic: {
10
+ width: number;
11
+ height: number;
12
+ }, controller?: ViewportController): {
13
+ viewport: Viewport;
14
+ stageWidth: number;
15
+ stageHeight: number;
16
+ } | undefined;
17
+ /** Paint into a preview canvas. The callback receives a DPR-scaled context positioned at (0,0) in stage CSS pixels. */
18
+ export declare function paintPreview(canvas: HTMLCanvasElement, stageWidth: number, stageHeight: number, draw: (ctx: CanvasRenderingContext2D) => void): void;
19
+ export { STAGE_PADDING_PX };
20
+ export type { SourceImage };
21
+ //# sourceMappingURL=preview-canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-canvas.d.ts","sourceRoot":"","sources":["../../src/canvas/preview-canvas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAExB,MAAM,0BAA0B,CAAC;AAElC,QAAA,MAAM,gBAAgB,KAAK,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAED,wBAAgB,kBAAkB,IAAI,aAAa,CAUlD;AAED,qHAAqH;AACrH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EACtB,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5C,UAAU,CAAC,EAAE,kBAAkB,GAC9B;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQ7E;AAED,uHAAuH;AACvH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,CAAC,GAAG,EAAE,wBAAwB,KAAK,IAAI,GAC5C,IAAI,CAgBN;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Viewport } from '@magicpages/kalotyp-core';
2
+ /** Paint the source image onto the canvas at the viewport's display size, DPR-scaled. */
3
+ export declare function renderImageCanvas(canvas: HTMLCanvasElement, source: CanvasImageSource, stageWidth: number, stageHeight: number, viewport: Viewport): void;
4
+ //# sourceMappingURL=render-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-image.d.ts","sourceRoot":"","sources":["../../src/canvas/render-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,yFAAyF;AACzF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAoBN"}
@@ -0,0 +1,4 @@
1
+ import { type Rect, type Viewport } from '@magicpages/kalotyp-core';
2
+ /** Repaint the overlay: dim mask outside the crop rect, outline, and rule-of-thirds grid. */
3
+ export declare function renderOverlayCanvas(canvas: HTMLCanvasElement, cropRectImage: Rect, stageWidth: number, stageHeight: number, viewport: Viewport): void;
4
+ //# sourceMappingURL=render-overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-overlay.d.ts","sourceRoot":"","sources":["../../src/canvas/render-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAcxF,6FAA6F;AAC7F,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,IAAI,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAyCN"}
@@ -0,0 +1,12 @@
1
+ import type { ViewportController } from '@magicpages/kalotyp-core';
2
+ /**
3
+ * Editor-level wheel + multi-pointer (pinch / two-finger pan) handler driving a `ViewportController`.
4
+ *
5
+ * - Wheel: zoom anchored at the cursor (1.0015 per `deltaY` unit).
6
+ * - Two pointers: pinch + pan applied together each frame (no pinch-vs-pan state machine —
7
+ * applying both feels more natural and matches Snapseed / Apple Photos).
8
+ * - Single pointer: pass-through to plugin gestures.
9
+ */
10
+ export type StageGestureHandle = () => void;
11
+ export declare function attachStageGestures(stage: HTMLElement, controller: ViewportController): StageGestureHandle;
12
+ //# sourceMappingURL=stage-gestures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-gestures.d.ts","sourceRoot":"","sources":["../../src/canvas/stage-gestures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC;AAe5C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,kBAAkB,GAC7B,kBAAkB,CA0HpB"}
@@ -0,0 +1,10 @@
1
+ /** Cheatsheet modal — renders `KEYBOARD_SHORTCUTS` grouped by context. Opened via `?`. */
2
+ export interface OpenCheatsheetOptions {
3
+ readonly host: HTMLElement;
4
+ onClose(): void;
5
+ }
6
+ export interface CheatsheetHandle {
7
+ close(): void;
8
+ }
9
+ export declare function openCheatsheet(options: OpenCheatsheetOptions): CheatsheetHandle;
10
+ //# sourceMappingURL=modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/cheatsheet/modal.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAU1F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,IAAI,CAAC;CACf;AASD,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,gBAAgB,CAsB/E"}
@@ -0,0 +1,10 @@
1
+ import type { CropPreset } from '@magicpages/kalotyp-core';
2
+ export interface PresetRowElements {
3
+ readonly container: HTMLDivElement;
4
+ readonly buttons: readonly HTMLButtonElement[];
5
+ }
6
+ /** Build the aspect-ratio preset row. `activeIndex` indexes into the visible presets passed in. */
7
+ export declare function buildPresetRow(visiblePresets: readonly CropPreset[], activeIndex: number, onSelect: (visibleIndex: number, preset: CropPreset) => void): PresetRowElements;
8
+ /** Update the active state of an existing preset row in place. */
9
+ export declare function setActivePresetButton(buttons: readonly HTMLButtonElement[], activeIndex: number): void;
10
+ //# sourceMappingURL=build-preset-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-preset-row.d.ts","sourceRoot":"","sources":["../../src/dom/build-preset-row.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAChD;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAC5B,cAAc,EAAE,SAAS,UAAU,EAAE,EACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,GAC3D,iBAAiB,CAsBnB;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,WAAW,EAAE,MAAM,GAClB,IAAI,CAIN"}
@@ -0,0 +1,39 @@
1
+ export interface ShellDom {
2
+ readonly editor: HTMLElement;
3
+ readonly modal: HTMLElement;
4
+ readonly root: HTMLElement;
5
+ readonly main: HTMLElement;
6
+ readonly stage: HTMLElement;
7
+ readonly navTools: HTMLElement;
8
+ readonly utilMain: HTMLElement;
9
+ readonly utilFooter: HTMLElement;
10
+ readonly closeButton: HTMLButtonElement;
11
+ /** Gear icon — opens the Preferences modal. */
12
+ readonly prefsButton: HTMLButtonElement;
13
+ readonly exportButton: HTMLButtonElement;
14
+ /** Caret next to Save — opens the output-format popover; the Save button itself bypasses it. */
15
+ readonly outputSettingsButton: HTMLButtonElement;
16
+ /** Visually-hidden polite live region for one-shot announcements. */
17
+ readonly liveRegion: HTMLElement;
18
+ readonly titleId: string;
19
+ }
20
+ export interface BuildShellDomOptions {
21
+ exportLabel: string;
22
+ }
23
+ /**
24
+ * Build the DOM skeleton for an editor session.
25
+ *
26
+ * The editor's own structure is namespaced `kalotyp-*`. Two class tokens are
27
+ * the exception — `pintura-editor` on the host and `PinturaModal` on the modal
28
+ * wrapper. Ghost's runtime looks those up by name (the host class scopes Ghost's
29
+ * theme-variable overrides; the modal class is what Ghost's close-button click
30
+ * handler selects on), so they exist purely for Ghost compatibility — not as
31
+ * branding, and implying no affiliation with or endorsement by the editor Ghost
32
+ * named them after. See `docs/ghost-contract.md`. The integration breaks if
33
+ * those two tokens change.
34
+ *
35
+ * The util-main `aria-labelledby` is updated on tab switch by `setActiveUtilityButton`
36
+ * to complete the tablist/tab/tabpanel triple.
37
+ */
38
+ export declare function buildShellDom(options: BuildShellDomOptions): ShellDom;
39
+ //# sourceMappingURL=build-shell-dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-shell-dom.d.ts","sourceRoot":"","sources":["../../src/dom/build-shell-dom.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,gGAAgG;IAChG,QAAQ,CAAC,oBAAoB,EAAE,iBAAiB,CAAC;IACjD,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;CACrB;AAKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,QAAQ,CAgIrE"}
@@ -0,0 +1,19 @@
1
+ import type { CornerHandle, HandleDirection } from '@magicpages/kalotyp-core';
2
+ export interface StageElements {
3
+ readonly container: HTMLDivElement;
4
+ readonly imageCanvas: HTMLCanvasElement;
5
+ readonly overlayCanvas: HTMLCanvasElement;
6
+ readonly handlesLayer: HTMLDivElement;
7
+ readonly handles: Readonly<Record<HandleDirection, HTMLButtonElement>>;
8
+ /**
9
+ * Per-corner wrapper providing the positioning context Ghost's pintura.css expects:
10
+ * `[data-direction=tr|bl|br] { left/top: -20px !important }` resolves against this
11
+ * anchor, not the stage. Without it three corner buttons end up off-screen.
12
+ */
13
+ readonly cornerAnchors: Readonly<Record<CornerHandle, HTMLDivElement>>;
14
+ /** Body drag surface — under handles, above canvases in z-order. */
15
+ readonly bodyHitArea: HTMLDivElement;
16
+ }
17
+ /** Build the interactive crop UI inside the stage. Class names and data-* come from the Ghost contract. */
18
+ export declare function buildStageElements(): StageElements;
19
+ //# sourceMappingURL=build-stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-stage.d.ts","sourceRoot":"","sources":["../../src/dom/build-stage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAc,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACvE;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;IACvE,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC;AAKD,2GAA2G;AAC3G,wBAAgB,kBAAkB,IAAI,aAAa,CAqDlD"}
@@ -0,0 +1,18 @@
1
+ import type { UtilityId } from '@magicpages/kalotyp-core';
2
+ export interface UtilityNavEntry {
3
+ readonly id: UtilityId;
4
+ readonly label: string;
5
+ }
6
+ export interface UtilityNavElements {
7
+ readonly container: HTMLDivElement;
8
+ readonly buttons: ReadonlyMap<UtilityId, HTMLButtonElement>;
9
+ }
10
+ export interface BuildUtilityNavOptions {
11
+ /** Tabpanel id wired into each tab's `aria-controls` to complete the tablist/tab/tabpanel triple. */
12
+ panelId: string;
13
+ }
14
+ /** Build the utility nav. Roving-tabindex per WAI-ARIA APG: active tab `tabindex=0`, others `-1`; Left/Right/Home/End move active state. */
15
+ export declare function buildUtilityNav(entries: readonly UtilityNavEntry[], initialActive: UtilityId, onSelect: (id: UtilityId) => void, options: BuildUtilityNavOptions): UtilityNavElements;
16
+ /** Update active tab state and scroll the newly-active tab into view (no-op on non-overflowing desktop strips). */
17
+ export declare function setActiveUtilityButton(nav: UtilityNavElements, active: UtilityId, panel?: HTMLElement): void;
18
+ //# sourceMappingURL=build-util-nav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-util-nav.d.ts","sourceRoot":"","sources":["../../src/dom/build-util-nav.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,sBAAsB;IACrC,qGAAqG;IACrG,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4IAA4I;AAC5I,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,aAAa,EAAE,SAAS,EACxB,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,EACjC,OAAO,EAAE,sBAAsB,GAC9B,kBAAkB,CAqDpB;AAED,mHAAmH;AACnH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,kBAAkB,EACvB,MAAM,EAAE,SAAS,EACjB,KAAK,CAAC,EAAE,WAAW,GAClB,IAAI,CAeN"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Focus trap + initial-focus + restore-on-release for the editor dialog.
3
+ *
4
+ * The Tab keydown path doesn't trap screen readers' virtual cursors — `aria-modal=true`
5
+ * is what makes content outside the dialog inert for assistive tech. On release, focus
6
+ * returns to the element that was active before the trap installed (usually the trigger).
7
+ */
8
+ export interface InstallFocusTrapOptions {
9
+ readonly host: HTMLElement;
10
+ /** Element to focus on mount. Defaults to the first focusable descendant of `host`. */
11
+ readonly initialFocus?: HTMLElement;
12
+ }
13
+ export interface FocusTrapHandle {
14
+ /** Hook for future use; currently a no-op because focusables are re-queried on every Tab. */
15
+ refresh(): void;
16
+ /** Tear down listeners and restore focus to the trigger element. */
17
+ release(): void;
18
+ }
19
+ /** Install the focus trap and seed initial focus. */
20
+ export declare function installFocusTrap(options: InstallFocusTrapOptions): FocusTrapHandle;
21
+ //# sourceMappingURL=focus-trap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-trap.d.ts","sourceRoot":"","sources":["../../src/dom/focus-trap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,uFAAuF;IACvF,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC9B,6FAA6F;IAC7F,OAAO,IAAI,IAAI,CAAC;IAChB,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,eAAe,CA2DlF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Nested overlay (modal or anchored popover) used for the Output popover, Preferences modal,
3
+ * and Keyboard cheatsheet. Lives inside the editor host so the editor's click-capture scope
4
+ * and Ghost's modal-service allowlist still cover it. Traps Tab in capture phase so it wins
5
+ * over the editor's outer trap.
6
+ */
7
+ export interface NestedModalOptions {
8
+ readonly host: HTMLElement;
9
+ /** When supplied, the overlay positions as a popover above this element instead of centred. */
10
+ readonly anchor?: HTMLElement;
11
+ readonly title: string;
12
+ readonly body: HTMLElement;
13
+ /** CSS class added to the overlay container. */
14
+ readonly variant?: string;
15
+ /** Default true; the popover variant typically sets false (Esc / click-outside dismiss). */
16
+ readonly showCloseButton?: boolean;
17
+ readonly onClose: () => void;
18
+ }
19
+ export interface NestedModalHandle {
20
+ readonly element: HTMLElement;
21
+ close(): void;
22
+ }
23
+ /** Open a nested modal or anchored popover. Caller owns the body content. */
24
+ export declare function openNestedModal(options: NestedModalOptions): NestedModalHandle;
25
+ //# sourceMappingURL=nested-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-modal.d.ts","sourceRoot":"","sources":["../../src/dom/nested-modal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAiI9E"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Icon library sourced from Lucide (ISC). Each icon is a named import so the
3
+ * bundler tree-shakes unused glyphs. We stringify nodes ourselves rather than
4
+ * use Lucide's `createElement` to avoid pulling its DOM runtime into the bundle.
5
+ */
6
+ type IconNode = ReadonlyArray<readonly [string, Record<string, string | number>]>;
7
+ /** Stringify a Lucide icon node to inline SVG markup. */
8
+ export declare function iconHtml(node: IconNode, attrs?: Record<string, string | number>): string;
9
+ export type IconName = 'select' | 'text' | 'rect' | 'ellipse' | 'arrow' | 'freehand' | 'highlight' | 'undo' | 'redo' | 'close' | 'delete' | 'check' | 'lockClosed' | 'lockOpen' | 'plus' | 'flipHorizontal' | 'flipVertical' | 'chevronDown' | 'settings' | 'keyboard';
10
+ /** Render an icon by name. */
11
+ export declare function icon(name: IconName, attrs?: Record<string, string | number>): string;
12
+ export {};
13
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,KAAK,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAelF,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,GAAG,MAAM,CAc5F;AAED,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,MAAM,GACN,MAAM,GACN,SAAS,GACT,OAAO,GACP,UAAU,GACV,WAAW,GACX,MAAM,GACN,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,GACP,YAAY,GACZ,UAAU,GACV,MAAM,GACN,gBAAgB,GAChB,cAAc,GACd,aAAa,GACb,UAAU,GACV,UAAU,CAAC;AA+Cf,8BAA8B;AAC9B,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAEpF"}
@@ -0,0 +1,61 @@
1
+ import './styles/base.css';
2
+ import './styles/crop.css';
3
+ import './styles/transform.css';
4
+ import './styles/annotate.css';
5
+ import './styles/finetune.css';
6
+ import './styles/filter.css';
7
+ import './styles/redact.css';
8
+ import './styles/frame.css';
9
+ import './styles/output.css';
10
+ import './styles/preferences.css';
11
+ import './styles/cheatsheet.css';
12
+ import './styles/mobile.css';
13
+ export { mountShell } from './shell.js';
14
+ export type { ShellHandle, ShellOptions } from './shell.js';
15
+ export { mountCropUtility } from './plugins/crop/mount.js';
16
+ export type { MountCropOptions, MountCropHandle } from './plugins/crop/mount.js';
17
+ export { createCropPlugin } from './plugins/crop/plugin.js';
18
+ export type { CropPluginOptions } from './plugins/crop/plugin.js';
19
+ export { mountFlipUtility } from './plugins/flip/mount.js';
20
+ export type { MountFlipOptions, MountFlipHandle } from './plugins/flip/mount.js';
21
+ export { createFlipPlugin } from './plugins/flip/plugin.js';
22
+ export type { FlipPluginOptions } from './plugins/flip/plugin.js';
23
+ export { mountRotateUtility } from './plugins/rotate/mount.js';
24
+ export type { MountRotateOptions, MountRotateHandle } from './plugins/rotate/mount.js';
25
+ export { createRotatePlugin } from './plugins/rotate/plugin.js';
26
+ export type { RotatePluginOptions } from './plugins/rotate/plugin.js';
27
+ export { mountResizeUtility } from './plugins/resize/mount.js';
28
+ export type { MountResizeOptions, MountResizeHandle } from './plugins/resize/mount.js';
29
+ export { createResizePlugin } from './plugins/resize/plugin.js';
30
+ export type { ResizePluginOptions } from './plugins/resize/plugin.js';
31
+ export { mountFinetuneUtility } from './plugins/finetune/mount.js';
32
+ export type { MountFinetuneOptions, MountFinetuneHandle, } from './plugins/finetune/mount.js';
33
+ export { createFinetunePlugin } from './plugins/finetune/plugin.js';
34
+ export type { FinetunePluginOptions } from './plugins/finetune/plugin.js';
35
+ export { mountFilterUtility } from './plugins/filter/mount.js';
36
+ export type { MountFilterOptions, MountFilterHandle, } from './plugins/filter/mount.js';
37
+ export { createFilterPlugin } from './plugins/filter/plugin.js';
38
+ export type { FilterPluginOptions } from './plugins/filter/plugin.js';
39
+ export { mountAnnotateUtility } from './plugins/annotate/mount.js';
40
+ export type { MountAnnotateOptions, MountAnnotateHandle, } from './plugins/annotate/mount.js';
41
+ export { createAnnotatePlugin } from './plugins/annotate/plugin.js';
42
+ export type { AnnotatePluginOptions } from './plugins/annotate/plugin.js';
43
+ export { mountRedactUtility } from './plugins/redact/mount.js';
44
+ export type { MountRedactOptions, MountRedactHandle, } from './plugins/redact/mount.js';
45
+ export { createRedactPlugin } from './plugins/redact/plugin.js';
46
+ export type { RedactPluginOptions } from './plugins/redact/plugin.js';
47
+ export { mountFrameUtility } from './plugins/frame/mount.js';
48
+ export type { MountFrameOptions, MountFrameHandle } from './plugins/frame/mount.js';
49
+ export { createFramePlugin } from './plugins/frame/plugin.js';
50
+ export type { FramePluginOptions } from './plugins/frame/plugin.js';
51
+ export { buildUtilityNav, setActiveUtilityButton, type UtilityNavElements, type UtilityNavEntry, } from './dom/build-util-nav.js';
52
+ export { installFocusTrap, type FocusTrapHandle, type InstallFocusTrapOptions, } from './dom/focus-trap.js';
53
+ export { attachStageGestures, type StageGestureHandle } from './canvas/stage-gestures.js';
54
+ export { icon, iconHtml, type IconName } from './icons.js';
55
+ export { openNestedModal, type NestedModalHandle, type NestedModalOptions, } from './dom/nested-modal.js';
56
+ export { openOutputPopover, type OpenOutputPopoverOptions, type OutputPopoverHandle, } from './output/popover.js';
57
+ export { DEFAULT_PREFERENCES, getSiteScope, loadPreferences, savePreferences, type KalotypPreferences, } from './preferences/storage.js';
58
+ export { openPreferencesModal, type OpenPreferencesModalOptions, type PreferencesModalHandle, } from './preferences/modal.js';
59
+ export { openCheatsheet, type OpenCheatsheetOptions, type CheatsheetHandle, } from './cheatsheet/modal.js';
60
+ export { KEYBOARD_SHORTCUTS, KEYBOARD_SHORTCUT_CONTEXT_LABELS, type KeyboardShortcut, type KeyboardShortcutContext, } from './keyboard-shortcuts.js';
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}