@wisemen/vue-core-actions 0.1.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 (37) hide show
  1. package/LICENSE.md +59 -0
  2. package/dist/composables/actionDropdownMenuContent.composable.d.ts +24 -0
  3. package/dist/composables/actionGroup.composable.d.ts +32 -0
  4. package/dist/composables/actionPreview.composable.d.ts +15 -0
  5. package/dist/composables/actionShortcuts.composable.d.ts +27 -0
  6. package/dist/composables/activeModels.composable.d.ts +3 -0
  7. package/dist/composables/commandMenuActions.composable.d.ts +28 -0
  8. package/dist/composables/commandMenuAnimation.composable.d.ts +5 -0
  9. package/dist/composables/commandMenuNavigation.composable.d.ts +35 -0
  10. package/dist/composables/focusedModels.composable.d.ts +6 -0
  11. package/dist/composables/isSelectorVisible.composable.d.ts +1 -0
  12. package/dist/composables/temporaryActions.composable.d.ts +6 -0
  13. package/dist/composables/viewModels.composable.d.ts +3 -0
  14. package/dist/const/index.d.ts +6 -0
  15. package/dist/createActions.d.ts +47 -0
  16. package/dist/index.cjs +1 -0
  17. package/dist/index.d.ts +22 -0
  18. package/dist/index.js +2122 -0
  19. package/dist/locales/en-US.json.d.ts +12 -0
  20. package/dist/locales/nl-BE.json.d.ts +12 -0
  21. package/dist/locales-BPtvPqGa.js +22 -0
  22. package/dist/locales-D5e1O21n.cjs +1 -0
  23. package/dist/locales.cjs +1 -0
  24. package/dist/locales.d.ts +20 -0
  25. package/dist/locales.js +2 -0
  26. package/dist/stores/actionManager.store.d.ts +82 -0
  27. package/dist/stores/actionRegistry.store.d.ts +17 -0
  28. package/dist/types/action.type.d.ts +225 -0
  29. package/dist/types/actionContext.type.d.ts +112 -0
  30. package/dist/types/actionGroup.type.d.ts +19 -0
  31. package/dist/types/actionModel.type.d.ts +4 -0
  32. package/dist/types/commandMenu.type.d.ts +11 -0
  33. package/dist/types/keyboardShortcut.type.d.ts +26 -0
  34. package/dist/utils/commandMenuGroups.util.d.ts +12 -0
  35. package/dist/utils/resolveActions.util.d.ts +13 -0
  36. package/dist/utils/subActions.util.d.ts +5 -0
  37. package/package.json +73 -0
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ "action.group.account": "Account",
3
+ "action.group.developer": "Developer",
4
+ "action.group.general": "General",
5
+ "action.group.navigation": "Navigation",
6
+ "action.group.preferences": "Preferences",
7
+ "search": "Search...",
8
+ "type_a_command_or_search": "Type a command or search..."
9
+ }
10
+ ;
11
+
12
+ export default _default;
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ "action.group.account": "Account",
3
+ "action.group.developer": "Ontwikkelaar",
4
+ "action.group.general": "Algemeen",
5
+ "action.group.navigation": "Navigatie",
6
+ "action.group.preferences": "Voorkeuren",
7
+ "search": "Zoeken...",
8
+ "type_a_command_or_search": "Type een command of zoek..."
9
+ }
10
+ ;
11
+
12
+ export default _default;
@@ -0,0 +1,22 @@
1
+ var en_US_default = {
2
+ "action.group.account": "Account",
3
+ "action.group.developer": "Developer",
4
+ "action.group.general": "General",
5
+ "action.group.navigation": "Navigation",
6
+ "action.group.preferences": "Preferences",
7
+ search: "Search...",
8
+ type_a_command_or_search: "Type a command or search..."
9
+ }, nl_BE_default = {
10
+ "action.group.account": "Account",
11
+ "action.group.developer": "Ontwikkelaar",
12
+ "action.group.general": "Algemeen",
13
+ "action.group.navigation": "Navigatie",
14
+ "action.group.preferences": "Voorkeuren",
15
+ search: "Zoeken...",
16
+ type_a_command_or_search: "Type een command of zoek..."
17
+ };
18
+ const actionsLocales = {
19
+ "en-US": en_US_default,
20
+ "nl-BE": nl_BE_default
21
+ };
22
+ export { actionsLocales as t };
@@ -0,0 +1 @@
1
+ const e=`Search...`,t=`Type a command or search...`;var n={"action.group.account":`Account`,"action.group.developer":`Developer`,"action.group.general":`General`,"action.group.navigation":`Navigation`,"action.group.preferences":`Preferences`,search:`Search...`,type_a_command_or_search:`Type a command or search...`};const r=`Zoeken...`,i=`Type een command of zoek...`;var a={"action.group.account":`Account`,"action.group.developer":`Ontwikkelaar`,"action.group.general":`Algemeen`,"action.group.navigation":`Navigatie`,"action.group.preferences":`Voorkeuren`,search:`Zoeken...`,type_a_command_or_search:`Type een command of zoek...`};const o={"en-US":n,"nl-BE":a};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return o}});
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./locales-D5e1O21n.cjs`);exports.actionsLocales=e.t;
@@ -0,0 +1,20 @@
1
+ export declare const actionsLocales: {
2
+ 'en-US': {
3
+ "action.group.account": string;
4
+ "action.group.developer": string;
5
+ "action.group.general": string;
6
+ "action.group.navigation": string;
7
+ "action.group.preferences": string;
8
+ search: string;
9
+ type_a_command_or_search: string;
10
+ };
11
+ 'nl-BE': {
12
+ "action.group.account": string;
13
+ "action.group.developer": string;
14
+ "action.group.general": string;
15
+ "action.group.navigation": string;
16
+ "action.group.preferences": string;
17
+ search: string;
18
+ type_a_command_or_search: string;
19
+ };
20
+ };
@@ -0,0 +1,2 @@
1
+ import { t as actionsLocales } from "./locales-BPtvPqGa.js";
2
+ export { actionsLocales };
@@ -0,0 +1,82 @@
1
+ import { Action } from '../types/action.type.ts';
2
+ import { ActionContext } from '../types/actionContext.type.ts';
3
+ import { ActionModel } from '../types/actionModel.type.ts';
4
+ interface ActionContextOptions {
5
+ keyboardEvent?: KeyboardEvent;
6
+ menuType?: 'commandMenu' | 'contextualMenu';
7
+ metadata?: Record<string, unknown>;
8
+ models?: ActionModel[];
9
+ searchInput?: string;
10
+ subActionsMeta?: Record<string, number | null>;
11
+ }
12
+ declare function executeAction(action: Action, ctx: ActionContext, options?: {
13
+ onComplete?: () => void;
14
+ }): Promise<void>;
15
+ export declare const useActionManagerStore: import('pinia').StoreDefinition<"actionManager", Pick<{
16
+ actionContext: (options: ActionContextOptions) => ActionContext;
17
+ executeAction: typeof executeAction;
18
+ focusedModels: import('vue').Ref<{
19
+ key: string;
20
+ modelName: string;
21
+ }[], ActionModel[] | {
22
+ key: string;
23
+ modelName: string;
24
+ }[]>;
25
+ metadata: import('vue').Ref<Record<string, unknown>, Record<string, unknown>>;
26
+ registerMetadata: (meta: Record<string, unknown>) => void;
27
+ setFocusedModels: (models: ActionModel[]) => void;
28
+ setViewModels: (models: ActionModel[]) => void;
29
+ unregisterMetadata: (key: string) => void;
30
+ viewModels: import('vue').Ref<{
31
+ key: string;
32
+ modelName: string;
33
+ }[], ActionModel[] | {
34
+ key: string;
35
+ modelName: string;
36
+ }[]>;
37
+ }, "metadata" | "focusedModels" | "viewModels">, Pick<{
38
+ actionContext: (options: ActionContextOptions) => ActionContext;
39
+ executeAction: typeof executeAction;
40
+ focusedModels: import('vue').Ref<{
41
+ key: string;
42
+ modelName: string;
43
+ }[], ActionModel[] | {
44
+ key: string;
45
+ modelName: string;
46
+ }[]>;
47
+ metadata: import('vue').Ref<Record<string, unknown>, Record<string, unknown>>;
48
+ registerMetadata: (meta: Record<string, unknown>) => void;
49
+ setFocusedModels: (models: ActionModel[]) => void;
50
+ setViewModels: (models: ActionModel[]) => void;
51
+ unregisterMetadata: (key: string) => void;
52
+ viewModels: import('vue').Ref<{
53
+ key: string;
54
+ modelName: string;
55
+ }[], ActionModel[] | {
56
+ key: string;
57
+ modelName: string;
58
+ }[]>;
59
+ }, never>, Pick<{
60
+ actionContext: (options: ActionContextOptions) => ActionContext;
61
+ executeAction: typeof executeAction;
62
+ focusedModels: import('vue').Ref<{
63
+ key: string;
64
+ modelName: string;
65
+ }[], ActionModel[] | {
66
+ key: string;
67
+ modelName: string;
68
+ }[]>;
69
+ metadata: import('vue').Ref<Record<string, unknown>, Record<string, unknown>>;
70
+ registerMetadata: (meta: Record<string, unknown>) => void;
71
+ setFocusedModels: (models: ActionModel[]) => void;
72
+ setViewModels: (models: ActionModel[]) => void;
73
+ unregisterMetadata: (key: string) => void;
74
+ viewModels: import('vue').Ref<{
75
+ key: string;
76
+ modelName: string;
77
+ }[], ActionModel[] | {
78
+ key: string;
79
+ modelName: string;
80
+ }[]>;
81
+ }, "actionContext" | "executeAction" | "registerMetadata" | "setFocusedModels" | "setViewModels" | "unregisterMetadata">>;
82
+ export {};
@@ -0,0 +1,17 @@
1
+ import { Action } from '../types/action.type.ts';
2
+ export declare const useActionRegistryStore: import('pinia').StoreDefinition<"actionRegistry", Pick<{
3
+ allActions: () => Action[];
4
+ registerActions: (...actions: Action[]) => void;
5
+ registerTemporaryAction: (action: Action) => number;
6
+ unregisterAction: (id: number) => void;
7
+ }, never>, Pick<{
8
+ allActions: () => Action[];
9
+ registerActions: (...actions: Action[]) => void;
10
+ registerTemporaryAction: (action: Action) => number;
11
+ unregisterAction: (id: number) => void;
12
+ }, never>, Pick<{
13
+ allActions: () => Action[];
14
+ registerActions: (...actions: Action[]) => void;
15
+ registerTemporaryAction: (action: Action) => number;
16
+ unregisterAction: (id: number) => void;
17
+ }, "allActions" | "registerActions" | "registerTemporaryAction" | "unregisterAction">>;
@@ -0,0 +1,225 @@
1
+ import { Component } from 'vue';
2
+ import { Resolvable } from './actionContext.type.ts';
3
+ import { ActionGroup } from './actionGroup.type.ts';
4
+ import { KeyboardShortcut } from './keyboardShortcut.type.ts';
5
+ export interface ActionAvatar {
6
+ /**
7
+ * By default, the avatar's background color is generated based on
8
+ * the provided name to ensure consistency across renders.
9
+ * Setting this prop to `true` will disable this behavior and
10
+ * use a static background color instead.
11
+ */
12
+ isStaticColor?: boolean;
13
+ /**
14
+ * The name used to generate fallback initials.
15
+ */
16
+ name: string;
17
+ /**
18
+ * The image source URL for the avatar's logo.
19
+ * Falls back to initials when not provided.
20
+ * @default null
21
+ */
22
+ logo?: string | null;
23
+ /**
24
+ * The image source URL for the avatar.
25
+ * Falls back to initials when not provided.
26
+ * @default null
27
+ */
28
+ src?: string | null;
29
+ }
30
+ export interface SearchSubActionsConfig {
31
+ maxResults?: number;
32
+ minLength?: number;
33
+ placeholder?: (() => string) | string;
34
+ }
35
+ export interface SubActionsWithMeta<TContext = any> {
36
+ actions: Action<TContext>[];
37
+ /** Next-page cursor offset. Pass back via `ctx.subActionsMeta` to fetch the next page. `null` = no more pages. */
38
+ pagination: {
39
+ nextOffset: number | null;
40
+ };
41
+ }
42
+ export interface Action<TContext = any> {
43
+ /**
44
+ * Stable UUID used for deduplication and keyboard-shortcut registration.
45
+ * Generated once at definition time (e.g. via crypto.randomUUID()).
46
+ */
47
+ id: string;
48
+ /**
49
+ * Returns false to hide the action entirely from the menu.
50
+ * Evaluated once per render cycle.
51
+ */
52
+ isApplicable?: (ctx: TContext) => boolean;
53
+ /**
54
+ * Primary display name. May be a static string or a function that reads the
55
+ * context (e.g. to return "Add" vs "Remove" based on current selection).
56
+ */
57
+ name: Resolvable<string, TContext>;
58
+ /**
59
+ * When false (default), the action is hidden when the user is not authenticated.
60
+ * Set to true to keep the action visible on unauthenticated views (e.g. login page).
61
+ */
62
+ availableWhenUnauthenticated?: boolean;
63
+ /**
64
+ *
65
+ */
66
+ avatar?: Resolvable<ActionAvatar, TContext>;
67
+ /**
68
+ * Returns a human-readable string explaining why the action is disabled, or
69
+ * undefined / null if it is enabled.
70
+ * A disabled action is still visible (greyed out) with the reason as a tooltip.
71
+ */
72
+ disabledReason?: (ctx: TContext) => string | null | undefined;
73
+ /**
74
+ * Called when the user activates the action.
75
+ * May return a Promise for async operations.
76
+ */
77
+ execute?: (ctx: TContext) => Promise<void> | void;
78
+ /**
79
+ * When true is set on an action, it prevents the action from being set
80
+ * as the parent action when opening its sub-menu
81
+ */
82
+ forceAsRootMenu?: boolean;
83
+ /**
84
+ * The group this action belongs to.
85
+ */
86
+ group?: ActionGroup<TContext>;
87
+ /**
88
+ * Short secondary label shown next to the action name (e.g. in the command
89
+ * menu). Use this to provide extra context that does not fit in the name —
90
+ * for example a file path, a record ID, or a status badge.
91
+ *
92
+ * May be a static string, `null`, or a function that reads the context.
93
+ */
94
+ hint?: Resolvable<string | null, TContext>;
95
+ /**
96
+ * Optionally show an icon for the action
97
+ */
98
+ icon?: (ctx: TContext) => Component | null;
99
+ /**
100
+ * Optional string key used for deduplication when the same logical action is
101
+ * registered from multiple places. Only the first registration wins.
102
+ */
103
+ key?: string;
104
+ /**
105
+ * Keyboard shortcut
106
+ */
107
+ keyboardShortcut?: KeyboardShortcut;
108
+ /**
109
+ * Extra search terms (not displayed) that boost discoverability.
110
+ * Matched against the fuzzy query in addition to name.
111
+ */
112
+ keywords?: string | string[];
113
+ /**
114
+ * Keywords that must be an exact substring match (case-insensitive) to boost
115
+ * the action score to 1.0.
116
+ */
117
+ keywordsExactMatch?: string[];
118
+ /**
119
+ * When set to true, the command menu will not close when toggling its sub actions
120
+ */
121
+ multiSelectSubActions?: boolean;
122
+ /**
123
+ * The name to show in breadcrumbs / parent references when this action is a
124
+ * parent of a sub-action drill-down. Falls back to `name` when absent.
125
+ */
126
+ nameAsParent?: Resolvable<string, TContext>;
127
+ /**
128
+ * The parent action of this action, if it is a sub-action. Injected automatically when drilling down or lifting.
129
+ */
130
+ parentAction?: Action<TContext>;
131
+ /**
132
+ * Controls how parent actions influence this action’s fuzzy search score.
133
+ *
134
+ * By default, parent metadata (e.g. parent label / context) is included in the
135
+ * scoring input to improve discoverability of nested actions.
136
+ *
137
+ * This option allows you to reduce or fully remove that influence.
138
+ *
139
+ * Values:
140
+ * - 'none' → Parents actions are fully excluded in scoring
141
+ * - 'direct' → Only the direct parent is included in the scoring
142
+ * - 'all' → All parent context is included
143
+ *
144
+ * @default 'all'
145
+ */
146
+ parentScoreInfluence?: 'all' | 'direct' | 'none';
147
+ /**
148
+ * Returns a Vue component displayed in a side panel when the user presses
149
+ * the right arrow key while this action is focused. Useful for showing a
150
+ * richer preview (e.g. details, metadata, a summary) without leaving the
151
+ * current menu context.
152
+ */
153
+ preview?: (ctx: TContext) => Component | null;
154
+ /**
155
+ * The root action of this action, if it is a sub-action. Injected automatically when drilling down or lifting.
156
+ */
157
+ rootAction?: Action<TContext>;
158
+ /**
159
+ * Override the computed fuzzy score with a fixed value.
160
+ * Applied after parent-action penalty and before sortPriority.
161
+ */
162
+ scoreOverride?: number;
163
+ /**
164
+ * Fine-grained control over how sub-actions are searched and displayed.
165
+ */
166
+ searchSubActionsConfig?: Resolvable<SearchSubActionsConfig, TContext>;
167
+ /**
168
+ * When resolved to true, a checkmark / selected indicator is shown.
169
+ * Used for toggle actions.
170
+ */
171
+ selected?: Resolvable<boolean, TContext>;
172
+ /**
173
+ * Groups this action into a named visual section for context menus and dropdown
174
+ * menus. A separator is rendered whenever the section key changes between two
175
+ * adjacent visible actions. Actions without a separatorGroup (or sharing the
176
+ * same key) are rendered without a separator between them.
177
+ *
178
+ * Has no effect when a search query is active.
179
+ *
180
+ * @example
181
+ * // Edit action — no separatorGroup (default section)
182
+ * // Availability actions — separatorGroup: 'availability'
183
+ * // Delete action — separatorGroup: 'delete'
184
+ * // → separator before first availability action and before delete
185
+ */
186
+ separatorGroup?: string;
187
+ /**
188
+ * Controls whether selected sub-actions are sorted to the top of the list.
189
+ *
190
+ * @default true
191
+ */
192
+ showSelectedSubActionsFirst?: boolean;
193
+ /**
194
+ * When true, this action is always included in results regardless of its fuzzy
195
+ * score (score is overridden to 1.0 when filtering is skipped).
196
+ */
197
+ skipFilterScoring?: boolean;
198
+ /**
199
+ * Manual sort offset applied after score-based sorting.
200
+ * Positive values push the action down; negative values pull it up.
201
+ */
202
+ sortPriority?: number;
203
+ /**
204
+ * Factory that returns child actions. When the user selects this action the
205
+ * menu drills down into the child list.
206
+ * During a search query, child actions are "lifted" to the top level with
207
+ * parentAction / rootAction injected.
208
+ *
209
+ * May return a `SubActionsWithMeta` wrapper to carry pagination state. The
210
+ * meta is stored by the host menu and passed back via `ctx.subActionsMeta`
211
+ * (keyed by this action's id) on subsequent "load more" calls.
212
+ */
213
+ subActions?: (ctx: TContext) => Action<TContext>[] | AsyncGenerator<Action<TContext>> | Promise<Action<TContext>[] | SubActionsWithMeta<TContext>> | SubActionsWithMeta<TContext>;
214
+ /**
215
+ * When true, keyboard shortcuts defined on sub-actions are registered globally.
216
+ * The actionShortcuts composable will recursively resolve sub-actions (synchronous
217
+ * results only) and include their shortcuts in the global hotkey map.
218
+ */
219
+ subActionsHaveKeyboardShortcuts?: boolean;
220
+ /**
221
+ * When true the action is hidden in the root menu (no search query).
222
+ * It only appears in search results.
223
+ */
224
+ onlyVisibleThroughSearch?: boolean;
225
+ }
@@ -0,0 +1,112 @@
1
+ import { Router } from 'vue-router';
2
+ import { ActionModel } from './actionModel.type.ts';
3
+ /**
4
+ * Contextual information available to actions during execution or evaluation.
5
+ * Provides access to models, routing state, user input, and UI context.
6
+ *
7
+ * @template TModelMap - A map of model names to their corresponding types.
8
+ * @template TRouter - A tuple of route definition objects, each having at least a `name` property.
9
+ */
10
+ export interface ActionContext<TModelMap = Record<string, ActionModel>, TRoutes extends any[] = any[], TMetadata = any> {
11
+ /**
12
+ * Returns the stored pagination offset for a given action id, or `null` if no
13
+ * offset is stored (initial call) or all pages are exhausted.
14
+ */
15
+ getPaginationOffsetForSubActionId: (id: string) => number | null;
16
+ /**
17
+ * Returns whether any dialog is currently open and active in the UI.
18
+ *
19
+ * @returns `true` if at least one dialog is currently active.
20
+ */
21
+ hasActiveDialogs: () => boolean;
22
+ /**
23
+ * Returns whether any targeted models of the given type are currently selected.
24
+ *
25
+ * @template TModelName - A key of `TModelMap`.
26
+ * @param modelName - The model type to check for.
27
+ * @returns `true` if at least one targeted model of the given type exists.
28
+ */
29
+ hasTargetedModelsOfType: <TModelName extends keyof TModelMap>(modelName: TModelName) => boolean;
30
+ /**
31
+ * Returns whether the specified route is currently active.
32
+ *
33
+ * @param routeName - The name of the route to check, constrained to known route names in `TRouter`.
34
+ * @param exact - When `true`, requires an exact route match rather than a prefix match. Defaults to `false`.
35
+ * @returns `true` if the route is active.
36
+ */
37
+ isRouteActive: (routeName: TRoutes[number]['name'], exact?: boolean) => boolean;
38
+ /**
39
+ * All models currently available in the application, regardless of selection or focus state.
40
+ */
41
+ allModels: TModelMap[keyof TModelMap][];
42
+ /**
43
+ * Models that currently have keyboard or UI focus.
44
+ * A subset of {@link allModels}.
45
+ */
46
+ focusedModels: TModelMap[keyof TModelMap][];
47
+ /**
48
+ * The keyboard event that triggered the current action, if any.
49
+ * Absent when the action was triggered through a non-keyboard interaction.
50
+ */
51
+ keyboardEvent?: KeyboardEvent;
52
+ /**
53
+ * The type of menu from which the action was invoked, if applicable.
54
+ *
55
+ * - `'commandMenu'` — triggered from a command palette or global search menu.
56
+ * - `'contextualMenu'` — triggered from a right-click or context-sensitive menu.
57
+ *
58
+ * Absent when the action was not invoked from a menu.
59
+ */
60
+ menuType?: 'commandMenu' | 'contextualMenu';
61
+ /**
62
+ * Arbitrary key/value data registered by components via `registerMetadata`.
63
+ * Typed at the application level by augmenting `TMetadata`.
64
+ */
65
+ metadata: TMetadata;
66
+ /**
67
+ * The currently targeted (selected) models.
68
+ * This is the primary set of models the action should operate on.
69
+ */
70
+ models: TModelMap[keyof TModelMap][];
71
+ /**
72
+ * The application's router state, represented as a tuple of route objects.
73
+ * Each entry corresponds to a route definition with at least a `name` field.
74
+ */
75
+ router: Router;
76
+ /**
77
+ * The current search or filter string entered by the user in the active menu.
78
+ * Empty string when no input has been provided.
79
+ */
80
+ searchInput: string;
81
+ /**
82
+ * Pagination offsets from previous `subActions` calls, keyed by action id.
83
+ * Set by the host menu when triggering a "load more" scroll event.
84
+ * Prefer `getPaginationOffsetForSubActionId` over reading this directly.
85
+ */
86
+ subActionsMeta?: Record<string, number | null>;
87
+ /**
88
+ * Returns the targeted model filtered to only those matching the given model type.
89
+ *
90
+ * @template TModelName - A key of `TModelMap`.
91
+ * @param modelName - The model type to filter by.
92
+ * @returns An first targeted model of the specified type, or null
93
+ */
94
+ targetedModelOfType: <TModelName extends keyof TModelMap>(modelName: TModelName) => TModelMap[TModelName] | null;
95
+ /**
96
+ * Returns the targeted model filtered to only those matching the given model type.
97
+ *
98
+ * @template TModelName - A key of `TModelMap`.
99
+ * @param modelName - The model type to filter by.
100
+ * @returns An first targeted model of the specified type.
101
+ */
102
+ targetedModelOfTypeOrThrow: <TModelName extends keyof TModelMap>(modelName: TModelName) => TModelMap[TModelName];
103
+ /**
104
+ * Returns the targeted models filtered to only those matching the given model type.
105
+ *
106
+ * @template TModelName - A key of `TModelMap`.
107
+ * @param modelName - The model type to filter by.
108
+ * @returns An array of targeted models of the specified type.
109
+ */
110
+ targetedModelsOfType: <TModelName extends keyof TModelMap>(modelName: TModelName) => TModelMap[TModelName][];
111
+ }
112
+ export type Resolvable<T, TContext> = ((ctx: TContext) => T) | T;
@@ -0,0 +1,19 @@
1
+ import { Component } from 'vue';
2
+ import { ActionContext, Resolvable } from './actionContext.type.ts';
3
+ export interface ActionGroup<TActionContext = any> {
4
+ name?: Resolvable<string, TActionContext>;
5
+ category?: Resolvable<string, TActionContext>;
6
+ /**
7
+ * When a child action is "lifted" into a top-level search result, its group is
8
+ * replaced with this one rather than the original group.
9
+ * Used to keep lifted children in a logical section (e.g. the parent's group).
10
+ */
11
+ groupWhenLifted?: ActionGroup<TActionContext>;
12
+ icon?: (ctx: ActionContext) => Component;
13
+ priority?: Resolvable<number, TActionContext>;
14
+ /**
15
+ * When there's only 1 group in the command menu results, the group label is hidden by default.
16
+ * When set to true, the label of this group will always be visible, even if there's only 1 group
17
+ */
18
+ showIfOnlyGroup?: boolean;
19
+ }
@@ -0,0 +1,4 @@
1
+ export interface ActionModel {
2
+ key: string;
3
+ modelName: string;
4
+ }
@@ -0,0 +1,11 @@
1
+ import { Action } from './action.type.ts';
2
+ export interface NavFrame {
3
+ actions: Action[];
4
+ parentAction: Action;
5
+ /** The action that was highlighted when we drilled in (so we can re-focus it on back). */
6
+ savedActiveAction: Action | null;
7
+ /** Resolved (filtered) actions at the time we drilled in, so we can restore them instantly on back. */
8
+ savedResolvedActions: Action[];
9
+ /** Search query active at the moment we drilled into this frame. */
10
+ savedSearchInput: string;
11
+ }
@@ -0,0 +1,26 @@
1
+ import { HotkeySequence, RawHotkey } from '@tanstack/vue-hotkeys';
2
+ /**
3
+ * A multi-step key sequence shortcut (e.g. ['g', 's'] — press g then s).
4
+ * Maps to TanStack's HotkeySequence.
5
+ */
6
+ export interface SequenceShortcut {
7
+ /**
8
+ * When true the shortcut fires even when a text input has focus.
9
+ * Default: false — shortcuts are suppressed while typing.
10
+ */
11
+ runWithInputFocus?: boolean;
12
+ sequence: HotkeySequence;
13
+ }
14
+ /**
15
+ * A single-key shortcut (e.g. Mod+S).
16
+ * Maps directly to TanStack's RawHotkey plus the `runWithInputFocus` flag.
17
+ */
18
+ export type SingleKeyShortcut = RawHotkey & {
19
+ /**
20
+ * When true the shortcut fires even when a text input has focus.
21
+ * Default: false — shortcuts are suppressed while typing.
22
+ */
23
+ runWithInputFocus?: boolean;
24
+ sequence?: never;
25
+ };
26
+ export type KeyboardShortcut = SequenceShortcut | SingleKeyShortcut;
@@ -0,0 +1,12 @@
1
+ import { Component } from 'vue';
2
+ import { Action } from '../types/action.type.ts';
3
+ import { ActionContext } from '../types/actionContext.type.ts';
4
+ export interface CommandMenuGroup {
5
+ category: string | null;
6
+ icon: Component | null;
7
+ items: Action[];
8
+ key: string;
9
+ label: string | null;
10
+ showIfOnlyGroup: boolean;
11
+ }
12
+ export declare function buildCommandMenuGroups(actions: Action[], ctx: ActionContext): CommandMenuGroup[];
@@ -0,0 +1,13 @@
1
+ import { Component } from 'vue';
2
+ import { Action, ActionAvatar, SearchSubActionsConfig } from '../types/action.type.ts';
3
+ import { ActionContext } from '../types/actionContext.type.ts';
4
+ export type ActionFactory = (() => Action[]) | Action;
5
+ export declare function applicableActions(actions: Action[], ctx: ActionContext, onUpdate?: (partial: Action[]) => void, parentAction?: Action): Promise<Action[]>;
6
+ export declare function resolveApplicable(action: Action, ctx: ActionContext): boolean;
7
+ export declare function resolveActionValue<T>(value: ((ctx: ActionContext) => T) | T, ctx: ActionContext): T;
8
+ export declare function resolveActionName(action: Action, ctx: ActionContext): string;
9
+ export declare function resolveActionAvatar(action: Action, ctx: ActionContext): ActionAvatar | null;
10
+ export declare function resolveActionHint(action: Action, ctx: ActionContext): string | null;
11
+ export declare function resolveActionSelected(action: Action, ctx: ActionContext): boolean | null;
12
+ export declare function resolveSearchSubActionsConfig(action: Action, ctx: ActionContext): SearchSubActionsConfig | null;
13
+ export declare function resolveActionPreview(action: Action, ctx: ActionContext): Component | null;
@@ -0,0 +1,5 @@
1
+ import { Action, SubActionsWithMeta } from '../types/action.type.ts';
2
+ import { ActionContext } from '../types/actionContext.type.ts';
3
+ export declare function isSubActionsWithMeta(v: unknown): v is SubActionsWithMeta;
4
+ export declare function storeSubActionsPagination(action: Action, result: Action[] | SubActionsWithMeta, subActionsMetaMap: Record<string, number | null>): Action[];
5
+ export declare function resolveSubActions(action: Action, ctx: ActionContext, subActionsMetaMap: Record<string, number | null>, limit?: number): Promise<Action[]>;