@astryxdesign/cli 0.1.2-canary.d9633cc → 0.1.2-canary.deb5aa0
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/principles.doc.dense.mjs +2 -2
- package/docs/principles.doc.mjs +0 -4
- package/docs/principles.doc.zh.mjs +2 -2
- package/package.json +7 -7
- package/src/api/index.mjs +0 -1
- package/src/commands/agent-docs.mjs +0 -3
- package/src/commands/build-theme.mjs +0 -117
- package/src/index.mjs +0 -1
- package/src/lib/error-codes.mjs +0 -8
- package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +5 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +4 -1
- package/templates/blocks/components/Lightbox/LightboxShowcase.tsx +3 -4
- package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +5 -0
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.doc.mjs +14 -0
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.tsx +64 -0
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.doc.mjs +14 -0
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.tsx +60 -0
- package/docs/layout.doc.dense.mjs +0 -90
- package/docs/layout.doc.mjs +0 -160
- package/src/api/blog.mjs +0 -192
- package/src/api/blog.test.mjs +0 -144
- package/src/commands/blog.mjs +0 -60
- package/src/commands/build-theme.watch.test.mjs +0 -157
- package/src/lib/site.mjs +0 -20
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.doc.mjs +0 -14
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +0 -28
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.doc.mjs +0 -14
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.tsx +0 -34
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.doc.mjs +0 -14
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.tsx +0 -21
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.tsx +0 -15
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.doc.mjs +0 -14
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.tsx +0 -16
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.doc.mjs +0 -19
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.tsx +0 -34
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.tsx +0 -30
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.doc.mjs +0 -14
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.tsx +0 -31
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.doc.mjs +0 -14
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.tsx +0 -26
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.doc.mjs +0 -14
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.tsx +0 -32
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.doc.mjs +0 -18
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.tsx +0 -32
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.tsx +0 -27
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.doc.mjs +0 -14
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.tsx +0 -32
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.doc.mjs +0 -14
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.tsx +0 -30
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.tsx +0 -27
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.doc.mjs +0 -14
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.tsx +0 -20
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.doc.mjs +0 -14
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.tsx +0 -23
- package/templates/blocks/components/FileInput/FileInputBasic.doc.mjs +0 -14
- package/templates/blocks/components/FileInput/FileInputBasic.tsx +0 -22
- package/templates/blocks/components/GridSpan/GridSpanColumns.doc.mjs +0 -14
- package/templates/blocks/components/GridSpan/GridSpanColumns.tsx +0 -38
- package/templates/blocks/components/HStack/HStackBasic.doc.mjs +0 -14
- package/templates/blocks/components/HStack/HStackBasic.tsx +0 -16
- package/templates/blocks/components/InputGroup/InputGroupBasic.doc.mjs +0 -14
- package/templates/blocks/components/InputGroup/InputGroupBasic.tsx +0 -27
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.doc.mjs +0 -23
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.tsx +0 -40
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.doc.mjs +0 -22
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.tsx +0 -41
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.doc.mjs +0 -23
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.tsx +0 -40
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.doc.mjs +0 -22
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.tsx +0 -37
- package/templates/blocks/components/Lightbox/LightboxGallery.doc.mjs +0 -14
- package/templates/blocks/components/Lightbox/LightboxGallery.tsx +0 -53
- package/templates/blocks/components/Lightbox/LightboxVideo.doc.mjs +0 -14
- package/templates/blocks/components/Lightbox/LightboxVideo.tsx +0 -27
- package/templates/blocks/components/Lightbox/LightboxZoom.doc.mjs +0 -14
- package/templates/blocks/components/Lightbox/LightboxZoom.tsx +0 -33
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.tsx +0 -19
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.doc.mjs +0 -23
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.tsx +0 -42
- package/templates/blocks/components/NavIcon/NavIconBasic.doc.mjs +0 -14
- package/templates/blocks/components/NavIcon/NavIconBasic.tsx +0 -16
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.tsx +0 -30
- package/templates/blocks/components/Resizable/ResizableSidebar.doc.mjs +0 -25
- package/templates/blocks/components/Resizable/ResizableSidebar.tsx +0 -67
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.tsx +0 -21
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.doc.mjs +0 -14
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.tsx +0 -39
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.doc.mjs +0 -14
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.tsx +0 -55
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.doc.mjs +0 -14
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.tsx +0 -38
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.tsx +0 -49
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.doc.mjs +0 -14
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.tsx +0 -71
- package/templates/blocks/components/StackItem/StackItemFill.doc.mjs +0 -14
- package/templates/blocks/components/StackItem/StackItemFill.tsx +0 -28
- package/templates/blocks/components/TabMenu/TabMenuBasic.doc.mjs +0 -14
- package/templates/blocks/components/TabMenu/TabMenuBasic.tsx +0 -23
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.doc.mjs +0 -14
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.tsx +0 -47
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.doc.mjs +0 -14
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.tsx +0 -22
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.tsx +0 -21
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.doc.mjs +0 -20
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.tsx +0 -46
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.doc.mjs +0 -14
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.tsx +0 -16
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.tsx +0 -26
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.doc.mjs +0 -14
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.tsx +0 -43
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.doc.mjs +0 -14
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.tsx +0 -43
- package/templates/blocks/components/VStack/VStackBasic.doc.mjs +0 -14
- package/templates/blocks/components/VStack/VStackBasic.tsx +0 -20
- package/templates/pages/kanban-board/page.tsx +0 -729
- package/templates/pages/kanban-board/template.doc.mjs +0 -12
|
@@ -6,9 +6,9 @@ export const docsDense = {
|
|
|
6
6
|
description: 'core design principles + rules for the design system',
|
|
7
7
|
sections: [
|
|
8
8
|
{ title: 'Philosophy', content: [{ type: 'list', items: ['components over primitives', 'semantic tokens over hardcoded values', 'theme-agnostic code', 'open internals'] }] },
|
|
9
|
-
{ title: 'Rules', content: [{ type: 'list', items: ['use components', '
|
|
9
|
+
{ title: 'Rules', content: [{ type: 'list', items: ['use components', 'StyleX or Tailwind for styling', 'semantic tokens only', 'CSS vars for colors', 'controlled form inputs', 'useLinkComponent() for navigation'] }] },
|
|
10
10
|
{ title: 'Styling', content: [{ type: 'prose', text: 'xstyle prop for component overrides. StyleX or Tailwind for layout. See astryx docs styling.' }] },
|
|
11
|
-
{ title: 'Anti-Patterns', content: [{ type: 'list', items: ['no inline styles on raw elements', 'no hardcoded colors — use tokens or Tailwind semantic classes', 'no hardcoded spacing', 'no hardcoded <a> — use useLinkComponent()', '
|
|
11
|
+
{ title: 'Anti-Patterns', content: [{ type: 'list', items: ['no inline styles on raw elements', 'no hardcoded colors — use tokens or Tailwind semantic classes', 'no hardcoded spacing', 'no hardcoded <a> — use useLinkComponent()', 'read docs before inventing props'] }] },
|
|
12
12
|
{ title: 'Tokens', content: [{ type: 'prose', text: 'run npx astryx docs tokens for full reference' }] },
|
|
13
13
|
],
|
|
14
14
|
};
|
package/docs/principles.doc.mjs
CHANGED
|
@@ -39,8 +39,6 @@ export const docs = {
|
|
|
39
39
|
style: 'ordered',
|
|
40
40
|
items: [
|
|
41
41
|
'Use components for everything they cover',
|
|
42
|
-
'Layout is frame-first: pick the shell and budget regions before writing content (see \`npx astryx docs layout\`)',
|
|
43
|
-
'Dense data renders as rows (Table, List/Item), edge-to-edge with dividers; Card is for widgets, galleries, and settings groups',
|
|
44
42
|
'StyleX or Tailwind for custom styling; both are first-class (see \`npx astryx docs styling\`)',
|
|
45
43
|
'Semantic tokens, not hardcoded values (see \`npx astryx docs tokens\`)',
|
|
46
44
|
'CSS custom properties for colors, not hex values',
|
|
@@ -76,8 +74,6 @@ export const docs = {
|
|
|
76
74
|
'Hardcoded colors (#fff). Use var(--color-*) or Tailwind semantic classes (text-primary, bg-surface)',
|
|
77
75
|
'Hardcoded spacing (16px). Use spacing tokens or Tailwind spacing utilities',
|
|
78
76
|
'Hardcoded <a> elements. Use useLinkComponent() so consumers can swap in their framework router via LinkProvider',
|
|
79
|
-
'Wrapping every list item or page section in a Card. Decide the frame first; dense data renders as rows (see \`npx astryx docs layout\`)',
|
|
80
|
-
'Badge as decoration. Reserve Badge for counts and enumerated states; use StatusDot or Token for status',
|
|
81
77
|
'Inventing props. Read component docs first',
|
|
82
78
|
],
|
|
83
79
|
},
|
|
@@ -6,9 +6,9 @@ export const docsZh = {
|
|
|
6
6
|
description: 'XDS 核心设计原则和规则。',
|
|
7
7
|
sections: [
|
|
8
8
|
{ title: '设计哲学', content: [{ type: 'list', items: ['组件优于原始元素 — 优先使用 XDS 组件', '语义化令牌优于硬编码值', '主题无关的代码 — 深色模式自动生效', '开放的内部机制 — 所有基础组件均可导出和组合'] }] },
|
|
9
|
-
{ title: '规则', content: [{ type: 'list', items: ['所有支持的场景都使用 XDS 组件', '
|
|
9
|
+
{ title: '规则', content: [{ type: 'list', items: ['所有支持的场景都使用 XDS 组件', '使用 StyleX 或 Tailwind 进行样式设置', '使用语义化令牌,不使用硬编码值', '使用 CSS 变量设置颜色,不使用十六进制值', '表单输入为受控组件(value + onChange)', '使用 useLinkComponent() 进行导航'] }] },
|
|
10
10
|
{ title: '样式方法', content: [{ type: 'prose', text: '组件覆盖使用 xstyle 属性。布局使用 StyleX 或 Tailwind。详见 astryx docs styling。' }] },
|
|
11
|
-
{ title: '反模式', content: [{ type: 'list', items: ['不要在原始元素上使用内联样式', '不要硬编码颜色 — 使用令牌或 Tailwind 语义类', '不要硬编码间距', '不要硬编码 <a> 元素 — 使用 useLinkComponent()', '
|
|
11
|
+
{ title: '反模式', content: [{ type: 'list', items: ['不要在原始元素上使用内联样式', '不要硬编码颜色 — 使用令牌或 Tailwind 语义类', '不要硬编码间距', '不要硬编码 <a> 元素 — 使用 useLinkComponent()', '不要自创属性。先阅读组件文档'] }] },
|
|
12
12
|
{ title: '设计令牌', content: [{ type: 'prose', text: '运行 npx astryx docs tokens 查看完整参考' }] },
|
|
13
13
|
],
|
|
14
14
|
};
|
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.deb5aa0",
|
|
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",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"zod": "^4.4.3"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
79
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
80
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
78
|
+
"@astryxdesign/core": "0.1.2-canary.deb5aa0",
|
|
79
|
+
"@astryxdesign/lab": "0.1.2-canary.deb5aa0",
|
|
80
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.deb5aa0",
|
|
81
81
|
"gpt-tokenizer": "^2.0.0"
|
|
82
82
|
},
|
|
83
83
|
"peerDependenciesMeta": {
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
96
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
97
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
95
|
+
"@astryxdesign/core": "0.1.2-canary.deb5aa0",
|
|
96
|
+
"@astryxdesign/lab": "0.1.2-canary.deb5aa0",
|
|
97
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.deb5aa0",
|
|
98
98
|
"gpt-tokenizer": "^2.0.0"
|
|
99
99
|
},
|
|
100
100
|
"scripts": {
|
package/src/api/index.mjs
CHANGED
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
|
|
22
22
|
export {component} from './component.mjs';
|
|
23
23
|
export {docs} from './docs.mjs';
|
|
24
|
-
export {blog} from './blog.mjs';
|
|
25
24
|
export {discover} from './discover.mjs';
|
|
26
25
|
export {template} from './template.mjs';
|
|
27
26
|
export {themeAdd, listThemes} from './theme-add.mjs';
|
|
@@ -180,9 +180,6 @@ export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPre
|
|
|
180
180
|
// Rules — the top error-preventers.
|
|
181
181
|
lines.push('RULES:');
|
|
182
182
|
lines.push('- No <div> — components do all layout/spacing. Full page → AppShell; sidebar nav → SideNav.');
|
|
183
|
-
lines.push('- Frame first: pick the shell (AppShell / Layout+LayoutPanel) and budget regions in px BEFORE writing content (`astryx docs layout`).');
|
|
184
|
-
lines.push('- Dense data = rows (Table, List/Item) edge-to-edge — never Card-wrapped list items. Card = dashboard widgets, galleries, settings groups only.');
|
|
185
|
-
lines.push('- Status → StatusDot/Token; Badge only for counts and enumerated states, never decoration.');
|
|
186
183
|
// Styling guidance tailored to the project's configured system — never
|
|
187
184
|
// recommend a path that isn't compiled here (xstyle needs the StyleX compiler;
|
|
188
185
|
// utilities need Tailwind). Tokens are always the source of truth.
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
import * as fs from 'node:fs';
|
|
16
16
|
import * as path from 'node:path';
|
|
17
17
|
import {pathToFileURL, fileURLToPath} from 'node:url';
|
|
18
|
-
import {spawn} from 'node:child_process';
|
|
19
18
|
import {createJiti} from 'jiti';
|
|
20
19
|
import {getRunPrefix} from '../utils/package-manager.mjs';
|
|
21
20
|
import {
|
|
@@ -598,104 +597,6 @@ function validatePrivateVars(themeDef) {
|
|
|
598
597
|
return errors;
|
|
599
598
|
}
|
|
600
599
|
|
|
601
|
-
/**
|
|
602
|
-
* Path to this CLI's real entry (bin/astryx.mjs), resolved from this module's
|
|
603
|
-
* location (src/commands/build-theme.mjs → ../../bin/astryx.mjs). Used to
|
|
604
|
-
* re-invoke `theme build` as a child process in watch mode.
|
|
605
|
-
*/
|
|
606
|
-
function resolveCliBin() {
|
|
607
|
-
const commandsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
608
|
-
return path.resolve(commandsDir, '../../bin/astryx.mjs');
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Run a single `theme build` as a child process, reusing the exact
|
|
613
|
-
* single-build code path (and its error handling) rather than duplicating it.
|
|
614
|
-
* Resolves with the child's exit code; never rejects.
|
|
615
|
-
*
|
|
616
|
-
* @param {string} file - The theme file argument, as the user passed it.
|
|
617
|
-
* @param {object} options - Parsed command options (only `out` is forwarded).
|
|
618
|
-
* @returns {Promise<number>}
|
|
619
|
-
*/
|
|
620
|
-
function runThemeBuildOnceChild(file, options) {
|
|
621
|
-
const cliBin = resolveCliBin();
|
|
622
|
-
const args = [cliBin, 'theme', 'build', file];
|
|
623
|
-
if (options.out) args.push('--out', options.out);
|
|
624
|
-
return new Promise(resolve => {
|
|
625
|
-
const child = spawn(process.execPath, args, {
|
|
626
|
-
stdio: 'inherit',
|
|
627
|
-
env: process.env,
|
|
628
|
-
});
|
|
629
|
-
child.on('close', code => resolve(code ?? 0));
|
|
630
|
-
child.on('error', () => resolve(1));
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
/**
|
|
635
|
-
* Watch a theme file and rebuild on change. Runs an initial build, then
|
|
636
|
-
* rebuilds (debounced) whenever the file changes, until interrupted with
|
|
637
|
-
* Ctrl-C. Each rebuild runs in a child process so a build error (which the
|
|
638
|
-
* single-build path reports via a hard exit) is contained and the watcher
|
|
639
|
-
* keeps running.
|
|
640
|
-
*
|
|
641
|
-
* @param {string} file - The theme file argument, as the user passed it.
|
|
642
|
-
* @param {string} filePath - Absolute path to the theme file.
|
|
643
|
-
* @param {object} options - Parsed command options.
|
|
644
|
-
* @returns {Promise<void>} Resolves when the watcher is stopped (Ctrl-C).
|
|
645
|
-
*/
|
|
646
|
-
async function runThemeBuildWatch(file, filePath, options) {
|
|
647
|
-
const rel = path.relative(process.cwd(), filePath);
|
|
648
|
-
|
|
649
|
-
// Initial build.
|
|
650
|
-
await runThemeBuildOnceChild(file, options);
|
|
651
|
-
|
|
652
|
-
humanLog(`\n👀 Watching ${rel} for changes — press Ctrl-C to stop.`);
|
|
653
|
-
|
|
654
|
-
let building = false;
|
|
655
|
-
let queued = false;
|
|
656
|
-
let debounce = null;
|
|
657
|
-
|
|
658
|
-
const rebuild = async () => {
|
|
659
|
-
if (building) {
|
|
660
|
-
// Coalesce changes that land mid-build into a single follow-up run.
|
|
661
|
-
queued = true;
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
building = true;
|
|
665
|
-
humanLog(`\n♻️ Change detected — rebuilding ${rel}...`);
|
|
666
|
-
await runThemeBuildOnceChild(file, options);
|
|
667
|
-
building = false;
|
|
668
|
-
humanLog(`\n👀 Watching ${rel} for changes — press Ctrl-C to stop.`);
|
|
669
|
-
if (queued) {
|
|
670
|
-
queued = false;
|
|
671
|
-
rebuild();
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
|
|
675
|
-
// Some editors replace the file (rename) rather than writing in place, which
|
|
676
|
-
// can drop the watch. Watch the containing directory and filter to our file
|
|
677
|
-
// so edits survive atomic-save/rename.
|
|
678
|
-
const watchDir = path.dirname(filePath);
|
|
679
|
-
const baseName = path.basename(filePath);
|
|
680
|
-
const watcher = fs.watch(watchDir, (_eventType, changed) => {
|
|
681
|
-
if (changed && changed !== baseName) return;
|
|
682
|
-
clearTimeout(debounce);
|
|
683
|
-
// Debounce: editors often emit several events per save.
|
|
684
|
-
debounce = setTimeout(rebuild, 100);
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
await new Promise(resolve => {
|
|
688
|
-
const stop = () => {
|
|
689
|
-
clearTimeout(debounce);
|
|
690
|
-
watcher.close();
|
|
691
|
-
humanLog('\nStopped watching.');
|
|
692
|
-
resolve();
|
|
693
|
-
};
|
|
694
|
-
process.once('SIGINT', stop);
|
|
695
|
-
process.once('SIGTERM', stop);
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
|
|
699
600
|
export function registerTheme(program) {
|
|
700
601
|
const theme = program
|
|
701
602
|
.command('theme')
|
|
@@ -720,10 +621,6 @@ export function registerTheme(program) {
|
|
|
720
621
|
.command('build <file>')
|
|
721
622
|
.description('Compile a defineTheme file to CSS + JS')
|
|
722
623
|
.option('-o, --out <path>', 'Output CSS file path')
|
|
723
|
-
.option(
|
|
724
|
-
'-w, --watch',
|
|
725
|
-
'Rebuild automatically when the theme file changes (Ctrl-C to stop)',
|
|
726
|
-
)
|
|
727
624
|
.action(async (file, options) => {
|
|
728
625
|
const filePath = path.resolve(process.cwd(), file);
|
|
729
626
|
const json = program.opts().json || false;
|
|
@@ -733,20 +630,6 @@ export function registerTheme(program) {
|
|
|
733
630
|
return;
|
|
734
631
|
}
|
|
735
632
|
|
|
736
|
-
// Watch mode: run an initial build, then rebuild on every change to the
|
|
737
|
-
// theme file. Watch is a human-interactive, long-running mode — it is not
|
|
738
|
-
// supported in --json (machine) mode, which expects a single envelope.
|
|
739
|
-
if (options.watch) {
|
|
740
|
-
if (json) {
|
|
741
|
-
cliError('--watch is not supported with --json', {
|
|
742
|
-
code: ERROR_CODES.ERR_THEME_INVALID,
|
|
743
|
-
});
|
|
744
|
-
return;
|
|
745
|
-
}
|
|
746
|
-
await runThemeBuildWatch(file, filePath, options);
|
|
747
|
-
return;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
633
|
if (!json) humanLog(`\nBuilding theme from ${path.relative(process.cwd(), filePath)}...`);
|
|
751
634
|
|
|
752
635
|
// Extract theme definition
|
package/src/index.mjs
CHANGED
|
@@ -245,7 +245,6 @@ const commands = [
|
|
|
245
245
|
{name: 'init', path: './commands/init.mjs', register: 'registerInit'},
|
|
246
246
|
{name: 'component', path: './commands/component/index.mjs', register: 'registerComponent'},
|
|
247
247
|
{name: 'docs', path: './commands/docs.mjs', register: 'registerDocs'},
|
|
248
|
-
{name: 'blog', path: './commands/blog.mjs', register: 'registerBlog'},
|
|
249
248
|
{name: 'swizzle', path: './commands/swizzle.mjs', register: 'registerSwizzle'},
|
|
250
249
|
// agent-docs folded into init — functions still importable from agent-docs.mjs
|
|
251
250
|
{name: 'template', path: './commands/template.mjs', register: 'registerTemplate'},
|
package/src/lib/error-codes.mjs
CHANGED
|
@@ -75,8 +75,6 @@
|
|
|
75
75
|
* | 'ERR_INVALID_VERSION'
|
|
76
76
|
* | 'ERR_DEP_MISSING'
|
|
77
77
|
* | 'ERR_GH_CLI'
|
|
78
|
-
* | 'ERR_UNKNOWN_POST'
|
|
79
|
-
* | 'ERR_FETCH_FAILED'
|
|
80
78
|
* | 'ERR_LAYOUT_PARSE'
|
|
81
79
|
* | 'ERR_LAYOUT_INVALID'
|
|
82
80
|
* )} ErrorCode
|
|
@@ -183,12 +181,6 @@ export const ERROR_CODES = Object.freeze({
|
|
|
183
181
|
/** GitHub CLI (`gh`) is not installed or not authenticated. */
|
|
184
182
|
ERR_GH_CLI: 'ERR_GH_CLI',
|
|
185
183
|
|
|
186
|
-
// ── Blog (read via the published RSS feed) ───────────────────────
|
|
187
|
-
/** No blog post matched the requested slug in the feed. */
|
|
188
|
-
ERR_UNKNOWN_POST: 'ERR_UNKNOWN_POST',
|
|
189
|
-
/** A network fetch (RSS feed or post text) failed. */
|
|
190
|
-
ERR_FETCH_FAILED: 'ERR_FETCH_FAILED',
|
|
191
|
-
|
|
192
184
|
// ── Layout expressions (XLE/XLO) ─────────────────────────────────
|
|
193
185
|
/** A layout expression failed to parse (syntax error, with line/col). */
|
|
194
186
|
ERR_LAYOUT_PARSE: 'ERR_LAYOUT_PARSE',
|
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {DropdownMenu} from '@astryxdesign/core/DropdownMenu';
|
|
6
7
|
|
|
7
8
|
export default function DropdownMenuShowcase() {
|
|
9
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
10
|
+
|
|
8
11
|
return (
|
|
9
12
|
<DropdownMenu
|
|
13
|
+
isMenuOpen={isMenuOpen}
|
|
14
|
+
onOpenChange={setIsMenuOpen}
|
|
10
15
|
button={{label: 'Actions'}}
|
|
11
16
|
items={[
|
|
12
17
|
{label: 'Edit', onClick: () => {}},
|
|
@@ -65,7 +65,10 @@ const TrashIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|
|
65
65
|
|
|
66
66
|
export default function DropdownMenuItemShowcase() {
|
|
67
67
|
return (
|
|
68
|
-
<DropdownMenu
|
|
68
|
+
<DropdownMenu
|
|
69
|
+
button={{label: 'Actions'}}
|
|
70
|
+
isMenuOpen
|
|
71
|
+
onOpenChange={() => {}}>
|
|
69
72
|
<DropdownMenuItem
|
|
70
73
|
icon={PencilIcon}
|
|
71
74
|
label="Edit"
|
|
@@ -12,10 +12,9 @@ export default function LightboxShowcase() {
|
|
|
12
12
|
isOpen={isOpen}
|
|
13
13
|
onOpenChange={setIsOpen}
|
|
14
14
|
media={{
|
|
15
|
-
src: 'https://
|
|
16
|
-
alt: '
|
|
17
|
-
caption:
|
|
18
|
-
'A scenic coastline with waves rolling onto a sandy beach beneath a clear sky.',
|
|
15
|
+
src: 'https://picsum.photos/id/10/1200/800',
|
|
16
|
+
alt: 'Forest path',
|
|
17
|
+
caption: 'A winding path through the forest',
|
|
19
18
|
}}
|
|
20
19
|
/>
|
|
21
20
|
</>
|
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {MoreMenu} from '@astryxdesign/core/MoreMenu';
|
|
6
7
|
|
|
7
8
|
export default function MoreMenuShowcase() {
|
|
9
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
10
|
+
|
|
8
11
|
return (
|
|
9
12
|
<MoreMenu
|
|
13
|
+
isMenuOpen={isMenuOpen}
|
|
14
|
+
onOpenChange={setIsMenuOpen}
|
|
10
15
|
items={[
|
|
11
16
|
{label: 'Edit', onClick: () => {}},
|
|
12
17
|
{label: 'Duplicate', onClick: () => {}},
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
|
|
4
|
+
export const doc = {
|
|
5
|
+
type: 'block',
|
|
6
|
+
exampleFor: 'TreeListBranches',
|
|
7
|
+
name: 'TreeListBranches',
|
|
8
|
+
displayName: 'Tree List Branches',
|
|
9
|
+
description: 'Tree with expandable branches at multiple nesting levels.',
|
|
10
|
+
isReady: true,
|
|
11
|
+
isShowcase: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['TreeList'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {TreeList} from '@astryxdesign/core/TreeList';
|
|
6
|
+
|
|
7
|
+
const noop = () => {};
|
|
8
|
+
|
|
9
|
+
export default function TreeListBranchesShowcase() {
|
|
10
|
+
return (
|
|
11
|
+
<TreeList
|
|
12
|
+
items={[
|
|
13
|
+
{
|
|
14
|
+
id: 'design-system',
|
|
15
|
+
label: 'Design System',
|
|
16
|
+
isExpanded: true,
|
|
17
|
+
children: [
|
|
18
|
+
{
|
|
19
|
+
id: 'components',
|
|
20
|
+
label: 'Components',
|
|
21
|
+
isExpanded: true,
|
|
22
|
+
children: [
|
|
23
|
+
{
|
|
24
|
+
id: 'inputs',
|
|
25
|
+
label: 'Inputs',
|
|
26
|
+
children: [
|
|
27
|
+
{id: 'text-input', label: 'TextInput', onClick: noop},
|
|
28
|
+
{id: 'checkbox', label: 'Checkbox', onClick: noop},
|
|
29
|
+
{id: 'selector', label: 'Selector', onClick: noop},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'layout',
|
|
34
|
+
label: 'Layout',
|
|
35
|
+
children: [
|
|
36
|
+
{id: 'stack', label: 'Stack', onClick: noop},
|
|
37
|
+
{id: 'grid', label: 'Grid', onClick: noop},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'tokens',
|
|
44
|
+
label: 'Tokens',
|
|
45
|
+
children: [
|
|
46
|
+
{id: 'colors', label: 'Colors', onClick: noop},
|
|
47
|
+
{id: 'spacing', label: 'Spacing', onClick: noop},
|
|
48
|
+
{id: 'typography', label: 'Typography', onClick: noop},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'utilities',
|
|
55
|
+
label: 'Utilities',
|
|
56
|
+
children: [
|
|
57
|
+
{id: 'hooks', label: 'Hooks', onClick: noop},
|
|
58
|
+
{id: 'helpers', label: 'Helpers', onClick: noop},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
]}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
|
|
4
|
+
export const doc = {
|
|
5
|
+
type: 'block',
|
|
6
|
+
exampleFor: 'TreeListItem',
|
|
7
|
+
name: 'TreeListItem',
|
|
8
|
+
displayName: 'Tree List Item',
|
|
9
|
+
description: 'Tree items with descriptions, icons, badges, selection, disabled state, and nested expand/collapse. TreeList is data-driven: no composed children API.',
|
|
10
|
+
isReady: true,
|
|
11
|
+
isShowcase: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['TreeList', 'Badge', 'Icon', 'Layout', 'Text'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {TreeList} from '@astryxdesign/core/TreeList';
|
|
6
|
+
import {Badge} from '@astryxdesign/core/Badge';
|
|
7
|
+
import {Icon} from '@astryxdesign/core/Icon';
|
|
8
|
+
|
|
9
|
+
const noop = () => {};
|
|
10
|
+
|
|
11
|
+
export default function TreeListItemShowcase() {
|
|
12
|
+
return (
|
|
13
|
+
<TreeList
|
|
14
|
+
style={{width: 400}}
|
|
15
|
+
items={[
|
|
16
|
+
{
|
|
17
|
+
id: 'inbox',
|
|
18
|
+
label: 'Inbox',
|
|
19
|
+
description: '12 unread messages',
|
|
20
|
+
isExpanded: true,
|
|
21
|
+
startContent: <Icon icon="info" size="sm" />,
|
|
22
|
+
endContent: <Badge label="12" variant="info" />,
|
|
23
|
+
children: [
|
|
24
|
+
{
|
|
25
|
+
id: 'primary',
|
|
26
|
+
label: 'Primary',
|
|
27
|
+
isSelected: true,
|
|
28
|
+
startContent: <Icon icon="check" size="sm" />,
|
|
29
|
+
onClick: noop,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'updates',
|
|
33
|
+
label: 'Updates',
|
|
34
|
+
endContent: <Badge label="4" variant="info" />,
|
|
35
|
+
onClick: noop,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'drafts',
|
|
41
|
+
label: 'Drafts',
|
|
42
|
+
description: '3 draft messages',
|
|
43
|
+
startContent: <Icon icon="clock" size="sm" />,
|
|
44
|
+
onClick: noop,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'archive',
|
|
48
|
+
label: 'Archive',
|
|
49
|
+
onClick: noop,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'spam',
|
|
53
|
+
label: 'Spam',
|
|
54
|
+
isDisabled: true,
|
|
55
|
+
startContent: <Icon icon="warning" size="sm" />,
|
|
56
|
+
},
|
|
57
|
+
]}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/** @type {import('../../core/src/docs-types').ReferenceTranslationDoc} */
|
|
4
|
-
|
|
5
|
-
export const docsDense = {
|
|
6
|
-
description:
|
|
7
|
-
'frame-first app layout: shell choice, region budgets, cards vs rows',
|
|
8
|
-
sections: [
|
|
9
|
-
{
|
|
10
|
-
title: 'Frame First',
|
|
11
|
-
content: [
|
|
12
|
-
{
|
|
13
|
-
type: 'prose',
|
|
14
|
-
text: 'decide frame before content. content-first (Card-wrapped sections in a scroll column) = prototype look.',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
type: 'list',
|
|
18
|
-
items: [
|
|
19
|
-
'pick frame: AppShell (nav apps) | Layout+LayoutPanel+LayoutContent (multi-pane tools) | plain column (docs/forms)',
|
|
20
|
-
'budget regions in px first: side nav 240-280, rail 64-72, inspector 340-420, facet rail 220-260',
|
|
21
|
-
'container policy per region: dense data = rows; dashboards/galleries = card grids',
|
|
22
|
-
'write responsive contract up front',
|
|
23
|
-
],
|
|
24
|
-
},
|
|
25
|
-
null,
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
title: 'App Archetypes',
|
|
30
|
-
content: [
|
|
31
|
-
{
|
|
32
|
-
type: 'prose',
|
|
33
|
-
text: 'container choice tracks archetype, not preference.',
|
|
34
|
-
},
|
|
35
|
-
null,
|
|
36
|
-
{
|
|
37
|
-
type: 'prose',
|
|
38
|
-
text: 'start from matching template (astryx template --list), study with --skeleton.',
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
title: 'Cards vs Rows',
|
|
44
|
-
content: [
|
|
45
|
-
{
|
|
46
|
-
type: 'prose',
|
|
47
|
-
text: 'Card = widget container, NOT list-item wrapper. dense/scannable/selectable data = rows: Table (columnar) or List/Item (single-line), edge-to-edge, 32-40px rows, dividers.',
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
type: 'list',
|
|
51
|
-
items: [
|
|
52
|
-
'Table+plugins: hosts, deployments, monitors, users',
|
|
53
|
-
'List/Item rows: issues, files, conversations',
|
|
54
|
-
'Card: KPI tiles, chart panels, gallery entries, settings groups',
|
|
55
|
-
'EmptyState for zero-match',
|
|
56
|
-
],
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
type: 'list',
|
|
60
|
-
items: [
|
|
61
|
-
'no Card-wrapped list items (card soup)',
|
|
62
|
-
'no stacked full-width Cards as page structure',
|
|
63
|
-
'no Cards in Cards',
|
|
64
|
-
'no decorative Badge — counts/enums only; StatusDot/Token for status',
|
|
65
|
-
],
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
title: 'Panels and Inspectors',
|
|
71
|
-
content: [
|
|
72
|
-
{
|
|
73
|
-
type: 'prose',
|
|
74
|
-
text: 'master-detail: row select opens fixed-width inspector (LayoutPanel end slot + width budget + resizable/useResizable). overlay content <=1024px, do not compress.',
|
|
75
|
-
},
|
|
76
|
-
null,
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
title: 'Responsive Contract',
|
|
81
|
-
content: [
|
|
82
|
-
{
|
|
83
|
-
type: 'prose',
|
|
84
|
-
text: 'declare breakpoint behavior as comment at frame root: which regions collapse/overlay/drop at which widths.',
|
|
85
|
-
},
|
|
86
|
-
null,
|
|
87
|
-
],
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
};
|