@spawnite/devtools 0.1.0-beta.15
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/LICENSE.md +169 -0
- package/README.md +21 -0
- package/dist/CQCYoLJa.js +3 -0
- package/dist/THIRD-PARTY-NOTICES +3 -0
- package/dist/index.d.ts +1658 -0
- package/dist/index.js +7 -0
- package/dist/nxAMn9sr.js +16 -0
- package/dist/styles.css +3 -0
- package/fonts.css +62 -0
- package/package.json +54 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1658 @@
|
|
|
1
|
+
import { BehaviourOption, CursorMode, DeclaredPanel, DevtoolsNode, DevtoolsPanel, DevtoolsPanel as DevtoolsPanel$1, FrameCost, FrameSplit, GroundSpot, LogLevel, LogLine, MapChoice, PaintMaterial, Placeable, PropEdit, PropRange, Relation, RoomState, ScatterPick, ScreenRect, SendOutcome, SentMessage, StatModifier, SystemEntry, TerrainEditorState, Wiki, WikiEntry, WikiRef, useDevtools } from "@spawnite/engine/devtools";
|
|
2
|
+
import { ComponentProps, InputHTMLAttributes, MouseEvent as MouseEvent$1, ReactNode, Ref } from "react";
|
|
3
|
+
import { AgentActivity, ChatPost, FavoriteField, MapPoint } from "@spawnite/schema";
|
|
4
|
+
import { AbilityInspection } from "@spawnite/engine";
|
|
5
|
+
import { HTMLMotionProps } from "motion/react";
|
|
6
|
+
import { MermaidConfig } from "mermaid";
|
|
7
|
+
import { TooltipProps } from "@spawnite/ui";
|
|
8
|
+
/** One step a game's playtest panel runs, such as a quick start past the
|
|
9
|
+
* title or a wave on demand, which `spawnite play action <name>` runs by
|
|
10
|
+
* name, as Unreal's console runs a cheat. */
|
|
11
|
+
interface PlaytestAction {
|
|
12
|
+
/** What the panel's button and the cli call it, such as "Quick start". */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Runs the step. A line it returns, such as "No damage on", is what
|
|
15
|
+
* the cli prints; it throws to refuse, with why, such as a quick start
|
|
16
|
+
* asked for mid-run. */
|
|
17
|
+
run: () => string | void | Promise<string | void>;
|
|
18
|
+
}
|
|
19
|
+
/** What the page exposes for the cli. */
|
|
20
|
+
interface PlaytestActionsOnPage {
|
|
21
|
+
list: () => string[];
|
|
22
|
+
run: (name: string) => Promise<string | undefined>;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface Window {
|
|
26
|
+
/** The game's playtest actions, while its devtools are mounted. */
|
|
27
|
+
__GAME_PLAYTEST_ACTIONS__?: PlaytestActionsOnPage;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
declare global {
|
|
31
|
+
interface Window {
|
|
32
|
+
/** The engine's devtools store, for a playtest driving the page
|
|
33
|
+
* from outside it. */
|
|
34
|
+
__GAME_DEVTOOLS__?: typeof useDevtools;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
interface DevtoolsProps {
|
|
38
|
+
/** The game's own sections, one icon each on the rail, beside those it
|
|
39
|
+
* registers with the store. */
|
|
40
|
+
panels?: DevtoolsPanel$1[];
|
|
41
|
+
/** The steps the game's playtest panel runs, by name, which
|
|
42
|
+
* `spawnite play action <name>` runs too. */
|
|
43
|
+
playtestActions?: PlaytestAction[];
|
|
44
|
+
}
|
|
45
|
+
/** The debugger overlay. A game mounts it inside `<Game>` in development
|
|
46
|
+
* only. With edit mode off it is the toggle and the frame rate; on, the
|
|
47
|
+
* top bar, the rail of icons down the left edge with the one sidebar
|
|
48
|
+
* beside it, and the frames on the hovered and the selected entity. The
|
|
49
|
+
* sidebar shows the section whose icon is pressed: the entity tree with
|
|
50
|
+
* the inspector under it, the map's placeables, the fields the creator
|
|
51
|
+
* starred, the game's own panels and
|
|
52
|
+
* those it registers with the store, the game's wiki, the console, the
|
|
53
|
+
* frame's times, the shortcuts, and at the rail's foot the console. It captures the console
|
|
54
|
+
* while mounted, so the log holds what came before edit mode too. With
|
|
55
|
+
* `?map=<name>` in the URL it shows that map alone. On a phone the
|
|
56
|
+
* sections open one at a time from a tab bar at the foot, in place of the
|
|
57
|
+
* rail. It draws nothing while the game's loading screen covers the page,
|
|
58
|
+
* and its store is on the page from its mount, so the agent's tools read a
|
|
59
|
+
* game still loading.
|
|
60
|
+
*
|
|
61
|
+
* ponytail: edit mode is the store's, so it starts the recording; the
|
|
62
|
+
* open section is the layout store's, which the browser keeps. */
|
|
63
|
+
export declare function Devtools({ panels, playtestActions }: DevtoolsProps): import("react").JSX.Element | null;
|
|
64
|
+
/** The overlay's own sections; a game's panel has the id `readPanelId`
|
|
65
|
+
* gives it. */
|
|
66
|
+
export declare enum SectionId {
|
|
67
|
+
Entities = "entities",
|
|
68
|
+
Map = "map",
|
|
69
|
+
Assets = "assets",
|
|
70
|
+
Favorites = "favorites",
|
|
71
|
+
Clips = "clips",
|
|
72
|
+
Wiki = "wiki",
|
|
73
|
+
Console = "console",
|
|
74
|
+
Shortcuts = "shortcuts"
|
|
75
|
+
}
|
|
76
|
+
/** The rail's top icons in the order the browser kept, `ids` by id. A kept
|
|
77
|
+
* id no item has any more is dropped, and an item the kept order does not
|
|
78
|
+
* name, such as a section a game registered since, stands after the item
|
|
79
|
+
* that comes before it by default, or first where none does. */
|
|
80
|
+
export declare function orderRail<Item extends {
|
|
81
|
+
id: string;
|
|
82
|
+
}>(items: Item[], ids: string[]): Item[];
|
|
83
|
+
interface LayoutState {
|
|
84
|
+
/** The section the sidebar shows, or showed before it folded. */
|
|
85
|
+
section: string;
|
|
86
|
+
/** Folded, the rail stands alone. */
|
|
87
|
+
open: boolean;
|
|
88
|
+
/** The sidebar's width in pixels, the same for every section. */
|
|
89
|
+
width: number;
|
|
90
|
+
treeShare: number;
|
|
91
|
+
/** The rail's top icons by id, in the order a drag left them; empty,
|
|
92
|
+
* the default order. */
|
|
93
|
+
railOrder: string[];
|
|
94
|
+
/** A press on a section's icon: opens it, or folds the sidebar where
|
|
95
|
+
* it is the open one. */
|
|
96
|
+
pressSection: (id: string) => void;
|
|
97
|
+
/** Opens a section, whatever showed before. */
|
|
98
|
+
openSection: (id: string) => void;
|
|
99
|
+
setWidth: (width: number) => void;
|
|
100
|
+
setTreeShare: (share: number) => void;
|
|
101
|
+
setRailOrder: (ids: string[]) => void;
|
|
102
|
+
resetRailOrder: () => void;
|
|
103
|
+
}
|
|
104
|
+
/** Where the sidebar stands, kept in the browser for the next page load. */
|
|
105
|
+
export declare const useLayout: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<LayoutState>, "persist" | "setState"> & {
|
|
106
|
+
setState(partial: LayoutState | Partial<LayoutState> | ((state: LayoutState) => LayoutState | Partial<LayoutState>), replace?: false | undefined): unknown;
|
|
107
|
+
setState(state: LayoutState | ((state: LayoutState) => LayoutState), replace: true): unknown;
|
|
108
|
+
persist: {
|
|
109
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<LayoutState, LayoutState, unknown>>) => void;
|
|
110
|
+
clearStorage: () => void;
|
|
111
|
+
rehydrate: () => Promise<void> | void;
|
|
112
|
+
hasHydrated: () => boolean;
|
|
113
|
+
onHydrate: (fn: (state: LayoutState) => void) => () => void;
|
|
114
|
+
onFinishHydration: (fn: (state: LayoutState) => void) => () => void;
|
|
115
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<LayoutState, LayoutState, unknown>>;
|
|
116
|
+
};
|
|
117
|
+
}>;
|
|
118
|
+
export declare enum PropKind {
|
|
119
|
+
Number = "number",
|
|
120
|
+
Toggle = "toggle",
|
|
121
|
+
/** Another entity, such as the one a behaviour chases. */
|
|
122
|
+
Entity = "entity",
|
|
123
|
+
Text = "text"
|
|
124
|
+
}
|
|
125
|
+
interface NumberProp {
|
|
126
|
+
kind: PropKind.Number;
|
|
127
|
+
name: string;
|
|
128
|
+
value: number;
|
|
129
|
+
/** Left out with `max`, the engine knows no range and no slider draws. */
|
|
130
|
+
min?: number;
|
|
131
|
+
max?: number;
|
|
132
|
+
/** Left out, a hundredth of the range. */
|
|
133
|
+
step?: number;
|
|
134
|
+
/** The box takes any finite value; only the slider keeps `min` and
|
|
135
|
+
* `max`, for a range the inspector made up rather than one declared. */
|
|
136
|
+
open?: boolean;
|
|
137
|
+
}
|
|
138
|
+
interface ToggleProp {
|
|
139
|
+
kind: PropKind.Toggle;
|
|
140
|
+
name: string;
|
|
141
|
+
value: boolean;
|
|
142
|
+
}
|
|
143
|
+
interface EntityProp {
|
|
144
|
+
kind: PropKind.Entity;
|
|
145
|
+
name: string;
|
|
146
|
+
/** The entity's name. */
|
|
147
|
+
value: string;
|
|
148
|
+
}
|
|
149
|
+
interface TextProp {
|
|
150
|
+
kind: PropKind.Text;
|
|
151
|
+
name: string;
|
|
152
|
+
value: string;
|
|
153
|
+
}
|
|
154
|
+
/** One prop of a behaviour, as the inspector edits it. Given a
|
|
155
|
+
* `readOnlyReason`, that field alone is greyed, with the reason as its
|
|
156
|
+
* tooltip. */
|
|
157
|
+
type BehaviourProp = (NumberProp | ToggleProp | EntityProp | TextProp) & {
|
|
158
|
+
readOnlyReason?: string;
|
|
159
|
+
};
|
|
160
|
+
type PropValue = BehaviourProp["value"];
|
|
161
|
+
interface BehaviourCardProps {
|
|
162
|
+
name: string;
|
|
163
|
+
/** Left out, no line under the name. */
|
|
164
|
+
description?: string;
|
|
165
|
+
/** Left out, the behaviour declares no wiki page. */
|
|
166
|
+
docsHref?: string;
|
|
167
|
+
/** Some prop differs from the behaviour's defaults. */
|
|
168
|
+
changed: boolean;
|
|
169
|
+
props: BehaviourProp[];
|
|
170
|
+
/** An edit, by the prop's name. The value comes back through `props`. */
|
|
171
|
+
onChange: (name: string, value: PropValue) => void;
|
|
172
|
+
/** Given, the fields are greyed and take no edit, and the card says
|
|
173
|
+
* why. */
|
|
174
|
+
readOnlyReason?: string;
|
|
175
|
+
/** What a game pastes into its component to keep the edits, which a
|
|
176
|
+
* Copy as prop button writes to the clipboard; left out, no button. */
|
|
177
|
+
copyText?: string;
|
|
178
|
+
/** The favourite a field's star keeps, by the field's name; left out,
|
|
179
|
+
* the fields carry no star. */
|
|
180
|
+
favorite?: (field: string) => FavoriteField;
|
|
181
|
+
/** Under the fields: the Stats card's stats. */
|
|
182
|
+
children?: ReactNode;
|
|
183
|
+
/** Where its host places it. */
|
|
184
|
+
className?: string;
|
|
185
|
+
}
|
|
186
|
+
/** One behaviour on the inspected entity: its name, what it does, a link to
|
|
187
|
+
* its docs, and a field for each prop. */
|
|
188
|
+
export declare function BehaviourCard({ name, description, docsHref, changed, props, onChange, readOnlyReason, copyText, favorite, children, className }: BehaviourCardProps): import("react").JSX.Element;
|
|
189
|
+
interface AbilitiesCardProps {
|
|
190
|
+
inspection: AbilityInspection;
|
|
191
|
+
/** The ability the rings draw and the range verdict is for, by name. */
|
|
192
|
+
selected: string | null;
|
|
193
|
+
onSelect: (name: string) => void;
|
|
194
|
+
/** Whether the range rings and the target line are drawn. */
|
|
195
|
+
rings: boolean;
|
|
196
|
+
onRingsChange: (rings: boolean) => void;
|
|
197
|
+
/** Where its host places it. */
|
|
198
|
+
className?: string;
|
|
199
|
+
}
|
|
200
|
+
/** The abilities the entity holds and the numbers that decide a cast: per
|
|
201
|
+
* ability its kind, range, cost, cooldown left and cast state, above them
|
|
202
|
+
* the target, its reach, whether it is in range of the selected ability
|
|
203
|
+
* and in sight, and why the last cast was refused. A switch draws the
|
|
204
|
+
* selected ability's range round the caster. The rows are live: the host
|
|
205
|
+
* hands a new inspection each frame the numbers change. */
|
|
206
|
+
export declare function AbilitiesCard({ inspection, selected, onSelect, rings, onRingsChange, className }: AbilitiesCardProps): import("react").JSX.Element;
|
|
207
|
+
interface AddBehaviourMenuProps {
|
|
208
|
+
/** The behaviours the entity can take, in the order the numbers pick. */
|
|
209
|
+
options: BehaviourOption[];
|
|
210
|
+
onAdd: (name: string) => void;
|
|
211
|
+
onClose: () => void;
|
|
212
|
+
/** Where the overlay places it: beside the context menu. */
|
|
213
|
+
className?: string;
|
|
214
|
+
}
|
|
215
|
+
/** The context menu's Add behaviour submenu: a search over the behaviours
|
|
216
|
+
* the entity can take. Focus stays in the search; the arrows move the
|
|
217
|
+
* highlight, Enter adds it, 1 to 9 add by number until the search has
|
|
218
|
+
* text, and Escape closes. */
|
|
219
|
+
export declare function AddBehaviourMenu({ options, onAdd, onClose, className }: AddBehaviourMenuProps): import("react").JSX.Element;
|
|
220
|
+
/** A row put on the next message, by its id and as the tree labels it. */
|
|
221
|
+
type ChatAttachment = ChatPost["attachments"][number];
|
|
222
|
+
interface ChatStripProps {
|
|
223
|
+
/** Every message the page sent, the pane's too, oldest first. */
|
|
224
|
+
sent: SentMessage[];
|
|
225
|
+
attachments: ChatAttachment[];
|
|
226
|
+
onDetach: (id: string) => void;
|
|
227
|
+
text: string;
|
|
228
|
+
onTextChange: (text: string) => void;
|
|
229
|
+
onSend: () => void;
|
|
230
|
+
/** Given, an X in the header closes the strip. */
|
|
231
|
+
onClose?: () => void;
|
|
232
|
+
/** Where the overlay places it, and how tall it is. */
|
|
233
|
+
className?: string;
|
|
234
|
+
}
|
|
235
|
+
/** A message to the agent: what was sent so far, the rows attached to the
|
|
236
|
+
* next one, and a field that grows with its text. ⌘↵ sends, since Enter
|
|
237
|
+
* starts a new line. */
|
|
238
|
+
export declare function ChatStrip({ sent, attachments, onDetach, text, onTextChange, onSend, onClose, className }: ChatStripProps): import("react").JSX.Element;
|
|
239
|
+
interface ConsoleStripProps {
|
|
240
|
+
lines: LogLine[];
|
|
241
|
+
onClear: () => void;
|
|
242
|
+
/** Given, an X in the header closes the pane: a phone's sheet. */
|
|
243
|
+
onClose?: () => void;
|
|
244
|
+
/** Where its host places it, and how tall it is. */
|
|
245
|
+
className?: string;
|
|
246
|
+
}
|
|
247
|
+
/** The game's log: a chip per level in the header, which counts it and
|
|
248
|
+
* hides it on a press, a filter and Clear, then the lines, each message
|
|
249
|
+
* on as many rows as it takes. */
|
|
250
|
+
export declare function ConsoleStrip({ lines, onClear, onClose, className }: ConsoleStripProps): import("react").JSX.Element;
|
|
251
|
+
export declare enum EntityAction {
|
|
252
|
+
SendToAgent = "sendToAgent",
|
|
253
|
+
Inspect = "inspect",
|
|
254
|
+
SelectParent = "selectParent",
|
|
255
|
+
FocusCamera = "focusCamera",
|
|
256
|
+
Hide = "hide",
|
|
257
|
+
Duplicate = "duplicate",
|
|
258
|
+
Delete = "delete",
|
|
259
|
+
AddBehaviour = "addBehaviour",
|
|
260
|
+
CopyId = "copyId"
|
|
261
|
+
}
|
|
262
|
+
/** A point in the world, as three's vectors carry one. */
|
|
263
|
+
interface WorldPoint {
|
|
264
|
+
x: number;
|
|
265
|
+
y: number;
|
|
266
|
+
z: number;
|
|
267
|
+
}
|
|
268
|
+
interface ContextMenuProps {
|
|
269
|
+
name: string;
|
|
270
|
+
/** The id as the game prints it: `#113`. */
|
|
271
|
+
entityId: string;
|
|
272
|
+
/** Its component type: Spline, Pickup. */
|
|
273
|
+
type: string;
|
|
274
|
+
/** The world point the right-click met on it. */
|
|
275
|
+
point?: WorldPoint;
|
|
276
|
+
/** Why an action is off for this entity, by action. */
|
|
277
|
+
disabled?: Partial<Record<EntityAction, string>>;
|
|
278
|
+
onAction: (action: EntityAction) => void;
|
|
279
|
+
onClose: () => void;
|
|
280
|
+
/** Where the overlay places it: at the pointer. */
|
|
281
|
+
className?: string;
|
|
282
|
+
}
|
|
283
|
+
/** What a right-click on an entity offers, headed by the entity. It opens
|
|
284
|
+
* on the first action; the arrows move, Enter picks, Escape closes. */
|
|
285
|
+
export declare function ContextMenu({ name, entityId, type, point, disabled, onAction, onClose, className }: ContextMenuProps): import("react").JSX.Element;
|
|
286
|
+
type TerrainTool = NonNullable<TerrainEditorState["tool"]>;
|
|
287
|
+
export declare enum GroundAction {
|
|
288
|
+
SendToAgent = "sendToAgent",
|
|
289
|
+
PlayFromHere = "playFromHere",
|
|
290
|
+
PickMaterial = "pickMaterial",
|
|
291
|
+
RemoveScattered = "removeScattered",
|
|
292
|
+
PickHeight = "pickHeight",
|
|
293
|
+
ResetHere = "resetHere",
|
|
294
|
+
CopyPosition = "copyPosition",
|
|
295
|
+
DuplicateMaterial = "duplicateMaterial",
|
|
296
|
+
ToggleWet = "toggleWet",
|
|
297
|
+
ToggleLower = "toggleLower",
|
|
298
|
+
SetSea = "setSea",
|
|
299
|
+
Undo = "undo",
|
|
300
|
+
Redo = "redo"
|
|
301
|
+
}
|
|
302
|
+
interface GroundContextMenuProps {
|
|
303
|
+
/** The map whose ground it is. */
|
|
304
|
+
map: string;
|
|
305
|
+
spot: GroundSpot;
|
|
306
|
+
/** The cell's own material, which the material's items act on. */
|
|
307
|
+
material: string;
|
|
308
|
+
/** Whether that material shows rain ripples. */
|
|
309
|
+
wet: boolean;
|
|
310
|
+
/** Whether the editor has a step to undo, and one to redo. */
|
|
311
|
+
undoable: boolean;
|
|
312
|
+
redoable: boolean;
|
|
313
|
+
/** Why Play from here is off, such as in a room, which places the
|
|
314
|
+
* player; on where left out. */
|
|
315
|
+
playFromHereDisabledReason?: string;
|
|
316
|
+
mode: CursorMode;
|
|
317
|
+
tool: TerrainTool | null;
|
|
318
|
+
brush: Pick<TerrainEditorState["brush"], "radius">;
|
|
319
|
+
/** Whether Sculpt lowers the ground. */
|
|
320
|
+
lower: boolean;
|
|
321
|
+
/** The scattered tree, bush, rock or tuft the click is on, its kind
|
|
322
|
+
* in words, such as `tree round`, which Remove this erases; left out
|
|
323
|
+
* on bare ground. */
|
|
324
|
+
scattered?: string;
|
|
325
|
+
onMode: (mode: CursorMode) => void;
|
|
326
|
+
onTool: (tool: TerrainTool) => void;
|
|
327
|
+
onBrush: (brush: Partial<TerrainEditorState["brush"]>) => void;
|
|
328
|
+
onAction: (action: GroundAction) => void;
|
|
329
|
+
onClose: () => void;
|
|
330
|
+
/** Whether the Other submenu starts open. */
|
|
331
|
+
defaultOtherOpen?: boolean;
|
|
332
|
+
/** Where the overlay places it: at the pointer. */
|
|
333
|
+
className?: string;
|
|
334
|
+
}
|
|
335
|
+
/** What a right-click on bare ground offers, headed by what is there: the
|
|
336
|
+
* cursor's mode, and in Terrain the tools, and the brush's sizes while
|
|
337
|
+
* one is in hand, then what to do at the spot, the rarer actions under
|
|
338
|
+
* Other. It opens on the first action; the arrows move, Enter picks,
|
|
339
|
+
* Escape closes. Other opens its submenu beside the menu, else over it,
|
|
340
|
+
* on a click or a mouse resting on it; Escape, a press outside the
|
|
341
|
+
* submenu or the mouse off both closes it alone. */
|
|
342
|
+
export declare function GroundContextMenu({ map, spot, material, wet, undoable, redoable, playFromHereDisabledReason, mode, tool, brush, lower, scattered, onMode, onTool, onBrush, onAction, onClose, defaultOtherOpen, className }: GroundContextMenuProps): import("react").JSX.Element;
|
|
343
|
+
interface DevtoolsOverlayProps {
|
|
344
|
+
topBar?: ReactNode;
|
|
345
|
+
/** The buttons before the top bar on a desktop: Record's and the
|
|
346
|
+
* screenshot's. */
|
|
347
|
+
leading?: ReactNode;
|
|
348
|
+
/** The buttons after the top bar on a desktop: the free camera's and
|
|
349
|
+
* the map's. */
|
|
350
|
+
camera?: ReactNode;
|
|
351
|
+
/** The rail of icons, down the left edge. */
|
|
352
|
+
rail?: ReactNode;
|
|
353
|
+
/** The sidebar beside the rail, with the open section; nothing while
|
|
354
|
+
* it is folded. */
|
|
355
|
+
sidebar?: ReactNode;
|
|
356
|
+
/** The frame on the hovered or selected entity. */
|
|
357
|
+
outline?: ReactNode;
|
|
358
|
+
/** The context menu, over everything, where it places itself. */
|
|
359
|
+
menu?: ReactNode;
|
|
360
|
+
/** A phone's tab bar, along the bottom edge. */
|
|
361
|
+
tabBar?: ReactNode;
|
|
362
|
+
/** A phone's open panel, in a sheet that springs up out of the tab bar
|
|
363
|
+
* and leaves the game above it free for a tap. */
|
|
364
|
+
sheet?: ReactNode;
|
|
365
|
+
/** A phone: the toolbar takes a row of its own under the toggles and
|
|
366
|
+
* slides down from under them, and the panels open one at a time in
|
|
367
|
+
* `sheet`. */
|
|
368
|
+
phone?: boolean;
|
|
369
|
+
}
|
|
370
|
+
/** Edit mode's layout: the bar along the top and the rail and its sidebar
|
|
371
|
+
* down the left edge, the rest left to the game. Only the surfaces take
|
|
372
|
+
* the pointer. A
|
|
373
|
+
* column, so the panels start under the top bar however many rows it
|
|
374
|
+
* wraps to; the insets keep clear of a phone's notch and home bar. */
|
|
375
|
+
export declare function DevtoolsOverlay({ topBar, leading, camera, rail, sidebar, outline, menu, tabBar, sheet, phone }: DevtoolsOverlayProps): import("react").JSX.Element;
|
|
376
|
+
/** A point on a rect as fractions of its width and height: `{ x: 1, y: 1 }`
|
|
377
|
+
* is its bottom-right corner. */
|
|
378
|
+
interface Anchor {
|
|
379
|
+
x: number;
|
|
380
|
+
y: number;
|
|
381
|
+
}
|
|
382
|
+
interface AnchoredBoxProps extends Omit<HTMLMotionProps<"div">, "style"> {
|
|
383
|
+
/** What it stands on, in the window's pixels, such as an entity's frame.
|
|
384
|
+
* Followed at once as it moves. */
|
|
385
|
+
rect: Pick<ScreenRect, "left" | "top" | "width" | "height">;
|
|
386
|
+
/** Where on the rect its top-left corner stands. A new anchor springs
|
|
387
|
+
* there, so the box glides across the rect rather than jumping. */
|
|
388
|
+
anchor: Anchor;
|
|
389
|
+
/** Its own size, so it stays inside the window. */
|
|
390
|
+
size: {
|
|
391
|
+
width: number;
|
|
392
|
+
height: number;
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/** A box pinned to a point on a moving rect, as a popover stands on its
|
|
396
|
+
* anchor in Floating UI: the rect is followed every frame exactly, and
|
|
397
|
+
* only the point on it springs, so the box slides to a new point while it
|
|
398
|
+
* keeps up with what it stands on. Absolutely placed; its place comes from
|
|
399
|
+
* motion values, so a slide renders nothing in React. */
|
|
400
|
+
export declare function AnchoredBox({ rect, anchor, size, ...box }: AnchoredBoxProps): import("react").JSX.Element;
|
|
401
|
+
interface EntityOutlineProps {
|
|
402
|
+
rect: ScreenRect;
|
|
403
|
+
/** With its id: `Coin #12`. */
|
|
404
|
+
name: string;
|
|
405
|
+
/** Its component type: Pickup, Enemy. */
|
|
406
|
+
type: string;
|
|
407
|
+
/** Selected, rather than under the pointer. */
|
|
408
|
+
selected?: boolean;
|
|
409
|
+
/** Its buttons stay whatever is selected after it, and its panel
|
|
410
|
+
* stands over it while the world panels are on: Pin reads Unpin,
|
|
411
|
+
* under a cross. */
|
|
412
|
+
pinned?: boolean;
|
|
413
|
+
/** The buttons alone, with no frame and no name: a pinned entity that
|
|
414
|
+
* is neither selected nor under the pointer. */
|
|
415
|
+
bare?: boolean;
|
|
416
|
+
/** The frame with no name above it: an entity whose world panel
|
|
417
|
+
* stands there and names it. */
|
|
418
|
+
nameless?: boolean;
|
|
419
|
+
/** Where on the frame the strip opens, as fractions of its width and
|
|
420
|
+
* height: the point the selecting click met, so the buttons open
|
|
421
|
+
* under the cursor and ride with the entity. The bottom-right corner
|
|
422
|
+
* for a selection made without a click, as from the tree. */
|
|
423
|
+
anchor?: StripAnchor;
|
|
424
|
+
/** The strip's buttons, one for each given: Send to agent, Inspect and
|
|
425
|
+
* Pin. Without Inspect, no strip. */
|
|
426
|
+
onSendToAgent?: () => void;
|
|
427
|
+
onInspect?: () => void;
|
|
428
|
+
onTogglePin?: () => void;
|
|
429
|
+
}
|
|
430
|
+
/** A point on a frame as fractions of its width and height. */
|
|
431
|
+
type StripAnchor = Anchor;
|
|
432
|
+
/** A frame drawn over the entity the pointer is on, or the selected one,
|
|
433
|
+
* with its name above. Nothing under it dims: the frame is the only mark.
|
|
434
|
+
* The frame and the name are hidden from assistive technology, which
|
|
435
|
+
* hears the selection from the tree and the inspector. A selected frame
|
|
436
|
+
* carries a row of round buttons at its anchor, which alone takes the
|
|
437
|
+
* pointer. */
|
|
438
|
+
export declare function EntityOutline({ rect, name, type, selected, anchor, pinned, bare, nameless, onSendToAgent, onInspect, onTogglePin }: EntityOutlineProps): import("react").JSX.Element;
|
|
439
|
+
interface EntityTreeProps {
|
|
440
|
+
nodes: DevtoolsNode[];
|
|
441
|
+
/** The ids whose children start hidden. Opening and closing a node is
|
|
442
|
+
* the tree's own business after that. */
|
|
443
|
+
initiallyCollapsed?: string[];
|
|
444
|
+
selectedId?: string;
|
|
445
|
+
/** The rest of a selection of several, marked as selected too. */
|
|
446
|
+
selectedIds?: string[];
|
|
447
|
+
/** `adding` on a ⇧ or ⌘ click, which adds the row to the selection or
|
|
448
|
+
* takes it out. */
|
|
449
|
+
onSelect: (id: string, adding: boolean) => void;
|
|
450
|
+
/** The pointer over a row, so the scene can outline its entity, and
|
|
451
|
+
* `null` once it leaves the tree. */
|
|
452
|
+
onHover?: (id: string | null) => void;
|
|
453
|
+
/** A right-click on a row, which the overlay opens its menu on. */
|
|
454
|
+
onContextMenu?: (id: string, event: MouseEvent$1) => void;
|
|
455
|
+
}
|
|
456
|
+
/** The scene as a tree: its world, the component types, their entities and
|
|
457
|
+
* each entity's behaviours, with a filter above and the counts below. */
|
|
458
|
+
export declare function EntityTree({ nodes, initiallyCollapsed, selectedId, selectedIds, onSelect, onHover, onContextMenu }: EntityTreeProps): import("react").JSX.Element;
|
|
459
|
+
/** What the bar reads of the game's room. */
|
|
460
|
+
type RoomReadout = Pick<RoomState, "roundTripMilliseconds" | "stepMilliseconds" | "snapshotsPerSecond" | "bytesPerSecond" | "players" | "corrections" | "correctionMetres">;
|
|
461
|
+
interface TopBarProps {
|
|
462
|
+
paused: boolean;
|
|
463
|
+
speed: number;
|
|
464
|
+
/** The recorded frames as bars, oldest first, spread across the window,
|
|
465
|
+
* each a fraction of the tallest bar between 0 and 1. */
|
|
466
|
+
recording: number[];
|
|
467
|
+
/** Where the replay stands, in seconds before now: 0 is the present,
|
|
468
|
+
* -10 the oldest frame kept. */
|
|
469
|
+
playheadSeconds: number;
|
|
470
|
+
framesPerSecond: number;
|
|
471
|
+
/** The room the game plays in; none outside one. In one, pause, step
|
|
472
|
+
* and speed are off. */
|
|
473
|
+
room?: RoomReadout;
|
|
474
|
+
/** Drawn after the controls, before the frame rate: on a phone, the
|
|
475
|
+
* free camera's button, since the round one has no place beside the
|
|
476
|
+
* bar there. */
|
|
477
|
+
camera?: ReactNode;
|
|
478
|
+
onTogglePause: () => void;
|
|
479
|
+
onStep: () => void;
|
|
480
|
+
onSpeed: (speed: number) => void;
|
|
481
|
+
/** A seek on the scrubber, in seconds before now. */
|
|
482
|
+
onSeek: (seconds: number) => void;
|
|
483
|
+
/** False leaves the scrubber out: a phone has no room for it and no
|
|
484
|
+
* keys to step through it. */
|
|
485
|
+
scrubber?: boolean;
|
|
486
|
+
/** Where the overlay places it. */
|
|
487
|
+
className?: string;
|
|
488
|
+
}
|
|
489
|
+
/** The playback bar at the top of the screen in edit mode: pause, step,
|
|
490
|
+
* speed, the last ten seconds as a scrubber, then the frame rate. The
|
|
491
|
+
* frame's times and a room's readouts are the Frame panel's. In a room,
|
|
492
|
+
* pause, step and speed are off. */
|
|
493
|
+
export declare function TopBar({ paused, speed, recording, playheadSeconds, framesPerSecond, room, camera, onTogglePause, onStep, onSpeed, onSeek, scrubber, className }: TopBarProps): import("react").JSX.Element;
|
|
494
|
+
interface FrameStatsProps {
|
|
495
|
+
frameMilliseconds: number;
|
|
496
|
+
/** The game's own clock, which stops when it pauses. */
|
|
497
|
+
simulatedSeconds: number;
|
|
498
|
+
/** None while the loop times no frames. */
|
|
499
|
+
frameSplit?: Pick<FrameSplit, "cpu" | "gpu"> | null;
|
|
500
|
+
/** The last frame's draw calls and triangles; none while the loop
|
|
501
|
+
* times no frames. */
|
|
502
|
+
cost?: Pick<FrameCost, "drawCalls" | "triangles"> | null;
|
|
503
|
+
/** The room the game plays in, with its own work per step where it
|
|
504
|
+
* sends it; none outside one. */
|
|
505
|
+
room?: RoomReadout & Partial<Pick<RoomState, "roomStepMilliseconds">>;
|
|
506
|
+
}
|
|
507
|
+
/** The frame's time, the CPU's and the GPU's share of it with the last
|
|
508
|
+
* frame's draw calls and triangles, and the game's clock, and in a room
|
|
509
|
+
* the round trip, the step time, the room's own step time, the stream's
|
|
510
|
+
* rates, the players and the room's corrections of the player's character. At
|
|
511
|
+
* the head of the Frame panel. */
|
|
512
|
+
export declare function FrameStats({ frameMilliseconds, simulatedSeconds, frameSplit, cost, room }: FrameStatsProps): import("react").JSX.Element;
|
|
513
|
+
interface FrameTimesProps {
|
|
514
|
+
/** None before the loop's first split arrives. */
|
|
515
|
+
split: FrameSplit | null;
|
|
516
|
+
}
|
|
517
|
+
/** The last 60 frames by part, then the totals, each by mean and worst. */
|
|
518
|
+
export declare function FrameTimes({ split }: FrameTimesProps): import("react").JSX.Element;
|
|
519
|
+
interface SidePanelProps {
|
|
520
|
+
title: string;
|
|
521
|
+
/** Drawn before the title. */
|
|
522
|
+
icon: ReactNode;
|
|
523
|
+
/** Given, an X in the header closes the pane: a phone's sheet. The
|
|
524
|
+
* sidebar's sections have none, since the rail folds them. */
|
|
525
|
+
onClose?: () => void;
|
|
526
|
+
/** Where its host places it. */
|
|
527
|
+
className?: string;
|
|
528
|
+
/** A function draws its own header instead of the title's row, and
|
|
529
|
+
* takes the X to place in it, where the pane has one. */
|
|
530
|
+
children: ReactNode | ((close: ReactNode) => ReactNode);
|
|
531
|
+
}
|
|
532
|
+
/** A section's pane, in the sidebar or a phone's sheet: its title, with a
|
|
533
|
+
* search in the pane standing at its right, then what it holds, as tall
|
|
534
|
+
* and as wide as its host. */
|
|
535
|
+
export declare function SidePanel({ title, icon, onClose, className, children }: SidePanelProps): import("react").JSX.Element;
|
|
536
|
+
interface ClipsPanelProps extends Pick<SidePanelProps, "onClose"> {
|
|
537
|
+
/** Where its host places it. */
|
|
538
|
+
className?: string;
|
|
539
|
+
}
|
|
540
|
+
/** The Clips section: the clip recording now, the shape the next records
|
|
541
|
+
* in, and every clip the game keeps, each to play here, delete, or send
|
|
542
|
+
* to the agent. */
|
|
543
|
+
export declare function ClipsPanel({ onClose, className }: ClipsPanelProps): import("react").JSX.Element;
|
|
544
|
+
interface FavoritesPanelProps extends Pick<SidePanelProps, "onClose"> {
|
|
545
|
+
/** Where its host places it. */
|
|
546
|
+
className?: string;
|
|
547
|
+
}
|
|
548
|
+
/** The fields a creator starred, gathered from the world and every entity
|
|
549
|
+
* as Unreal's Details panel gathers its Favorites: the world's settings
|
|
550
|
+
* first, then a card per component, each field edited live. */
|
|
551
|
+
export declare function FavoritesPanel({ onClose, className }: FavoritesPanelProps): import("react").JSX.Element;
|
|
552
|
+
interface ScatterInstanceActionsProps {
|
|
553
|
+
/** The map's prop the instance stands for, or null for one the seed
|
|
554
|
+
* placed. */
|
|
555
|
+
prop: string | null;
|
|
556
|
+
/** Where it stands, [x, z] in metres. */
|
|
557
|
+
position: [number, number];
|
|
558
|
+
onMakeEditable: () => void;
|
|
559
|
+
onMove: (point: [number, number]) => void;
|
|
560
|
+
onDelete: () => void;
|
|
561
|
+
className?: string;
|
|
562
|
+
}
|
|
563
|
+
/** Under a scattered tree, bush or rock in the Inspector: Make editable,
|
|
564
|
+
* which makes it a prop of the map; under a prop, where it stands, which
|
|
565
|
+
* moves it, and Delete. */
|
|
566
|
+
export declare function ScatterInstanceActions({ prop, position, onMakeEditable, onMove, onDelete, className }: ScatterInstanceActionsProps): import("react").JSX.Element;
|
|
567
|
+
/** One stat as the Stats card shows it. */
|
|
568
|
+
interface InspectedStat {
|
|
569
|
+
name: string;
|
|
570
|
+
base: number;
|
|
571
|
+
/** The base under its modifiers, clamped to its bounds. */
|
|
572
|
+
value: number;
|
|
573
|
+
modifiers: StatModifier[];
|
|
574
|
+
/** The base's slider. */
|
|
575
|
+
range: PropRange;
|
|
576
|
+
}
|
|
577
|
+
interface StatsCardProps extends Pick<ComponentProps<typeof BehaviourCard>, "description" | "docsHref" | "copyText" | "readOnlyReason" | "favorite" | "className"> {
|
|
578
|
+
stats: InspectedStat[];
|
|
579
|
+
/** Some base was edited here; left out, none was. */
|
|
580
|
+
changed?: boolean;
|
|
581
|
+
/** A base edited, by its stat's name. */
|
|
582
|
+
onChange: (name: string, base: number) => void;
|
|
583
|
+
}
|
|
584
|
+
/** The entity's stats, whatever declared them: a slider on each one's
|
|
585
|
+
* base, and under them the value each resolves to where its modifiers or
|
|
586
|
+
* bounds move it, with each modifier and a timed one's seconds left. */
|
|
587
|
+
export declare function StatsCard({ stats, onChange, description, docsHref, changed, copyText, readOnlyReason, favorite, className }: StatsCardProps): import("react").JSX.Element;
|
|
588
|
+
/** A behaviour's card, with the id of the row it edits. */
|
|
589
|
+
type InspectedBehaviour = Omit<ComponentProps<typeof BehaviourCard>, "onChange"> & Pick<DevtoolsNode, "id">;
|
|
590
|
+
/** A card that takes no edit, and why. */
|
|
591
|
+
type ReadOnlyCard = Pick<ComponentProps<typeof BehaviourCard>, "name" | "props" | "readOnlyReason">;
|
|
592
|
+
interface InspectedEntity {
|
|
593
|
+
name: string;
|
|
594
|
+
/** The id as the game prints it: `#01`. Left out for a row that is no
|
|
595
|
+
* entity's, such as a HUD's, which shows no behaviours and sends
|
|
596
|
+
* nothing to the agent. */
|
|
597
|
+
entityId?: string;
|
|
598
|
+
/** Its component type: Enemy, Pickup. Left out, no chip. */
|
|
599
|
+
type?: string;
|
|
600
|
+
/** Left out, the row goes. */
|
|
601
|
+
model?: string;
|
|
602
|
+
/** Left out where the entity has no transform. */
|
|
603
|
+
position?: MapPoint;
|
|
604
|
+
behaviours: InspectedBehaviour[];
|
|
605
|
+
/** Left out where the entity has no stats: one card after the
|
|
606
|
+
* behaviours'. */
|
|
607
|
+
stats?: Omit<ComponentProps<typeof StatsCard>, "onChange" | "className">;
|
|
608
|
+
systems: SystemEntry[];
|
|
609
|
+
relations: Relation[];
|
|
610
|
+
/** The panel its component declared through `useDevtoolsPanel`, drawn
|
|
611
|
+
* above the behaviours; left out where it declared none. */
|
|
612
|
+
panel?: DeclaredPanel;
|
|
613
|
+
/** A card that takes no edit, and why, drawn in place of the
|
|
614
|
+
* behaviours: a scattered instance's placement, or the props a game
|
|
615
|
+
* wrote on a HUD component. */
|
|
616
|
+
readOnlyCard?: ReadOnlyCard;
|
|
617
|
+
/** A scattered tree, bush or rock's actions under its placement: Make
|
|
618
|
+
* editable, or, for one that is a prop, where it stands and Delete. */
|
|
619
|
+
scatter?: Pick<ComponentProps<typeof ScatterInstanceActions>, "prop" | "position">;
|
|
620
|
+
/** A card that takes no edit for each state machine it holds, after
|
|
621
|
+
* the behaviours'. */
|
|
622
|
+
machines?: ReadOnlyCard[];
|
|
623
|
+
/** The numbers that decide a cast, for an entity that holds abilities,
|
|
624
|
+
* in a section after the behaviours; left out, no section. */
|
|
625
|
+
abilities?: Omit<AbilitiesCardProps, "className">;
|
|
626
|
+
}
|
|
627
|
+
interface InspectorProps {
|
|
628
|
+
/** Left out, nothing is selected. */
|
|
629
|
+
entity?: InspectedEntity;
|
|
630
|
+
/** The saved sets of prop values, by name. None, and the row goes. */
|
|
631
|
+
presets: string[];
|
|
632
|
+
preset: string;
|
|
633
|
+
/** A prop edited on a card, by its row's id. */
|
|
634
|
+
onChange: (edit: PropEdit) => void;
|
|
635
|
+
/** A stat's base edited on the Stats card, by the stat's name. */
|
|
636
|
+
onStatChange: (name: string, base: number) => void;
|
|
637
|
+
onSendToAgent: () => void;
|
|
638
|
+
/** A related entity pressed, by its id. */
|
|
639
|
+
onSelectEntity: (id: string) => void;
|
|
640
|
+
/** Its pane's X on a phone, at the end of the header. */
|
|
641
|
+
close?: ReactNode;
|
|
642
|
+
onPreset: (preset: string) => void;
|
|
643
|
+
onSavePreset: () => void;
|
|
644
|
+
onDeletePreset: () => void;
|
|
645
|
+
/** What a scattered instance's actions do; left out, they are not
|
|
646
|
+
* shown, as where no map editor runs. */
|
|
647
|
+
onScatter?: Pick<ComponentProps<typeof ScatterInstanceActions>, "onMakeEditable" | "onMove" | "onDelete">;
|
|
648
|
+
}
|
|
649
|
+
/** The selected entity: its header, a card per behaviour, the systems that
|
|
650
|
+
* run on it and its relations, with its presets at the foot. */
|
|
651
|
+
export declare function Inspector({ entity, presets, preset, onChange, onStatChange, onSendToAgent, onSelectEntity, onPreset, onSavePreset, onDeletePreset, onScatter, close }: InspectorProps): import("react").JSX.Element;
|
|
652
|
+
/** One part of what goes to the agent, as `describe` gathers it. */
|
|
653
|
+
interface BundlePart {
|
|
654
|
+
id: string;
|
|
655
|
+
title: string;
|
|
656
|
+
/** What it holds, in a line: the files, the systems. */
|
|
657
|
+
summary: string;
|
|
658
|
+
included: boolean;
|
|
659
|
+
/** A picture of it, such as the framed screenshot. */
|
|
660
|
+
image?: string;
|
|
661
|
+
}
|
|
662
|
+
/** A send under way. */
|
|
663
|
+
interface SendProgress {
|
|
664
|
+
/** Who it goes to: "Claude Code". */
|
|
665
|
+
agent: string;
|
|
666
|
+
/** Between 0 and 1. */
|
|
667
|
+
progress: number;
|
|
668
|
+
sentPartIds: string[];
|
|
669
|
+
}
|
|
670
|
+
interface SendToAgentProps {
|
|
671
|
+
name: string;
|
|
672
|
+
entityId: string;
|
|
673
|
+
intent: string;
|
|
674
|
+
onIntentChange: (intent: string) => void;
|
|
675
|
+
parts: BundlePart[];
|
|
676
|
+
onTogglePart: (id: string) => void;
|
|
677
|
+
/** The bundle's size, the image aside. */
|
|
678
|
+
bundleKilobytes: number;
|
|
679
|
+
/** Left out until Send is pressed. */
|
|
680
|
+
sending?: SendProgress;
|
|
681
|
+
/** How the last send went, where it left the pane open. */
|
|
682
|
+
outcome?: SendOutcome;
|
|
683
|
+
onSend: () => void;
|
|
684
|
+
onCopyBundle: () => void;
|
|
685
|
+
onCancel: () => void;
|
|
686
|
+
/** Where the overlay places it. */
|
|
687
|
+
className?: string;
|
|
688
|
+
}
|
|
689
|
+
/** What goes to the agent about one entity: a line of intent and the parts
|
|
690
|
+
* `describe` gathers, each of which can be left out. */
|
|
691
|
+
export declare function SendToAgent({ name, entityId, intent, onIntentChange, parts, onTogglePart, bundleKilobytes, sending, outcome, onSend, onCopyBundle, onCancel, className }: SendToAgentProps): import("react").JSX.Element;
|
|
692
|
+
/** A part of the overlay that answers keys of its own. */
|
|
693
|
+
declare enum DevtoolsSurface {
|
|
694
|
+
Tree = "tree",
|
|
695
|
+
Inspector = "inspector",
|
|
696
|
+
Console = "console",
|
|
697
|
+
TopBar = "top-bar",
|
|
698
|
+
/** The outline and the context menu over the game. */
|
|
699
|
+
Scene = "scene"
|
|
700
|
+
}
|
|
701
|
+
/** Every key the overlay answers to, by what it does. */
|
|
702
|
+
declare enum DevtoolsAction {
|
|
703
|
+
ToggleEditMode = "toggle-edit-mode",
|
|
704
|
+
ShowShortcuts = "show-shortcuts",
|
|
705
|
+
SendToAgent = "send-to-agent",
|
|
706
|
+
CopyAgentBundle = "copy-agent-bundle",
|
|
707
|
+
Undo = "undo",
|
|
708
|
+
Redo = "redo",
|
|
709
|
+
Save = "save",
|
|
710
|
+
ShowRailSection = "show-rail-section",
|
|
711
|
+
ToggleConsole = "toggle-console",
|
|
712
|
+
NextGamePanel = "next-game-panel",
|
|
713
|
+
FoldSidebar = "fold-sidebar",
|
|
714
|
+
Close = "close",
|
|
715
|
+
Select = "select",
|
|
716
|
+
AddToSelection = "add-to-selection",
|
|
717
|
+
SelectParent = "select-parent",
|
|
718
|
+
OpenContextMenu = "open-context-menu",
|
|
719
|
+
Inspect = "inspect",
|
|
720
|
+
FocusCamera = "focus-camera",
|
|
721
|
+
Hide = "hide",
|
|
722
|
+
Duplicate = "duplicate",
|
|
723
|
+
Delete = "delete",
|
|
724
|
+
AddBehaviour = "add-behaviour",
|
|
725
|
+
CopyId = "copy-id",
|
|
726
|
+
FilterTree = "filter-tree",
|
|
727
|
+
MoveInTree = "move-in-tree",
|
|
728
|
+
ExpandInTree = "expand-in-tree",
|
|
729
|
+
SelectInTree = "select-in-tree",
|
|
730
|
+
ShowBehaviours = "show-behaviours",
|
|
731
|
+
NextProp = "next-prop",
|
|
732
|
+
SavePreset = "save-preset",
|
|
733
|
+
ResetProps = "reset-props",
|
|
734
|
+
ClearConsole = "clear-console",
|
|
735
|
+
TogglePause = "toggle-pause",
|
|
736
|
+
ToggleClip = "toggle-clip",
|
|
737
|
+
StepFrame = "step-frame",
|
|
738
|
+
StepBack = "step-back",
|
|
739
|
+
LowerTerrain = "lower-terrain",
|
|
740
|
+
SmoothTerrain = "smooth-terrain",
|
|
741
|
+
ResizeBrush = "resize-brush",
|
|
742
|
+
BrushStrength = "brush-strength",
|
|
743
|
+
PutToolDown = "put-tool-down",
|
|
744
|
+
PutCardDown = "put-card-down"
|
|
745
|
+
}
|
|
746
|
+
interface ShortcutsPanelProps {
|
|
747
|
+
/** Escape in its search. */
|
|
748
|
+
onClose: () => void;
|
|
749
|
+
/** Focus the search as it mounts, as `?` asks. */
|
|
750
|
+
focusSearch?: boolean;
|
|
751
|
+
/** The surfaces on screen. A key whose surface is missing is dimmed and
|
|
752
|
+
* marked not yet; left out, every key is live. */
|
|
753
|
+
surfaces?: DevtoolsSurface[];
|
|
754
|
+
/** Keys a surface on screen shows but does not answer yet, dimmed the
|
|
755
|
+
* same way. */
|
|
756
|
+
unanswered?: DevtoolsAction[];
|
|
757
|
+
/** Where its host places it. */
|
|
758
|
+
className?: string;
|
|
759
|
+
}
|
|
760
|
+
/** Every key the overlay answers to, by where it works, with a search over
|
|
761
|
+
* actions and keys: Settings' Shortcuts, which `?` opens. */
|
|
762
|
+
export declare function ShortcutsPanel({ onClose, focusSearch, surfaces, unanswered, className }: ShortcutsPanelProps): import("react").JSX.Element;
|
|
763
|
+
/** The lines logged since the console last showed, for its icon's circle. */
|
|
764
|
+
interface UnreadLog {
|
|
765
|
+
count: number;
|
|
766
|
+
/** The worst level among them; none with nothing unread. */
|
|
767
|
+
level?: LogLevel;
|
|
768
|
+
}
|
|
769
|
+
/** One section of the sidebar, as its icon on the rail. */
|
|
770
|
+
interface RailItem {
|
|
771
|
+
id: string;
|
|
772
|
+
/** The section's name, which the icon's tooltip says. */
|
|
773
|
+
title: string;
|
|
774
|
+
icon: ReactNode;
|
|
775
|
+
/** The chord that opens it. */
|
|
776
|
+
shortcut?: string[];
|
|
777
|
+
/** The console's: the lines logged since it last showed. */
|
|
778
|
+
unread?: UnreadLog;
|
|
779
|
+
}
|
|
780
|
+
interface RailProps {
|
|
781
|
+
/** From the top: the overlay's sections and the game's. */
|
|
782
|
+
items: RailItem[];
|
|
783
|
+
/** At the foot, apart from the rest. */
|
|
784
|
+
footItems: RailItem[];
|
|
785
|
+
/** Last of all, under a line of its own: the console. */
|
|
786
|
+
apart?: RailItem;
|
|
787
|
+
/** The section the sidebar shows; null while it is folded. */
|
|
788
|
+
active: string | null;
|
|
789
|
+
/** A press on a section's icon, the open one's included. */
|
|
790
|
+
onSelect: (id: string) => void;
|
|
791
|
+
/** Given, the top icons move on a drag up or down the rail, and a
|
|
792
|
+
* release hands over their ids in the new order. */
|
|
793
|
+
onOrder?: (ids: string[]) => void;
|
|
794
|
+
/** Where the overlay places it, and how tall it is. */
|
|
795
|
+
className?: string;
|
|
796
|
+
}
|
|
797
|
+
/** The column of icons down the left edge, one a section of the sidebar
|
|
798
|
+
* beside it, as VS Code's activity bar and Figma's navigation bar: what a
|
|
799
|
+
* creator builds with at the top, what they look things up in at the
|
|
800
|
+
* foot, and one apart under a line at the very bottom. */
|
|
801
|
+
export declare function Rail({ items, footItems, apart, active, onSelect, onOrder, className }: RailProps): import("react").JSX.Element;
|
|
802
|
+
interface SidebarProps {
|
|
803
|
+
/** In pixels, the same for every section. */
|
|
804
|
+
width: number;
|
|
805
|
+
/** A drag on its edge, or an arrow key with the edge focused: the
|
|
806
|
+
* width asked for, which the caller keeps inside its limits. */
|
|
807
|
+
onWidth: (width: number) => void;
|
|
808
|
+
/** The open section's pane. */
|
|
809
|
+
children: ReactNode;
|
|
810
|
+
}
|
|
811
|
+
/** The one sidebar beside the rail: the open section at the width a drag
|
|
812
|
+
* on its edge set, or wider where the section needs it. It grows out of
|
|
813
|
+
* the rail as it opens and narrows back into it as it folds, what it holds
|
|
814
|
+
* keeping its width and riding the moving edge, so it slides in and out of
|
|
815
|
+
* the rail rather than squeezing; a
|
|
816
|
+
* change of width, such as the console's, springs the same way, and a drag
|
|
817
|
+
* follows the pointer at once. A direct child of `AnimatePresence`, so its
|
|
818
|
+
* fold plays before it goes. */
|
|
819
|
+
export declare function Sidebar({ width, onWidth, children }: SidebarProps): import("react").JSX.Element;
|
|
820
|
+
interface SplitPaneProps {
|
|
821
|
+
/** The section's pane, which takes the whole height alone. */
|
|
822
|
+
top: ReactNode;
|
|
823
|
+
/** Under it, the pane about what is selected; nothing, and it goes. */
|
|
824
|
+
bottom?: ReactNode;
|
|
825
|
+
/** The top pane's share of the height while both show, from 0 to 1. */
|
|
826
|
+
share: number;
|
|
827
|
+
/** A drag on the line between them, or an arrow key with the line
|
|
828
|
+
* focused: the share asked for, which the caller keeps inside its
|
|
829
|
+
* limits. */
|
|
830
|
+
onShare: (share: number) => void;
|
|
831
|
+
}
|
|
832
|
+
/** The sidebar's column: the section, and under it the inspector once a
|
|
833
|
+
* row is selected, with a line between them that a drag moves. Both in
|
|
834
|
+
* view together, as Roblox stacks Explorer over Properties. The section
|
|
835
|
+
* springs to its share as the inspector rises under it, and back to the
|
|
836
|
+
* whole height as it folds away; a drag follows the pointer at once. */
|
|
837
|
+
export declare function SplitPane({ top, bottom, share, onShare }: SplitPaneProps): import("react").JSX.Element;
|
|
838
|
+
interface SectionPaneProps {
|
|
839
|
+
panel: DevtoolsPanel$1;
|
|
840
|
+
/** Given, an X in the header closes it: a phone's sheet. */
|
|
841
|
+
onClose?: () => void;
|
|
842
|
+
}
|
|
843
|
+
/** A panel of the engine's or the game's as a section, in the sidebar or a
|
|
844
|
+
* phone's sheet: its icon and its title, then what its component draws,
|
|
845
|
+
* scrolling inside the pane's height. */
|
|
846
|
+
export declare function SectionPane({ panel, onClose }: SectionPaneProps): import("react").JSX.Element;
|
|
847
|
+
interface SegmentOption<Value extends string> {
|
|
848
|
+
value: Value;
|
|
849
|
+
label: string;
|
|
850
|
+
shortcut?: string[];
|
|
851
|
+
/** Drawn above the label: a phone's tab bar, big enough for a thumb.
|
|
852
|
+
* A segment with an icon shows its label only while chosen, so a row
|
|
853
|
+
* of them fits a phone; the label stays its name. */
|
|
854
|
+
icon?: ReactNode;
|
|
855
|
+
}
|
|
856
|
+
interface SegmentedControlProps<Value extends string> {
|
|
857
|
+
/** The group's accessible name. */
|
|
858
|
+
label: string;
|
|
859
|
+
options: SegmentOption<Value>[];
|
|
860
|
+
value: Value;
|
|
861
|
+
onChange: (value: Value) => void;
|
|
862
|
+
/** Given, every segment is disabled and says why as its tooltip. */
|
|
863
|
+
disabledReason?: string;
|
|
864
|
+
/** The frame and the font differ by use: the speed is framed and mono,
|
|
865
|
+
* the game panels' tabs are neither, and a phone's tab bar is taller,
|
|
866
|
+
* which the segments fill. */
|
|
867
|
+
className?: string;
|
|
868
|
+
}
|
|
869
|
+
/** One choice out of a few, side by side: the playback speed, the game
|
|
870
|
+
* panels' tabs. The accent slides to the chosen one. */
|
|
871
|
+
export declare function SegmentedControl<Value extends string>({ label, options, value, onChange, disabledReason, className }: SegmentedControlProps<Value>): import("react").JSX.Element;
|
|
872
|
+
/** The seven panels the overlay always has; a game's own panels take the
|
|
873
|
+
* ids `Devtools` gives them. */
|
|
874
|
+
export declare enum PhoneTab {
|
|
875
|
+
Entities = "entities",
|
|
876
|
+
Map = "map",
|
|
877
|
+
Wiki = "wiki",
|
|
878
|
+
Assets = "assets",
|
|
879
|
+
Inspector = "inspector",
|
|
880
|
+
Console = "console",
|
|
881
|
+
Clips = "clips"
|
|
882
|
+
}
|
|
883
|
+
interface PhoneTabBarProps {
|
|
884
|
+
/** A tab per panel, each with its icon. */
|
|
885
|
+
tabs: SegmentOption<string>[];
|
|
886
|
+
/** The open panel's tab; null with none open. */
|
|
887
|
+
active: string | null;
|
|
888
|
+
/** A tap: the tab's id, or null when the open one is tapped again. */
|
|
889
|
+
onSelect: (id: string | null) => void;
|
|
890
|
+
}
|
|
891
|
+
/** The phone's bar along the bottom edge: the game panels' segmented
|
|
892
|
+
* control, grown to a thumb's height with an icon over each label, one
|
|
893
|
+
* segment per panel and none chosen while every panel is closed. The row
|
|
894
|
+
* scrolls sideways once the game adds more panels than fit. A second tap
|
|
895
|
+
* on the chosen segment closes its panel. */
|
|
896
|
+
export declare function PhoneTabBar({ tabs, active, onSelect }: PhoneTabBarProps): import("react").JSX.Element;
|
|
897
|
+
/** Where the entity menu opens: the row it acts on, the pointer in pixels
|
|
898
|
+
* from the viewport's corner, and the world point the pointer met. */
|
|
899
|
+
interface EntityMenuAnchor {
|
|
900
|
+
id: string;
|
|
901
|
+
x: number;
|
|
902
|
+
y: number;
|
|
903
|
+
point?: WorldPoint;
|
|
904
|
+
}
|
|
905
|
+
/** What the pane keeps while another tab shows: the search, the kind
|
|
906
|
+
* whose page is open, whether each section a press folded or opened is
|
|
907
|
+
* open, by its key, on every page alike, and how far out the map reaches.
|
|
908
|
+
* A section no press reached shows as it starts: open, except the
|
|
909
|
+
* overview and each kind's engine entries nothing uses. */
|
|
910
|
+
interface WikiBrowse {
|
|
911
|
+
search: string;
|
|
912
|
+
kind: string | null;
|
|
913
|
+
sections: Record<string, boolean>;
|
|
914
|
+
}
|
|
915
|
+
interface WikiBrowserProps {
|
|
916
|
+
/** What `wiki()` returned. */
|
|
917
|
+
wiki: Wiki;
|
|
918
|
+
/** The entity tree, which names each entity an entry is used by. */
|
|
919
|
+
tree: DevtoolsNode[];
|
|
920
|
+
/** The entry on screen, or null for the list. The overlay holds it, so
|
|
921
|
+
* it outlasts a switch to another tab. */
|
|
922
|
+
open: WikiRef | null;
|
|
923
|
+
onOpen: (ref: WikiRef | null) => void;
|
|
924
|
+
/** The overlay holds it too, so it outlasts a switch to another tab. */
|
|
925
|
+
browse: WikiBrowse;
|
|
926
|
+
onBrowse: (browse: WikiBrowse) => void;
|
|
927
|
+
/** A press on an entity an entry is used by: its row's id. */
|
|
928
|
+
onSelectEntity: (id: string) => void;
|
|
929
|
+
/** A press on a missing page's path: Send to agent on that page. */
|
|
930
|
+
onSendToAgent: (page: string, intent: string) => void;
|
|
931
|
+
className?: string;
|
|
932
|
+
}
|
|
933
|
+
/** The running game's wiki: a map at the top, of where the page on screen
|
|
934
|
+
* sits and what it relates to, which takes you anywhere with a press, and
|
|
935
|
+
* under it the page. The home holds a search, the entries by kind, and the
|
|
936
|
+
* game's overview; a kind's page and an entry's open in its place. The
|
|
937
|
+
* kinds come in the map's tiers, and each lists the game's entries, then
|
|
938
|
+
* the engine's it uses, and folds the rest of the engine's into one
|
|
939
|
+
* row. */
|
|
940
|
+
export declare function WikiBrowser({ wiki, tree, open, onOpen, browse, onBrowse, onSelectEntity, onSendToAgent, className }: WikiBrowserProps): import("react").JSX.Element;
|
|
941
|
+
export declare enum LeftPanelTab {
|
|
942
|
+
Entities = "entities",
|
|
943
|
+
Map = "map",
|
|
944
|
+
Wiki = "wiki",
|
|
945
|
+
Assets = "assets"
|
|
946
|
+
}
|
|
947
|
+
interface LeftPanelProps extends Pick<SidePanelProps, "onClose"> {
|
|
948
|
+
tab: LeftPanelTab;
|
|
949
|
+
/** A press on an entity an entry is used by, which goes to Entities.
|
|
950
|
+
* Left out by a phone's sheet, which opens the inspector instead. */
|
|
951
|
+
onTab?: (tab: LeftPanelTab) => void;
|
|
952
|
+
/** The wiki entry on screen, or null for the list: the overlay's, so
|
|
953
|
+
* it stays open while the tree shows. */
|
|
954
|
+
open: WikiRef | null;
|
|
955
|
+
onOpen: (ref: WikiRef | null) => void;
|
|
956
|
+
/** The Wiki tab's search, open kind and folds: the overlay's too, so a
|
|
957
|
+
* switch to another section keeps them. */
|
|
958
|
+
browse: WikiBrowse;
|
|
959
|
+
onBrowse: (browse: WikiBrowse) => void;
|
|
960
|
+
/** The Map tab's folded and opened sections, the overlay's for the
|
|
961
|
+
* same reason. */
|
|
962
|
+
mapSections: Record<string, boolean>;
|
|
963
|
+
onMapSections: (sections: Record<string, boolean>) => void;
|
|
964
|
+
/** A right-click on an entity's row. */
|
|
965
|
+
onOpenMenu: (anchor: EntityMenuAnchor) => void;
|
|
966
|
+
/** A press on a row, after the store selects it, the same row again
|
|
967
|
+
* included, or on an entity an entry is used by: a phone opens the
|
|
968
|
+
* inspector on it. */
|
|
969
|
+
onSelect?: () => void;
|
|
970
|
+
/** A press on a missing wiki page's path: Send to agent on that
|
|
971
|
+
* page. */
|
|
972
|
+
onSendToAgent: (page: string, intent: string) => void;
|
|
973
|
+
}
|
|
974
|
+
/** One of the sections the engine fills: its tree, a press on a row being
|
|
975
|
+
* the store's selection, the map's editor, the running game's wiki, or
|
|
976
|
+
* what a creator can place. */
|
|
977
|
+
export declare function LeftPanel({ tab, onTab, open, onOpen, browse, onBrowse, mapSections, onMapSections, onClose, onOpenMenu, onSelect, onSendToAgent }: LeftPanelProps): import("react").JSX.Element;
|
|
978
|
+
interface MapPaletteProps {
|
|
979
|
+
/** A press on an avatar's card, after the store selects its
|
|
980
|
+
* characters; a card that places keeps the section open. */
|
|
981
|
+
onSelect?: () => void;
|
|
982
|
+
}
|
|
983
|
+
/** The Assets section: what a creator can place, as cards in four
|
|
984
|
+
* sections, models, avatars, scatter and shapes, each with how many stand
|
|
985
|
+
* in the map now, under a search that filters the cards by name. A press
|
|
986
|
+
* on a card selects every entity that draws it; with Shift, Cmd or Ctrl
|
|
987
|
+
* held it adds them, as a click on the canvas does. A model's, a scatter
|
|
988
|
+
* kind's or a shape's press also picks the card up, for a click on the
|
|
989
|
+
* ground to place, and a second press puts it down. */
|
|
990
|
+
export declare function MapPalette({ onSelect }: MapPaletteProps): import("react").JSX.Element;
|
|
991
|
+
/** Whether a section shows its body, and what a press on its header does.
|
|
992
|
+
* The Wiki tab and the Map tab keep which sections are folded. With no
|
|
993
|
+
* `onToggle`, the section is held open with no fold to press, as a search
|
|
994
|
+
* holds the home's. */
|
|
995
|
+
interface SectionFold {
|
|
996
|
+
label: string;
|
|
997
|
+
open: boolean;
|
|
998
|
+
onToggle?: () => void;
|
|
999
|
+
}
|
|
1000
|
+
interface MaterialTilesProps {
|
|
1001
|
+
materials: PaintMaterial[];
|
|
1002
|
+
/** The material chosen now. */
|
|
1003
|
+
value: string;
|
|
1004
|
+
onChange: (name: string) => void;
|
|
1005
|
+
/** Whether a family's section is open, and what a press on its header
|
|
1006
|
+
* does. */
|
|
1007
|
+
fold: (family: string) => SectionFold;
|
|
1008
|
+
className?: string;
|
|
1009
|
+
}
|
|
1010
|
+
/** One tile per ground material, its colour texture over its name and the
|
|
1011
|
+
* chosen one ringed, in a section per family that folds, its tiles
|
|
1012
|
+
* wrapping to the pane's width: what Paint and Fill lay down. Alt and a click on the ground picks the
|
|
1013
|
+
* material under the cursor, as an eyedropper does. */
|
|
1014
|
+
export declare function MaterialTiles({ materials, value, onChange, fold, className }: MaterialTilesProps): import("react").JSX.Element;
|
|
1015
|
+
/** The settings of a material's look the editor refines. */
|
|
1016
|
+
interface RefinedLook {
|
|
1017
|
+
/** #rrggbb, which multiplies the texture's colour. */
|
|
1018
|
+
tint: string;
|
|
1019
|
+
/** How much of the tint applies, 0 to 1. */
|
|
1020
|
+
tintAmount: number;
|
|
1021
|
+
/** Metres one repeat of the texture covers. */
|
|
1022
|
+
tile: number;
|
|
1023
|
+
/** How strongly the detail shades, 0 to 2. */
|
|
1024
|
+
bumps: number;
|
|
1025
|
+
/** Rain ripples play on it. */
|
|
1026
|
+
wet: boolean;
|
|
1027
|
+
}
|
|
1028
|
+
interface MaterialRefineProps {
|
|
1029
|
+
look: RefinedLook;
|
|
1030
|
+
/** A change as it is dragged, shown and not yet an undo step. */
|
|
1031
|
+
onPreview: (look: Partial<RefinedLook>) => void;
|
|
1032
|
+
/** A change where the drag ends, as one undo step. */
|
|
1033
|
+
onCommit: (look: Partial<RefinedLook>) => void;
|
|
1034
|
+
className?: string;
|
|
1035
|
+
}
|
|
1036
|
+
/** A material's tint, tile and bumps, each shown on the ground as it is
|
|
1037
|
+
* dragged and written where the drag ends, and Wet, written as it is
|
|
1038
|
+
* pressed. */
|
|
1039
|
+
export declare function MaterialRefine({ look, onPreview, onCommit, className }: MaterialRefineProps): import("react").JSX.Element;
|
|
1040
|
+
interface ScatterControlsProps extends ScatterPick {
|
|
1041
|
+
onChange: (pick: Partial<ScatterPick>) => void;
|
|
1042
|
+
className?: string;
|
|
1043
|
+
}
|
|
1044
|
+
/** What the Scatter tool paints: the families as chips, any of them on,
|
|
1045
|
+
* and whether a stroke grows them to double, growing back what was
|
|
1046
|
+
* erased, thins them to half or erases each one under the brush. */
|
|
1047
|
+
export declare function ScatterControls({ families, action, onChange, className }: ScatterControlsProps): import("react").JSX.Element;
|
|
1048
|
+
interface MapPickerProps {
|
|
1049
|
+
/** Every map the game registered, each marked where it is on screen. */
|
|
1050
|
+
maps: MapChoice[];
|
|
1051
|
+
/** The map the editor edits, or "" while there is none. */
|
|
1052
|
+
value: string;
|
|
1053
|
+
onPick: (map: string) => void;
|
|
1054
|
+
/** Edits the map file lacks, which another map asks about first. */
|
|
1055
|
+
unsaved?: boolean;
|
|
1056
|
+
/** Saves the edits before another map opens; false keeps this one. */
|
|
1057
|
+
onSave?: () => Promise<boolean>;
|
|
1058
|
+
/** Drops the edits before another map opens; false keeps this one. */
|
|
1059
|
+
onDiscard?: () => Promise<boolean>;
|
|
1060
|
+
/** Given, the list ends in "Reset <map> to base…", which asks first. */
|
|
1061
|
+
onResetToBase?: () => void;
|
|
1062
|
+
}
|
|
1063
|
+
/** The map the Map section edits, as its header's name with a chevron:
|
|
1064
|
+
* a press lists the game's maps under it, as Figma's page picker and VS
|
|
1065
|
+
* Code's branch picker do. The arrows move, Enter picks, and Escape or a
|
|
1066
|
+
* press outside closes it. Another map picked over unsaved edits asks
|
|
1067
|
+
* Save, Discard or Cancel first, as a desktop editor's close does. */
|
|
1068
|
+
export declare function MapPicker({ maps, value, onPick, unsaved, onSave, onDiscard, onResetToBase }: MapPickerProps): import("react").JSX.Element;
|
|
1069
|
+
interface TerrainSectionProps {
|
|
1070
|
+
/** Whether each section a press folded or opened is open, by its key:
|
|
1071
|
+
* the overlay's, so a switch to another section keeps them. A section
|
|
1072
|
+
* no press reached is open. */
|
|
1073
|
+
sections: Record<string, boolean>;
|
|
1074
|
+
onSections: (sections: Record<string, boolean>) => void;
|
|
1075
|
+
}
|
|
1076
|
+
/** The Map tab's terrain editor, toolbar first: the six tools and Clear
|
|
1077
|
+
* as icons, pinned; then sections that fold. Brush holds the size, the
|
|
1078
|
+
* strength and the rows of the tool in hand: Sculpt's Raise or Lower,
|
|
1079
|
+
* Flatten's level, Scatter's families and what it does, Fill's region.
|
|
1080
|
+
* The chosen material's section, headed by its name and Duplicate, holds
|
|
1081
|
+
* its refine controls; a section per family holds its tiles; Map, last,
|
|
1082
|
+
* holds the sea's height. The pane's header names the map, which picks
|
|
1083
|
+
* another, and holds Undo, Redo and the moved base's two ways out. A tool
|
|
1084
|
+
* pressed is in hand until it is pressed again or Escape puts it down;
|
|
1085
|
+
* while it is, a drag over the ground paints it. */
|
|
1086
|
+
export declare function TerrainSection({ sections, onSections }: TerrainSectionProps): import("react").JSX.Element;
|
|
1087
|
+
/** A class the Wiki tab's map puts each node in, which a theme styles with
|
|
1088
|
+
* a `classDef`. The groups' classes are also their subgraphs' ids, but for
|
|
1089
|
+
* a relation's group, which takes Refers to's class. */
|
|
1090
|
+
export declare enum DiagramClass {
|
|
1091
|
+
Centre = "centre",
|
|
1092
|
+
/** The chain on the left, from the game to the centre's parent. */
|
|
1093
|
+
BelongsTo = "belongsTo",
|
|
1094
|
+
MadeOf = "madeOf",
|
|
1095
|
+
RefersTo = "refersTo",
|
|
1096
|
+
UsedBy = "usedBy",
|
|
1097
|
+
/** The rows under the running scene's row in the entity tree, drawn as
|
|
1098
|
+
* the entities that use an entry are. */
|
|
1099
|
+
Holds = "holds",
|
|
1100
|
+
/** The `N more` node a group of more than 8 folds its rest into. */
|
|
1101
|
+
Fold = "fold",
|
|
1102
|
+
/** The entities that use the entry but have no row in the tree. */
|
|
1103
|
+
OffTree = "offTree",
|
|
1104
|
+
/** An entry the game registered, or a kind that holds one: bright, with
|
|
1105
|
+
* an accent outline, at every step out. */
|
|
1106
|
+
Game = "game",
|
|
1107
|
+
/** An entry the engine registered, or a kind that holds only the
|
|
1108
|
+
* engine's: muted, so the game's stand out among them. */
|
|
1109
|
+
Engine = "engine",
|
|
1110
|
+
/** The second step out: the parts of each entry on the right, the
|
|
1111
|
+
* game's aside. */
|
|
1112
|
+
Faded = "faded"
|
|
1113
|
+
}
|
|
1114
|
+
interface DiagramTheme {
|
|
1115
|
+
/** Mermaid's options: the `base` theme's variables, the faces, the
|
|
1116
|
+
* spacing and the curve. The wiki site's diagrams take these alone. */
|
|
1117
|
+
mermaid: MermaidConfig;
|
|
1118
|
+
/** The body of the `classDef` for each class. */
|
|
1119
|
+
classes: Record<DiagramClass, string>;
|
|
1120
|
+
/** Behind a diagram with no game under it, such as a wiki page's: the
|
|
1121
|
+
* glass's own colour, whole. */
|
|
1122
|
+
background: string;
|
|
1123
|
+
}
|
|
1124
|
+
/** Translucent nodes in dark group wells: made of in a white tint, used
|
|
1125
|
+
* by in the accent chip's fill, the parent quieter, and soft curves
|
|
1126
|
+
* between them. */
|
|
1127
|
+
export declare const glassDiagramTheme: DiagramTheme;
|
|
1128
|
+
/** Lines alone: no node fill but the centre's, a dashed line around each
|
|
1129
|
+
* group's faint well, each group told apart by its outline, and edges
|
|
1130
|
+
* that leave and arrive level. */
|
|
1131
|
+
export declare const outlineDiagramTheme: DiagramTheme;
|
|
1132
|
+
/** Solid cards in dark group wells, and edges that turn square corners,
|
|
1133
|
+
* as a schematic's do. */
|
|
1134
|
+
export declare const cardDiagramTheme: DiagramTheme;
|
|
1135
|
+
/** The theme the Wiki tab's map, its pages' diagrams and the wiki site
|
|
1136
|
+
* draw with. */
|
|
1137
|
+
export declare const diagramTheme: DiagramTheme;
|
|
1138
|
+
/** What the map centres on: an entry, a kind, or null for the game. */
|
|
1139
|
+
type DiagramCentre = WikiRef | {
|
|
1140
|
+
kind: string;
|
|
1141
|
+
} | null;
|
|
1142
|
+
/** How far out the map reaches: 1, the centre and its neighbours; 2, each
|
|
1143
|
+
* neighbour's own parts one column further; 3, one ring more. */
|
|
1144
|
+
type DiagramSteps = 1 | 2 | 3;
|
|
1145
|
+
interface WikiDiagramProps {
|
|
1146
|
+
/** What `wiki()` returned. */
|
|
1147
|
+
wiki: Wiki;
|
|
1148
|
+
/** The entity tree, which names each entity an entry is used by. */
|
|
1149
|
+
tree: DevtoolsNode[];
|
|
1150
|
+
/** What the map centres on: the Wiki tab's open entry, else its open
|
|
1151
|
+
* kind, else the game. */
|
|
1152
|
+
centre: DiagramCentre;
|
|
1153
|
+
/** A press on an entry, a kind or the game. */
|
|
1154
|
+
onCentre: (centre: DiagramCentre) => void;
|
|
1155
|
+
/** A press on an entity an entry is used by: its row's id. */
|
|
1156
|
+
onSelectEntity: (id: string) => void;
|
|
1157
|
+
/** How far out the map reaches: two steps in the overlay, where a
|
|
1158
|
+
* press on a node centres it to go further; a story draws one. */
|
|
1159
|
+
steps?: DiagramSteps;
|
|
1160
|
+
/** The stories draw each variant; the overlay takes the default. */
|
|
1161
|
+
theme?: DiagramTheme;
|
|
1162
|
+
className?: string;
|
|
1163
|
+
}
|
|
1164
|
+
/** The Wiki tab's map of the running game: the centre, the 2 steps nearest
|
|
1165
|
+
* it of the chain that leads to it from the game on its left, and what it
|
|
1166
|
+
* is made of, what it refers to and the entities that use it on its right,
|
|
1167
|
+
* or the rows the running scene holds, the game's bright among the
|
|
1168
|
+
* engine's. A press on an entry, a kind or the game hands it on to centre
|
|
1169
|
+
* there, and a press on an entity or a row hands its row on. Mermaid draws
|
|
1170
|
+
* it with `securityLevel: "strict"`, so its own click handlers are off:
|
|
1171
|
+
* each node listens by the element id mermaid gives it instead.
|
|
1172
|
+
*
|
|
1173
|
+
* The box scrolls like any other, and a drawing for a new centre scrolls
|
|
1174
|
+
* that centre to the box's middle. */
|
|
1175
|
+
export declare function WikiDiagram({ wiki, tree, centre, onCentre, onSelectEntity, steps, theme, className }: WikiDiagramProps): import("react").JSX.Element;
|
|
1176
|
+
interface WikiEntryListProps {
|
|
1177
|
+
/** The list's accessible name: its kind, or its place on an entry's
|
|
1178
|
+
* page. */
|
|
1179
|
+
label: string;
|
|
1180
|
+
entries: WikiEntry[];
|
|
1181
|
+
/** Muted after each name, for a list that holds several kinds. */
|
|
1182
|
+
showKind?: boolean;
|
|
1183
|
+
onOpen: (ref: WikiRef) => void;
|
|
1184
|
+
}
|
|
1185
|
+
/** Wiki entries as rows, each with the number of entities that use it at
|
|
1186
|
+
* the right. An entry whose registry cannot tell shows no number, rather
|
|
1187
|
+
* than a 0 that reads as unused. The engine's entries are muted, so the
|
|
1188
|
+
* game's own stand out among them. Tab lands on the first row. */
|
|
1189
|
+
export declare function WikiEntryList({ label, entries, showKind, onOpen }: WikiEntryListProps): import("react").JSX.Element;
|
|
1190
|
+
interface WikiEntryPageProps {
|
|
1191
|
+
entry: WikiEntry;
|
|
1192
|
+
/** The wiki route of the entry's kind, whose page an engine entry with
|
|
1193
|
+
* no page of its own shows and links to. */
|
|
1194
|
+
kindPage?: string;
|
|
1195
|
+
/** Another entry, or null for the Wiki tab's home, which a link on the
|
|
1196
|
+
* page to the game's overview opens. */
|
|
1197
|
+
onOpen: (ref: WikiRef | null) => void;
|
|
1198
|
+
/** A link on the page to a site route: what opens the entry or kind
|
|
1199
|
+
* whose page it names in the panel, or undefined where none does. */
|
|
1200
|
+
openRoute?: (route: string) => (() => void) | undefined;
|
|
1201
|
+
/** A press on a missing page's path: Send to agent on that page, with
|
|
1202
|
+
* a line of intent that asks for it. */
|
|
1203
|
+
onSendToAgent: (page: string, intent: string) => void;
|
|
1204
|
+
/** Whether the section with this label is open, as the Wiki tab keeps
|
|
1205
|
+
* it. */
|
|
1206
|
+
fold: (label: string) => SectionFold;
|
|
1207
|
+
/** A line under the description about the entry as the game runs,
|
|
1208
|
+
* such as a scene's that is not running, or the phase of the step a
|
|
1209
|
+
* system runs in. */
|
|
1210
|
+
note?: string;
|
|
1211
|
+
}
|
|
1212
|
+
/** One wiki entry: a header with its name and kind, and its code name,
|
|
1213
|
+
* wiki page and file as icons at the right; its description under it;
|
|
1214
|
+
* then Properties, which folds, with its own data where it has any; then
|
|
1215
|
+
* Used by, which folds, with each entity that carries a behaviour or a
|
|
1216
|
+
* trait and its value there; then Page, which folds, with the opening of its page, the game's or the
|
|
1217
|
+
* engine's, and Read more for the whole page there, with Show less at its
|
|
1218
|
+
* top. What it relates to is the Wiki tab's map, above it. */
|
|
1219
|
+
export declare function WikiEntryPage({ entry, kindPage, onOpen, openRoute, onSendToAgent, fold, note }: WikiEntryPageProps): import("react").JSX.Element;
|
|
1220
|
+
interface WikiKindPageProps {
|
|
1221
|
+
kind: Wiki["kinds"][number];
|
|
1222
|
+
/** How many entries the kind has, the engine's among them. */
|
|
1223
|
+
count: number;
|
|
1224
|
+
/** Whether the section with this label is open, as the Wiki tab keeps
|
|
1225
|
+
* it. */
|
|
1226
|
+
fold: (label: string) => SectionFold;
|
|
1227
|
+
/** Its entries, as the Wiki tab's home lists them. */
|
|
1228
|
+
children: ReactNode;
|
|
1229
|
+
}
|
|
1230
|
+
/** One kind of wiki entry, headed as an entry is: its name, its code name
|
|
1231
|
+
* and its wiki page as an icon at the right; its description under it;
|
|
1232
|
+
* then its entries, which fold. */
|
|
1233
|
+
export declare function WikiKindPage({ kind, count, fold, children }: WikiKindPageProps): import("react").JSX.Element;
|
|
1234
|
+
interface WikiLinksProps {
|
|
1235
|
+
/** The name the code and an agent use for it, such as `maxHealth`,
|
|
1236
|
+
* which a press copies. */
|
|
1237
|
+
code?: string;
|
|
1238
|
+
/** A wiki route, opened on the wiki site in a new tab. */
|
|
1239
|
+
page?: string;
|
|
1240
|
+
/** The file that declares it, by its path from the game's folder,
|
|
1241
|
+
* such as `src/behaviours/chase.ts`, where the dev server opens it. */
|
|
1242
|
+
source?: string;
|
|
1243
|
+
className?: string;
|
|
1244
|
+
}
|
|
1245
|
+
/** A wiki entry's or kind's code name, which a press copies, its page on
|
|
1246
|
+
* the wiki site, as a book, and the file that declares it, as a file,
|
|
1247
|
+
* each named in a tooltip. Draws nothing where it has none of them. */
|
|
1248
|
+
export declare function WikiLinks({ code, page, source, className }: WikiLinksProps): import("react").JSX.Element | null;
|
|
1249
|
+
export declare enum ButtonTone {
|
|
1250
|
+
/** The one action a surface is for: Agent, Send. */
|
|
1251
|
+
Accent = "accent",
|
|
1252
|
+
Neutral = "neutral",
|
|
1253
|
+
/** No fill of its own, for a button that is the whole of its pane,
|
|
1254
|
+
* which shrinks under the press in its place. */
|
|
1255
|
+
Plain = "plain"
|
|
1256
|
+
}
|
|
1257
|
+
interface ButtonProps {
|
|
1258
|
+
/** The words on the button, which are its accessible name too. */
|
|
1259
|
+
label: string;
|
|
1260
|
+
/** Leaves the words off the face, for a button its icon says enough
|
|
1261
|
+
* for; the label stays its name. */
|
|
1262
|
+
hideLabel?: boolean;
|
|
1263
|
+
tone: ButtonTone;
|
|
1264
|
+
/** Drawn before the label. */
|
|
1265
|
+
icon?: ReactNode;
|
|
1266
|
+
/** The chord that does the same, named in the tooltip. */
|
|
1267
|
+
shortcut?: string[];
|
|
1268
|
+
/** A line in the tooltip under the chord. */
|
|
1269
|
+
detail?: string;
|
|
1270
|
+
/** Given, the button is disabled and says why as its tooltip. */
|
|
1271
|
+
disabledReason?: string;
|
|
1272
|
+
/** Left out by a button that holds no state. */
|
|
1273
|
+
pressed?: boolean;
|
|
1274
|
+
/** One of a menu's choices, which the menu's arrows reach, checked
|
|
1275
|
+
* where it is pressed. */
|
|
1276
|
+
menuItem?: boolean;
|
|
1277
|
+
onPress: () => void;
|
|
1278
|
+
className?: string;
|
|
1279
|
+
}
|
|
1280
|
+
/** A text button with an icon. */
|
|
1281
|
+
export declare function Button({ label, hideLabel, tone, icon, shortcut, detail, disabledReason, pressed, menuItem, onPress, className }: ButtonProps): import("react").JSX.Element;
|
|
1282
|
+
export declare enum LampTone {
|
|
1283
|
+
/** Edit mode on, or a replay away from the present. */
|
|
1284
|
+
Accent = "accent",
|
|
1285
|
+
/** The game running at the present. */
|
|
1286
|
+
Live = "live",
|
|
1287
|
+
/** Off. */
|
|
1288
|
+
Idle = "idle",
|
|
1289
|
+
Info = "info",
|
|
1290
|
+
Warning = "warning",
|
|
1291
|
+
Error = "error"
|
|
1292
|
+
}
|
|
1293
|
+
interface LampProps {
|
|
1294
|
+
tone: LampTone;
|
|
1295
|
+
}
|
|
1296
|
+
/** A status dot. Decoration: whatever it reports, the words beside it say
|
|
1297
|
+
* too. */
|
|
1298
|
+
export declare function Lamp({ tone }: LampProps): import("react").JSX.Element;
|
|
1299
|
+
export declare enum ChipTone {
|
|
1300
|
+
/** The entity's type beside its name. */
|
|
1301
|
+
Accent = "accent",
|
|
1302
|
+
/** A relation, a log level's count. */
|
|
1303
|
+
Neutral = "neutral"
|
|
1304
|
+
}
|
|
1305
|
+
interface ChipProps {
|
|
1306
|
+
tone: ChipTone;
|
|
1307
|
+
/** A status dot before the words. */
|
|
1308
|
+
lamp?: LampTone;
|
|
1309
|
+
/** Given, the chip is a button: a relation that selects its entity, a
|
|
1310
|
+
* level that filters the log. */
|
|
1311
|
+
onPress?: () => void;
|
|
1312
|
+
/** A chip that toggles, such as a log level's filter. Off, it dims. */
|
|
1313
|
+
pressed?: boolean;
|
|
1314
|
+
/** The accessible name, where the chip's face says less than it means:
|
|
1315
|
+
* a phone's log level, a lamp and a count. */
|
|
1316
|
+
label?: string;
|
|
1317
|
+
/** An element elsewhere on the page holding what a screen reader
|
|
1318
|
+
* reads as this chip's accessible description. */
|
|
1319
|
+
"aria-describedby"?: string;
|
|
1320
|
+
/** Where the caller places it: a margin, an alignment. */
|
|
1321
|
+
className?: string;
|
|
1322
|
+
children: ReactNode;
|
|
1323
|
+
}
|
|
1324
|
+
/** A small rounded tag. */
|
|
1325
|
+
export declare function Chip({ tone, lamp, onPress, pressed, label, "aria-describedby": ariaDescribedby, className, children }: ChipProps): import("react").JSX.Element;
|
|
1326
|
+
interface CameraToggleProps {
|
|
1327
|
+
on: boolean;
|
|
1328
|
+
/** The press. The free camera belongs to the caller, and `on` is how it
|
|
1329
|
+
* comes back. */
|
|
1330
|
+
onToggle: () => void;
|
|
1331
|
+
}
|
|
1332
|
+
/** The round button beside the top bar that flies the free camera in place
|
|
1333
|
+
* of the scene's, and gives the scene's back. */
|
|
1334
|
+
export declare function CameraToggle({ on, onToggle }: CameraToggleProps): import("react").JSX.Element;
|
|
1335
|
+
interface MapToggleProps {
|
|
1336
|
+
on: boolean;
|
|
1337
|
+
/** The press. The map camera belongs to the caller, and `on` is how it
|
|
1338
|
+
* comes back. */
|
|
1339
|
+
onToggle: () => void;
|
|
1340
|
+
/** The toolbar's small button, in place of the round one beside the
|
|
1341
|
+
* bar. */
|
|
1342
|
+
phone?: boolean;
|
|
1343
|
+
}
|
|
1344
|
+
/** The button beside the free camera's that puts the map camera in the
|
|
1345
|
+
* scene's place, flying it up over the player's character until the whole map is in
|
|
1346
|
+
* view, and a second press gives the scene's camera back. */
|
|
1347
|
+
export declare function MapToggle({ on, onToggle, phone }: MapToggleProps): import("react").JSX.Element;
|
|
1348
|
+
export declare enum ResizeAxis {
|
|
1349
|
+
/** Dragged left and right: the edge of a column. */
|
|
1350
|
+
Horizontal = "horizontal",
|
|
1351
|
+
/** Dragged up and down: the line between two rows. */
|
|
1352
|
+
Vertical = "vertical"
|
|
1353
|
+
}
|
|
1354
|
+
interface ResizeHandleProps {
|
|
1355
|
+
/** The accessible name: what a drag resizes. */
|
|
1356
|
+
label: string;
|
|
1357
|
+
axis: ResizeAxis;
|
|
1358
|
+
/** The pixels moved since the last call, right and down positive. The
|
|
1359
|
+
* caller keeps the size and its limits. */
|
|
1360
|
+
onMove: (pixels: number) => void;
|
|
1361
|
+
/** A pointer taking hold of it, and letting go: for a host that
|
|
1362
|
+
* animates its size, so a drag follows the pointer at once. */
|
|
1363
|
+
onDragging?: (dragging: boolean) => void;
|
|
1364
|
+
className?: string;
|
|
1365
|
+
}
|
|
1366
|
+
/** The line between two panes that a drag moves, or an arrow key with the
|
|
1367
|
+
* line focused. */
|
|
1368
|
+
export declare function ResizeHandle({ label, axis, onMove, onDragging, className }: ResizeHandleProps): import("react").JSX.Element;
|
|
1369
|
+
interface RoundButtonProps extends Pick<ButtonProps, "label" | "icon" | "onPress" | "pressed" | "className" | "shortcut" | "detail" | "disabledReason"> {
|
|
1370
|
+
/** Drawn in the pane beside the button, such as a status for a screen
|
|
1371
|
+
* reader. */
|
|
1372
|
+
children?: ReactNode;
|
|
1373
|
+
}
|
|
1374
|
+
/** A round glass button the top bar's height, with an icon and no words,
|
|
1375
|
+
* for the rows beside the bar: Record's and the screenshot's before it,
|
|
1376
|
+
* the free camera's and the map camera's after it. Tinted while pressed. */
|
|
1377
|
+
export declare function RoundButton({ label, icon, onPress, pressed, className, shortcut, detail, disabledReason, children }: RoundButtonProps): import("react").JSX.Element;
|
|
1378
|
+
/** The circle on the console's icon: how many lines were logged since the
|
|
1379
|
+
* console last showed, in the colour of the worst of them. Nothing at
|
|
1380
|
+
* none. */
|
|
1381
|
+
export declare function UnreadBadge({ count, level }: UnreadLog): import("react").JSX.Element | null;
|
|
1382
|
+
interface PaletteCardProps {
|
|
1383
|
+
placeable: Placeable;
|
|
1384
|
+
/** The card is in hand, for a click on the ground to place. */
|
|
1385
|
+
held?: boolean;
|
|
1386
|
+
/** A press: `adding` where Shift, Cmd or Ctrl was held, as a click on
|
|
1387
|
+
* the canvas adds. An avatar's card nothing stands for takes none. */
|
|
1388
|
+
onPress?: (adding: boolean) => void;
|
|
1389
|
+
}
|
|
1390
|
+
/** One thing a creator can place: its picture, its name, how tall it is
|
|
1391
|
+
* and how many stand in the map. A press selects them, and picks a card
|
|
1392
|
+
* that places up, ringed in the accent while it is in hand. */
|
|
1393
|
+
export declare function PaletteCard({ placeable, held, onPress }: PaletteCardProps): import("react").JSX.Element;
|
|
1394
|
+
interface CaptureButtonProps {
|
|
1395
|
+
/** The press; whether the copy landed comes back, and the icon says
|
|
1396
|
+
* so. What is captured, and where it goes, is the caller's. */
|
|
1397
|
+
onCapture: () => Promise<boolean>;
|
|
1398
|
+
/** The toolbar's small button, in place of the round one beside the
|
|
1399
|
+
* bar. */
|
|
1400
|
+
phone?: boolean;
|
|
1401
|
+
}
|
|
1402
|
+
/** The button beside the free camera's that copies what the player sees,
|
|
1403
|
+
* then shows a check, or a cross where the copy failed. */
|
|
1404
|
+
export declare function CaptureButton({ onCapture, phone }: CaptureButtonProps): import("react").JSX.Element;
|
|
1405
|
+
interface RecordButtonProps {
|
|
1406
|
+
/** The press: the caller starts or stops the clip and opens the Clips
|
|
1407
|
+
* section. */
|
|
1408
|
+
onPress: () => void;
|
|
1409
|
+
}
|
|
1410
|
+
/** The button before the top bar, and by Spawnite while the dev tools are
|
|
1411
|
+
* closed, that records a clip of what the game draws: a red dot while
|
|
1412
|
+
* idle; while it records, a stop square on a red tint with a pulsing dot,
|
|
1413
|
+
* and the time so far in its tooltip. It waits, disabled, while the clip
|
|
1414
|
+
* starts and while it saves. */
|
|
1415
|
+
export declare function RecordButton({ onPress }: RecordButtonProps): import("react").JSX.Element;
|
|
1416
|
+
interface EditToggleProps {
|
|
1417
|
+
on: boolean;
|
|
1418
|
+
/** The press. Edit mode belongs to the caller, and `on` is how it comes
|
|
1419
|
+
* back. */
|
|
1420
|
+
onToggle: () => void;
|
|
1421
|
+
/** An agent's playtest attached to this tab: the pane lights green,
|
|
1422
|
+
* and its tooltip says what the agent does. */
|
|
1423
|
+
agent?: AgentActivity;
|
|
1424
|
+
}
|
|
1425
|
+
/** The one control left when edit mode is off: Spawnite's wordmark,
|
|
1426
|
+
* with its chord in the tooltip, and on a phone the gem alone, or an X
|
|
1427
|
+
* once edit mode is on. While an agent drives the tab the pane's edge
|
|
1428
|
+
* turns green, and the pane and the gem glow in that green, breathing
|
|
1429
|
+
* together while a call runs, so the corner says so without a control
|
|
1430
|
+
* of its own. */
|
|
1431
|
+
export declare function EditToggle({ on, onToggle, agent }: EditToggleProps): import("react").JSX.Element;
|
|
1432
|
+
export declare enum SparkTone {
|
|
1433
|
+
/** White, as the name beside it. */
|
|
1434
|
+
Plain = "plain",
|
|
1435
|
+
/** Send to agent's own mark, in the accent, where a pane or a menu
|
|
1436
|
+
* names it. */
|
|
1437
|
+
Accent = "accent"
|
|
1438
|
+
}
|
|
1439
|
+
interface SparkMarkProps {
|
|
1440
|
+
tone: SparkTone;
|
|
1441
|
+
}
|
|
1442
|
+
/** Spawnite's mark, the four-pointed spark of the wiki's icon, drawn in
|
|
1443
|
+
* the current colour. Decoration: the name beside it says what it is. */
|
|
1444
|
+
export declare function SparkMark({ tone }: SparkMarkProps): import("react").JSX.Element;
|
|
1445
|
+
interface FrameRateProps {
|
|
1446
|
+
framesPerSecond: number;
|
|
1447
|
+
frameMilliseconds: number;
|
|
1448
|
+
/** The recent frames as bars, oldest first, each a fraction of the
|
|
1449
|
+
* sparkline's height between 0 and 1. The caller decides what full
|
|
1450
|
+
* means. */
|
|
1451
|
+
history: number[];
|
|
1452
|
+
}
|
|
1453
|
+
/** The frame rate as a sparkline and two numbers, drawn straight onto the
|
|
1454
|
+
* scene with no pane behind it. */
|
|
1455
|
+
export declare function FrameRate({ framesPerSecond, frameMilliseconds, history }: FrameRateProps): import("react").JSX.Element;
|
|
1456
|
+
interface FreeCameraIconProps {
|
|
1457
|
+
/** The free camera is flying, in place of the player's. */
|
|
1458
|
+
on: boolean;
|
|
1459
|
+
className?: string;
|
|
1460
|
+
}
|
|
1461
|
+
/** The free camera's icon, after Unreal's play-in-editor: eject, while the
|
|
1462
|
+
* player's camera runs, to leave it and fly free; a gamepad, while flying,
|
|
1463
|
+
* to take the player's camera back. */
|
|
1464
|
+
export declare function FreeCameraIcon({ on, className }: FreeCameraIconProps): import("react").JSX.Element;
|
|
1465
|
+
/** The pane's corners and insets differ by surface, so the caller's classes
|
|
1466
|
+
* win over these. A pane that opens and closes animates through Motion's
|
|
1467
|
+
* props. */
|
|
1468
|
+
interface GlassPaneProps extends HTMLMotionProps<"div"> {
|
|
1469
|
+
/** Shrinks under a press, for a pane whose whole face is one button:
|
|
1470
|
+
* the button has no fill, so a shrink of its own would not show. */
|
|
1471
|
+
pressable?: boolean;
|
|
1472
|
+
}
|
|
1473
|
+
/** The dark pane every surface of the overlay sits in. It takes the pointer,
|
|
1474
|
+
* where the overlay around it lets the pointer through to the game. */
|
|
1475
|
+
export declare function GlassPane({ className, pressable, ...props }: GlassPaneProps): import("react").JSX.Element;
|
|
1476
|
+
/** A small glass label beside a control, shown on hover and on keyboard
|
|
1477
|
+
* focus: `@spawnite/ui`'s tooltip on the devtools' glass. */
|
|
1478
|
+
export declare function Tooltip(props: Omit<TooltipProps, "className">): import("react").JSX.Element;
|
|
1479
|
+
interface KeyboardShortcutProps {
|
|
1480
|
+
/** What the control does, first in the tooltip. */
|
|
1481
|
+
label: string;
|
|
1482
|
+
/** The chord that does the same, as keycaps after the label. Left out,
|
|
1483
|
+
* the control shows no tooltip. */
|
|
1484
|
+
keys?: string[];
|
|
1485
|
+
/** Given, the tooltip says why the control is disabled in place of its
|
|
1486
|
+
* chord. */
|
|
1487
|
+
disabledReason?: string;
|
|
1488
|
+
/** The control's face shows no words, so with no chord the tooltip
|
|
1489
|
+
* still names it. */
|
|
1490
|
+
iconOnly?: boolean;
|
|
1491
|
+
/** A line under the label and the chord, such as the state the control
|
|
1492
|
+
* stands for. */
|
|
1493
|
+
detail?: string;
|
|
1494
|
+
/** The one control the chord stands for. */
|
|
1495
|
+
children: ComponentProps<typeof Tooltip>["children"];
|
|
1496
|
+
}
|
|
1497
|
+
/** Gives a control its chord: the chrome keeps chords out of sight, so the
|
|
1498
|
+
* tooltip names it, and the shortcuts panel lists them all. */
|
|
1499
|
+
export declare function KeyboardShortcut({ label, keys, disabledReason, iconOnly, detail, children }: KeyboardShortcutProps): import("react").JSX.Element;
|
|
1500
|
+
export declare enum ListRowRole {
|
|
1501
|
+
TreeItem = "treeitem",
|
|
1502
|
+
MenuItem = "menuitem",
|
|
1503
|
+
/** One of a menu's choices, checked where it is selected. */
|
|
1504
|
+
MenuItemRadio = "menuitemradio",
|
|
1505
|
+
Option = "option"
|
|
1506
|
+
}
|
|
1507
|
+
interface ListRowProps {
|
|
1508
|
+
/** For a field that points at the row, such as a picker's search. */
|
|
1509
|
+
id?: string;
|
|
1510
|
+
/** What the row is inside its list. The list owns the arrow keys. */
|
|
1511
|
+
role: ListRowRole;
|
|
1512
|
+
label: string;
|
|
1513
|
+
/** Drawn before the label: an icon, a chevron. */
|
|
1514
|
+
leading?: ReactNode;
|
|
1515
|
+
/** Muted, straight after the label: an entity's id. */
|
|
1516
|
+
detail?: ReactNode;
|
|
1517
|
+
/** Drawn at the right: a shortcut, a count, a submenu's arrow. */
|
|
1518
|
+
trailing?: ReactNode;
|
|
1519
|
+
/** How far a tree row sits in, in levels. */
|
|
1520
|
+
depth?: number;
|
|
1521
|
+
/** A tree row with children: whether they show. Left out by a row with
|
|
1522
|
+
* none. */
|
|
1523
|
+
expanded?: boolean;
|
|
1524
|
+
/** The one row of its list that Tab lands on. */
|
|
1525
|
+
tabbable?: boolean;
|
|
1526
|
+
selected?: boolean;
|
|
1527
|
+
/** Given, the row is disabled and says why: in its tooltip where it
|
|
1528
|
+
* has a hint, which the reason stands in for, else beside its label. */
|
|
1529
|
+
disabledReason?: string;
|
|
1530
|
+
/** The click, where a pointer pressed it rather than a key. */
|
|
1531
|
+
onPress?: (event?: MouseEvent$1) => void;
|
|
1532
|
+
onHover?: () => void;
|
|
1533
|
+
/** What the row does, in a tooltip on hover and keyboard focus. */
|
|
1534
|
+
hint?: string;
|
|
1535
|
+
className?: string;
|
|
1536
|
+
}
|
|
1537
|
+
/** One row of a list: a tree's entity, a menu's action, a picker's option. */
|
|
1538
|
+
export declare function ListRow({ id, role, label, leading, detail, trailing, depth, expanded, tabbable, selected, disabledReason, onPress, onHover, hint, className }: ListRowProps): import("react").JSX.Element;
|
|
1539
|
+
interface PaneHeaderProps {
|
|
1540
|
+
/** Drawn before the title. */
|
|
1541
|
+
icon?: ReactNode;
|
|
1542
|
+
title: string;
|
|
1543
|
+
/** Muted, after the title: an id, a count, what the pane is about. */
|
|
1544
|
+
detail?: ReactNode;
|
|
1545
|
+
/** Drawn at the right of the title's row: buttons, a close. */
|
|
1546
|
+
actions?: ReactNode;
|
|
1547
|
+
/** Rows under the title, inside the header: the inspector's model and
|
|
1548
|
+
* position, the shortcuts panel's search. */
|
|
1549
|
+
children?: ReactNode;
|
|
1550
|
+
}
|
|
1551
|
+
/** The bold title a pane opens with when it is about one thing: an entity,
|
|
1552
|
+
* the shortcuts, what goes to the agent. */
|
|
1553
|
+
export declare function PaneHeader({ icon, title, detail, actions, children }: PaneHeaderProps): import("react").JSX.Element;
|
|
1554
|
+
/** What a field that drives a list, such as a picker's search, sets on its
|
|
1555
|
+
* input. */
|
|
1556
|
+
type ComboboxAttributes = Pick<InputHTMLAttributes<HTMLInputElement>, "role" | "aria-controls" | "aria-expanded" | "aria-activedescendant" | "onKeyDown">;
|
|
1557
|
+
interface SearchFieldProps extends ComboboxAttributes {
|
|
1558
|
+
/** The accessible name. */
|
|
1559
|
+
label: string;
|
|
1560
|
+
value: string;
|
|
1561
|
+
onChange: (value: string) => void;
|
|
1562
|
+
placeholder?: string;
|
|
1563
|
+
/** Drawn before the text, such as a magnifier. */
|
|
1564
|
+
icon?: ReactNode;
|
|
1565
|
+
/** The key that focuses the field, named in the tooltip. */
|
|
1566
|
+
shortcut?: string[];
|
|
1567
|
+
/** For the pane that moves focus here on its shortcut. */
|
|
1568
|
+
ref?: Ref<HTMLInputElement>;
|
|
1569
|
+
className?: string;
|
|
1570
|
+
}
|
|
1571
|
+
/** A one-line text field: a filter, a search, the intent sent to the
|
|
1572
|
+
* agent. */
|
|
1573
|
+
export declare function SearchField({ label, value, onChange, placeholder, icon, shortcut, ref, className, ...inputAttributes }: SearchFieldProps): import("react").JSX.Element;
|
|
1574
|
+
interface SectionLabelProps {
|
|
1575
|
+
label: string;
|
|
1576
|
+
/** Drawn before the label. */
|
|
1577
|
+
icon?: ReactNode;
|
|
1578
|
+
/** Given, the label is a button: a wiki kind's, which opens its page,
|
|
1579
|
+
* or a section's, which folds and unfolds it. */
|
|
1580
|
+
onPress?: () => void;
|
|
1581
|
+
/** Given with `onPress`, the button folds what the label heads, and
|
|
1582
|
+
* this says whether it is open. */
|
|
1583
|
+
expanded?: boolean;
|
|
1584
|
+
/** Given with `onPress`, the button's tooltip. */
|
|
1585
|
+
hint?: string;
|
|
1586
|
+
/** Drawn at the right: a count, a shortcut, a column heading. */
|
|
1587
|
+
children?: ReactNode;
|
|
1588
|
+
className?: string;
|
|
1589
|
+
}
|
|
1590
|
+
/** The small capitals that head a pane or a section of one: ENTITIES,
|
|
1591
|
+
* BEHAVIOURS, SYSTEMS. */
|
|
1592
|
+
export declare function SectionLabel({ label, icon, onPress, expanded, hint, children, className }: SectionLabelProps): import("react").JSX.Element;
|
|
1593
|
+
interface ShortcutProps {
|
|
1594
|
+
/** Each key of the chord in the order they are pressed, as printed on the
|
|
1595
|
+
* cap: `["⌘", "E"]`. */
|
|
1596
|
+
keys: string[];
|
|
1597
|
+
/** Where the caller places it: a margin, an alignment. */
|
|
1598
|
+
className?: string;
|
|
1599
|
+
}
|
|
1600
|
+
/** A chord as keycaps. Nested `kbd`, which is HTML's own spelling for a
|
|
1601
|
+
* combination of keys. */
|
|
1602
|
+
export declare function Shortcut({ keys, className }: ShortcutProps): import("react").JSX.Element;
|
|
1603
|
+
interface StatProps {
|
|
1604
|
+
value: ReactNode;
|
|
1605
|
+
/** Muted after the value: "fps", "ms", "cards". */
|
|
1606
|
+
unit: string;
|
|
1607
|
+
/** Drawn straight onto the scene, with no pane behind it. */
|
|
1608
|
+
outlined?: boolean;
|
|
1609
|
+
}
|
|
1610
|
+
/** A number and its unit. Stats in a row are told apart by the gap the caller
|
|
1611
|
+
* puts between them, never by a separator character. */
|
|
1612
|
+
export declare function Stat({ value, unit, outlined }: StatProps): import("react").JSX.Element;
|
|
1613
|
+
interface ToolbarToggleProps {
|
|
1614
|
+
on: boolean;
|
|
1615
|
+
/** The press. The toolbar belongs to the caller, and `on` is how it
|
|
1616
|
+
* comes back. */
|
|
1617
|
+
onToggle: () => void;
|
|
1618
|
+
}
|
|
1619
|
+
/** The button beside a phone's Edit toggle that shows and hides the
|
|
1620
|
+
* toolbar: chevrons folding in while it shows, out while it is hidden. */
|
|
1621
|
+
export declare function ToolbarToggle({ on, onToggle }: ToolbarToggleProps): import("react").JSX.Element;
|
|
1622
|
+
interface ToolButtonProps {
|
|
1623
|
+
/** The accessible name. The button shows an icon and no words. */
|
|
1624
|
+
label: string;
|
|
1625
|
+
/** Left out by a button that holds no state. */
|
|
1626
|
+
pressed?: boolean;
|
|
1627
|
+
/** Shows the accent tint without holding state, as Save does while
|
|
1628
|
+
* there is something to save. */
|
|
1629
|
+
lit?: boolean;
|
|
1630
|
+
shortcut?: string[];
|
|
1631
|
+
/** Given, the button is disabled and says why as its tooltip. */
|
|
1632
|
+
disabledReason?: string;
|
|
1633
|
+
onPress: () => void;
|
|
1634
|
+
/** The icon. */
|
|
1635
|
+
children: ReactNode;
|
|
1636
|
+
}
|
|
1637
|
+
/** A small icon button in a pane's header: pin, collapse, close. */
|
|
1638
|
+
export declare function ToolButton({ label, pressed, lit, shortcut, disabledReason, onPress, children }: ToolButtonProps): import("react").JSX.Element;
|
|
1639
|
+
export declare const palette: {
|
|
1640
|
+
readonly sans: "font-['IBM_Plex_Sans',system-ui,sans-serif]";
|
|
1641
|
+
readonly mono: "font-['IBM_Plex_Mono',ui-monospace,monospace]";
|
|
1642
|
+
readonly glassSurface: "bg-[#12162094] bg-clip-padding backdrop-blur-[14px] backdrop-saturate-90";
|
|
1643
|
+
readonly glassBorder: "border border-[#FFFFFF33]";
|
|
1644
|
+
readonly glassShadow: "shadow-[0_8px_28px_rgba(0,0,0,0.28),inset_0_1px_0_rgba(255,255,255,0.28)]";
|
|
1645
|
+
readonly mutedText: "text-[#FFFFFFB8]";
|
|
1646
|
+
readonly divider: "border-[#FFFFFF24]";
|
|
1647
|
+
readonly readoutBar: "bg-white shadow-[0_0_0_1px_rgba(8,12,22,0.9)]";
|
|
1648
|
+
readonly accentFill: "bg-[#FFC14D]";
|
|
1649
|
+
readonly accentText: "text-[#1B1206]";
|
|
1650
|
+
readonly accentGlow: "shadow-[0_0_0_2px_rgba(0,0,0,0.35),0_0_10px_#FFC14D]";
|
|
1651
|
+
readonly accentRing: "focus-visible:ring-2 focus-visible:ring-[#FFC14D]";
|
|
1652
|
+
readonly control: "h-7 focus-visible:ring-2 focus-visible:ring-[#FFC14D] focus-visible:ring-offset-0";
|
|
1653
|
+
readonly accentTint: "bg-[#FFC14D38]";
|
|
1654
|
+
readonly errorTint: "bg-[rgba(255,107,107,0.22)]";
|
|
1655
|
+
readonly accentBorder: "border-[#FFC14D]";
|
|
1656
|
+
readonly keycap: "min-w-[18px] h-[18px] px-[5px] rounded-[5px] border border-b-2 border-current/35 bg-current/12 text-[10.5px] font-medium leading-none opacity-90";
|
|
1657
|
+
};
|
|
1658
|
+
export type { Anchor, BehaviourProp, BundlePart, ChatAttachment, DevtoolsPanel, DiagramTheme, InspectedEntity, InspectedStat, PlaytestAction, RailItem, SegmentOption, SendProgress };
|