@openpen/module-api 1.1.1 → 1.3.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 (97) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/_chunks/AppButtonDropdown.vue_vue_type_style_index_0_lang-B9dHU-LE.js +246 -0
  3. package/dist/_chunks/AppButtonDropdown.vue_vue_type_style_index_0_lang-B9dHU-LE.js.map +1 -0
  4. package/dist/_chunks/inject-keys-CRXCpN-M.js +196 -0
  5. package/dist/_chunks/inject-keys-CRXCpN-M.js.map +1 -0
  6. package/dist/_chunks/module-context-registry-Cn1IWYu9.js +16 -0
  7. package/dist/_chunks/module-context-registry-Cn1IWYu9.js.map +1 -0
  8. package/dist/_chunks/passthrough-DKU7JYuQ.js +6 -0
  9. package/dist/_chunks/passthrough-DKU7JYuQ.js.map +1 -0
  10. package/dist/cursors.d.ts +83 -0
  11. package/dist/define-module.d.ts +17 -0
  12. package/dist/host/color-utils.d.ts +11 -0
  13. package/{src/host/event-bus.ts → dist/host/event-bus.d.ts} +7 -5
  14. package/dist/host/host-commands.d.ts +1 -0
  15. package/dist/host/index.d.ts +24 -0
  16. package/dist/host/index.js +51 -0
  17. package/dist/host/index.js.map +1 -0
  18. package/{src/host/module-context-registry.ts → dist/host/module-context-registry.d.ts} +5 -19
  19. package/dist/host/passthrough.d.ts +2 -0
  20. package/dist/host/popup-anchor.d.ts +3 -0
  21. package/dist/host/registry.d.ts +39 -0
  22. package/dist/host/registry.js +37 -0
  23. package/dist/host/registry.js.map +1 -0
  24. package/dist/host/slot-entries.d.ts +2 -0
  25. package/dist/host/stroke-store.d.ts +6 -0
  26. package/dist/host/stroke-style.d.ts +3 -0
  27. package/dist/host/types.d.ts +176 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.js +349 -0
  30. package/dist/index.js.map +1 -0
  31. package/{src/inject-keys.ts → dist/inject-keys.d.ts} +37 -66
  32. package/{src/locale.ts → dist/locale.d.ts} +3 -22
  33. package/dist/slots.d.ts +57 -0
  34. package/dist/types/contributions.d.ts +288 -0
  35. package/dist/types/control-bar-layout.d.ts +227 -0
  36. package/dist/types/module.d.ts +208 -0
  37. package/{src/types/notification.ts → dist/types/notification.d.ts} +12 -14
  38. package/dist/types/tool.d.ts +77 -0
  39. package/dist/uikit/components/AppBanner.vue.d.ts +34 -0
  40. package/dist/uikit/components/AppButton.vue.d.ts +30 -0
  41. package/dist/uikit/components/AppButtonDropdown.vue.d.ts +52 -0
  42. package/dist/uikit/components/AppDialog.vue.d.ts +53 -0
  43. package/dist/uikit/components/AppPopover.vue.d.ts +43 -0
  44. package/dist/uikit/components/AppSegmented.vue.d.ts +19 -0
  45. package/dist/uikit/components/AppSelect.vue.d.ts +26 -0
  46. package/dist/uikit/components/AppSlider.vue.d.ts +43 -0
  47. package/dist/uikit/components/AppTabs.vue.d.ts +35 -0
  48. package/dist/uikit/components/AppToggle.vue.d.ts +15 -0
  49. package/dist/uikit/components/AppTooltip.vue.d.ts +27 -0
  50. package/dist/uikit/components/DialogHost.vue.d.ts +3 -0
  51. package/{src/uikit/composables/dialog-internal-keys.ts → dist/uikit/composables/dialog-internal-keys.d.ts} +3 -5
  52. package/dist/uikit/composables/useDialog.d.ts +399 -0
  53. package/dist/uikit/composables/useDialogPluginComponent.d.ts +9 -0
  54. package/dist/uikit/index.d.ts +42 -0
  55. package/dist/uikit/index.js +898 -0
  56. package/dist/uikit/index.js.map +1 -0
  57. package/{src/uikit/internal.ts → dist/uikit/internal.d.ts} +1 -1
  58. package/dist/uikit/internal.js +157 -0
  59. package/dist/uikit/internal.js.map +1 -0
  60. package/dist/uikit/module-api.css +851 -0
  61. package/dist/uikit/primitives.d.ts +42 -0
  62. package/{src/use-module-context.ts → dist/use-module-context.d.ts} +2 -15
  63. package/{src/validation.ts → dist/validation.d.ts} +2 -6
  64. package/package.json +28 -14
  65. package/src/cursors.ts +0 -369
  66. package/src/define-module.ts +0 -55
  67. package/src/host/color-utils.ts +0 -18
  68. package/src/host/host-commands.ts +0 -9
  69. package/src/host/index.ts +0 -53
  70. package/src/host/passthrough.ts +0 -10
  71. package/src/host/popup-anchor.ts +0 -14
  72. package/src/host/slot-entries.ts +0 -9
  73. package/src/host/stroke-store.ts +0 -20
  74. package/src/host/stroke-style.ts +0 -15
  75. package/src/index.ts +0 -131
  76. package/src/slots.ts +0 -135
  77. package/src/types/contributions.ts +0 -333
  78. package/src/types/control-bar-layout.ts +0 -174
  79. package/src/types/module.ts +0 -225
  80. package/src/types/tool.ts +0 -82
  81. package/src/uikit/components/.gitkeep +0 -0
  82. package/src/uikit/components/AppBanner.vue +0 -131
  83. package/src/uikit/components/AppButton.vue +0 -135
  84. package/src/uikit/components/AppDialog.vue +0 -393
  85. package/src/uikit/components/AppPopover.vue +0 -268
  86. package/src/uikit/components/AppSegmented.vue +0 -128
  87. package/src/uikit/components/AppSelect.vue +0 -235
  88. package/src/uikit/components/AppSlider.vue +0 -204
  89. package/src/uikit/components/AppTabs.vue +0 -163
  90. package/src/uikit/components/AppToggle.vue +0 -96
  91. package/src/uikit/components/AppTooltip.vue +0 -118
  92. package/src/uikit/components/DialogHost.vue +0 -272
  93. package/src/uikit/composables/useDialog.ts +0 -141
  94. package/src/uikit/composables/useDialogPluginComponent.ts +0 -27
  95. package/src/uikit/index.ts +0 -79
  96. package/src/uikit/primitives.ts +0 -150
  97. /package/{src → dist}/uikit/tokens.css +0 -0
