@astryxdesign/cli 0.1.2-canary.609e358 → 0.1.2-canary.b712653
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.1.2-canary.
|
|
3
|
+
"version": "0.1.2-canary.b712653",
|
|
4
4
|
"displayName": "CLI",
|
|
5
5
|
"description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"zod": "^4.4.3"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
67
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
68
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
66
|
+
"@astryxdesign/core": "0.1.2-canary.b712653",
|
|
67
|
+
"@astryxdesign/lab": "0.1.2-canary.b712653",
|
|
68
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.b712653",
|
|
69
69
|
"gpt-tokenizer": "^2.0.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
@@ -80,9 +80,9 @@
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
84
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
85
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
83
|
+
"@astryxdesign/core": "0.1.2-canary.b712653",
|
|
84
|
+
"@astryxdesign/lab": "0.1.2-canary.b712653",
|
|
85
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.b712653",
|
|
86
86
|
"gpt-tokenizer": "^2.0.0"
|
|
87
87
|
},
|
|
88
88
|
"scripts": {
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {Fragment, useState, useMemo, useEffect} from 'react';
|
|
6
|
+
import {AppShell} from '@astryxdesign/core/AppShell';
|
|
7
|
+
import {Layout, LayoutHeader, LayoutContent} from '@astryxdesign/core/Layout';
|
|
8
|
+
import {TopNav} from '@astryxdesign/core/TopNav';
|
|
9
|
+
import {DropdownMenu, DropdownMenuItem} from '@astryxdesign/core/DropdownMenu';
|
|
10
|
+
import {CommandPalette} from '@astryxdesign/core/CommandPalette';
|
|
11
|
+
import {createStaticSource} from '@astryxdesign/core/Typeahead';
|
|
12
|
+
import {Divider} from '@astryxdesign/core/Divider';
|
|
13
|
+
import {Kbd} from '@astryxdesign/core/Kbd';
|
|
14
|
+
import {SideNav} from '@astryxdesign/core/SideNav';
|
|
15
|
+
import {TreeList} from '@astryxdesign/core/TreeList';
|
|
16
|
+
import type {TreeListItemData} from '@astryxdesign/core/TreeList';
|
|
17
|
+
import {Icon} from '@astryxdesign/core/Icon';
|
|
18
|
+
import {Text} from '@astryxdesign/core/Text';
|
|
19
|
+
import {IconButton} from '@astryxdesign/core/IconButton';
|
|
20
|
+
import {Button} from '@astryxdesign/core/Button';
|
|
21
|
+
import {TextInput} from '@astryxdesign/core/TextInput';
|
|
22
|
+
import {Card} from '@astryxdesign/core/Card';
|
|
23
|
+
import {Stack, VStack, HStack} from '@astryxdesign/core/Stack';
|
|
24
|
+
import {
|
|
25
|
+
PlayIcon,
|
|
26
|
+
MagnifyingGlassIcon,
|
|
27
|
+
FolderIcon,
|
|
28
|
+
DocumentTextIcon,
|
|
29
|
+
} from '@heroicons/react/24/outline';
|
|
30
|
+
|
|
31
|
+
const noop = () => {};
|
|
32
|
+
|
|
33
|
+
const folder = (
|
|
34
|
+
id: string,
|
|
35
|
+
children: TreeListItemData[],
|
|
36
|
+
isExpanded = true,
|
|
37
|
+
): TreeListItemData => ({
|
|
38
|
+
id,
|
|
39
|
+
label: <Text maxLines={1}>{id}</Text>,
|
|
40
|
+
startContent: <Icon icon={FolderIcon} size="xsm" />,
|
|
41
|
+
isExpanded,
|
|
42
|
+
children,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const file = (id: string, isSelected = false): TreeListItemData => ({
|
|
46
|
+
id,
|
|
47
|
+
label: <Text maxLines={1}>{id}</Text>,
|
|
48
|
+
startContent: <Icon icon={DocumentTextIcon} size="xsm" />,
|
|
49
|
+
isSelected,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const FILE_TREE: TreeListItemData[] = [
|
|
53
|
+
folder('src', [
|
|
54
|
+
folder('components', [
|
|
55
|
+
file('AppShell.tsx', true),
|
|
56
|
+
file('TopNav.tsx'),
|
|
57
|
+
file('SideNav.tsx'),
|
|
58
|
+
]),
|
|
59
|
+
folder('hooks', [file('useTheme.ts'), file('useResizable.ts')]),
|
|
60
|
+
file('index.tsx'),
|
|
61
|
+
file('App.tsx'),
|
|
62
|
+
]),
|
|
63
|
+
folder('public', [file('favicon.ico'), file('robots.txt')], false),
|
|
64
|
+
file('package.json'),
|
|
65
|
+
file('tsconfig.json'),
|
|
66
|
+
file('README.md'),
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// Each menu is split into groups; groups are separated by a divider.
|
|
70
|
+
// `[label, shortcut]` — the shortcut renders as a single combined Kbd
|
|
71
|
+
// (e.g. ⌘N); an empty shortcut renders no Kbd.
|
|
72
|
+
type MenuEntry = [label: string, shortcut: string];
|
|
73
|
+
|
|
74
|
+
const MENU_WIDTH = 280;
|
|
75
|
+
|
|
76
|
+
const MENUS: {label: string; groups: MenuEntry[][]}[] = [
|
|
77
|
+
{
|
|
78
|
+
label: 'File',
|
|
79
|
+
groups: [
|
|
80
|
+
[
|
|
81
|
+
['New File', '⌘N'],
|
|
82
|
+
['New Window', '⇧⌘N'],
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
['Open...', '⌘O'],
|
|
86
|
+
['Save', '⌘S'],
|
|
87
|
+
['Save As...', '⇧⌘S'],
|
|
88
|
+
],
|
|
89
|
+
[['Close Editor', '⌘W']],
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: 'Edit',
|
|
94
|
+
groups: [
|
|
95
|
+
[
|
|
96
|
+
['Undo', '⌘Z'],
|
|
97
|
+
['Redo', '⇧⌘Z'],
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
['Cut', '⌘X'],
|
|
101
|
+
['Copy', '⌘C'],
|
|
102
|
+
['Paste', '⌘V'],
|
|
103
|
+
],
|
|
104
|
+
[['Find', '⌘F']],
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
label: 'View',
|
|
109
|
+
groups: [
|
|
110
|
+
[['Command Palette', '⇧⌘P']],
|
|
111
|
+
[
|
|
112
|
+
['Explorer', '⇧⌘E'],
|
|
113
|
+
['Search', '⇧⌘F'],
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
['Toggle Terminal', '⌃`'],
|
|
117
|
+
['Zen Mode', '⌘K'],
|
|
118
|
+
],
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
label: 'Window',
|
|
123
|
+
groups: [
|
|
124
|
+
[
|
|
125
|
+
['Minimize', '⌘M'],
|
|
126
|
+
['Zoom', ''],
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
['Next Tab', '⌃⇥'],
|
|
130
|
+
['Previous Tab', '⌃⇧⇥'],
|
|
131
|
+
],
|
|
132
|
+
[['Bring All to Front', '']],
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: 'Help',
|
|
137
|
+
groups: [
|
|
138
|
+
[
|
|
139
|
+
['Documentation', ''],
|
|
140
|
+
['Release Notes', ''],
|
|
141
|
+
['Report Issue', ''],
|
|
142
|
+
['About', ''],
|
|
143
|
+
],
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
const CODE_LINES = [
|
|
149
|
+
'38%',
|
|
150
|
+
'62%',
|
|
151
|
+
'54%',
|
|
152
|
+
'0%',
|
|
153
|
+
'46%',
|
|
154
|
+
'70%',
|
|
155
|
+
'58%',
|
|
156
|
+
'34%',
|
|
157
|
+
'0%',
|
|
158
|
+
'50%',
|
|
159
|
+
'66%',
|
|
160
|
+
'42%',
|
|
161
|
+
'60%',
|
|
162
|
+
'28%',
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
const EDITOR_TABS = ['AppShell.tsx', 'TopNav.tsx', 'theme.ts'];
|
|
166
|
+
|
|
167
|
+
const COMMANDS = [
|
|
168
|
+
{id: 'new-file', label: 'New File'},
|
|
169
|
+
{id: 'open-file', label: 'Open File…'},
|
|
170
|
+
{id: 'save-all', label: 'Save All'},
|
|
171
|
+
{id: 'find-in-files', label: 'Find in Files'},
|
|
172
|
+
{id: 'toggle-terminal', label: 'Toggle Terminal'},
|
|
173
|
+
{id: 'go-to-symbol', label: 'Go to Symbol…'},
|
|
174
|
+
{id: 'appshell', label: 'AppShell.tsx'},
|
|
175
|
+
{id: 'topnav', label: 'TopNav.tsx'},
|
|
176
|
+
{id: 'sidenav', label: 'SideNav.tsx'},
|
|
177
|
+
{id: 'use-theme', label: 'useTheme.ts'},
|
|
178
|
+
{id: 'theme', label: 'theme.ts'},
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
export default function ShellNav() {
|
|
182
|
+
const [isPaletteOpen, setIsPaletteOpen] = useState(false);
|
|
183
|
+
const searchSource = useMemo(() => createStaticSource(COMMANDS), []);
|
|
184
|
+
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
187
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
|
|
188
|
+
e.preventDefault();
|
|
189
|
+
setIsPaletteOpen(true);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
193
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
194
|
+
}, []);
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<>
|
|
198
|
+
<AppShell
|
|
199
|
+
contentPadding={0}
|
|
200
|
+
topNav={
|
|
201
|
+
<TopNav
|
|
202
|
+
label="Astryx Studio menu bar"
|
|
203
|
+
startContent={
|
|
204
|
+
<>
|
|
205
|
+
{MENUS.map(menu => (
|
|
206
|
+
<DropdownMenu
|
|
207
|
+
key={menu.label}
|
|
208
|
+
button={{label: menu.label, variant: 'ghost', size: 'sm'}}
|
|
209
|
+
hasChevron={false}
|
|
210
|
+
menuWidth={MENU_WIDTH}>
|
|
211
|
+
{menu.groups.map((group, gi) => (
|
|
212
|
+
<Fragment key={gi}>
|
|
213
|
+
{gi > 0 && <Divider />}
|
|
214
|
+
{group.map(([label, shortcut]) => (
|
|
215
|
+
<DropdownMenuItem
|
|
216
|
+
key={label}
|
|
217
|
+
label={label}
|
|
218
|
+
onClick={noop}
|
|
219
|
+
endContent={
|
|
220
|
+
shortcut ? <Kbd keys={shortcut} /> : undefined
|
|
221
|
+
}
|
|
222
|
+
/>
|
|
223
|
+
))}
|
|
224
|
+
</Fragment>
|
|
225
|
+
))}
|
|
226
|
+
</DropdownMenu>
|
|
227
|
+
))}
|
|
228
|
+
</>
|
|
229
|
+
}
|
|
230
|
+
endContent={
|
|
231
|
+
<>
|
|
232
|
+
<Stack onClick={() => setIsPaletteOpen(true)}>
|
|
233
|
+
<TextInput
|
|
234
|
+
label="Search files and commands"
|
|
235
|
+
isLabelHidden
|
|
236
|
+
size="sm"
|
|
237
|
+
width={240}
|
|
238
|
+
startIcon={MagnifyingGlassIcon}
|
|
239
|
+
placeholder="Search files and commands…"
|
|
240
|
+
value=""
|
|
241
|
+
onChange={() => {}}
|
|
242
|
+
/>
|
|
243
|
+
</Stack>
|
|
244
|
+
<IconButton
|
|
245
|
+
label="Run project"
|
|
246
|
+
tooltip="Run"
|
|
247
|
+
variant="ghost"
|
|
248
|
+
icon={<Icon icon={PlayIcon} size="sm" />}
|
|
249
|
+
/>
|
|
250
|
+
<Button label="Share" variant="secondary" />
|
|
251
|
+
</>
|
|
252
|
+
}
|
|
253
|
+
/>
|
|
254
|
+
}
|
|
255
|
+
sideNav={
|
|
256
|
+
<SideNav
|
|
257
|
+
resizable={{defaultWidth: 240, minWidth: 180, maxWidth: 400}}>
|
|
258
|
+
<TreeList items={FILE_TREE} density="compact" />
|
|
259
|
+
</SideNav>
|
|
260
|
+
}>
|
|
261
|
+
<Layout
|
|
262
|
+
height="fill"
|
|
263
|
+
header={
|
|
264
|
+
<LayoutHeader hasDivider padding={6}>
|
|
265
|
+
<HStack gap={2}>
|
|
266
|
+
{EDITOR_TABS.map(tab => (
|
|
267
|
+
<Card
|
|
268
|
+
key={tab}
|
|
269
|
+
variant="muted"
|
|
270
|
+
padding={0}
|
|
271
|
+
width={132}
|
|
272
|
+
height={36}
|
|
273
|
+
/>
|
|
274
|
+
))}
|
|
275
|
+
</HStack>
|
|
276
|
+
</LayoutHeader>
|
|
277
|
+
}
|
|
278
|
+
content={
|
|
279
|
+
<LayoutContent padding={6}>
|
|
280
|
+
<VStack gap={2}>
|
|
281
|
+
{CODE_LINES.map((width, i) =>
|
|
282
|
+
width === '0%' ? (
|
|
283
|
+
<Card
|
|
284
|
+
key={i}
|
|
285
|
+
variant="muted"
|
|
286
|
+
padding={0}
|
|
287
|
+
width={1}
|
|
288
|
+
height={14}
|
|
289
|
+
/>
|
|
290
|
+
) : (
|
|
291
|
+
<HStack key={i} gap={3} vAlign="center">
|
|
292
|
+
<Card
|
|
293
|
+
variant="muted"
|
|
294
|
+
padding={0}
|
|
295
|
+
width={20}
|
|
296
|
+
height={14}
|
|
297
|
+
/>
|
|
298
|
+
<Card
|
|
299
|
+
variant="muted"
|
|
300
|
+
padding={0}
|
|
301
|
+
width={width}
|
|
302
|
+
height={14}
|
|
303
|
+
/>
|
|
304
|
+
</HStack>
|
|
305
|
+
),
|
|
306
|
+
)}
|
|
307
|
+
</VStack>
|
|
308
|
+
</LayoutContent>
|
|
309
|
+
}
|
|
310
|
+
/>
|
|
311
|
+
</AppShell>
|
|
312
|
+
<CommandPalette
|
|
313
|
+
isOpen={isPaletteOpen}
|
|
314
|
+
onOpenChange={setIsPaletteOpen}
|
|
315
|
+
searchSource={searchSource}
|
|
316
|
+
label="Search files and commands"
|
|
317
|
+
onValueChange={() => setIsPaletteOpen(false)}
|
|
318
|
+
/>
|
|
319
|
+
</>
|
|
320
|
+
);
|
|
321
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../../../../core/src/docs-types').TemplateDoc} */
|
|
4
|
+
export const doc = {
|
|
5
|
+
type: 'page',
|
|
6
|
+
name: 'Shell Nav',
|
|
7
|
+
displayName: 'Shell Nav',
|
|
8
|
+
description:
|
|
9
|
+
'A top + side nav app shell with a File/Edit/View/Window/Help menu bar plus command-palette search, a resizable file-tree SideNav, and a static grey-card tabbed code editor.',
|
|
10
|
+
isReady: true,
|
|
11
|
+
category: 'Shell - Top Nav + Left Sidebar',
|
|
12
|
+
};
|