use-kbd 0.4.0 → 0.6.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.
- package/dist/index.cjs +884 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +288 -33
- package/dist/index.d.ts +288 -33
- package/dist/index.js +882 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/styles.css +48 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as react from 'react';
|
|
3
2
|
import { ReactNode, ComponentType, RefObject, SVGProps, CSSProperties } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Modifier keys state
|
|
@@ -24,7 +24,6 @@ interface KeyCombination {
|
|
|
24
24
|
* Represents a hotkey - either a single key or a sequence of keys.
|
|
25
25
|
* Single key: [{ key: 'k', modifiers: {...} }]
|
|
26
26
|
* Sequence: [{ key: '2', ... }, { key: 'w', ... }]
|
|
27
|
-
* @deprecated Use KeySeq for new code
|
|
28
27
|
*/
|
|
29
28
|
type HotkeySequence = KeyCombination[];
|
|
30
29
|
/**
|
|
@@ -118,10 +117,6 @@ interface RecordHotkeyResult {
|
|
|
118
117
|
activeKeys: KeyCombination | null;
|
|
119
118
|
/** The timeout duration for sequences (ms) */
|
|
120
119
|
sequenceTimeout: number;
|
|
121
|
-
/**
|
|
122
|
-
* @deprecated Use `sequence` instead
|
|
123
|
-
*/
|
|
124
|
-
combination: KeyCombination | null;
|
|
125
120
|
}
|
|
126
121
|
/**
|
|
127
122
|
* Options for useRecordHotkey
|
|
@@ -160,6 +155,8 @@ interface ActionDefinition {
|
|
|
160
155
|
icon?: string;
|
|
161
156
|
/** Whether the action is currently enabled (default: true) */
|
|
162
157
|
enabled?: boolean;
|
|
158
|
+
/** Hide from ShortcutsModal (still searchable in omnibar) */
|
|
159
|
+
hideFromModal?: boolean;
|
|
163
160
|
}
|
|
164
161
|
/**
|
|
165
162
|
* Registry of all available actions
|
|
@@ -184,15 +181,125 @@ interface ActionSearchResult {
|
|
|
184
181
|
* A possible completion for a partially-typed sequence
|
|
185
182
|
*/
|
|
186
183
|
interface SequenceCompletion {
|
|
187
|
-
/** The next key(s) needed to complete this sequence */
|
|
184
|
+
/** The next key(s) needed to complete this sequence (empty string if complete) */
|
|
188
185
|
nextKeys: string;
|
|
186
|
+
/** Structured next keys for rendering with icons (undefined if complete) */
|
|
187
|
+
nextKeySeq?: KeySeq;
|
|
189
188
|
/** The full hotkey string */
|
|
190
189
|
fullSequence: string;
|
|
191
190
|
/** Display format for the full sequence */
|
|
192
191
|
display: KeyCombinationDisplay;
|
|
193
192
|
/** Actions triggered by this sequence */
|
|
194
193
|
actions: string[];
|
|
194
|
+
/** Whether the sequence is already complete (can be executed now with Enter) */
|
|
195
|
+
isComplete: boolean;
|
|
196
|
+
/** Captured digit values from \d and \d+ placeholders */
|
|
197
|
+
captures?: number[];
|
|
195
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Base fields for all omnibar entries
|
|
201
|
+
*/
|
|
202
|
+
interface OmnibarEntryBase {
|
|
203
|
+
/** Unique identifier for this entry */
|
|
204
|
+
id: string;
|
|
205
|
+
/** Display label */
|
|
206
|
+
label: string;
|
|
207
|
+
/** Optional description (shown below label) */
|
|
208
|
+
description?: string;
|
|
209
|
+
/** Group name for organizing results */
|
|
210
|
+
group?: string;
|
|
211
|
+
/** Additional search keywords */
|
|
212
|
+
keywords?: string[];
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Omnibar entry that navigates to a URL when selected
|
|
216
|
+
*/
|
|
217
|
+
interface OmnibarLinkEntry extends OmnibarEntryBase {
|
|
218
|
+
/** URL to navigate to */
|
|
219
|
+
href: string;
|
|
220
|
+
handler?: never;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Omnibar entry that executes a handler when selected
|
|
224
|
+
*/
|
|
225
|
+
interface OmnibarActionEntry extends OmnibarEntryBase {
|
|
226
|
+
/** Handler to execute (can close over data) */
|
|
227
|
+
handler: () => void;
|
|
228
|
+
href?: never;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* An entry returned from a remote omnibar endpoint.
|
|
232
|
+
* Must have either `href` (for navigation) or `handler` (for custom action).
|
|
233
|
+
*/
|
|
234
|
+
type OmnibarEntry = OmnibarLinkEntry | OmnibarActionEntry;
|
|
235
|
+
/**
|
|
236
|
+
* Pagination parameters passed to endpoint fetch function
|
|
237
|
+
*/
|
|
238
|
+
interface EndpointPagination {
|
|
239
|
+
/** Starting offset (0-indexed) */
|
|
240
|
+
offset: number;
|
|
241
|
+
/** Maximum number of entries to return */
|
|
242
|
+
limit: number;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Response from an endpoint fetch, including pagination metadata
|
|
246
|
+
*/
|
|
247
|
+
interface EndpointResponse {
|
|
248
|
+
/** Entries for this page */
|
|
249
|
+
entries: OmnibarEntry[];
|
|
250
|
+
/** Total count if known (enables "X of Y" display) */
|
|
251
|
+
total?: number;
|
|
252
|
+
/** Whether more results exist (fallback when total is expensive to compute) */
|
|
253
|
+
hasMore?: boolean;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Pagination mode for an endpoint
|
|
257
|
+
* - 'scroll': Fetch more when scrolling near bottom (IntersectionObserver)
|
|
258
|
+
* - 'buttons': Show pagination controls at bottom of endpoint's group
|
|
259
|
+
* - 'none': Single page, no pagination (default)
|
|
260
|
+
*/
|
|
261
|
+
type EndpointPaginationMode = 'scroll' | 'buttons' | 'none';
|
|
262
|
+
/**
|
|
263
|
+
* Base configuration shared by async and sync endpoints
|
|
264
|
+
*/
|
|
265
|
+
interface OmnibarEndpointConfigBase {
|
|
266
|
+
/** Default group for entries from this endpoint */
|
|
267
|
+
group?: string;
|
|
268
|
+
/** Priority for result ordering (higher = shown first, default: 0, local actions: 100) */
|
|
269
|
+
priority?: number;
|
|
270
|
+
/** Minimum query length before fetching (default: 2) */
|
|
271
|
+
minQueryLength?: number;
|
|
272
|
+
/** Whether this endpoint is enabled (default: true) */
|
|
273
|
+
enabled?: boolean;
|
|
274
|
+
/** Number of results per page (default: 10) */
|
|
275
|
+
pageSize?: number;
|
|
276
|
+
/** Pagination mode (default: 'none') */
|
|
277
|
+
pagination?: EndpointPaginationMode;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Configuration for an async omnibar endpoint (remote API calls)
|
|
281
|
+
*/
|
|
282
|
+
interface OmnibarEndpointAsyncConfig extends OmnibarEndpointConfigBase {
|
|
283
|
+
/** Async fetch function for remote data sources */
|
|
284
|
+
fetch: (query: string, signal: AbortSignal, pagination: EndpointPagination) => Promise<EndpointResponse>;
|
|
285
|
+
filter?: never;
|
|
286
|
+
/** Internal: true if this was originally a sync endpoint (skip debouncing) */
|
|
287
|
+
isSync?: boolean;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Configuration for a sync omnibar endpoint (in-memory filtering)
|
|
291
|
+
*
|
|
292
|
+
* Sync endpoints skip debouncing for instant results.
|
|
293
|
+
*/
|
|
294
|
+
interface OmnibarEndpointSyncConfig extends OmnibarEndpointConfigBase {
|
|
295
|
+
/** Sync filter function for in-memory data sources */
|
|
296
|
+
filter: (query: string, pagination: EndpointPagination) => EndpointResponse;
|
|
297
|
+
fetch?: never;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Configuration for an omnibar endpoint (async or sync)
|
|
301
|
+
*/
|
|
302
|
+
type OmnibarEndpointConfig = OmnibarEndpointAsyncConfig | OmnibarEndpointSyncConfig;
|
|
196
303
|
|
|
197
304
|
/**
|
|
198
305
|
* Hotkey definition - maps key combinations/sequences to action names
|
|
@@ -306,6 +413,71 @@ interface UseEditableHotkeysResult {
|
|
|
306
413
|
*/
|
|
307
414
|
declare function useEditableHotkeys(defaults: HotkeyMap, handlers: HandlerMap, options?: UseEditableHotkeysOptions): UseEditableHotkeysResult;
|
|
308
415
|
|
|
416
|
+
interface RegisteredEndpoint {
|
|
417
|
+
id: string;
|
|
418
|
+
/** Internal config is always async (useOmnibarEndpoint normalizes sync endpoints) */
|
|
419
|
+
config: OmnibarEndpointAsyncConfig;
|
|
420
|
+
registeredAt: number;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Result from querying an endpoint
|
|
424
|
+
*/
|
|
425
|
+
interface EndpointQueryResult {
|
|
426
|
+
endpointId: string;
|
|
427
|
+
entries: OmnibarEntry[];
|
|
428
|
+
/** Total count from endpoint (if provided) */
|
|
429
|
+
total?: number;
|
|
430
|
+
/** Whether endpoint has more results (if provided) */
|
|
431
|
+
hasMore?: boolean;
|
|
432
|
+
error?: Error;
|
|
433
|
+
}
|
|
434
|
+
interface OmnibarEndpointsRegistryValue {
|
|
435
|
+
/** Register an endpoint. Called by useOmnibarEndpoint on mount. */
|
|
436
|
+
register: (id: string, config: OmnibarEndpointAsyncConfig) => void;
|
|
437
|
+
/** Unregister an endpoint. Called by useOmnibarEndpoint on unmount. */
|
|
438
|
+
unregister: (id: string) => void;
|
|
439
|
+
/** Currently registered endpoints */
|
|
440
|
+
endpoints: Map<string, RegisteredEndpoint>;
|
|
441
|
+
/** Query all registered endpoints (initial page) */
|
|
442
|
+
queryAll: (query: string, signal: AbortSignal) => Promise<EndpointQueryResult[]>;
|
|
443
|
+
/** Query a single endpoint with specific pagination (for load-more) */
|
|
444
|
+
queryEndpoint: (endpointId: string, query: string, pagination: EndpointPagination, signal: AbortSignal) => Promise<EndpointQueryResult | null>;
|
|
445
|
+
}
|
|
446
|
+
declare const OmnibarEndpointsRegistryContext: react.Context<OmnibarEndpointsRegistryValue | null>;
|
|
447
|
+
/**
|
|
448
|
+
* Hook to create an omnibar endpoints registry.
|
|
449
|
+
* Used internally by HotkeysProvider.
|
|
450
|
+
*/
|
|
451
|
+
declare function useOmnibarEndpointsRegistry(): OmnibarEndpointsRegistryValue;
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Result from remote endpoint, normalized for display
|
|
455
|
+
*/
|
|
456
|
+
interface RemoteOmnibarResult {
|
|
457
|
+
/** Unique ID (prefixed with endpoint ID) */
|
|
458
|
+
id: string;
|
|
459
|
+
/** Entry data from endpoint */
|
|
460
|
+
entry: OmnibarEntry;
|
|
461
|
+
/** Endpoint ID this came from */
|
|
462
|
+
endpointId: string;
|
|
463
|
+
/** Priority from endpoint config */
|
|
464
|
+
priority: number;
|
|
465
|
+
/** Fuzzy match score */
|
|
466
|
+
score: number;
|
|
467
|
+
/** Matched ranges in label for highlighting */
|
|
468
|
+
labelMatches: Array<[number, number]>;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Pagination info for an endpoint's results group
|
|
472
|
+
*/
|
|
473
|
+
interface EndpointPaginationInfo {
|
|
474
|
+
endpointId: string;
|
|
475
|
+
loaded: number;
|
|
476
|
+
total?: number;
|
|
477
|
+
hasMore: boolean;
|
|
478
|
+
isLoading: boolean;
|
|
479
|
+
mode: EndpointPaginationMode;
|
|
480
|
+
}
|
|
309
481
|
interface UseOmnibarOptions {
|
|
310
482
|
/** Registry of available actions */
|
|
311
483
|
actions: ActionRegistry;
|
|
@@ -319,12 +491,18 @@ interface UseOmnibarOptions {
|
|
|
319
491
|
enabled?: boolean;
|
|
320
492
|
/** Called when an action is executed (if handlers not provided, or in addition to) */
|
|
321
493
|
onExecute?: (actionId: string) => void;
|
|
494
|
+
/** Called when a remote entry is executed */
|
|
495
|
+
onExecuteRemote?: (entry: OmnibarEntry) => void;
|
|
322
496
|
/** Called when omnibar opens */
|
|
323
497
|
onOpen?: () => void;
|
|
324
498
|
/** Called when omnibar closes */
|
|
325
499
|
onClose?: () => void;
|
|
326
500
|
/** Maximum number of results to show (default: 10) */
|
|
327
501
|
maxResults?: number;
|
|
502
|
+
/** Remote endpoints registry (optional - enables remote search) */
|
|
503
|
+
endpointsRegistry?: OmnibarEndpointsRegistryValue;
|
|
504
|
+
/** Debounce time for remote queries in ms (default: 150) */
|
|
505
|
+
debounceMs?: number;
|
|
328
506
|
}
|
|
329
507
|
interface UseOmnibarResult {
|
|
330
508
|
/** Whether omnibar is open */
|
|
@@ -339,10 +517,20 @@ interface UseOmnibarResult {
|
|
|
339
517
|
query: string;
|
|
340
518
|
/** Set the search query */
|
|
341
519
|
setQuery: (query: string) => void;
|
|
342
|
-
/**
|
|
520
|
+
/** Local action search results (filtered and sorted) */
|
|
343
521
|
results: ActionSearchResult[];
|
|
344
|
-
/**
|
|
522
|
+
/** Remote endpoint results */
|
|
523
|
+
remoteResults: RemoteOmnibarResult[];
|
|
524
|
+
/** Whether any remote endpoint is loading (initial or more) */
|
|
525
|
+
isLoadingRemote: boolean;
|
|
526
|
+
/** Pagination info per endpoint */
|
|
527
|
+
endpointPagination: Map<string, EndpointPaginationInfo>;
|
|
528
|
+
/** Load more results for a specific endpoint */
|
|
529
|
+
loadMore: (endpointId: string) => void;
|
|
530
|
+
/** Currently selected result index (across local + remote) */
|
|
345
531
|
selectedIndex: number;
|
|
532
|
+
/** Total number of results (local + remote) */
|
|
533
|
+
totalResults: number;
|
|
346
534
|
/** Select the next result */
|
|
347
535
|
selectNext: () => void;
|
|
348
536
|
/** Select the previous result */
|
|
@@ -733,10 +921,15 @@ interface OmnibarProps {
|
|
|
733
921
|
*/
|
|
734
922
|
onClose?: () => void;
|
|
735
923
|
/**
|
|
736
|
-
* Called when
|
|
924
|
+
* Called when a local action is executed.
|
|
737
925
|
* If not provided, uses executeAction from HotkeysContext.
|
|
738
926
|
*/
|
|
739
927
|
onExecute?: (actionId: string) => void;
|
|
928
|
+
/**
|
|
929
|
+
* Called when a remote omnibar entry is executed.
|
|
930
|
+
* Use this to handle navigation for entries with `href`.
|
|
931
|
+
*/
|
|
932
|
+
onExecuteRemote?: (entry: OmnibarEntry) => void;
|
|
740
933
|
/** Maximum number of results to show (default: 10) */
|
|
741
934
|
maxResults?: number;
|
|
742
935
|
/** Placeholder text for input (default: 'Type a command...') */
|
|
@@ -751,8 +944,20 @@ interface OmnibarProps {
|
|
|
751
944
|
interface OmnibarRenderProps {
|
|
752
945
|
query: string;
|
|
753
946
|
setQuery: (query: string) => void;
|
|
947
|
+
/** Local action search results */
|
|
754
948
|
results: ActionSearchResult[];
|
|
949
|
+
/** Remote endpoint results */
|
|
950
|
+
remoteResults: RemoteOmnibarResult[];
|
|
951
|
+
/** Whether remote endpoints are being queried */
|
|
952
|
+
isLoadingRemote: boolean;
|
|
953
|
+
/** Pagination info per endpoint */
|
|
954
|
+
endpointPagination: Map<string, EndpointPaginationInfo>;
|
|
955
|
+
/** Load more results for a specific endpoint */
|
|
956
|
+
loadMore: (endpointId: string) => void;
|
|
957
|
+
/** Currently selected index (across local + remote) */
|
|
755
958
|
selectedIndex: number;
|
|
959
|
+
/** Total number of results (local + remote) */
|
|
960
|
+
totalResults: number;
|
|
756
961
|
selectNext: () => void;
|
|
757
962
|
selectPrev: () => void;
|
|
758
963
|
execute: (actionId?: string) => void;
|
|
@@ -796,7 +1001,7 @@ interface OmnibarRenderProps {
|
|
|
796
1001
|
* />
|
|
797
1002
|
* ```
|
|
798
1003
|
*/
|
|
799
|
-
declare function Omnibar({ actions: actionsProp, handlers: handlersProp, keymap: keymapProp, defaultBinding, isOpen: isOpenProp, onOpen: onOpenProp, onClose: onCloseProp, onExecute: onExecuteProp, maxResults, placeholder, children, backdropClassName, omnibarClassName, }: OmnibarProps): react_jsx_runtime.JSX.Element | null;
|
|
1004
|
+
declare function Omnibar({ actions: actionsProp, handlers: handlersProp, keymap: keymapProp, defaultBinding, isOpen: isOpenProp, onOpen: onOpenProp, onClose: onCloseProp, onExecute: onExecuteProp, onExecuteRemote: onExecuteRemoteProp, maxResults, placeholder, children, backdropClassName, omnibarClassName, }: OmnibarProps): react_jsx_runtime.JSX.Element | null;
|
|
800
1005
|
|
|
801
1006
|
/**
|
|
802
1007
|
* Check if a key is a shifted symbol (requires Shift on US keyboard).
|
|
@@ -804,7 +1009,7 @@ declare function Omnibar({ actions: actionsProp, handlers: handlersProp, keymap:
|
|
|
804
1009
|
*/
|
|
805
1010
|
declare function isShiftedSymbol(key: string): boolean;
|
|
806
1011
|
/**
|
|
807
|
-
* Detect if running on macOS
|
|
1012
|
+
* Detect if running on macOS/iOS
|
|
808
1013
|
*/
|
|
809
1014
|
declare function isMac(): boolean;
|
|
810
1015
|
/**
|
|
@@ -854,11 +1059,6 @@ declare function isSequence(hotkeyStr: string): boolean;
|
|
|
854
1059
|
* Handles both single keys ("ctrl+k") and sequences ("2 w", "ctrl+k ctrl+c")
|
|
855
1060
|
*/
|
|
856
1061
|
declare function parseHotkeyString(hotkeyStr: string): HotkeySequence;
|
|
857
|
-
/**
|
|
858
|
-
* Parse a combination ID back to a KeyCombination (single key only)
|
|
859
|
-
* @deprecated Use parseHotkeyString for sequence support
|
|
860
|
-
*/
|
|
861
|
-
declare function parseCombinationId(id: string): KeyCombination;
|
|
862
1062
|
/**
|
|
863
1063
|
* Parse a hotkey string to a KeySeq (new sequence type with digit placeholders).
|
|
864
1064
|
* Handles both single keys ("ctrl+k") and sequences ("2 w", "\\d+ d")
|
|
@@ -920,16 +1120,17 @@ declare function getConflictsArray(keymap: Record<string, string | string[]>): K
|
|
|
920
1120
|
|
|
921
1121
|
/**
|
|
922
1122
|
* Get possible completions for a partially-typed sequence.
|
|
1123
|
+
* Returns both exact matches (isComplete: true) and continuations (isComplete: false).
|
|
923
1124
|
*
|
|
924
1125
|
* @example
|
|
925
1126
|
* ```tsx
|
|
926
|
-
* const keymap = { '
|
|
927
|
-
* const pending = parseHotkeyString('
|
|
1127
|
+
* const keymap = { 'h': 'humidity', 'h \\d+': 'nHours', '2 w': 'twoWeeks' }
|
|
1128
|
+
* const pending = parseHotkeyString('h')
|
|
928
1129
|
* const completions = getSequenceCompletions(pending, keymap)
|
|
929
1130
|
* // Returns:
|
|
930
1131
|
* // [
|
|
931
|
-
* // { nextKeys: '
|
|
932
|
-
* // { nextKeys: '
|
|
1132
|
+
* // { nextKeys: '', fullSequence: 'h', actions: ['humidity'], isComplete: true },
|
|
1133
|
+
* // { nextKeys: '⟨##⟩', fullSequence: 'h \\d+', actions: ['nHours'], isComplete: false },
|
|
933
1134
|
* // ]
|
|
934
1135
|
* ```
|
|
935
1136
|
*/
|
|
@@ -1002,6 +1203,8 @@ interface ActionConfig {
|
|
|
1002
1203
|
enabled?: boolean;
|
|
1003
1204
|
/** Priority for conflict resolution (higher wins, default: 0) */
|
|
1004
1205
|
priority?: number;
|
|
1206
|
+
/** Hide from ShortcutsModal (still searchable in omnibar) */
|
|
1207
|
+
hideFromModal?: boolean;
|
|
1005
1208
|
}
|
|
1006
1209
|
/**
|
|
1007
1210
|
* Register an action with the hotkeys system.
|
|
@@ -1054,8 +1257,8 @@ interface ActionsRegistryValue {
|
|
|
1054
1257
|
register: (id: string, config: ActionConfig) => void;
|
|
1055
1258
|
/** Unregister an action. Called by useAction on unmount. */
|
|
1056
1259
|
unregister: (id: string) => void;
|
|
1057
|
-
/** Execute an action by ID */
|
|
1058
|
-
execute: (id: string) => void;
|
|
1260
|
+
/** Execute an action by ID, optionally with captured digit values */
|
|
1261
|
+
execute: (id: string, captures?: number[]) => void;
|
|
1059
1262
|
/** Currently registered actions */
|
|
1060
1263
|
actions: Map<string, RegisteredAction>;
|
|
1061
1264
|
/** Computed keymap from registered actions + user overrides */
|
|
@@ -1107,6 +1310,8 @@ interface HotkeysConfig {
|
|
|
1107
1310
|
interface HotkeysContextValue {
|
|
1108
1311
|
/** The actions registry */
|
|
1109
1312
|
registry: ActionsRegistryValue;
|
|
1313
|
+
/** The omnibar endpoints registry */
|
|
1314
|
+
endpointsRegistry: OmnibarEndpointsRegistryValue;
|
|
1110
1315
|
/** Whether hotkeys are enabled (based on viewport/touch) */
|
|
1111
1316
|
isEnabled: boolean;
|
|
1112
1317
|
/** Modal open state */
|
|
@@ -1138,7 +1343,7 @@ interface HotkeysContextValue {
|
|
|
1138
1343
|
/** Toggle the lookup modal */
|
|
1139
1344
|
toggleLookup: () => void;
|
|
1140
1345
|
/** Execute an action by ID */
|
|
1141
|
-
executeAction: (id: string) => void;
|
|
1346
|
+
executeAction: (id: string, captures?: number[]) => void;
|
|
1142
1347
|
/** Sequence state: pending key combinations */
|
|
1143
1348
|
pendingKeys: HotkeySequence;
|
|
1144
1349
|
/** Sequence state: whether waiting for more keys */
|
|
@@ -1205,6 +1410,55 @@ declare function useHotkeysContext(): HotkeysContextValue;
|
|
|
1205
1410
|
*/
|
|
1206
1411
|
declare function useMaybeHotkeysContext(): HotkeysContextValue | null;
|
|
1207
1412
|
|
|
1413
|
+
/**
|
|
1414
|
+
* Register an omnibar endpoint for dynamic search results.
|
|
1415
|
+
*
|
|
1416
|
+
* Supports both async (remote API) and sync (in-memory) endpoints:
|
|
1417
|
+
* - Use `fetch` for async operations that need AbortSignal support
|
|
1418
|
+
* - Use `filter` for sync in-memory filtering (skips debouncing for instant results)
|
|
1419
|
+
*
|
|
1420
|
+
* Endpoints are automatically unregistered when the component unmounts,
|
|
1421
|
+
* making this ideal for colocating search providers with their data context.
|
|
1422
|
+
*
|
|
1423
|
+
* @example Async endpoint (remote API)
|
|
1424
|
+
* ```tsx
|
|
1425
|
+
* useOmnibarEndpoint('users', {
|
|
1426
|
+
* fetch: async (query, signal, pagination) => {
|
|
1427
|
+
* const res = await fetch(`/api/users?q=${query}`, { signal })
|
|
1428
|
+
* const { users, total } = await res.json()
|
|
1429
|
+
* return {
|
|
1430
|
+
* entries: users.map(u => ({
|
|
1431
|
+
* id: `user:${u.id}`,
|
|
1432
|
+
* label: u.name,
|
|
1433
|
+
* handler: () => navigate(`/users/${u.id}`),
|
|
1434
|
+
* })),
|
|
1435
|
+
* total,
|
|
1436
|
+
* hasMore: pagination.offset + users.length < total,
|
|
1437
|
+
* }
|
|
1438
|
+
* },
|
|
1439
|
+
* group: 'Users',
|
|
1440
|
+
* })
|
|
1441
|
+
* ```
|
|
1442
|
+
*
|
|
1443
|
+
* @example Sync endpoint (in-memory filtering)
|
|
1444
|
+
* ```tsx
|
|
1445
|
+
* useOmnibarEndpoint('stations', {
|
|
1446
|
+
* filter: (query, pagination) => {
|
|
1447
|
+
* const matches = stations.filter(s => s.name.includes(query))
|
|
1448
|
+
* return {
|
|
1449
|
+
* entries: matches.slice(pagination.offset, pagination.offset + pagination.limit)
|
|
1450
|
+
* .map(s => ({ id: s.id, label: s.name, handler: () => select(s) })),
|
|
1451
|
+
* total: matches.length,
|
|
1452
|
+
* hasMore: pagination.offset + pagination.limit < matches.length,
|
|
1453
|
+
* }
|
|
1454
|
+
* },
|
|
1455
|
+
* group: 'Stations',
|
|
1456
|
+
* minQueryLength: 0,
|
|
1457
|
+
* })
|
|
1458
|
+
* ```
|
|
1459
|
+
*/
|
|
1460
|
+
declare function useOmnibarEndpoint(id: string, config: OmnibarEndpointConfig): void;
|
|
1461
|
+
|
|
1208
1462
|
/**
|
|
1209
1463
|
* Hook to record a keyboard shortcut (single key or sequence) from user input.
|
|
1210
1464
|
*
|
|
@@ -1335,14 +1589,15 @@ declare function LookupModal({ defaultBinding }?: LookupModalProps): react_jsx_r
|
|
|
1335
1589
|
* When a user presses a key that starts a sequence, this modal appears showing:
|
|
1336
1590
|
* - The keys pressed so far
|
|
1337
1591
|
* - Available completions (what keys can come next)
|
|
1338
|
-
* - A timeout indicator
|
|
1592
|
+
* - A timeout indicator (only shown when exactly one completion exists)
|
|
1339
1593
|
*
|
|
1340
|
-
*
|
|
1341
|
-
*
|
|
1342
|
-
*
|
|
1594
|
+
* Features:
|
|
1595
|
+
* - Arrow keys navigate between completions (cancels auto-timeout)
|
|
1596
|
+
* - Enter executes the selected completion (even for digit patterns - handler gets undefined captures)
|
|
1597
|
+
* - Escape cancels the sequence
|
|
1343
1598
|
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1599
|
+
* Unlike LookupModal (which requires explicit activation and lets you browse/search),
|
|
1600
|
+
* SequenceModal appears automatically when you start typing a sequence.
|
|
1346
1601
|
*
|
|
1347
1602
|
* @example
|
|
1348
1603
|
* ```tsx
|
|
@@ -1393,9 +1648,9 @@ declare function Right({ className, style }: KeyIconProps): react_jsx_runtime.JS
|
|
|
1393
1648
|
declare function Enter({ className, style }: KeyIconProps): react_jsx_runtime.JSX.Element;
|
|
1394
1649
|
/** Backspace icon (⌫) */
|
|
1395
1650
|
declare function Backspace({ className, style }: KeyIconProps): react_jsx_runtime.JSX.Element;
|
|
1396
|
-
type KeyIconType = 'arrowup' | 'arrowdown' | 'arrowleft' | 'arrowright' | 'enter' | 'backspace';
|
|
1651
|
+
type KeyIconType = 'arrowup' | 'arrowdown' | 'arrowleft' | 'arrowright' | 'enter' | 'backspace' | 'tab';
|
|
1397
1652
|
/** Get the icon component for a key, or null if no icon exists */
|
|
1398
|
-
declare function getKeyIcon(key: string):
|
|
1653
|
+
declare function getKeyIcon(key: string): ComponentType<KeyIconProps> | null;
|
|
1399
1654
|
|
|
1400
1655
|
/**
|
|
1401
1656
|
* Default timeout for key sequences (no timeout).
|
|
@@ -1410,4 +1665,4 @@ declare const ACTION_MODAL = "__hotkeys:modal";
|
|
|
1410
1665
|
declare const ACTION_OMNIBAR = "__hotkeys:omnibar";
|
|
1411
1666
|
declare const ACTION_LOOKUP = "__hotkeys:lookup";
|
|
1412
1667
|
|
|
1413
|
-
export { ACTION_LOOKUP, ACTION_MODAL, ACTION_OMNIBAR, type ActionConfig, type ActionDefinition, type ActionHandler, type ActionRegistry, type ActionSearchResult, ActionsRegistryContext, type ActionsRegistryValue, Alt, Backspace, type BindingInfo, Command, Ctrl, DEFAULT_SEQUENCE_TIMEOUT, DIGITS_PLACEHOLDER, DIGIT_PLACEHOLDER, Down, Enter, type FuzzyMatchResult, type GroupRenderer, type GroupRendererProps, type HandlerMap, type HotkeyHandler, type HotkeyMap, type HotkeySequence, type HotkeysConfig, type HotkeysContextValue, HotkeysProvider, type HotkeysProviderProps, Kbd, KbdLookup, KbdModal, KbdOmnibar, type KbdProps, Kbds, Key, type KeyCombination, type KeyCombinationDisplay, type KeyConflict, type KeyIconProps, type KeyIconType, type KeySeq, KeybindingEditor, type KeybindingEditorProps, type KeybindingEditorRenderProps, Left, LookupModal, ModifierIcon, type ModifierIconProps, type ModifierType, type Modifiers, Omnibar, type OmnibarProps, type OmnibarRenderProps, Option, type RecordHotkeyOptions, type RecordHotkeyResult, type RegisteredAction, Right, type SeqElem, type SeqElemState, type SeqMatchState, type SequenceCompletion, SequenceModal, Shift, type ShortcutGroup, ShortcutsModal, type ShortcutsModalProps, type ShortcutsModalRenderProps, type TooltipComponent, type TooltipProps, type TwoColumnConfig, type TwoColumnRow, Up, type UseEditableHotkeysOptions, type UseEditableHotkeysResult, type UseHotkeysOptions, type UseHotkeysResult, type UseOmnibarOptions, type UseOmnibarResult, countPlaceholders, createTwoColumnRenderer, extractCaptures, findConflicts, formatBinding, formatCombination, formatKeyForDisplay, formatKeySeq, fuzzyMatch, getActionBindings, getConflictsArray, getKeyIcon, getModifierIcon, getSequenceCompletions, hasConflicts, hasDigitPlaceholders, hotkeySequenceToKeySeq, isDigitPlaceholder, isMac, isModifierKey, isPlaceholderSentinel, isSequence, isShiftedSymbol, keySeqToHotkeySequence, normalizeKey,
|
|
1668
|
+
export { ACTION_LOOKUP, ACTION_MODAL, ACTION_OMNIBAR, type ActionConfig, type ActionDefinition, type ActionHandler, type ActionRegistry, type ActionSearchResult, ActionsRegistryContext, type ActionsRegistryValue, Alt, Backspace, type BindingInfo, Command, Ctrl, DEFAULT_SEQUENCE_TIMEOUT, DIGITS_PLACEHOLDER, DIGIT_PLACEHOLDER, Down, type EndpointPagination, type EndpointPaginationInfo, type EndpointPaginationMode, type EndpointQueryResult, type EndpointResponse, Enter, type FuzzyMatchResult, type GroupRenderer, type GroupRendererProps, type HandlerMap, type HotkeyHandler, type HotkeyMap, type HotkeySequence, type HotkeysConfig, type HotkeysContextValue, HotkeysProvider, type HotkeysProviderProps, Kbd, KbdLookup, KbdModal, KbdOmnibar, type KbdProps, Kbds, Key, type KeyCombination, type KeyCombinationDisplay, type KeyConflict, type KeyIconProps, type KeyIconType, type KeySeq, KeybindingEditor, type KeybindingEditorProps, type KeybindingEditorRenderProps, Left, LookupModal, ModifierIcon, type ModifierIconProps, type ModifierType, type Modifiers, Omnibar, type OmnibarActionEntry, type OmnibarEndpointAsyncConfig, type OmnibarEndpointConfig, type OmnibarEndpointConfigBase, type OmnibarEndpointSyncConfig, OmnibarEndpointsRegistryContext, type OmnibarEndpointsRegistryValue, type OmnibarEntry, type OmnibarEntryBase, type OmnibarLinkEntry, type OmnibarProps, type OmnibarRenderProps, Option, type RecordHotkeyOptions, type RecordHotkeyResult, type RegisteredAction, type RegisteredEndpoint, type RemoteOmnibarResult, Right, type SeqElem, type SeqElemState, type SeqMatchState, type SequenceCompletion, SequenceModal, Shift, type ShortcutGroup, ShortcutsModal, type ShortcutsModalProps, type ShortcutsModalRenderProps, type TooltipComponent, type TooltipProps, type TwoColumnConfig, type TwoColumnRow, Up, type UseEditableHotkeysOptions, type UseEditableHotkeysResult, type UseHotkeysOptions, type UseHotkeysResult, type UseOmnibarOptions, type UseOmnibarResult, countPlaceholders, createTwoColumnRenderer, extractCaptures, findConflicts, formatBinding, formatCombination, formatKeyForDisplay, formatKeySeq, fuzzyMatch, getActionBindings, getConflictsArray, getKeyIcon, getModifierIcon, getSequenceCompletions, hasConflicts, hasDigitPlaceholders, hotkeySequenceToKeySeq, isDigitPlaceholder, isMac, isModifierKey, isPlaceholderSentinel, isSequence, isShiftedSymbol, keySeqToHotkeySequence, normalizeKey, parseHotkeyString, parseKeySeq, searchActions, useAction, useActions, useActionsRegistry, useEditableHotkeys, useHotkeys, useHotkeysContext, useMaybeHotkeysContext, useOmnibar, useOmnibarEndpoint, useOmnibarEndpointsRegistry, useRecordHotkey };
|