@blastlauncher/runtime 1.0.5 → 3.0.0-alpha.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/README.md +4 -10
- package/dist/api/action-panel.d.ts +134 -0
- package/dist/api/action-panel.js +36 -0
- package/dist/api/action.d.ts +386 -0
- package/dist/api/action.js +260 -0
- package/dist/api/ai-browser.d.ts +423 -0
- package/dist/api/ai-browser.js +113 -0
- package/dist/api/ai-decide.d.ts +41 -0
- package/dist/api/ai-decide.js +62 -0
- package/dist/api/applications.d.ts +13 -0
- package/dist/api/applications.js +48 -0
- package/dist/api/cache.d.ts +27 -0
- package/dist/api/cache.js +126 -0
- package/dist/api/capability.d.ts +14 -0
- package/dist/api/capability.js +30 -0
- package/dist/api/clipboard.d.ts +57 -0
- package/dist/api/clipboard.js +83 -0
- package/dist/api/detail.d.ts +33 -0
- package/dist/api/detail.js +11 -0
- package/dist/api/diagnostics.d.ts +16 -0
- package/dist/api/diagnostics.js +26 -0
- package/dist/api/dropdown.d.ts +17 -0
- package/dist/api/dropdown.js +48 -0
- package/dist/api/enums.generated.d.ts +750 -0
- package/dist/api/enums.generated.js +719 -0
- package/dist/api/environment.d.ts +44 -0
- package/dist/api/environment.js +61 -0
- package/dist/api/feedback.d.ts +94 -0
- package/dist/api/feedback.js +228 -0
- package/dist/api/form.d.ts +162 -0
- package/dist/api/form.js +345 -0
- package/dist/api/grid.d.ts +293 -0
- package/dist/api/grid.js +36 -0
- package/dist/api/implemented.d.ts +53 -0
- package/dist/api/implemented.js +43 -0
- package/dist/api/index.d.ts +612 -0
- package/dist/api/index.js +82 -0
- package/dist/api/keyboard.d.ts +182 -0
- package/dist/api/keyboard.js +107 -0
- package/dist/api/launch.d.ts +40 -0
- package/dist/api/launch.js +27 -0
- package/dist/api/legacy.d.ts +9 -0
- package/dist/api/legacy.js +25 -0
- package/dist/api/list.d.ts +291 -0
- package/dist/api/list.js +28 -0
- package/dist/api/menu-bar.d.ts +54 -0
- package/dist/api/menu-bar.js +30 -0
- package/dist/api/metadata.d.ts +62 -0
- package/dist/api/metadata.js +33 -0
- package/dist/api/navigation.d.ts +36 -0
- package/dist/api/navigation.js +99 -0
- package/dist/api/oauth.d.ts +84 -0
- package/dist/api/oauth.js +125 -0
- package/dist/api/open.d.ts +18 -0
- package/dist/api/open.js +36 -0
- package/dist/api/preferences.d.ts +43 -0
- package/dist/api/preferences.js +41 -0
- package/dist/api/selection.d.ts +10 -0
- package/dist/api/selection.js +31 -0
- package/dist/api/slot.d.ts +7 -0
- package/dist/api/slot.js +11 -0
- package/dist/api/storage.d.ts +24 -0
- package/dist/api/storage.js +45 -0
- package/dist/api/types.d.ts +46 -0
- package/dist/api/types.js +5 -0
- package/dist/api/unsupported.d.ts +18 -0
- package/dist/api/unsupported.generated.d.ts +1255 -0
- package/dist/api/unsupported.generated.js +56 -0
- package/dist/api/unsupported.js +65 -0
- package/dist/api/window-management.d.ts +97 -0
- package/dist/api/window-management.js +164 -0
- package/dist/api/window.d.ts +16 -0
- package/dist/api/window.js +32 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +339 -0
- package/dist/provider.d.ts +8 -0
- package/dist/provider.js +107 -0
- package/dist/reconciler/index.d.ts +9 -0
- package/dist/reconciler/index.js +186 -0
- package/dist/reconciler/serialize.d.ts +3 -0
- package/dist/reconciler/serialize.js +53 -0
- package/dist/reconciler/types.d.ts +8 -0
- package/dist/reconciler/types.js +1 -0
- package/package.json +32 -23
- package/.eslintrc.js +0 -6
- package/CHANGELOG.md +0 -19
- package/dist/App.d.ts +0 -5
- package/dist/App.js +0 -10
- package/dist/components/CommandList/index.d.ts +0 -1
- package/dist/components/CommandList/index.js +0 -20
- package/dist/components/CommandList/utils.d.ts +0 -1
- package/dist/components/CommandList/utils.js +0 -24
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -11
- package/dist/utils/connectDevtools.d.ts +0 -1
- package/dist/utils/connectDevtools.js +0 -11
- package/dist/utils/run.d.ts +0 -4
- package/dist/utils/run.js +0 -12
- package/dist/utils/window.d.ts +0 -0
- package/dist/utils/window.js +0 -2
- package/src/@types/raycast.d.ts +0 -4
- package/src/@types/react-devtools-core.d.ts +0 -19
- package/src/App.tsx +0 -18
- package/src/components/CommandList/index.tsx +0 -27
- package/src/components/CommandList/utils.ts +0 -26
- package/src/index.ts +0 -13
- package/src/utils/connectDevtools.ts +0 -8
- package/src/utils/run.ts +0 -7
- package/src/utils/window.js +0 -1
- package/tsconfig.json +0 -10
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ColorLike, ImageLike } from "./types.js";
|
|
3
|
+
/** `List.Item.Accessory`: a text, date or tag label with optional icon/tooltip. */
|
|
4
|
+
export interface ListAccessory {
|
|
5
|
+
/** An optional text label, optionally colored. */
|
|
6
|
+
text?: string | null | {
|
|
7
|
+
value: string | null | undefined;
|
|
8
|
+
color?: string;
|
|
9
|
+
};
|
|
10
|
+
/** An optional date label (rendered relative to now), optionally colored. */
|
|
11
|
+
date?: Date | null | {
|
|
12
|
+
value: Date | null | undefined;
|
|
13
|
+
color?: string;
|
|
14
|
+
};
|
|
15
|
+
/** A string or date tag; the color also tints the background. */
|
|
16
|
+
tag?: string | Date | null | {
|
|
17
|
+
value: string | Date | null | undefined;
|
|
18
|
+
color?: ColorLike;
|
|
19
|
+
};
|
|
20
|
+
/** An optional image shown in front of the label. */
|
|
21
|
+
icon?: ImageLike | null;
|
|
22
|
+
/** An optional tooltip shown when the accessory is hovered. */
|
|
23
|
+
tooltip?: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface ListProps {
|
|
26
|
+
/** List sections or items. */
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
/** The main title for that view displayed in the host. */
|
|
29
|
+
navigationTitle?: string;
|
|
30
|
+
/** Indicates whether a loading bar should be shown below the search bar. */
|
|
31
|
+
isLoading?: boolean;
|
|
32
|
+
/** The text that will be displayed in the search bar. */
|
|
33
|
+
searchText?: string;
|
|
34
|
+
/** Placeholder text of the search bar. */
|
|
35
|
+
searchBarPlaceholder?: string;
|
|
36
|
+
/** Whether the list should show details for the selected item. */
|
|
37
|
+
isShowingDetail?: boolean;
|
|
38
|
+
/** Selects the item with the specified id. */
|
|
39
|
+
selectedItemId?: string;
|
|
40
|
+
/** Deprecated alias of filtering. */
|
|
41
|
+
enableFiltering?: boolean;
|
|
42
|
+
/** Clients request subsequent pages through onLoadMore. */
|
|
43
|
+
pagination?: {
|
|
44
|
+
pageSize: number;
|
|
45
|
+
hasMore: boolean;
|
|
46
|
+
onLoadMore: () => void;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Toggles client-side filtering of the items through the search bar; the
|
|
50
|
+
* client decides how to honor it (see task 0020, "Out of scope").
|
|
51
|
+
*/
|
|
52
|
+
filtering?: boolean | {
|
|
53
|
+
keepSectionOrder: boolean;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Defines whether the `onSearchTextChange` handler fires on every keystroke
|
|
57
|
+
* or with a throttling delay.
|
|
58
|
+
*/
|
|
59
|
+
throttle?: boolean;
|
|
60
|
+
/** Callback triggered when the search bar text changes. */
|
|
61
|
+
onSearchTextChange?: (text: string) => void;
|
|
62
|
+
/** Callback triggered when the item selection in the list changes. */
|
|
63
|
+
onSelectionChange?: (id: string | null) => void;
|
|
64
|
+
/** An ActionPanel; rendered as a `Slot` child named `actions`. */
|
|
65
|
+
actions?: ReactNode;
|
|
66
|
+
/** A search bar accessory; rendered as a `Slot` child named `searchBarAccessory`. */
|
|
67
|
+
searchBarAccessory?: ReactNode;
|
|
68
|
+
}
|
|
69
|
+
export interface ListItemProps {
|
|
70
|
+
/** Passed to the `onSelectionChange` handler of the List when selected. */
|
|
71
|
+
id?: string;
|
|
72
|
+
/** The main title displayed for the item, optionally with a tooltip. */
|
|
73
|
+
title: string | {
|
|
74
|
+
value: string;
|
|
75
|
+
tooltip?: string | null;
|
|
76
|
+
};
|
|
77
|
+
/** An optional subtitle, optionally with a tooltip. */
|
|
78
|
+
subtitle?: string | {
|
|
79
|
+
value?: string | null;
|
|
80
|
+
tooltip?: string | null;
|
|
81
|
+
};
|
|
82
|
+
/** Additional indexable strings for search. */
|
|
83
|
+
keywords?: string[];
|
|
84
|
+
/** An optional icon displayed for the item. */
|
|
85
|
+
icon?: ImageLike | {
|
|
86
|
+
value: ImageLike | null | undefined;
|
|
87
|
+
tooltip: string;
|
|
88
|
+
};
|
|
89
|
+
/** Accessory items displayed on the right side of the item. */
|
|
90
|
+
accessories?: ListAccessory[] | null;
|
|
91
|
+
/** Deprecated single-accessory props, retained for clients. */
|
|
92
|
+
accessoryIcon?: ImageLike;
|
|
93
|
+
accessoryTitle?: string;
|
|
94
|
+
/** File metadata for client Quick Look previews. */
|
|
95
|
+
quickLook?: {
|
|
96
|
+
name?: string | null;
|
|
97
|
+
path: string;
|
|
98
|
+
};
|
|
99
|
+
/** An ActionPanel; rendered as a `Slot` child named `actions`. */
|
|
100
|
+
actions?: ReactNode;
|
|
101
|
+
/** A `List.Item.Detail`; rendered as a `Slot` child named `detail`. */
|
|
102
|
+
detail?: ReactNode;
|
|
103
|
+
}
|
|
104
|
+
export interface ListSectionProps {
|
|
105
|
+
/** Deprecated internal section identifier. */
|
|
106
|
+
id?: string;
|
|
107
|
+
/** The `List.Item` elements of the section. */
|
|
108
|
+
children?: ReactNode;
|
|
109
|
+
/** Title displayed above the section. */
|
|
110
|
+
title?: string;
|
|
111
|
+
/** An optional subtitle displayed next to the title of the section. */
|
|
112
|
+
subtitle?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface ListEmptyViewProps {
|
|
115
|
+
/** The main title displayed for the empty view. */
|
|
116
|
+
title?: string;
|
|
117
|
+
/** An optional description for why the empty view is shown. */
|
|
118
|
+
description?: string;
|
|
119
|
+
/** An optional icon displayed in the center of the empty view. */
|
|
120
|
+
icon?: ImageLike | null;
|
|
121
|
+
/** An ActionPanel; rendered as a `Slot` child named `actions`. */
|
|
122
|
+
actions?: ReactNode;
|
|
123
|
+
}
|
|
124
|
+
export interface ListDropdownItemProps {
|
|
125
|
+
/** Value of the dropdown item; passed to `onChange` when selected. */
|
|
126
|
+
value: string;
|
|
127
|
+
/** The title displayed for the item. */
|
|
128
|
+
title: string;
|
|
129
|
+
/** An optional icon displayed for the item. */
|
|
130
|
+
icon?: ImageLike | null;
|
|
131
|
+
/** Additional indexable strings for search. */
|
|
132
|
+
keywords?: string[];
|
|
133
|
+
}
|
|
134
|
+
export interface ListDropdownSectionProps {
|
|
135
|
+
/** The `List.Dropdown.Item` elements of the section. */
|
|
136
|
+
children?: ReactNode;
|
|
137
|
+
/** Title displayed above the section. */
|
|
138
|
+
title?: string;
|
|
139
|
+
}
|
|
140
|
+
export interface ListDropdownProps {
|
|
141
|
+
/** The dropdown sections or items. */
|
|
142
|
+
children?: ReactNode;
|
|
143
|
+
/** ID of the dropdown. */
|
|
144
|
+
id?: string;
|
|
145
|
+
/** Tooltip displayed when hovering the dropdown. */
|
|
146
|
+
tooltip: string;
|
|
147
|
+
/** Placeholder text shown in the dropdown search field. */
|
|
148
|
+
placeholder?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Persist the selected value per command and dropdown id across runs.
|
|
151
|
+
*/
|
|
152
|
+
storeValue?: boolean;
|
|
153
|
+
/** The current value of the dropdown. */
|
|
154
|
+
value?: string;
|
|
155
|
+
/** The default value of the dropdown, configured once per component lifecycle. */
|
|
156
|
+
defaultValue?: string;
|
|
157
|
+
/** Toggles client-side filtering of the dropdown items. */
|
|
158
|
+
filtering?: boolean | {
|
|
159
|
+
keepSectionOrder: boolean;
|
|
160
|
+
};
|
|
161
|
+
/** Indicates whether a loading indicator should be shown next to the dropdown. */
|
|
162
|
+
isLoading?: boolean;
|
|
163
|
+
/** Defines whether `onSearchTextChange` fires on every keystroke or throttled. */
|
|
164
|
+
throttle?: boolean;
|
|
165
|
+
/** Callback triggered when the dropdown search field text changes. */
|
|
166
|
+
onSearchTextChange?: (text: string) => void;
|
|
167
|
+
/** Callback triggered when the dropdown selection changes. */
|
|
168
|
+
onChange?: (newValue: string) => void;
|
|
169
|
+
}
|
|
170
|
+
declare const ListDropdownItem: (props: ListDropdownItemProps) => import("react").ReactElement<ListDropdownItemProps, string | import("react").JSXElementConstructor<any>>;
|
|
171
|
+
declare const ListDropdownSection: (props: ListDropdownSectionProps) => import("react").DOMElement<ListDropdownSectionProps, Element>;
|
|
172
|
+
declare function ListSection(props: ListSectionProps): import("react").DOMElement<ListSectionProps, Element>;
|
|
173
|
+
declare function ListEmptyView(props: ListEmptyViewProps): import("react").ReactElement<{
|
|
174
|
+
/** The main title displayed for the empty view. */
|
|
175
|
+
title?: string;
|
|
176
|
+
/** An optional description for why the empty view is shown. */
|
|
177
|
+
description?: string;
|
|
178
|
+
/** An optional icon displayed in the center of the empty view. */
|
|
179
|
+
icon?: ImageLike | null;
|
|
180
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
181
|
+
export declare const List: ((props: ListProps) => import("react").ReactElement<{
|
|
182
|
+
/** The main title for that view displayed in the host. */
|
|
183
|
+
navigationTitle?: string;
|
|
184
|
+
/** Indicates whether a loading bar should be shown below the search bar. */
|
|
185
|
+
isLoading?: boolean;
|
|
186
|
+
/** The text that will be displayed in the search bar. */
|
|
187
|
+
searchText?: string;
|
|
188
|
+
/** Placeholder text of the search bar. */
|
|
189
|
+
searchBarPlaceholder?: string;
|
|
190
|
+
/** Whether the list should show details for the selected item. */
|
|
191
|
+
isShowingDetail?: boolean;
|
|
192
|
+
/** Selects the item with the specified id. */
|
|
193
|
+
selectedItemId?: string;
|
|
194
|
+
/** Deprecated alias of filtering. */
|
|
195
|
+
enableFiltering?: boolean;
|
|
196
|
+
/** Clients request subsequent pages through onLoadMore. */
|
|
197
|
+
pagination?: {
|
|
198
|
+
pageSize: number;
|
|
199
|
+
hasMore: boolean;
|
|
200
|
+
onLoadMore: () => void;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Toggles client-side filtering of the items through the search bar; the
|
|
204
|
+
* client decides how to honor it (see task 0020, "Out of scope").
|
|
205
|
+
*/
|
|
206
|
+
filtering?: boolean | {
|
|
207
|
+
keepSectionOrder: boolean;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Defines whether the `onSearchTextChange` handler fires on every keystroke
|
|
211
|
+
* or with a throttling delay.
|
|
212
|
+
*/
|
|
213
|
+
throttle?: boolean;
|
|
214
|
+
/** Callback triggered when the search bar text changes. */
|
|
215
|
+
onSearchTextChange?: (text: string) => void;
|
|
216
|
+
/** Callback triggered when the item selection in the list changes. */
|
|
217
|
+
onSelectionChange?: (id: string | null) => void;
|
|
218
|
+
}, string | import("react").JSXElementConstructor<any>>) & {
|
|
219
|
+
Item: ((props: ListItemProps) => import("react").ReactElement<{
|
|
220
|
+
/** Passed to the `onSelectionChange` handler of the List when selected. */
|
|
221
|
+
id?: string;
|
|
222
|
+
/** The main title displayed for the item, optionally with a tooltip. */
|
|
223
|
+
title: string | {
|
|
224
|
+
value: string;
|
|
225
|
+
tooltip?: string | null;
|
|
226
|
+
};
|
|
227
|
+
/** An optional subtitle, optionally with a tooltip. */
|
|
228
|
+
subtitle?: string | {
|
|
229
|
+
value?: string | null;
|
|
230
|
+
tooltip?: string | null;
|
|
231
|
+
};
|
|
232
|
+
/** Additional indexable strings for search. */
|
|
233
|
+
keywords?: string[];
|
|
234
|
+
/** An optional icon displayed for the item. */
|
|
235
|
+
icon?: ImageLike | {
|
|
236
|
+
value: ImageLike | null | undefined;
|
|
237
|
+
tooltip: string;
|
|
238
|
+
};
|
|
239
|
+
/** Accessory items displayed on the right side of the item. */
|
|
240
|
+
accessories?: ListAccessory[] | null;
|
|
241
|
+
/** Deprecated single-accessory props, retained for clients. */
|
|
242
|
+
accessoryIcon?: ImageLike;
|
|
243
|
+
accessoryTitle?: string;
|
|
244
|
+
/** File metadata for client Quick Look previews. */
|
|
245
|
+
quickLook?: {
|
|
246
|
+
name?: string | null;
|
|
247
|
+
path: string;
|
|
248
|
+
};
|
|
249
|
+
}, string | import("react").JSXElementConstructor<any>>) & {
|
|
250
|
+
Detail: ((props: import("./detail.js").ListItemDetailProps) => import("react").ReactElement<{
|
|
251
|
+
isLoading?: boolean;
|
|
252
|
+
markdown?: string | null;
|
|
253
|
+
}, string | import("react").JSXElementConstructor<any>>) & {
|
|
254
|
+
Metadata: import("./metadata.js").MetadataComponents;
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
Section: typeof ListSection;
|
|
258
|
+
EmptyView: typeof ListEmptyView;
|
|
259
|
+
Dropdown: ((props: ListDropdownProps) => import("react").ReactElement<{
|
|
260
|
+
/** The dropdown sections or items. */
|
|
261
|
+
children?: ReactNode;
|
|
262
|
+
/** ID of the dropdown. */
|
|
263
|
+
id?: string;
|
|
264
|
+
/** Tooltip displayed when hovering the dropdown. */
|
|
265
|
+
tooltip: string;
|
|
266
|
+
/** Placeholder text shown in the dropdown search field. */
|
|
267
|
+
placeholder?: string;
|
|
268
|
+
/**
|
|
269
|
+
* Persist the selected value per command and dropdown id across runs.
|
|
270
|
+
*/
|
|
271
|
+
storeValue?: boolean;
|
|
272
|
+
/** The default value of the dropdown, configured once per component lifecycle. */
|
|
273
|
+
defaultValue?: string;
|
|
274
|
+
/** Toggles client-side filtering of the dropdown items. */
|
|
275
|
+
filtering?: boolean | {
|
|
276
|
+
keepSectionOrder: boolean;
|
|
277
|
+
};
|
|
278
|
+
/** Indicates whether a loading indicator should be shown next to the dropdown. */
|
|
279
|
+
isLoading?: boolean;
|
|
280
|
+
/** Defines whether `onSearchTextChange` fires on every keystroke or throttled. */
|
|
281
|
+
throttle?: boolean;
|
|
282
|
+
/** Callback triggered when the dropdown search field text changes. */
|
|
283
|
+
onSearchTextChange?: (text: string) => void;
|
|
284
|
+
value: string | undefined;
|
|
285
|
+
onChange: ((value: string) => void | undefined) | undefined;
|
|
286
|
+
}, string | import("react").JSXElementConstructor<any>>) & {
|
|
287
|
+
Item: typeof ListDropdownItem;
|
|
288
|
+
Section: typeof ListDropdownSection;
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
export {};
|
package/dist/api/list.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
import { useDropdown } from "./dropdown.js";
|
|
3
|
+
import { ListItemDetail } from "./detail.js";
|
|
4
|
+
import { slot } from "./slot.js";
|
|
5
|
+
const ListDropdownItem = function ListDropdownItem(props) {
|
|
6
|
+
return createElement("List.Dropdown.Item", props);
|
|
7
|
+
};
|
|
8
|
+
const ListDropdownSection = function ListDropdownSection(props) {
|
|
9
|
+
return createElement("List.Dropdown.Section", props);
|
|
10
|
+
};
|
|
11
|
+
const ListDropdown = Object.assign(function ListDropdown(props) {
|
|
12
|
+
return useDropdown("List.Dropdown", props);
|
|
13
|
+
}, { Item: ListDropdownItem, Section: ListDropdownSection });
|
|
14
|
+
const ListItem = Object.assign(function ListItem(props) {
|
|
15
|
+
const { actions, detail, ...rest } = props;
|
|
16
|
+
return createElement("List.Item", rest, slot("actions", actions), slot("detail", detail));
|
|
17
|
+
}, { Detail: ListItemDetail });
|
|
18
|
+
function ListSection(props) {
|
|
19
|
+
return createElement("List.Section", props);
|
|
20
|
+
}
|
|
21
|
+
function ListEmptyView(props) {
|
|
22
|
+
const { actions, ...rest } = props;
|
|
23
|
+
return createElement("List.EmptyView", rest, slot("actions", actions));
|
|
24
|
+
}
|
|
25
|
+
export const List = Object.assign(function List(props) {
|
|
26
|
+
const { actions, searchBarAccessory, children, ...rest } = props;
|
|
27
|
+
return createElement("List", rest, children, slot("actions", actions), slot("searchBarAccessory", searchBarAccessory));
|
|
28
|
+
}, { Item: ListItem, Section: ListSection, EmptyView: ListEmptyView, Dropdown: ListDropdown });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
2
|
+
import type { ImageLike, Shortcut } from "./types.js";
|
|
3
|
+
export interface MenuBarActionEvent {
|
|
4
|
+
type: "left-click" | "right-click";
|
|
5
|
+
}
|
|
6
|
+
export interface MenuBarExtraProps {
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
title?: string;
|
|
9
|
+
tooltip?: string;
|
|
10
|
+
icon?: ImageLike;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export interface MenuBarItemProps {
|
|
14
|
+
title: string;
|
|
15
|
+
subtitle?: string;
|
|
16
|
+
icon?: ImageLike;
|
|
17
|
+
tooltip?: string;
|
|
18
|
+
onAction?: (event: MenuBarActionEvent) => void;
|
|
19
|
+
shortcut?: Shortcut | undefined;
|
|
20
|
+
alternate?: ReactElement<MenuBarItemProps>;
|
|
21
|
+
}
|
|
22
|
+
export interface MenuBarSectionProps {
|
|
23
|
+
children?: ReactNode;
|
|
24
|
+
title?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface MenuBarSubmenuProps {
|
|
27
|
+
title: string;
|
|
28
|
+
icon?: ImageLike;
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
declare function Item({ alternate, shortcut, ...props }: MenuBarItemProps): ReactElement<{
|
|
32
|
+
title: string;
|
|
33
|
+
subtitle?: string;
|
|
34
|
+
icon?: ImageLike;
|
|
35
|
+
tooltip?: string;
|
|
36
|
+
onAction?: (event: MenuBarActionEvent) => void;
|
|
37
|
+
shortcut: Shortcut | undefined;
|
|
38
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
39
|
+
declare function Section(props: MenuBarSectionProps): import("react").DOMElement<MenuBarSectionProps, Element>;
|
|
40
|
+
declare function Submenu(props: MenuBarSubmenuProps): import("react").DOMElement<MenuBarSubmenuProps, Element>;
|
|
41
|
+
declare function Separator(): import("react").DOMElement<import("react").DOMAttributes<Element>, Element>;
|
|
42
|
+
export declare const MenuBarExtra: ((props: MenuBarExtraProps) => import("react").DOMElement<{
|
|
43
|
+
title?: string;
|
|
44
|
+
tooltip?: string;
|
|
45
|
+
icon?: ImageLike;
|
|
46
|
+
children?: ReactNode;
|
|
47
|
+
isLoading: boolean;
|
|
48
|
+
}, Element>) & {
|
|
49
|
+
Item: typeof Item;
|
|
50
|
+
Section: typeof Section;
|
|
51
|
+
Submenu: typeof Submenu;
|
|
52
|
+
Separator: typeof Separator;
|
|
53
|
+
};
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { cloneElement, createElement } from "react";
|
|
2
|
+
import { slot } from "./slot.js";
|
|
3
|
+
function modifiers(shortcut, alternate) {
|
|
4
|
+
if (!shortcut)
|
|
5
|
+
return undefined;
|
|
6
|
+
const adjust = (value) => ({
|
|
7
|
+
...value,
|
|
8
|
+
modifiers: [...value.modifiers.filter((key) => key !== "opt"), ...(alternate ? ["opt"] : [])],
|
|
9
|
+
});
|
|
10
|
+
if ("modifiers" in shortcut)
|
|
11
|
+
return adjust(shortcut);
|
|
12
|
+
return { ...shortcut, macOS: adjust(shortcut.macOS) };
|
|
13
|
+
}
|
|
14
|
+
function Item({ alternate, shortcut, ...props }) {
|
|
15
|
+
// Alternates inherit the parent's shortcut plus Option, never their own.
|
|
16
|
+
const primaryShortcut = alternate ? modifiers(shortcut, false) : shortcut;
|
|
17
|
+
return createElement("MenuBarExtra.Item", { ...props, shortcut: primaryShortcut }, slot("alternate", alternate ? cloneElement(alternate, { shortcut: modifiers(shortcut, true) }) : null));
|
|
18
|
+
}
|
|
19
|
+
function Section(props) {
|
|
20
|
+
return createElement("MenuBarExtra.Section", props);
|
|
21
|
+
}
|
|
22
|
+
function Submenu(props) {
|
|
23
|
+
return createElement("MenuBarExtra.Submenu", props);
|
|
24
|
+
}
|
|
25
|
+
function Separator() {
|
|
26
|
+
return createElement("MenuBarExtra.Separator");
|
|
27
|
+
}
|
|
28
|
+
export const MenuBarExtra = Object.assign(function MenuBarExtra(props) {
|
|
29
|
+
return createElement("MenuBarExtra", { ...props, isLoading: props.isLoading ?? false });
|
|
30
|
+
}, { Item, Section, Submenu, Separator });
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ColorLike, ImageLike } from "./types.js";
|
|
3
|
+
export interface MetadataLabelProps {
|
|
4
|
+
/** The title of the item. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** An icon to illustrate the value of the item. */
|
|
7
|
+
icon?: ImageLike | null;
|
|
8
|
+
/**
|
|
9
|
+
* The text value of the item. Specifying `color` displays the text in the
|
|
10
|
+
* provided color, defaulting to `Color.PrimaryText`.
|
|
11
|
+
*/
|
|
12
|
+
text?: string | {
|
|
13
|
+
value: string;
|
|
14
|
+
color?: ColorLike | null;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface MetadataLinkProps {
|
|
18
|
+
/** The title shown above the item. */
|
|
19
|
+
title: string;
|
|
20
|
+
/** The target of the link. */
|
|
21
|
+
target: string;
|
|
22
|
+
/** The text value of the item. */
|
|
23
|
+
text: string;
|
|
24
|
+
}
|
|
25
|
+
export interface MetadataProps {
|
|
26
|
+
/** The elements of the Metadata view. */
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
export interface MetadataSeparatorProps {
|
|
30
|
+
}
|
|
31
|
+
export interface MetadataTagListProps {
|
|
32
|
+
/** The title shown above the item. */
|
|
33
|
+
title: string;
|
|
34
|
+
/** The tags contained in the TagList. */
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
}
|
|
37
|
+
export interface MetadataTagListItemProps {
|
|
38
|
+
/** The optional tag icon. Required if the tag has no text. */
|
|
39
|
+
icon?: ImageLike | null;
|
|
40
|
+
/** The optional tag text. Required if the tag has no icon. */
|
|
41
|
+
text?: string;
|
|
42
|
+
/** Changes the text color to the provided color and sets a transparent background with the same color. */
|
|
43
|
+
color?: ColorLike | null;
|
|
44
|
+
/** Callback that is triggered when the item is clicked. */
|
|
45
|
+
onAction?: () => void;
|
|
46
|
+
}
|
|
47
|
+
export interface MetadataComponents {
|
|
48
|
+
(props: MetadataProps): ReactNode;
|
|
49
|
+
Label: (props: MetadataLabelProps) => ReactNode;
|
|
50
|
+
Link: (props: MetadataLinkProps) => ReactNode;
|
|
51
|
+
Separator: (props: MetadataSeparatorProps) => ReactNode;
|
|
52
|
+
TagList: {
|
|
53
|
+
(props: MetadataTagListProps): ReactNode;
|
|
54
|
+
Item: (props: MetadataTagListItemProps) => ReactNode;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* `Detail.Metadata` and `List.Item.Detail.Metadata` render the same props, but
|
|
59
|
+
* scene element types are the public Raycast paths, so the namespace is built
|
|
60
|
+
* from the path of the view that owns it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createMetadata(prefix: "Detail" | "List.Item.Detail"): MetadataComponents;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* `Detail.Metadata` and `List.Item.Detail.Metadata` render the same props, but
|
|
4
|
+
* scene element types are the public Raycast paths, so the namespace is built
|
|
5
|
+
* from the path of the view that owns it.
|
|
6
|
+
*/
|
|
7
|
+
export function createMetadata(prefix) {
|
|
8
|
+
const path = `${prefix}.Metadata`;
|
|
9
|
+
function Metadata(props) {
|
|
10
|
+
return createElement(path, props);
|
|
11
|
+
}
|
|
12
|
+
function Label(props) {
|
|
13
|
+
return createElement(`${path}.Label`, props);
|
|
14
|
+
}
|
|
15
|
+
function Link(props) {
|
|
16
|
+
return createElement(`${path}.Link`, props);
|
|
17
|
+
}
|
|
18
|
+
function Separator(props) {
|
|
19
|
+
return createElement(`${path}.Separator`, props);
|
|
20
|
+
}
|
|
21
|
+
function TagList(props) {
|
|
22
|
+
return createElement(`${path}.TagList`, props);
|
|
23
|
+
}
|
|
24
|
+
function TagListItem(props) {
|
|
25
|
+
return createElement(`${path}.TagList.Item`, props);
|
|
26
|
+
}
|
|
27
|
+
return Object.assign(Metadata, {
|
|
28
|
+
Label,
|
|
29
|
+
Link,
|
|
30
|
+
Separator,
|
|
31
|
+
TagList: Object.assign(TagList, { Item: TagListItem }),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface Navigation {
|
|
3
|
+
push(component: ReactNode, onPop?: () => void): void;
|
|
4
|
+
pop(): void;
|
|
5
|
+
}
|
|
6
|
+
/** `popToRoot` options from the declarations. */
|
|
7
|
+
export interface PopToRootOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Raycast also clears the root search bar. Blast's headless clients own any
|
|
10
|
+
* search-bar state, so the request is recorded on the `Navigation` scene
|
|
11
|
+
* element (`props.popToRoot`) for clients to act on.
|
|
12
|
+
*/
|
|
13
|
+
clearSearchBar?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** `clearSearchBar` options from the declarations. */
|
|
16
|
+
export interface ClearSearchBarOptions {
|
|
17
|
+
/** Forces scrolling to the top of the list; the default is the client's. */
|
|
18
|
+
forceScrollToTop?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const RootNavigationEntryContext: import("react").Context<boolean>;
|
|
21
|
+
export declare function subscribeClearSearchBar(listener: () => void): () => void;
|
|
22
|
+
/** The recorded request, or `undefined` while no clear was asked for. */
|
|
23
|
+
export declare function clearSearchBarRequest(): ClearSearchBarOptions | undefined;
|
|
24
|
+
export declare function NavigationProvider({ children }: {
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}): import("react").FunctionComponentElement<import("react").ProviderProps<Navigation | null>>;
|
|
27
|
+
export declare function useNavigation(): Navigation;
|
|
28
|
+
/** `popToRoot` from the declarations: pop the current command's stack to root. */
|
|
29
|
+
export declare function popToRoot(options?: PopToRootOptions): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* `clearSearchBar` from the declarations. Blast has no search-bar state, so
|
|
32
|
+
* the request is recorded on the `Navigation` scene element
|
|
33
|
+
* (`props.clearSearchBar`) for clients to act on, exactly like `closeMainWindow`
|
|
34
|
+
* records its own request.
|
|
35
|
+
*/
|
|
36
|
+
export declare function clearSearchBar(options?: ClearSearchBarOptions): Promise<void>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createContext, createElement, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
|
|
2
|
+
import { FeedbackScene } from "./feedback.js";
|
|
3
|
+
import { closeRequest, subscribeCloseRequest } from "./window.js";
|
|
4
|
+
export const RootNavigationEntryContext = createContext(true);
|
|
5
|
+
const NavigationContext = createContext(null);
|
|
6
|
+
// `popToRoot()` is a module-level API without React context, so mounted
|
|
7
|
+
// providers register their stack; the most recent one answers. One command per
|
|
8
|
+
// runtime process in production; tests may hold several.
|
|
9
|
+
const stacks = new Set();
|
|
10
|
+
// Like `closeMainWindow`, a `clearSearchBar()` request is module state: it is
|
|
11
|
+
// rendered by whichever `Navigation` is mounted and dropped with that scene, so
|
|
12
|
+
// a later command starts with a clean search bar.
|
|
13
|
+
let searchBarRequest;
|
|
14
|
+
const searchBarListeners = new Set();
|
|
15
|
+
export function subscribeClearSearchBar(listener) {
|
|
16
|
+
searchBarListeners.add(listener);
|
|
17
|
+
return () => {
|
|
18
|
+
searchBarListeners.delete(listener);
|
|
19
|
+
if (searchBarListeners.size === 0)
|
|
20
|
+
searchBarRequest = undefined;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** The recorded request, or `undefined` while no clear was asked for. */
|
|
24
|
+
export function clearSearchBarRequest() {
|
|
25
|
+
return searchBarRequest;
|
|
26
|
+
}
|
|
27
|
+
export function NavigationProvider({ children }) {
|
|
28
|
+
const entries = useRef([]);
|
|
29
|
+
const nextId = useRef(1);
|
|
30
|
+
const [stack, setStack] = useState([]);
|
|
31
|
+
const [popToRootOptions, setPopToRootOptions] = useState();
|
|
32
|
+
// A fresh object per `closeMainWindow()` call, so the snapshot identity
|
|
33
|
+
// changes and `closeMainWindow` props follow the recorded request.
|
|
34
|
+
const closeMainWindow = useSyncExternalStore(subscribeCloseRequest, closeRequest, closeRequest);
|
|
35
|
+
const searchBarClear = useSyncExternalStore(subscribeClearSearchBar, clearSearchBarRequest, clearSearchBarRequest);
|
|
36
|
+
const navigation = useMemo(() => ({
|
|
37
|
+
push(component, onPop) {
|
|
38
|
+
entries.current = [...entries.current, { id: nextId.current++, component, onPop }];
|
|
39
|
+
setStack(entries.current);
|
|
40
|
+
},
|
|
41
|
+
pop() {
|
|
42
|
+
const entry = entries.current.at(-1);
|
|
43
|
+
if (!entry)
|
|
44
|
+
return;
|
|
45
|
+
entries.current = entries.current.slice(0, -1);
|
|
46
|
+
setStack(entries.current);
|
|
47
|
+
entry.onPop?.();
|
|
48
|
+
},
|
|
49
|
+
}), []);
|
|
50
|
+
const popToRootStack = useMemo(() => (options) => {
|
|
51
|
+
setPopToRootOptions(options);
|
|
52
|
+
// The root view is the provider's own children, not an entry (decision
|
|
53
|
+
// 0003), so nothing above it is kept; onPops run topmost first, like
|
|
54
|
+
// successive `pop()` calls.
|
|
55
|
+
if (entries.current.length === 0)
|
|
56
|
+
return;
|
|
57
|
+
const popped = entries.current.toReversed();
|
|
58
|
+
entries.current = [];
|
|
59
|
+
setStack(entries.current);
|
|
60
|
+
for (const entry of popped)
|
|
61
|
+
entry.onPop?.();
|
|
62
|
+
}, []);
|
|
63
|
+
stacks.add(popToRootStack);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
return () => {
|
|
66
|
+
stacks.delete(popToRootStack);
|
|
67
|
+
};
|
|
68
|
+
}, [popToRootStack]);
|
|
69
|
+
return createElement(NavigationContext.Provider, { value: navigation }, createElement("Navigation", {
|
|
70
|
+
depth: stack.length + 1,
|
|
71
|
+
pop: stack.length ? navigation.pop : undefined,
|
|
72
|
+
popToRoot: popToRootOptions,
|
|
73
|
+
clearSearchBar: searchBarClear,
|
|
74
|
+
closeMainWindow,
|
|
75
|
+
}, createElement("Navigation.Entry", { key: 0, active: stack.length === 0 }, children), ...stack.map((entry, index) => createElement("Navigation.Entry", { key: entry.id, active: index === stack.length - 1 }, createElement(RootNavigationEntryContext.Provider, { value: false }, entry.component))), createElement(FeedbackScene, { key: "feedback" })));
|
|
76
|
+
}
|
|
77
|
+
export function useNavigation() {
|
|
78
|
+
const navigation = useContext(NavigationContext);
|
|
79
|
+
if (!navigation)
|
|
80
|
+
throw new Error("useNavigation requires a running view command");
|
|
81
|
+
return navigation;
|
|
82
|
+
}
|
|
83
|
+
/** `popToRoot` from the declarations: pop the current command's stack to root. */
|
|
84
|
+
export async function popToRoot(options) {
|
|
85
|
+
[...stacks].at(-1)?.(options);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* `clearSearchBar` from the declarations. Blast has no search-bar state, so
|
|
89
|
+
* the request is recorded on the `Navigation` scene element
|
|
90
|
+
* (`props.clearSearchBar`) for clients to act on, exactly like `closeMainWindow`
|
|
91
|
+
* records its own request.
|
|
92
|
+
*/
|
|
93
|
+
export async function clearSearchBar(options = {}) {
|
|
94
|
+
if (searchBarListeners.size === 0)
|
|
95
|
+
return;
|
|
96
|
+
searchBarRequest = { ...options };
|
|
97
|
+
for (const listener of searchBarListeners)
|
|
98
|
+
listener();
|
|
99
|
+
}
|