@astryxdesign/cli 0.1.0-canary.f94dd07 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/getting-started.doc.mjs +11 -11
- package/docs/styling.doc.mjs +2 -1
- package/package.json +7 -7
- package/src/api/doctor.mjs +3 -3
- package/src/commands/agent-docs.mjs +10 -27
- package/src/commands/agent-docs.test.mjs +21 -21
- package/src/commands/init.mjs +1 -1
- package/src/utils/package-manager.mjs +1 -1
- package/templates/pages/documentation/page.tsx +52 -39
- package/templates/pages/documentation-design/page.tsx +55 -80
- package/templates/pages/documentation-technical/page.tsx +59 -101
- package/templates/pages/ide/page.tsx +236 -167
|
@@ -88,7 +88,7 @@ import {VStack} from '@astryxdesign/core/Layout';
|
|
|
88
88
|
export default function Page() {
|
|
89
89
|
return (
|
|
90
90
|
<VStack gap={2}>
|
|
91
|
-
<Button label="Hello
|
|
91
|
+
<Button label="Hello XDS" onClick={() => alert('Hi!')} />
|
|
92
92
|
</VStack>
|
|
93
93
|
);
|
|
94
94
|
}`,
|
|
@@ -96,11 +96,11 @@ export default function Page() {
|
|
|
96
96
|
],
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
|
-
title: 'Customize with
|
|
99
|
+
title: 'Customize with xstyle',
|
|
100
100
|
content: [
|
|
101
101
|
{
|
|
102
102
|
type: 'prose',
|
|
103
|
-
text: '
|
|
103
|
+
text: 'Every component accepts an `xstyle` prop for StyleX style overrides created via `stylex.create()`.',
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
type: 'code',
|
|
@@ -127,19 +127,19 @@ const overrides = stylex.create({
|
|
|
127
127
|
type: 'table',
|
|
128
128
|
headers: ['Example', 'Stack', 'Path'],
|
|
129
129
|
rows: [
|
|
130
|
-
['Next.js', 'Next.js + theme CSS', '
|
|
131
|
-
['Next.js + StyleX', 'Next.js + StyleX for custom styles', '
|
|
132
|
-
['Next.js + Tailwind', 'Next.js + Tailwind bridge', '
|
|
133
|
-
['Next.js Source', 'Next.js importing from source', '
|
|
134
|
-
['Vite', 'Vite', '
|
|
130
|
+
['Next.js', 'Next.js + theme CSS', 'apps/example-nextjs'],
|
|
131
|
+
['Next.js + StyleX', 'Next.js + StyleX for custom styles', 'apps/example-nextjs-stylex'],
|
|
132
|
+
['Next.js + Tailwind', 'Next.js + Tailwind bridge', 'apps/example-nextjs-tailwind'],
|
|
133
|
+
['Next.js Source', 'Next.js importing from source', 'apps/example-nextjs-source'],
|
|
134
|
+
['Vite', 'Vite', 'apps/example-vite'],
|
|
135
135
|
],
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
type: 'code',
|
|
139
139
|
lang: 'bash',
|
|
140
140
|
label: 'Clone and run an example',
|
|
141
|
-
code: `git clone https://github.com/
|
|
142
|
-
cd
|
|
141
|
+
code: `git clone https://github.com/facebookexperimental/xds.git
|
|
142
|
+
cd xds/apps/example-nextjs
|
|
143
143
|
pnpm install
|
|
144
144
|
pnpm dev`,
|
|
145
145
|
},
|
|
@@ -157,7 +157,7 @@ pnpm dev`,
|
|
|
157
157
|
lang: 'json',
|
|
158
158
|
label: 'package.json',
|
|
159
159
|
code: `"scripts": {
|
|
160
|
-
"
|
|
160
|
+
"xds": "node node_modules/@astryxdesign/cli/bin/astryx.mjs"
|
|
161
161
|
}`,
|
|
162
162
|
},
|
|
163
163
|
{
|
package/docs/styling.doc.mjs
CHANGED
|
@@ -22,8 +22,9 @@ export const docs = {
|
|
|
22
22
|
type: 'table',
|
|
23
23
|
headers: ['Approach', 'Use for', 'Example'],
|
|
24
24
|
rows: [
|
|
25
|
-
['
|
|
25
|
+
['xstyle prop', 'Overriding a specific component', 'xstyle={styles.override}'],
|
|
26
26
|
['Tailwind utilities', 'Layout, wrappers, and utility styling', 'className="flex gap-3 p-4"'],
|
|
27
|
+
['stylex.create', 'Reusable styles, pseudo-classes, typed tokens', 'stylex.create({ card: { ... } })'],
|
|
27
28
|
['className', 'Integrating with external CSS or Tailwind on components', 'className="my-card shadow-lg"'],
|
|
28
29
|
['Styling-library token aliases', 'Keeping Panda, Chakra, MUI, Emotion, styled-components, UnoCSS, CSS Modules, or Sass in sync with the system', "colors.surface = 'var(--color-background-surface)'"],
|
|
29
30
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
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",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"jscodeshift": "^17.3.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@astryxdesign/core": "
|
|
58
|
-
"@astryxdesign/lab": "
|
|
59
|
-
"@astryxdesign/theme-neutral": "
|
|
57
|
+
"@astryxdesign/core": "*",
|
|
58
|
+
"@astryxdesign/lab": "*",
|
|
59
|
+
"@astryxdesign/theme-neutral": "*"
|
|
60
60
|
},
|
|
61
61
|
"peerDependenciesMeta": {
|
|
62
62
|
"@astryxdesign/core": {
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@astryxdesign/core": "
|
|
74
|
-
"@astryxdesign/lab": "
|
|
75
|
-
"@astryxdesign/theme-neutral": "
|
|
73
|
+
"@astryxdesign/core": "*",
|
|
74
|
+
"@astryxdesign/lab": "*",
|
|
75
|
+
"@astryxdesign/theme-neutral": "*"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"astryx": "node bin/astryx.mjs",
|
package/src/api/doctor.mjs
CHANGED
|
@@ -355,8 +355,8 @@ export function checkAgentDocs(ctx) {
|
|
|
355
355
|
try {
|
|
356
356
|
const content = fs.readFileSync(path.join(ctx.cwd, rel), 'utf-8');
|
|
357
357
|
return (
|
|
358
|
-
|
|
359
|
-
|
|
358
|
+
content.includes('<!-- XDS:START -->') &&
|
|
359
|
+
content.includes('<!-- XDS:END -->')
|
|
360
360
|
);
|
|
361
361
|
} catch {
|
|
362
362
|
return false;
|
|
@@ -368,7 +368,7 @@ export function checkAgentDocs(ctx) {
|
|
|
368
368
|
id: 'agent-docs',
|
|
369
369
|
label: 'AI agent docs',
|
|
370
370
|
status: 'warn',
|
|
371
|
-
message: `Agent docs present (${present.join(', ')}) but no
|
|
371
|
+
message: `Agent docs present (${present.join(', ')}) but no XDS section markers found.`,
|
|
372
372
|
fix: 'Add the XDS section to your agent docs with `astryx init --features agents`.',
|
|
373
373
|
};
|
|
374
374
|
}
|
|
@@ -31,11 +31,8 @@ const AGENTS_MD = 'AGENTS.md';
|
|
|
31
31
|
const CLAUDE_MD = 'CLAUDE.md';
|
|
32
32
|
const CLAUDE_DIR_MD = path.join('.claude', 'CLAUDE.md');
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
// Legacy markers — read during migration so the script finds existing XDS blocks
|
|
37
|
-
const LEGACY_MARKER_START = '<!-- XDS:START -->';
|
|
38
|
-
const LEGACY_MARKER_END = '<!-- XDS:END -->';
|
|
34
|
+
const XDS_MARKER_START = '<!-- XDS:START -->';
|
|
35
|
+
const XDS_MARKER_END = '<!-- XDS:END -->';
|
|
39
36
|
|
|
40
37
|
/**
|
|
41
38
|
* Agent tool presets — maps tool names to their file search paths.
|
|
@@ -102,7 +99,7 @@ export function resolveAgentPaths(targetDir, agent) {
|
|
|
102
99
|
*/
|
|
103
100
|
export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPrefix()} = {}) {
|
|
104
101
|
const run = `${runPrefix} astryx`;
|
|
105
|
-
const lines = [
|
|
102
|
+
const lines = [XDS_MARKER_START];
|
|
106
103
|
|
|
107
104
|
// Component count from live discovery
|
|
108
105
|
let componentCount = '90+';
|
|
@@ -180,7 +177,7 @@ export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPre
|
|
|
180
177
|
lines.push(`${run} swizzle <Name> eject source (--gap to report why)`);
|
|
181
178
|
lines.push(`${run} upgrade --apply codemods after version bump`);
|
|
182
179
|
lines.push(`after @astryxdesign/core bump, always run ${run} upgrade --apply`);
|
|
183
|
-
lines.push(
|
|
180
|
+
lines.push(XDS_MARKER_END);
|
|
184
181
|
|
|
185
182
|
return lines.join('\n');
|
|
186
183
|
}
|
|
@@ -221,21 +218,14 @@ export function injectXdsBlock(filePath, compressedIndex, {createIfMissing = fal
|
|
|
221
218
|
if (fs.existsSync(filePath)) {
|
|
222
219
|
content = fs.readFileSync(filePath, 'utf-8');
|
|
223
220
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
let endIdx = content.indexOf(MARKER_END);
|
|
227
|
-
let markerEndLength = MARKER_END.length;
|
|
228
|
-
if (startIdx === -1) {
|
|
229
|
-
startIdx = content.indexOf(LEGACY_MARKER_START);
|
|
230
|
-
endIdx = content.indexOf(LEGACY_MARKER_END);
|
|
231
|
-
markerEndLength = LEGACY_MARKER_END.length;
|
|
232
|
-
}
|
|
221
|
+
const startIdx = content.indexOf(XDS_MARKER_START);
|
|
222
|
+
const endIdx = content.indexOf(XDS_MARKER_END);
|
|
233
223
|
|
|
234
224
|
if (startIdx !== -1 && endIdx !== -1) {
|
|
235
225
|
content =
|
|
236
226
|
content.slice(0, startIdx) +
|
|
237
227
|
compressedIndex +
|
|
238
|
-
content.slice(endIdx +
|
|
228
|
+
content.slice(endIdx + XDS_MARKER_END.length);
|
|
239
229
|
} else if (onlyReplace) {
|
|
240
230
|
// File exists but has no Astryx markers — skip it
|
|
241
231
|
return false;
|
|
@@ -287,20 +277,13 @@ export function removeXdsBlock(filePath, {deleteIfEmpty = false} = {}) {
|
|
|
287
277
|
if (!fs.existsSync(filePath)) return false;
|
|
288
278
|
|
|
289
279
|
let content = fs.readFileSync(filePath, 'utf-8');
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
let endIdx = content.indexOf(MARKER_END);
|
|
293
|
-
let markerEndLen = MARKER_END.length;
|
|
294
|
-
if (startIdx === -1) {
|
|
295
|
-
startIdx = content.indexOf(LEGACY_MARKER_START);
|
|
296
|
-
endIdx = content.indexOf(LEGACY_MARKER_END);
|
|
297
|
-
markerEndLen = LEGACY_MARKER_END.length;
|
|
298
|
-
}
|
|
280
|
+
const startIdx = content.indexOf(XDS_MARKER_START);
|
|
281
|
+
const endIdx = content.indexOf(XDS_MARKER_END);
|
|
299
282
|
|
|
300
283
|
if (startIdx === -1 || endIdx === -1) return false;
|
|
301
284
|
|
|
302
285
|
const before = content.slice(0, startIdx).trimEnd();
|
|
303
|
-
const after = content.slice(endIdx +
|
|
286
|
+
const after = content.slice(endIdx + XDS_MARKER_END.length).trimStart();
|
|
304
287
|
content = before + (after ? '\n\n' + after : '') + '\n';
|
|
305
288
|
|
|
306
289
|
if (deleteIfEmpty) {
|
|
@@ -32,8 +32,8 @@ describe('generateCompressedIndex', () => {
|
|
|
32
32
|
it('includes the version number', () => {
|
|
33
33
|
const result = generateCompressedIndex('1.2.3');
|
|
34
34
|
expect(result).toContain('Astryx v1.2.3');
|
|
35
|
-
expect(result).toContain('<!--
|
|
36
|
-
expect(result).toContain('<!--
|
|
35
|
+
expect(result).toContain('<!-- XDS:START -->');
|
|
36
|
+
expect(result).toContain('<!-- XDS:END -->');
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('includes theme nudge rule', () => {
|
|
@@ -82,19 +82,19 @@ describe('injectXdsBlock', () => {
|
|
|
82
82
|
const filePath = path.join(tmpDir, 'test.md');
|
|
83
83
|
fs.writeFileSync(filePath, '# Existing content\n');
|
|
84
84
|
|
|
85
|
-
const result = injectXdsBlock(filePath, '<!--
|
|
85
|
+
const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->');
|
|
86
86
|
|
|
87
87
|
expect(result).toBe(true);
|
|
88
88
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
89
89
|
expect(content).toContain('# Existing content');
|
|
90
|
-
expect(content).toContain('<!--
|
|
90
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
it('replaces existing markers', () => {
|
|
94
94
|
const filePath = path.join(tmpDir, 'test.md');
|
|
95
95
|
fs.writeFileSync(filePath, 'before\n<!-- XDS:START -->\nold\n<!-- XDS:END -->\nafter\n');
|
|
96
96
|
|
|
97
|
-
injectXdsBlock(filePath, '<!--
|
|
97
|
+
injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->');
|
|
98
98
|
|
|
99
99
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
100
100
|
expect(content).toContain('new');
|
|
@@ -106,7 +106,7 @@ describe('injectXdsBlock', () => {
|
|
|
106
106
|
it('returns false and does not create file when createIfMissing is false', () => {
|
|
107
107
|
const filePath = path.join(tmpDir, 'nonexistent.md');
|
|
108
108
|
|
|
109
|
-
const result = injectXdsBlock(filePath, '<!--
|
|
109
|
+
const result = injectXdsBlock(filePath, '<!-- XDS:START -->\ncontent\n<!-- XDS:END -->');
|
|
110
110
|
|
|
111
111
|
expect(result).toBe(false);
|
|
112
112
|
expect(fs.existsSync(filePath)).toBe(false);
|
|
@@ -116,11 +116,11 @@ describe('injectXdsBlock', () => {
|
|
|
116
116
|
const filePath = path.join(tmpDir, 'test.md');
|
|
117
117
|
fs.writeFileSync(filePath, '# Existing content\n\nNo XDS markers here.\n');
|
|
118
118
|
|
|
119
|
-
const result = injectXdsBlock(filePath, '<!--
|
|
119
|
+
const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->', {onlyReplace: true});
|
|
120
120
|
|
|
121
121
|
expect(result).toBe(false);
|
|
122
122
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
123
|
-
expect(content).not.toContain('<!--
|
|
123
|
+
expect(content).not.toContain('<!-- XDS:START -->');
|
|
124
124
|
expect(content).toBe('# Existing content\n\nNo XDS markers here.\n');
|
|
125
125
|
});
|
|
126
126
|
|
|
@@ -128,7 +128,7 @@ describe('injectXdsBlock', () => {
|
|
|
128
128
|
const filePath = path.join(tmpDir, 'test.md');
|
|
129
129
|
fs.writeFileSync(filePath, 'before\n<!-- XDS:START -->\nold\n<!-- XDS:END -->\nafter\n');
|
|
130
130
|
|
|
131
|
-
const result = injectXdsBlock(filePath, '<!--
|
|
131
|
+
const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->', {onlyReplace: true});
|
|
132
132
|
|
|
133
133
|
expect(result).toBe(true);
|
|
134
134
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -139,7 +139,7 @@ describe('injectXdsBlock', () => {
|
|
|
139
139
|
it('creates file when createIfMissing is true', () => {
|
|
140
140
|
const filePath = path.join(tmpDir, 'new.md');
|
|
141
141
|
|
|
142
|
-
const result = injectXdsBlock(filePath, '<!--
|
|
142
|
+
const result = injectXdsBlock(filePath, '<!-- XDS:START -->\ncontent\n<!-- XDS:END -->', {
|
|
143
143
|
createIfMissing: true,
|
|
144
144
|
header: '# Header',
|
|
145
145
|
});
|
|
@@ -147,7 +147,7 @@ describe('injectXdsBlock', () => {
|
|
|
147
147
|
expect(result).toBe(true);
|
|
148
148
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
149
149
|
expect(content).toContain('# Header');
|
|
150
|
-
expect(content).toContain('<!--
|
|
150
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
151
151
|
});
|
|
152
152
|
});
|
|
153
153
|
|
|
@@ -157,9 +157,9 @@ describe('injectAgentsMd', () => {
|
|
|
157
157
|
|
|
158
158
|
const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
159
159
|
expect(content).toContain('# AGENTS.md');
|
|
160
|
-
expect(content).toContain('<!--
|
|
160
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
161
161
|
expect(content).toContain('Astryx v1.0.0');
|
|
162
|
-
expect(content).toContain('<!--
|
|
162
|
+
expect(content).toContain('<!-- XDS:END -->');
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
it('updates existing AGENTS.md by replacing XDS markers', () => {
|
|
@@ -195,7 +195,7 @@ Existing agent docs.
|
|
|
195
195
|
|
|
196
196
|
const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
197
197
|
expect(content).toContain('Existing agent docs.');
|
|
198
|
-
expect(content).toContain('<!--
|
|
198
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
199
199
|
expect(content).toContain('Astryx v1.0.0');
|
|
200
200
|
});
|
|
201
201
|
});
|
|
@@ -210,7 +210,7 @@ describe('injectClaudeMd', () => {
|
|
|
210
210
|
const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
|
|
211
211
|
expect(content).toContain('# Claude Config');
|
|
212
212
|
expect(content).toContain('Existing rules.');
|
|
213
|
-
expect(content).toContain('<!--
|
|
213
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
214
214
|
expect(content).toContain('Astryx v1.0.0');
|
|
215
215
|
});
|
|
216
216
|
|
|
@@ -322,7 +322,7 @@ describe('installAgentDocs', () => {
|
|
|
322
322
|
expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(true);
|
|
323
323
|
expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
|
|
324
324
|
const content = fs.readFileSync(path.join(tmpDir, '.claude', 'CLAUDE.md'), 'utf-8');
|
|
325
|
-
expect(content).toContain('<!--
|
|
325
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
326
326
|
});
|
|
327
327
|
|
|
328
328
|
it('injects into CLAUDE.md at root when it exists', () => {
|
|
@@ -334,7 +334,7 @@ describe('installAgentDocs', () => {
|
|
|
334
334
|
expect(written).toEqual(['CLAUDE.md']);
|
|
335
335
|
expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
|
|
336
336
|
const claudeContent = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
|
|
337
|
-
expect(claudeContent).toContain('<!--
|
|
337
|
+
expect(claudeContent).toContain('<!-- XDS:START -->');
|
|
338
338
|
expect(claudeContent).toContain('Project rules.');
|
|
339
339
|
});
|
|
340
340
|
|
|
@@ -349,8 +349,8 @@ describe('installAgentDocs', () => {
|
|
|
349
349
|
expect(written).toContain('CLAUDE.md');
|
|
350
350
|
const agentsContent = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
351
351
|
const claudeContent = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
|
|
352
|
-
expect(agentsContent).toContain('<!--
|
|
353
|
-
expect(claudeContent).toContain('<!--
|
|
352
|
+
expect(agentsContent).toContain('<!-- XDS:START -->');
|
|
353
|
+
expect(claudeContent).toContain('<!-- XDS:START -->');
|
|
354
354
|
});
|
|
355
355
|
|
|
356
356
|
it('updates existing .claude/CLAUDE.md', () => {
|
|
@@ -363,7 +363,7 @@ describe('installAgentDocs', () => {
|
|
|
363
363
|
expect(written).toEqual(['.claude/CLAUDE.md']);
|
|
364
364
|
const content = fs.readFileSync(path.join(tmpDir, '.claude', 'CLAUDE.md'), 'utf-8');
|
|
365
365
|
expect(content).toContain('Existing content.');
|
|
366
|
-
expect(content).toContain('<!--
|
|
366
|
+
expect(content).toContain('<!-- XDS:START -->');
|
|
367
367
|
});
|
|
368
368
|
|
|
369
369
|
it('respects --agent claude preset: finds existing CLAUDE.md', () => {
|
|
@@ -410,7 +410,7 @@ describe('installAgentDocs', () => {
|
|
|
410
410
|
|
|
411
411
|
expect(written).toEqual([]);
|
|
412
412
|
const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
|
|
413
|
-
expect(content).not.toContain('<!--
|
|
413
|
+
expect(content).not.toContain('<!-- XDS:START -->');
|
|
414
414
|
expect(content).toBe('# Claude\n\nProject rules only.\n');
|
|
415
415
|
});
|
|
416
416
|
|
package/src/commands/init.mjs
CHANGED
|
@@ -248,7 +248,7 @@ export function registerInit(program) {
|
|
|
248
248
|
humanLog(' 2. Optionally add a theme:');
|
|
249
249
|
humanLog(" import { neutralTheme } from '@astryxdesign/theme-neutral'");
|
|
250
250
|
humanLog(' <Theme theme={neutralTheme}>...</Theme>');
|
|
251
|
-
humanLog(` 3. ${run}
|
|
251
|
+
humanLog(` 3. ${run} xds --help for all commands`);
|
|
252
252
|
humanLog('');
|
|
253
253
|
});
|
|
254
254
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @file Detect the project's package manager from lockfiles.
|
|
5
5
|
*
|
|
6
6
|
* Returns the correct command prefix for running package binaries
|
|
7
|
-
* (e.g. 'npx
|
|
7
|
+
* (e.g. 'npx xds', 'yarn xds', 'pnpm exec xds').
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import * as fs from 'node:fs';
|
|
@@ -3,23 +3,24 @@
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
5
|
import * as stylex from '@stylexjs/stylex';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
SideNav,
|
|
8
|
+
SideNavHeading,
|
|
9
|
+
SideNavItem,
|
|
10
|
+
SideNavSection,
|
|
11
|
+
} from '@astryxdesign/core/SideNav';
|
|
12
|
+
import {Text} from '@astryxdesign/core/Text';
|
|
7
13
|
import {Button} from '@astryxdesign/core/Button';
|
|
8
14
|
import {Card} from '@astryxdesign/core/Card';
|
|
9
|
-
import {ClickableCard} from '@astryxdesign/core/ClickableCard';
|
|
10
15
|
import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
|
|
11
|
-
import {Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
16
|
+
import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
|
|
12
17
|
import {Grid} from '@astryxdesign/core/Grid';
|
|
13
18
|
import {radiusVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
14
19
|
|
|
15
20
|
const styles = stylex.create({
|
|
16
21
|
previewCard: {
|
|
17
|
-
borderRadius: radiusVars['--radius-
|
|
18
|
-
|
|
19
|
-
// Negative margin offsets each card's 8px padding so the grid content stays
|
|
20
|
-
// visually aligned while giving every card a padded hover/click target.
|
|
21
|
-
cardGrid: {
|
|
22
|
-
margin: -8,
|
|
22
|
+
borderRadius: radiusVars['--radius-container'],
|
|
23
|
+
cursor: 'pointer',
|
|
23
24
|
},
|
|
24
25
|
});
|
|
25
26
|
|
|
@@ -212,12 +213,30 @@ const COMPONENT_CATEGORIES = [
|
|
|
212
213
|
export default function DocumentationOverviewPage() {
|
|
213
214
|
return (
|
|
214
215
|
<Layout
|
|
215
|
-
height="
|
|
216
|
+
height="fill"
|
|
216
217
|
contentWidth={1200}
|
|
218
|
+
start={
|
|
219
|
+
<LayoutPanel hasDivider padding={0}>
|
|
220
|
+
<SideNav header={<SideNavHeading heading="Product Name" />}>
|
|
221
|
+
<SideNavSection title="Navigation" isHeaderHidden>
|
|
222
|
+
<SideNavItem label="Home" isSelected />
|
|
223
|
+
<SideNavItem label="Getting started" />
|
|
224
|
+
</SideNavSection>
|
|
225
|
+
|
|
226
|
+
{COMPONENT_CATEGORIES.map(category => (
|
|
227
|
+
<SideNavSection key={category.label} title={category.label}>
|
|
228
|
+
{category.items.map(item => (
|
|
229
|
+
<SideNavItem key={item.key} label={item.name} />
|
|
230
|
+
))}
|
|
231
|
+
</SideNavSection>
|
|
232
|
+
))}
|
|
233
|
+
</SideNav>
|
|
234
|
+
</LayoutPanel>
|
|
235
|
+
}
|
|
217
236
|
content={
|
|
218
237
|
<LayoutContent padding={8}>
|
|
219
238
|
<VStack gap={10}>
|
|
220
|
-
<Card variant="
|
|
239
|
+
<Card variant="cyan" padding={10}>
|
|
221
240
|
<HStack gap={8} vAlign="center">
|
|
222
241
|
<StackItem size="fill">
|
|
223
242
|
<VStack gap={4}>
|
|
@@ -227,7 +246,11 @@ export default function DocumentationOverviewPage() {
|
|
|
227
246
|
beautiful, accessible products.
|
|
228
247
|
</Text>
|
|
229
248
|
<HStack>
|
|
230
|
-
<Button
|
|
249
|
+
<Button
|
|
250
|
+
label="Get started"
|
|
251
|
+
variant="primary"
|
|
252
|
+
size="lg"
|
|
253
|
+
/>
|
|
231
254
|
</HStack>
|
|
232
255
|
</VStack>
|
|
233
256
|
</StackItem>
|
|
@@ -237,35 +260,25 @@ export default function DocumentationOverviewPage() {
|
|
|
237
260
|
|
|
238
261
|
{COMPONENT_CATEGORIES.map(category => (
|
|
239
262
|
<VStack key={category.label} gap={4}>
|
|
240
|
-
<
|
|
241
|
-
<Grid
|
|
242
|
-
columns={{minWidth: 260}}
|
|
243
|
-
gap={2}
|
|
244
|
-
xstyle={styles.cardGrid}>
|
|
263
|
+
<Text type="display-2">{category.label}</Text>
|
|
264
|
+
<Grid columns={{minWidth: 260}} gap={8}>
|
|
245
265
|
{category.items.map(item => (
|
|
246
|
-
<
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
<Text type="body" weight="bold">
|
|
261
|
-
{item.name}
|
|
262
|
-
</Text>
|
|
263
|
-
<Text type="body" color="secondary" maxLines={3}>
|
|
264
|
-
{item.desc}
|
|
265
|
-
</Text>
|
|
266
|
-
</VStack>
|
|
266
|
+
<VStack key={item.key} gap={3}>
|
|
267
|
+
<Card
|
|
268
|
+
variant="muted"
|
|
269
|
+
padding={0}
|
|
270
|
+
minHeight={160}
|
|
271
|
+
xstyle={styles.previewCard}
|
|
272
|
+
/>
|
|
273
|
+
<VStack gap={0.5}>
|
|
274
|
+
<Text type="body" weight="bold">
|
|
275
|
+
{item.name}
|
|
276
|
+
</Text>
|
|
277
|
+
<Text type="body" color="secondary">
|
|
278
|
+
{item.desc}
|
|
279
|
+
</Text>
|
|
267
280
|
</VStack>
|
|
268
|
-
</
|
|
281
|
+
</VStack>
|
|
269
282
|
))}
|
|
270
283
|
</Grid>
|
|
271
284
|
</VStack>
|