@@ -0,0 +1,208 @@
1
+ import type { z } from 'zod';
2
+ import type { ModuleContributions } from './contributions';
3
+ import type { NotifyPayload, NotifyHandle } from './notification';
4
+ import type { LocaleMap } from '../locale';
5
+ /**
6
+ * Public contract that every OpenPen module — first-party (`src/core/modules/*`)
7
+ * and third-party plugin alike — must satisfy.
8
+ *
9
+ * Modules express their behaviour entirely via `contributes` and
10
+ * (optionally) `setup`. They never touch host-app internals directly:
11
+ * cross-module communication goes through declared contribution slots
12
+ * and the domain event bus.
13
+ */
14
+ export interface OpenPenModule {
15
+ /** Globally unique kebab-case id. Subject to {@link import('../validation').MODULE_ID_RE}. */
16
+ id: string;
17
+ /**
18
+ * i18n-independent display metadata. Used as a fallback layer in the
19
+ * Settings UI when the module's `contributes.locales` entries are not
20
+ * registered (e.g. the module is disabled and its contributions are not
21
+ * wired into the host). The runtime i18n contribution is always preferred
22
+ * as the primary source; this field is only consulted on a cache miss.
23
+ *
24
+ * Values are `LocaleMap` (`Record<string, string>`) keyed by BCP-47 tag.
25
+ * Resolution follows the same order as `resolveLabel`: exact tag → language
26
+ * prefix → `'en'` fallback → first declared value.
27
+ */
28
+ metadata?: {
29
+ name: LocaleMap;
30
+ description?: LocaleMap;
31
+ };
32
+ /**
33
+ * SemVer string. **Required for plugins** — the host validator
34
+ * rejects any non-built-in module whose `version` is missing or
35
+ * empty with a `'missing-version'` ValidationError, so a plugin
36
+ * with no version never finishes loading.
37
+ *
38
+ * Built-in modules (those bundled with the host under
39
+ * `src/core/modules/`) MAY omit it and inherit the host version;
40
+ * the type stays optional only to accommodate that case.
41
+ */
42
+ version?: string;
43
+ /**
44
+ * Minimum OpenPen app version this module requires (semver).
45
+ *
46
+ * Validated at load time by the host: a plugin whose `minAppVersion`
47
+ * exceeds the running host version is skipped with a console warning.
48
+ * Set this to `"1.0.0"` (or omit it) for broad v1.x compatibility.
49
+ */
50
+ minAppVersion?: string;
51
+ /**
52
+ * One-shot initialisation, called after manifest validation and
53
+ * before contributions are wired into the host. Use this for things
54
+ * that need to happen exactly once, like seeding default settings or
55
+ * subscribing to long-running event streams.
56
+ */
57
+ setup?: (ctx: ModuleSetupContext) => void | Promise<void>;
58
+ /** At least one field on this object is required (enforced by `defineModule`). */
59
+ contributes?: ModuleContributions;
60
+ /**
61
+ * Zod schema for this module's user-facing settings. The host renders
62
+ * the settings form from this schema and persists the parsed value
63
+ * under `config.json.modules[id]`. The same schema validates writes
64
+ * made via `ctx.updateSettings()`; writes that fail validation reject
65
+ * with the underlying `ZodError`.
66
+ *
67
+ * Modules that intend to call `ctx.updateSettings()` MUST declare
68
+ * this field; calling `updateSettings` without a schema throws at
69
+ * runtime so the missing contract surfaces during development.
70
+ */
71
+ settingsSchema?: z.ZodType;
72
+ /**
73
+ * Settings schema version. Increment when the schema's shape changes
74
+ * in a way that needs migration (renames, removals, or restructuring).
75
+ * Pure additive changes (new keys with `.default()` values) do not
76
+ * require a bump — Zod's defaults fill in on parse.
77
+ *
78
+ * Defaults to `1` if omitted. The host persists the version under
79
+ * `config.json.moduleMeta[id].schemaVersion` (separate from the data
80
+ * blob) so plugins never see this sentinel in their settings object.
81
+ */
82
+ settingsVersion?: number;
83
+ /**
84
+ * Optional migration hook run before `settingsSchema` parses persisted
85
+ * data. Called when the stored `schemaVersion` is less than the
86
+ * module's `settingsVersion`. Receives the stored version + raw data
87
+ * blob; returns the migrated blob, which is then validated by
88
+ * `settingsSchema` and persisted at the new version.
89
+ *
90
+ * Use this for renames, removals, or restructuring. For pure additive
91
+ * changes (new keys), Zod's `.default()` covers it — no migrate hook
92
+ * needed.
93
+ *
94
+ * @example
95
+ * migrate(stored, data) {
96
+ * if (stored < 2 && 'oldName' in data) {
97
+ * data.newName = data.oldName
98
+ * delete data.oldName
99
+ * }
100
+ * return data
101
+ * }
102
+ */
103
+ migrate?: (storedVersion: number, data: Record<string, unknown>) => Record<string, unknown>;
104
+ }
105
+ /**
106
+ * Runtime context handed to `setup()`. Intentionally narrow — modules
107
+ * that need more capabilities should declare them via contribution
108
+ * slots so the dependency is visible at validation time.
109
+ */
110
+ export interface ModuleSetupContext {
111
+ /** This module's id, for logging / error messages. */
112
+ moduleId: string;
113
+ /** Currently active locale, e.g. 'zh-TW'. Read-only. */
114
+ locale: string;
115
+ /**
116
+ * Returns this module's current settings — a live in-memory snapshot
117
+ * already validated by `settingsSchema`. Synchronous and zero-I/O:
118
+ * the host hydrates the cache before `setup()` is called and updates
119
+ * it in-place after every successful `updateSettings()`.
120
+ *
121
+ * Generic `T` should match the inferred type of your `settingsSchema`
122
+ * (use `z.infer<typeof MySchema>` at the call site).
123
+ *
124
+ * @example
125
+ * const settings = ctx.getSettings<z.infer<typeof MySchema>>()
126
+ */
127
+ getSettings: <T = unknown>() => T;
128
+ /**
129
+ * Shallow-merges `patch` into this module's settings, validates the
130
+ * result against `settingsSchema` (Zod), and persists to `config.json`.
131
+ * Resolves once the write is durable; rejects with the underlying
132
+ * `ZodError` if the merged object fails validation (no I/O happens
133
+ * on validation failure).
134
+ *
135
+ * The in-memory snapshot returned by `getSettings()` is updated
136
+ * before the Promise resolves; subscribers registered via
137
+ * `onSettingsChange()` then fire with the new snapshot.
138
+ *
139
+ * Note on nested objects: the merge is shallow. Updating a nested
140
+ * object replaces it entirely — spread the existing nested value
141
+ * yourself if you only want to change one inner field:
142
+ *
143
+ * ```ts
144
+ * const cur = ctx.getSettings<MySettings>()
145
+ * await ctx.updateSettings({ colors: { ...cur.colors, primary: '#0f0' } })
146
+ * ```
147
+ *
148
+ * Throws synchronously if the module did not declare `settingsSchema`.
149
+ */
150
+ updateSettings: <T = unknown>(patch: Partial<T>) => Promise<void>;
151
+ /**
152
+ * Subscribe to settings changes for this module. The callback fires
153
+ * after every successful `updateSettings()` — including writes that
154
+ * originated from the host's settings panel — with the fresh,
155
+ * already-validated snapshot.
156
+ *
157
+ * Returns an unsubscribe function. The host also calls it
158
+ * automatically when the module is rolled back, so manual cleanup
159
+ * is only needed if you want to stop listening sooner than
160
+ * module dispose.
161
+ *
162
+ * @example
163
+ * const stop = ctx.onSettingsChange<MySettings>((s) => {
164
+ * redrawWithColor(s.primary)
165
+ * })
166
+ */
167
+ onSettingsChange: <T = unknown>(cb: (settings: T) => void) => () => void;
168
+ /**
169
+ * Invoke one of THIS module's main-side handlers (declared via
170
+ * `contributes.mainHandlers`). The moduleId is captured by the host
171
+ * so plugins cannot reach into other modules' handlers — use this
172
+ * helper rather than the lower-level `openPenApi.moduleCall`.
173
+ *
174
+ * Returns whatever the handler returns (typed by the caller).
175
+ */
176
+ callMain: <T = unknown>(action: string, payload?: unknown) => Promise<T>;
177
+ /**
178
+ * Register a cleanup callback. Called in reverse registration order
179
+ * when the module is unloaded (hot-reload, user-disable, or app quit).
180
+ * Use this to cancel timers, remove listeners, or release resources
181
+ * that `setup()` acquired.
182
+ */
183
+ onDispose: (fn: () => void | Promise<void>) => void;
184
+ /**
185
+ * Shows a short-lived toast notification in the overlay window.
186
+ * Visibility and position are controlled by the user's settings.
187
+ * Returns a NotifyHandle for early dismissal.
188
+ */
189
+ notify: (payload: NotifyPayload) => NotifyHandle;
190
+ /**
191
+ * Resolves an i18n key for this module to the current-locale string.
192
+ *
193
+ * The key is automatically namespaced as `${moduleId}.${key}`, matching
194
+ * the dictionary structure registered via `contributes.locales` (the host
195
+ * merges each locale dict into the global vue-i18n instance under the
196
+ * module's id namespace).
197
+ *
198
+ * Aligned with VS Code's `vscode.l10n.t()` convention:
199
+ * ```typescript
200
+ * ctx.t('notif.start')
201
+ * ctx.t('notif.greeting', { name: 'Alice' }) // dict entry: 'Hello {name}'
202
+ * ```
203
+ *
204
+ * When a key has no matching translation the namespaced key string is
205
+ * returned (vue-i18n's default missing-key behaviour).
206
+ */
207
+ t: (key: string, params?: Record<string, unknown>) => string;
208
+ }
@@ -9,7 +9,6 @@
9
9
  * for module manifest metadata (name, description, contribution label),
10
10
  * following the VS Code package.nls.json / JetBrains plugin.xml convention.
11
11
  */
12
-
13
12
  /**
14
13
  * Input payload for ctx.notify().
15
14
  *
@@ -21,20 +20,19 @@
21
20
  * for guidance on choosing notify() versus your own UI surface.
22
21
  */
23
22
  export interface NotifyPayload {
24
- /** Required. Already-resolved plain string; use ctx.t(key) for i18n. */
25
- message: string
26
- /** Subtitle text. Already-resolved plain string, e.g. "Press again to exit". */
27
- description?: string
28
- /** Inline SVG string, same convention as ToolContribution.icon. */
29
- icon?: string
30
- /** Semantic colour variant. Defaults to 'default'. */
31
- variant?: 'default' | 'success' | 'warning' | 'danger'
32
- /** Auto-dismiss delay in milliseconds. Defaults to 1800. */
33
- duration?: number
23
+ /** Required. Already-resolved plain string; use ctx.t(key) for i18n. */
24
+ message: string;
25
+ /** Subtitle text. Already-resolved plain string, e.g. "Press again to exit". */
26
+ description?: string;
27
+ /** Inline SVG string, same convention as ToolContribution.icon. */
28
+ icon?: string;
29
+ /** Semantic colour variant. Defaults to 'default'. */
30
+ variant?: 'default' | 'success' | 'warning' | 'danger';
31
+ /** Auto-dismiss delay in milliseconds. Defaults to 1800. */
32
+ duration?: number;
34
33
  }
35
-
36
34
  /** Return value of ctx.notify(), allowing early dismissal. */
37
35
  export interface NotifyHandle {
38
- /** Immediately closes this notification. */
39
- dismiss(): void
36
+ /** Immediately closes this notification. */
37
+ dismiss(): void;
40
38
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Public Tool / Stroke / Point primitives shared by host code and
3
+ * every module / plugin. Declared inside @openpen/module-api so
4
+ * third parties don't need to import host internals to type their
5
+ * `canvas.tools` contributions.
6
+ */
7
+ export interface Point {
8
+ x: number;
9
+ y: number;
10
+ }
11
+ /** Solid color or linear gradient between two stops. */
12
+ export type StrokeColor = string | {
13
+ type: 'linear';
14
+ from: string;
15
+ to: string;
16
+ };
17
+ /**
18
+ * Reduce a `StrokeColor` to a single CSS colour string.
19
+ *
20
+ * `CanvasRenderingContext2D.strokeStyle` accepts a single colour string but
21
+ * not a structured gradient descriptor; custom `renderStroke` implementations
22
+ * that don't draw the gradient natively need a representative fallback.
23
+ * Returns the string as-is for solid colours, and the `from` stop for linear
24
+ * gradients. Future gradient kinds can pick their own representative without
25
+ * touching callers.
26
+ */
27
+ export declare function resolveStrokeColor(color: StrokeColor): string;
28
+ export interface StrokeStyle {
29
+ color: StrokeColor;
30
+ lineWidth: number;
31
+ lineCap: CanvasLineCap;
32
+ lineJoin: CanvasLineJoin;
33
+ }
34
+ export interface Stroke {
35
+ id: string;
36
+ /** Id of the tool that produced this stroke (matches a ToolContribution.id). */
37
+ tool: string;
38
+ points: Point[];
39
+ style: StrokeStyle;
40
+ /**
41
+ * Tool-specific extra state. Tools MAY store arbitrary keys here during
42
+ * `onPointerDown` / `onPointerMove` / `onPointerUp`; those keys survive
43
+ * into `renderStroke(stroke, canvasCtx)` calls so the renderer can read
44
+ * them back.
45
+ *
46
+ * The host treats extra keys as `unknown` — type-cast at the read site is
47
+ * the plugin author's responsibility (TypeScript cannot infer the shape).
48
+ *
49
+ * @example
50
+ * // Store during onPointerUp:
51
+ * const stroke: Stroke = { id, tool: 'my-tool', points, style, opacity: 0.5 }
52
+ *
53
+ * // Read back in renderStroke:
54
+ * const opacity = (stroke.opacity as number) ?? 1
55
+ * canvasCtx.globalAlpha = opacity
56
+ */
57
+ [key: string]: unknown;
58
+ }
59
+ export interface PointerModifiers {
60
+ shiftKey?: boolean;
61
+ }
62
+ export interface Tool {
63
+ onPointerDown(canvasCtx: CanvasRenderingContext2D, point: Point, style: StrokeStyle): void;
64
+ /**
65
+ * Returns `true` when the engine should perform a full redraw
66
+ * (e.g. stroke-eraser removed an existing stroke). Otherwise `void`.
67
+ */
68
+ onPointerMove(canvasCtx: CanvasRenderingContext2D, point: Point, modifiers?: PointerModifiers): void | boolean;
69
+ /**
70
+ * Returns the finished `Stroke` to push into the store, or `null`
71
+ * to discard (e.g. an eraser that doesn't accumulate state).
72
+ */
73
+ onPointerUp(canvasCtx: CanvasRenderingContext2D, point: Point, modifiers?: PointerModifiers): Stroke | null;
74
+ /** When true, canvas-engine clears + redraws all strokes before each move. */
75
+ needsPreviewRedraw?: boolean;
76
+ renderPreview?(canvasCtx: CanvasRenderingContext2D): void;
77
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * AppBanner — High-level wrapper (Layer 1).
3
+ *
4
+ * Presents info / warning / success / error status messages using the
5
+ * --openpen-color-state-* design tokens. The icon is auto-rendered based on
6
+ * the variant; message content goes in the default slot; optional inline action
7
+ * buttons (e.g. restart / dismiss) go in the `#actions` slot.
8
+ *
9
+ * Inline mode (compact single-line) is enabled via the `inline` prop and is
10
+ * suited for form validation feedback and status lines inside dialogs.
11
+ */
12
+ export type BannerVariant = 'info' | 'warning' | 'success' | 'error';
13
+ type __VLS_Props = {
14
+ variant: BannerVariant;
15
+ /** Compact single-line layout: smaller padding, vertically centered. */
16
+ inline?: boolean;
17
+ };
18
+ declare var __VLS_1: {}, __VLS_3: {};
19
+ type __VLS_Slots = {} & {
20
+ default?: (props: typeof __VLS_1) => any;
21
+ } & {
22
+ actions?: (props: typeof __VLS_3) => any;
23
+ };
24
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
25
+ inline: boolean;
26
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
30
+ type __VLS_WithSlots<T, S> = T & {
31
+ new (): {
32
+ $slots: S;
33
+ };
34
+ };
@@ -0,0 +1,30 @@
1
+ type __VLS_Props = {
2
+ variant?: 'default' | 'danger';
3
+ active?: boolean;
4
+ disabled?: boolean;
5
+ tooltip?: string;
6
+ ariaLabel?: string;
7
+ };
8
+ declare var __VLS_1: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_1) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
+ click: () => any;
14
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
15
+ onClick?: (() => any) | undefined;
16
+ }>, {
17
+ disabled: boolean;
18
+ ariaLabel: string;
19
+ active: boolean;
20
+ variant: "default" | "danger";
21
+ tooltip: string;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,52 @@
1
+ type __VLS_Props = {
2
+ /** Globally unique popover id (passed through to the inner AppPopover). */
3
+ popoverId: string;
4
+ /** Preferred popover placement; defaults to 'auto'. */
5
+ popoverPlacement?: 'auto' | 'top' | 'bottom' | 'left' | 'right';
6
+ /** Main button active state (drives accent highlight). */
7
+ active?: boolean;
8
+ /** Disables both main and caret buttons; tooltip remains active. */
9
+ disabled?: boolean;
10
+ /** Main button variant (passed through to AppButton). */
11
+ variant?: 'default' | 'danger';
12
+ /** Tooltip shown above the main button. */
13
+ mainTooltip?: string;
14
+ /** Main button aria-label. */
15
+ mainAriaLabel?: string;
16
+ /** Caret button aria-label. Required for screen-reader users. */
17
+ caretAriaLabel?: string;
18
+ /** Optional test ids forwarded to the rendered buttons. */
19
+ mainTestid?: string;
20
+ caretTestid?: string;
21
+ };
22
+ declare var __VLS_9: {}, __VLS_19: {};
23
+ type __VLS_Slots = {} & {
24
+ 'main-content'?: (props: typeof __VLS_9) => any;
25
+ } & {
26
+ 'popover-content'?: (props: typeof __VLS_19) => any;
27
+ };
28
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
29
+ mainClick: () => any;
30
+ caretClick: () => any;
31
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
32
+ onMainClick?: (() => any) | undefined;
33
+ onCaretClick?: (() => any) | undefined;
34
+ }>, {
35
+ disabled: boolean;
36
+ active: boolean;
37
+ variant: "default" | "danger";
38
+ popoverPlacement: "auto" | "top" | "bottom" | "left" | "right";
39
+ mainTooltip: string;
40
+ mainAriaLabel: string;
41
+ caretAriaLabel: string;
42
+ mainTestid: string;
43
+ caretTestid: string;
44
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
45
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
46
+ declare const _default: typeof __VLS_export;
47
+ export default _default;
48
+ type __VLS_WithSlots<T, S> = T & {
49
+ new (): {
50
+ $slots: S;
51
+ };
52
+ };
@@ -0,0 +1,53 @@
1
+ export interface AppDialogProps {
2
+ /** Globally unique modal id; used for modal-stack mutual exclusion. */
3
+ modalId: string;
4
+ /** Dialog title displayed in the dialog header. */
5
+ title: string;
6
+ /** Controlled open state. The parent must handle update:open to toggle. */
7
+ open: boolean;
8
+ /**
9
+ * When true, ESC key and backdrop clicks do not close the dialog.
10
+ * Use for confirmations that require an explicit button press.
11
+ */
12
+ persistent?: boolean;
13
+ /**
14
+ * When true, adds the `openpen-modal-danger` CSS class on the content
15
+ * element — a hook for styling destructive-action dialogs.
16
+ */
17
+ danger?: boolean;
18
+ }
19
+ export interface AppDialogSlots {
20
+ /**
21
+ * Trigger slot; scope exposes active state + toggle / open / close actions.
22
+ * MUST NOT write @click="toggle" on the trigger — DialogTrigger's as-child
23
+ * handles activation automatically; toggle/open/close are escape hatches for
24
+ * programmatic control only.
25
+ */
26
+ trigger: (scope: {
27
+ active: boolean;
28
+ toggle: () => void;
29
+ open: () => void;
30
+ close: () => void;
31
+ }) => unknown;
32
+ /** Dialog body content slot. */
33
+ default: () => unknown;
34
+ /** Optional footer slot (action buttons etc.). */
35
+ footer?: () => unknown;
36
+ }
37
+ type __VLS_Slots = AppDialogSlots;
38
+ declare const __VLS_base: import("vue").DefineComponent<AppDialogProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
39
+ "update:open": (value: boolean) => any;
40
+ }, string, import("vue").PublicProps, Readonly<AppDialogProps> & Readonly<{
41
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
42
+ }>, {
43
+ danger: boolean;
44
+ persistent: boolean;
45
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
46
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
47
+ declare const _default: typeof __VLS_export;
48
+ export default _default;
49
+ type __VLS_WithSlots<T, S> = T & {
50
+ new (): {
51
+ $slots: S;
52
+ };
53
+ };
@@ -0,0 +1,43 @@
1
+ /** Preferred placement for the popover content relative to the trigger. */
2
+ export type Placement = 'auto' | 'top' | 'bottom' | 'left' | 'right';
3
+ export interface AppPopoverProps {
4
+ /** Globally unique popover id; used for modal-stack mutual exclusion. */
5
+ popoverId: string;
6
+ /**
7
+ * Popover placement direction.
8
+ * - 'auto' (default, recommended): the host's snap-edge hint picks the side that
9
+ * keeps the popover on-screen across all control-bar modes.
10
+ * - explicit values ('top' | 'bottom' | 'left' | 'right'): bypass the auto hint.
11
+ * In dev mode a console warning is emitted because explicit values can position
12
+ * popovers off-screen or away from the trigger button when the control bar is
13
+ * in a vertical mode. Only use when you have verified the placement stays
14
+ * on-screen across all snap layouts.
15
+ */
16
+ placement?: Placement;
17
+ /** Gap between trigger and content in px. Default 8. */
18
+ gap?: number;
19
+ }
20
+ export interface AppPopoverSlots {
21
+ /** Trigger slot; scope exposes active state + toggle / open / close actions. */
22
+ trigger: (scope: {
23
+ active: boolean;
24
+ toggle: () => void;
25
+ open: () => void;
26
+ close: () => void;
27
+ }) => unknown;
28
+ /** Popover content slot. */
29
+ content: () => unknown;
30
+ }
31
+ type __VLS_Slots = AppPopoverSlots;
32
+ declare const __VLS_base: import("vue").DefineComponent<AppPopoverProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AppPopoverProps> & Readonly<{}>, {
33
+ placement: Placement;
34
+ gap: number;
35
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
36
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
37
+ declare const _default: typeof __VLS_export;
38
+ export default _default;
39
+ type __VLS_WithSlots<T, S> = T & {
40
+ new (): {
41
+ $slots: S;
42
+ };
43
+ };
@@ -0,0 +1,19 @@
1
+ interface Option {
2
+ value: string;
3
+ label: string;
4
+ icon?: string;
5
+ testid?: string;
6
+ }
7
+ type __VLS_Props = {
8
+ modelValue: string;
9
+ options: Option[];
10
+ /** When true, all options are non-interactive and visually dimmed. */
11
+ disabled?: boolean;
12
+ };
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ "update:modelValue": (value: string) => any;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
17
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,26 @@
1
+ /** A single option in the dropdown list. */
2
+ export interface SelectOption {
3
+ /** The value emitted on selection. */
4
+ value: string;
5
+ /** The label shown to the user. */
6
+ label: string;
7
+ }
8
+ export interface AppSelectProps {
9
+ /** Currently selected value (bind with v-model). */
10
+ modelValue: string;
11
+ /** List of selectable options. */
12
+ options: SelectOption[];
13
+ /** Placeholder shown when no option is selected. */
14
+ placeholder: string;
15
+ /** Whether the select is disabled. */
16
+ disabled?: boolean;
17
+ }
18
+ declare const __VLS_export: import("vue").DefineComponent<AppSelectProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (value: string) => any;
20
+ }, string, import("vue").PublicProps, Readonly<AppSelectProps> & Readonly<{
21
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
22
+ }>, {
23
+ disabled: boolean;
24
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
+ declare const _default: typeof __VLS_export;
26
+ export default _default;
@@ -0,0 +1,43 @@
1
+ type __VLS_Props = {
2
+ modelValue: number;
3
+ min?: number;
4
+ max?: number;
5
+ step?: number;
6
+ /** Container width (e.g. '100%', '72px'). In vertical mode this sets the height. */
7
+ width?: string;
8
+ orientation?: 'horizontal' | 'vertical';
9
+ trackHeight?: string;
10
+ trackRadius?: string;
11
+ thumbWidth?: string;
12
+ thumbHeight?: string;
13
+ thumbRadius?: string;
14
+ /**
15
+ * Reverse the value-to-position mapping. With orientation='vertical', sets
16
+ * top=min and bottom=max (drag down to increase). With orientation='horizontal',
17
+ * sets right=min and left=max (drag left to increase). Useful when an icon
18
+ * legend implies the opposite direction of the underlying control.
19
+ *
20
+ * Delegates to reka-ui SliderRoot's native `inverted` prop, which swaps
21
+ * startEdge/endEdge on SliderRange — no manual value transformation needed.
22
+ */
23
+ inverted?: boolean;
24
+ };
25
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
26
+ "update:modelValue": (value: number) => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ "onUpdate:modelValue"?: ((value: number) => any) | undefined;
29
+ }>, {
30
+ width: string;
31
+ min: number;
32
+ max: number;
33
+ step: number;
34
+ orientation: "horizontal" | "vertical";
35
+ trackHeight: string;
36
+ trackRadius: string;
37
+ thumbWidth: string;
38
+ thumbHeight: string;
39
+ thumbRadius: string;
40
+ inverted: boolean;
41
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
42
+ declare const _default: typeof __VLS_export;
43
+ export default _default;
@@ -0,0 +1,35 @@
1
+ export interface AppTabItem {
2
+ /** Unique identifier for this tab. Used as the v-model value. */
3
+ id: string;
4
+ /** Human-readable label rendered in the tab trigger button. */
5
+ label: string;
6
+ }
7
+ export interface AppTabsProps {
8
+ /** Currently active tab id (controlled mode). */
9
+ modelValue: string;
10
+ /** Ordered list of tab descriptors. */
11
+ tabs: AppTabItem[];
12
+ }
13
+ export interface AppTabsSlots {
14
+ /**
15
+ * Default slot for tab content area.
16
+ * Receives the currently active tab id via scoped slot.
17
+ */
18
+ default: (scope: {
19
+ activeTabId: string;
20
+ }) => unknown;
21
+ }
22
+ type __VLS_Slots = AppTabsSlots;
23
+ declare const __VLS_base: import("vue").DefineComponent<AppTabsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
24
+ "update:modelValue": (value: string) => any;
25
+ }, string, import("vue").PublicProps, Readonly<AppTabsProps> & Readonly<{
26
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
27
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
29
+ declare const _default: typeof __VLS_export;
30
+ export default _default;
31
+ type __VLS_WithSlots<T, S> = T & {
32
+ new (): {
33
+ $slots: S;
34
+ };
35
+ };