@astryxdesign/cli 0.1.2 → 0.1.3
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/CHANGELOG.md +64 -1
- package/README.md +49 -55
- package/docs/layout.doc.dense.mjs +90 -0
- package/docs/layout.doc.mjs +160 -0
- package/docs/principles.doc.dense.mjs +2 -2
- package/docs/principles.doc.mjs +4 -0
- package/docs/principles.doc.zh.mjs +2 -2
- package/docs/theme.doc.mjs +2 -2
- package/package.json +13 -1
- package/src/api/blog.mjs +192 -0
- package/src/api/blog.test.mjs +144 -0
- package/src/api/component.mjs +253 -12
- package/src/api/discover.mjs +14 -7
- package/src/api/doctor.mjs +10 -25
- package/src/api/index.mjs +1 -0
- package/src/api/layout.mjs +11 -10
- package/src/api/layout.test.mjs +4 -1
- package/src/api/template-integration.test.mjs +225 -0
- package/src/api/template.mjs +242 -84
- package/src/api/validate-integration.mjs +370 -0
- package/src/api/validate-integration.test.mjs +222 -0
- package/src/codemod.mjs +93 -0
- package/src/codemod.test.mjs +134 -0
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/__tests__/runner.test.mjs +103 -0
- package/src/codemods/integration-discovery.mjs +168 -0
- package/src/codemods/integration-discovery.test.mjs +234 -0
- package/src/codemods/integration-runner.mjs +109 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/run-codemod.mjs +207 -0
- package/src/codemods/runner.mjs +73 -96
- package/src/codemods/transforms/v0.0.15/index.mjs +0 -13
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +67 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +61 -0
- package/src/codemods/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +104 -0
- package/src/codemods/transforms/{v0.0.15 → v0.1.0}/drop-xds-prefix-imports.mjs +15 -4
- package/src/codemods/transforms/v0.1.0/index.mjs +43 -6
- package/src/codemods/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +77 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-declare-module.mjs +78 -0
- package/src/codemods/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +360 -0
- package/src/codemods/transforms/v0.1.3/index.mjs +19 -0
- package/src/codemods/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +260 -0
- package/src/commands/agent-docs.mjs +4 -1
- package/src/commands/blog.mjs +60 -0
- package/src/commands/build-theme.import-path.test.mjs +2 -12
- package/src/commands/build-theme.mjs +117 -0
- package/src/commands/build-theme.prose.test.mjs +5 -15
- package/src/commands/build-theme.watch.test.mjs +149 -0
- package/src/commands/component/index.mjs +44 -10
- package/src/commands/component-ownership.test.mjs +227 -0
- package/src/commands/discover.mjs +5 -16
- package/src/commands/doctor.test.mjs +3 -3
- package/src/commands/ensure-core-built.mjs +120 -0
- package/src/commands/json-contract.test.mjs +0 -32
- package/src/commands/swizzle.mjs +224 -235
- package/src/commands/swizzle.path-safety.test.mjs +3 -3
- package/src/commands/swizzle.routing.test.mjs +279 -0
- package/src/commands/template.mjs +33 -37
- package/src/commands/upgrade.config-ordering.test.mjs +273 -0
- package/src/commands/upgrade.integration-policy.test.mjs +204 -0
- package/src/commands/upgrade.mjs +349 -170
- package/src/commands/validate-integration.mjs +110 -0
- package/src/commands/validate-integration.test.mjs +124 -0
- package/src/config.mjs +7 -20
- package/src/config.test.mjs +89 -13
- package/src/index.mjs +8 -3
- package/src/integration.mjs +19 -0
- package/src/lib/component-discovery.mjs +177 -0
- package/src/lib/config-cache.mjs +91 -0
- package/src/lib/config-cache.test.mjs +83 -0
- package/src/lib/config-schema.mjs +41 -55
- package/src/lib/error-codes.mjs +15 -12
- package/src/lib/integration-warnings.mjs +62 -0
- package/src/lib/integration-warnings.test.mjs +102 -0
- package/src/lib/integrations.mjs +92 -115
- package/src/lib/integrations.test.mjs +88 -107
- package/src/lib/manifest.mjs +5 -2
- package/src/lib/module-loader.mjs +80 -0
- package/src/lib/module-loader.test.mjs +106 -0
- package/src/lib/project.mjs +502 -0
- package/src/lib/project.test.mjs +308 -0
- package/src/lib/site.mjs +20 -0
- package/src/template.mjs +73 -0
- package/src/template.test.mjs +127 -0
- package/src/types/api.d.ts +2 -6
- package/src/types/base.d.ts +3 -9
- package/src/types/codemod.d.ts +81 -0
- package/src/types/component.d.ts +27 -2
- package/src/types/config.d.ts +56 -85
- package/src/types/error-codes.d.ts +5 -3
- package/src/types/index.d.ts +0 -1
- package/src/types/integration.d.ts +29 -0
- package/src/types/swizzle.d.ts +9 -2
- package/src/types/template-api.d.ts +54 -0
- package/src/types/template.d.ts +10 -7
- package/src/types/upgrade.d.ts +29 -0
- package/src/types/validate-integration.d.ts +24 -0
- package/src/utils/github.mjs +0 -237
- package/src/utils/interactive.mjs +2 -2
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.doc.mjs +14 -0
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +28 -0
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.doc.mjs +14 -0
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.tsx +34 -0
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.doc.mjs +14 -0
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.tsx +21 -0
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.tsx +15 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.doc.mjs +14 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.tsx +16 -0
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.doc.mjs +19 -0
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.tsx +34 -0
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.tsx +30 -0
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.doc.mjs +14 -0
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.tsx +31 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.tsx +26 -0
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.tsx +32 -0
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.doc.mjs +18 -0
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.tsx +32 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.tsx +27 -0
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.tsx +32 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.doc.mjs +14 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.tsx +46 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.doc.mjs +14 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.tsx +52 -0
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.doc.mjs +14 -0
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.tsx +43 -0
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.doc.mjs +14 -0
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.tsx +30 -0
- package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +0 -6
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.tsx +27 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +1 -5
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.doc.mjs +14 -0
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.tsx +20 -0
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.doc.mjs +14 -0
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.tsx +23 -0
- package/templates/blocks/components/FileInput/FileInputBasic.doc.mjs +14 -0
- package/templates/blocks/components/FileInput/FileInputBasic.tsx +22 -0
- package/templates/blocks/components/GridSpan/GridSpanColumns.doc.mjs +14 -0
- package/templates/blocks/components/GridSpan/GridSpanColumns.tsx +38 -0
- package/templates/blocks/components/HStack/HStackBasic.doc.mjs +14 -0
- package/templates/blocks/components/HStack/HStackBasic.tsx +16 -0
- package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.doc.mjs +14 -0
- package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.tsx +57 -0
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +9 -4
- package/templates/blocks/components/InputGroup/InputGroupBasic.doc.mjs +14 -0
- package/templates/blocks/components/InputGroup/InputGroupBasic.tsx +27 -0
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.doc.mjs +23 -0
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.tsx +40 -0
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.doc.mjs +22 -0
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.tsx +41 -0
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.doc.mjs +23 -0
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.tsx +40 -0
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.doc.mjs +22 -0
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.tsx +37 -0
- package/templates/blocks/components/Lightbox/LightboxGallery.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxGallery.tsx +53 -0
- package/templates/blocks/components/Lightbox/LightboxShowcase.tsx +4 -3
- package/templates/blocks/components/Lightbox/LightboxVideo.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxVideo.tsx +27 -0
- package/templates/blocks/components/Lightbox/LightboxZoom.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxZoom.tsx +33 -0
- package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +1 -1
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.tsx +19 -0
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.doc.mjs +23 -0
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.tsx +42 -0
- package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +0 -6
- package/templates/blocks/components/NavIcon/NavIconBasic.doc.mjs +14 -0
- package/templates/blocks/components/NavIcon/NavIconBasic.tsx +16 -0
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.tsx +30 -0
- package/templates/blocks/components/Resizable/ResizableSidebar.doc.mjs +25 -0
- package/templates/blocks/components/Resizable/ResizableSidebar.tsx +67 -0
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.tsx +21 -0
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.doc.mjs +14 -0
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.tsx +39 -0
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.tsx +55 -0
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.tsx +38 -0
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.tsx +49 -0
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.tsx +71 -0
- package/templates/blocks/components/StackItem/StackItemFill.doc.mjs +14 -0
- package/templates/blocks/components/StackItem/StackItemFill.tsx +28 -0
- package/templates/blocks/components/Tab/TabWithSelectedIcon.doc.mjs +13 -0
- package/templates/blocks/components/Tab/TabWithSelectedIcon.tsx +39 -0
- package/templates/blocks/components/TabMenu/TabMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/TabMenu/TabMenuBasic.tsx +23 -0
- package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +1 -1
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.doc.mjs +14 -0
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.tsx +47 -0
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.tsx +22 -0
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.tsx +21 -0
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.doc.mjs +20 -0
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.tsx +46 -0
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.tsx +16 -0
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.tsx +26 -0
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.tsx +43 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.tsx +43 -0
- package/templates/blocks/components/VStack/VStackBasic.doc.mjs +14 -0
- package/templates/blocks/components/VStack/VStackBasic.tsx +20 -0
- package/templates/pages/kanban-board/page.tsx +729 -0
- package/templates/pages/kanban-board/template.doc.mjs +12 -0
- package/templates/pages/shell-nav/page.tsx +321 -0
- package/templates/pages/shell-nav/template.doc.mjs +12 -0
- package/templates/pages/shell-side-nav/page.tsx +241 -0
- package/templates/pages/shell-side-nav/template.doc.mjs +12 -0
- package/templates/pages/shell-top-nav/page.tsx +224 -0
- package/templates/pages/shell-top-nav/template.doc.mjs +12 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +0 -116
- package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +0 -230
- package/src/commands/gap-report.mjs +0 -464
- package/src/commands/gap-report.test.mjs +0 -168
- package/src/commands/swizzle-gap-safety.test.mjs +0 -273
- package/src/lib/config.mjs +0 -113
- package/src/lib/config.test.mjs +0 -91
- package/src/types/gap-report.d.ts +0 -29
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.doc.mjs +0 -14
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.tsx +0 -64
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.doc.mjs +0 -14
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.tsx +0 -60
- /package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* End-to-end safety tests for `astryx swizzle --gap` and `xds gap-report`.
|
|
5
|
-
*
|
|
6
|
-
* Critical: these tests must NEVER actually invoke `gh issue create`. We
|
|
7
|
-
* defend in depth:
|
|
8
|
-
*
|
|
9
|
-
* 1. We spawn the CLI in a non-TTY pipe → triggers the dry-run gate.
|
|
10
|
-
* 2. We set ASTRYX_GAP_REPORT=off as an extra belt-and-suspenders for tests
|
|
11
|
-
* that would otherwise risk filing.
|
|
12
|
-
* 3. We unset GH_TOKEN so that any unexpected `gh` invocation fails fast.
|
|
13
|
-
* 4. We put a sabotaged `gh` shim earlier on PATH that blocks real
|
|
14
|
-
* `gh issue create` calls and writes a marker file. Any successful
|
|
15
|
-
* "filing" path leaves a marker we can assert against — so a regression
|
|
16
|
-
* is detected even if the gate silently breaks.
|
|
17
|
-
*
|
|
18
|
-
* Regression cases for issues #2370 and #2371: real gap-report issues filed
|
|
19
|
-
* unintentionally during a verification run because the non-interactive path
|
|
20
|
-
* called `gh issue create` with no confirmation.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import {describe, it, expect, beforeAll, afterAll, beforeEach, afterEach} from 'vitest';
|
|
24
|
-
import {spawnSync} from 'node:child_process';
|
|
25
|
-
import * as fs from 'node:fs';
|
|
26
|
-
import * as os from 'node:os';
|
|
27
|
-
import * as path from 'node:path';
|
|
28
|
-
import {fileURLToPath} from 'node:url';
|
|
29
|
-
|
|
30
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
-
const cliBin = path.resolve(__dirname, '../../bin/astryx.mjs');
|
|
32
|
-
const repoRoot = path.resolve(__dirname, '../../../..');
|
|
33
|
-
|
|
34
|
-
let shimDir;
|
|
35
|
-
let markerFile;
|
|
36
|
-
let baseEnv;
|
|
37
|
-
|
|
38
|
-
beforeAll(() => {
|
|
39
|
-
shimDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-gh-shim-'));
|
|
40
|
-
markerFile = path.join(shimDir, 'gh-issue-create-was-called.marker');
|
|
41
|
-
|
|
42
|
-
// Sabotaged `gh` shim. Records ONLY `gh issue create` invocations to the
|
|
43
|
-
// marker file, since that's the only command we want to detect as a
|
|
44
|
-
// "would-have-filed" event. Other subcommands (auth status, label create)
|
|
45
|
-
// succeed silently so they don't break the gh availability check or the
|
|
46
|
-
// label-ensure path.
|
|
47
|
-
const shim = `#!/usr/bin/env node
|
|
48
|
-
import * as fs from 'node:fs';
|
|
49
|
-
const args = process.argv.slice(2);
|
|
50
|
-
const isIssueCreate = args[0] === 'issue' && args[1] === 'create';
|
|
51
|
-
if (isIssueCreate) {
|
|
52
|
-
fs.appendFileSync(${JSON.stringify(markerFile)}, JSON.stringify(args) + '\\n');
|
|
53
|
-
process.stderr.write('TEST GUARD: real gh issue create blocked\\n');
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
// Other commands (auth status, label create) succeed silently.
|
|
57
|
-
process.exit(0);
|
|
58
|
-
`;
|
|
59
|
-
fs.writeFileSync(path.join(shimDir, 'gh'), shim);
|
|
60
|
-
fs.chmodSync(path.join(shimDir, 'gh'), 0o755);
|
|
61
|
-
|
|
62
|
-
baseEnv = {
|
|
63
|
-
...process.env,
|
|
64
|
-
PATH: `${shimDir}:${process.env.PATH}`,
|
|
65
|
-
// Belt-and-suspenders: even if a gate breaks, this disables the feature.
|
|
66
|
-
// For tests that need the feature on, individual cases override this.
|
|
67
|
-
GH_TOKEN: '',
|
|
68
|
-
};
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
afterAll(() => {
|
|
72
|
-
fs.rmSync(shimDir, {recursive: true, force: true});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
function runXds(args, {env = {}, cwd = repoRoot} = {}) {
|
|
76
|
-
// Reset marker for each run.
|
|
77
|
-
if (fs.existsSync(markerFile)) fs.unlinkSync(markerFile);
|
|
78
|
-
const result = spawnSync('node', [cliBin, ...args], {
|
|
79
|
-
cwd,
|
|
80
|
-
env: {...baseEnv, ...env},
|
|
81
|
-
encoding: 'utf-8',
|
|
82
|
-
});
|
|
83
|
-
return {
|
|
84
|
-
...result,
|
|
85
|
-
// True iff the CLI tried to call `gh issue create` — the actual filing
|
|
86
|
-
// operation. Other gh subcommands (auth status, label create) are
|
|
87
|
-
// ignored as benign.
|
|
88
|
-
ghWasCalled: fs.existsSync(markerFile),
|
|
89
|
-
ghCallArgs: fs.existsSync(markerFile)
|
|
90
|
-
? fs.readFileSync(markerFile, 'utf-8')
|
|
91
|
-
: null,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
describe('gap-report: dry-run by default in non-interactive mode', () => {
|
|
96
|
-
it('non-TTY pipe with all required flags → dry-run, exit 0, no gh call', () => {
|
|
97
|
-
const r = runXds([
|
|
98
|
-
'gap-report',
|
|
99
|
-
'--component',
|
|
100
|
-
'Button',
|
|
101
|
-
'--category',
|
|
102
|
-
'missing_variant',
|
|
103
|
-
'--reason',
|
|
104
|
-
'Test that we never file in non-interactive mode',
|
|
105
|
-
]);
|
|
106
|
-
expect(r.status).toBe(0);
|
|
107
|
-
expect(r.ghWasCalled).toBe(false);
|
|
108
|
-
expect(r.stdout).toMatch(/dry-run/i);
|
|
109
|
-
expect(r.stdout).toMatch(/Re-run with --commit/i);
|
|
110
|
-
// Preview should include the title we'd file.
|
|
111
|
-
expect(r.stdout).toContain('Button');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('--json mode in non-TTY → structured dry-run JSON, no gh call', () => {
|
|
115
|
-
const r = runXds([
|
|
116
|
-
'--json',
|
|
117
|
-
'gap-report',
|
|
118
|
-
'--component',
|
|
119
|
-
'Button',
|
|
120
|
-
'--category',
|
|
121
|
-
'missing_variant',
|
|
122
|
-
'--reason',
|
|
123
|
-
'JSON dry-run',
|
|
124
|
-
]);
|
|
125
|
-
expect(r.status).toBe(0);
|
|
126
|
-
expect(r.ghWasCalled).toBe(false);
|
|
127
|
-
// jsonOut pretty-prints across multiple lines; parse the whole stdout
|
|
128
|
-
// as JSON (after stripping any trailing whitespace).
|
|
129
|
-
const parsed = JSON.parse(r.stdout.trim());
|
|
130
|
-
expect(parsed.type).toBe('gap-report.dryRun');
|
|
131
|
-
expect(parsed.data.dryRun).toBe(true);
|
|
132
|
-
expect(parsed.data.title).toContain('Button');
|
|
133
|
-
expect(parsed.data.wouldFile).toBe(true);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('ASTRYX_GAP_REPORT=off → no gh call, even with --commit flag', () => {
|
|
137
|
-
const r = runXds(
|
|
138
|
-
[
|
|
139
|
-
'gap-report',
|
|
140
|
-
'--component',
|
|
141
|
-
'Button',
|
|
142
|
-
'--category',
|
|
143
|
-
'other',
|
|
144
|
-
'--reason',
|
|
145
|
-
'should be disabled',
|
|
146
|
-
'--commit',
|
|
147
|
-
],
|
|
148
|
-
{env: {ASTRYX_GAP_REPORT: 'off'}},
|
|
149
|
-
);
|
|
150
|
-
// Should exit 0 with a "disabled" message; never calls gh.
|
|
151
|
-
expect(r.ghWasCalled).toBe(false);
|
|
152
|
-
expect(r.status).toBe(0);
|
|
153
|
-
expect(r.stdout + r.stderr).toMatch(/disabled/i);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('--commit in non-TTY mode WOULD invoke gh (verified via shim)', () => {
|
|
157
|
-
// This proves --commit actually engages the file path. Our shim exits 1
|
|
158
|
-
// so the CLI will report failure, but the marker proves gh was invoked
|
|
159
|
-
// with the expected args.
|
|
160
|
-
const r = runXds(
|
|
161
|
-
[
|
|
162
|
-
'gap-report',
|
|
163
|
-
'--component',
|
|
164
|
-
'Button',
|
|
165
|
-
'--category',
|
|
166
|
-
'other',
|
|
167
|
-
'--reason',
|
|
168
|
-
'commit flag should engage filing',
|
|
169
|
-
'--commit',
|
|
170
|
-
],
|
|
171
|
-
{env: {ASTRYX_GAP_REPORT: ''}}, // re-enable feature; shim will block real call
|
|
172
|
-
);
|
|
173
|
-
expect(r.ghWasCalled).toBe(true);
|
|
174
|
-
expect(r.ghCallArgs).toContain('issue');
|
|
175
|
-
expect(r.ghCallArgs).toContain('create');
|
|
176
|
-
expect(r.ghCallArgs).toContain('facebookexperimental/xds');
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe('swizzle --gap respects safety gates', () => {
|
|
181
|
-
// swizzle's --output is path-safety guarded: absolute paths and `..`
|
|
182
|
-
// traversal are rejected (see swizzle.path-safety.test.mjs). These gap
|
|
183
|
-
// tests only care about the gh-call / status gates, so they write into a
|
|
184
|
-
// *relative* output dir created under the repo root (a valid, in-root
|
|
185
|
-
// target) and clean it up afterward. The CLI still resolves @astryxdesign/core via
|
|
186
|
-
// findCoreDir walking up from the cwd.
|
|
187
|
-
let swizzleOutDir;
|
|
188
|
-
beforeEach(() => {
|
|
189
|
-
swizzleOutDir = fs.mkdtempSync(path.join(repoRoot, '.xds-swizzle-gap-test-'));
|
|
190
|
-
});
|
|
191
|
-
afterEach(() => {
|
|
192
|
-
if (swizzleOutDir) fs.rmSync(swizzleOutDir, {recursive: true, force: true});
|
|
193
|
-
});
|
|
194
|
-
// Relative path into the temp dir, so it passes the path-safety guard
|
|
195
|
-
// (cwd === repoRoot for runXds by default).
|
|
196
|
-
const relOut = () => path.relative(repoRoot, swizzleOutDir);
|
|
197
|
-
|
|
198
|
-
it('swizzle --gap in non-TTY → dry-run, no gh call', () => {
|
|
199
|
-
const r = runXds([
|
|
200
|
-
'swizzle',
|
|
201
|
-
'Button',
|
|
202
|
-
'--output',
|
|
203
|
-
relOut(),
|
|
204
|
-
'--gap',
|
|
205
|
-
'Need a compact variant',
|
|
206
|
-
'--gap-category',
|
|
207
|
-
'missing_variant',
|
|
208
|
-
]);
|
|
209
|
-
expect(r.ghWasCalled).toBe(false);
|
|
210
|
-
expect(r.status).toBe(0);
|
|
211
|
-
expect(r.stdout).toMatch(/dry-run/i);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('swizzle --gap --no-report → never engages gap reporting at all', () => {
|
|
215
|
-
const r = runXds([
|
|
216
|
-
'swizzle',
|
|
217
|
-
'Button',
|
|
218
|
-
'--output',
|
|
219
|
-
relOut(),
|
|
220
|
-
'--gap',
|
|
221
|
-
'Should be suppressed entirely',
|
|
222
|
-
'--gap-category',
|
|
223
|
-
'missing_variant',
|
|
224
|
-
'--no-report',
|
|
225
|
-
]);
|
|
226
|
-
expect(r.ghWasCalled).toBe(false);
|
|
227
|
-
expect(r.status).toBe(0);
|
|
228
|
-
// Should not even show a dry-run preview — reporting is suppressed.
|
|
229
|
-
expect(r.stdout).toMatch(/suppressed/i);
|
|
230
|
-
expect(r.stdout).not.toMatch(/Would file GitHub issue/i);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('swizzle --gap --no-report --commit → STILL no gh call (no-report wins)', () => {
|
|
234
|
-
// Critical regression test: --no-report must beat --commit for the
|
|
235
|
-
// --gap auto-file path. Otherwise CI scripts could file issues.
|
|
236
|
-
const r = runXds(
|
|
237
|
-
[
|
|
238
|
-
'swizzle',
|
|
239
|
-
'Button',
|
|
240
|
-
'--output',
|
|
241
|
-
relOut(),
|
|
242
|
-
'--gap',
|
|
243
|
-
'should never file',
|
|
244
|
-
'--gap-category',
|
|
245
|
-
'other',
|
|
246
|
-
'--no-report',
|
|
247
|
-
'--commit',
|
|
248
|
-
],
|
|
249
|
-
{env: {ASTRYX_GAP_REPORT: ''}},
|
|
250
|
-
);
|
|
251
|
-
expect(r.ghWasCalled).toBe(false);
|
|
252
|
-
expect(r.status).toBe(0);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('swizzle --gap with ASTRYX_GAP_REPORT=off → no gh call', () => {
|
|
256
|
-
const r = runXds(
|
|
257
|
-
[
|
|
258
|
-
'swizzle',
|
|
259
|
-
'Button',
|
|
260
|
-
'--output',
|
|
261
|
-
relOut(),
|
|
262
|
-
'--gap',
|
|
263
|
-
'should be disabled by env',
|
|
264
|
-
'--gap-category',
|
|
265
|
-
'other',
|
|
266
|
-
'--commit',
|
|
267
|
-
],
|
|
268
|
-
{env: {ASTRYX_GAP_REPORT: 'off'}},
|
|
269
|
-
);
|
|
270
|
-
expect(r.ghWasCalled).toBe(false);
|
|
271
|
-
expect(r.status).toBe(0);
|
|
272
|
-
});
|
|
273
|
-
});
|
package/src/lib/config.mjs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Config loader — reads astryx.config.mjs from project root
|
|
5
|
-
*
|
|
6
|
-
* Walks up from cwd looking for astryx.config.mjs.
|
|
7
|
-
* Returns the config object or defaults if not found.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import * as fs from 'node:fs';
|
|
11
|
-
import * as path from 'node:path';
|
|
12
|
-
import {pathToFileURL} from 'node:url';
|
|
13
|
-
import {loadIntegrations} from './integrations.mjs';
|
|
14
|
-
import {validateConfig} from './config-schema.mjs';
|
|
15
|
-
|
|
16
|
-
const DEFAULTS = {
|
|
17
|
-
packages: [],
|
|
18
|
-
integrations: [],
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Find astryx.config.mjs by walking up from startDir.
|
|
23
|
-
* Returns the absolute path or null.
|
|
24
|
-
*/
|
|
25
|
-
export function findConfigPath(startDir = process.cwd()) {
|
|
26
|
-
let dir = startDir;
|
|
27
|
-
for (let i = 0; i < 10; i++) {
|
|
28
|
-
const candidate = path.join(dir, 'astryx.config.mjs');
|
|
29
|
-
if (fs.existsSync(candidate)) return candidate;
|
|
30
|
-
const parent = path.dirname(dir);
|
|
31
|
-
if (parent === dir) break;
|
|
32
|
-
dir = parent;
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Load and return the config from astryx.config.mjs.
|
|
39
|
-
* Returns defaults if no config file is found.
|
|
40
|
-
*/
|
|
41
|
-
export async function loadConfig(startDir = process.cwd()) {
|
|
42
|
-
const configPath = findConfigPath(startDir);
|
|
43
|
-
if (!configPath) return {...DEFAULTS};
|
|
44
|
-
|
|
45
|
-
let rawConfig;
|
|
46
|
-
try {
|
|
47
|
-
const mod = await import(pathToFileURL(configPath).href);
|
|
48
|
-
rawConfig = mod.default || {};
|
|
49
|
-
} catch {
|
|
50
|
-
return {...DEFAULTS};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const config = validateConfig(rawConfig);
|
|
54
|
-
const configDir = path.dirname(configPath);
|
|
55
|
-
const integrationSpecs = normalizeIntegrations(config.integrations);
|
|
56
|
-
const loadedIntegrations = await loadIntegrations(integrationSpecs, {
|
|
57
|
-
cwd: configDir,
|
|
58
|
-
});
|
|
59
|
-
return {
|
|
60
|
-
...DEFAULTS,
|
|
61
|
-
...config,
|
|
62
|
-
packages: normalizePackages(config.packages, configDir),
|
|
63
|
-
integrations: integrationSpecs,
|
|
64
|
-
loadedIntegrations,
|
|
65
|
-
gapReport:
|
|
66
|
-
config.gapReport ?? firstDefined(loadedIntegrations, 'gapReport'),
|
|
67
|
-
template: mergeTemplateConfig(config.template, loadedIntegrations),
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Normalize packages to an array of unique absolute paths.
|
|
73
|
-
* Filters out empty strings and non-string values.
|
|
74
|
-
* Relative paths resolved from config file directory.
|
|
75
|
-
* Deduplicates by resolved path.
|
|
76
|
-
*/
|
|
77
|
-
function normalizePackages(packages, configDir) {
|
|
78
|
-
if (!packages) return [];
|
|
79
|
-
const arr = Array.isArray(packages) ? packages : [packages];
|
|
80
|
-
const seen = new Set();
|
|
81
|
-
const result = [];
|
|
82
|
-
for (const p of arr) {
|
|
83
|
-
if (typeof p !== 'string' || p === '') continue;
|
|
84
|
-
const resolved = path.isAbsolute(p) ? p : path.resolve(configDir, p);
|
|
85
|
-
if (seen.has(resolved)) continue;
|
|
86
|
-
seen.add(resolved);
|
|
87
|
-
result.push(resolved);
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Normalize integration specs to a string array. Integrations are package names
|
|
94
|
-
* or manifest paths consumed by `astryx upgrade --integration`.
|
|
95
|
-
*/
|
|
96
|
-
function normalizeIntegrations(integrations) {
|
|
97
|
-
if (!integrations) return [];
|
|
98
|
-
const arr = Array.isArray(integrations) ? integrations : [integrations];
|
|
99
|
-
return arr.filter(value => typeof value === 'string' && value !== '');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function firstDefined(integrations, key) {
|
|
103
|
-
for (const integration of integrations) {
|
|
104
|
-
if (integration[key] !== undefined) return integration[key];
|
|
105
|
-
}
|
|
106
|
-
return undefined;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function mergeTemplateConfig(template, integrations) {
|
|
110
|
-
if (template?.get) return template;
|
|
111
|
-
const integrationTemplate = firstDefined(integrations, 'template');
|
|
112
|
-
return integrationTemplate ?? template;
|
|
113
|
-
}
|
package/src/lib/config.test.mjs
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
4
|
-
import * as fs from 'node:fs';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import {loadConfig} from './config.mjs';
|
|
7
|
-
|
|
8
|
-
let tmpDir;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-config-test-'));
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
function installIntegrationPackage(dir, name = '@nest/xds-meta') {
|
|
19
|
-
const packageDir = path.join(dir, 'node_modules', ...name.split('/'));
|
|
20
|
-
fs.mkdirSync(packageDir, {recursive: true});
|
|
21
|
-
fs.writeFileSync(
|
|
22
|
-
path.join(packageDir, 'package.json'),
|
|
23
|
-
JSON.stringify({name, astryx: {integration: './astryx.integration.mjs'}}),
|
|
24
|
-
);
|
|
25
|
-
fs.writeFileSync(
|
|
26
|
-
path.join(packageDir, 'astryx.integration.mjs'),
|
|
27
|
-
`export default { name: '${name}' };
|
|
28
|
-
`,
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
describe('loadConfig', () => {
|
|
33
|
-
it('normalizes integrations from astryx.config.mjs', async () => {
|
|
34
|
-
const dir = path.join(tmpDir, 'one');
|
|
35
|
-
fs.mkdirSync(dir);
|
|
36
|
-
installIntegrationPackage(dir);
|
|
37
|
-
fs.writeFileSync(
|
|
38
|
-
path.join(dir, 'astryx.config.mjs'),
|
|
39
|
-
`export default { integrations: '@nest/xds-meta' };\n`,
|
|
40
|
-
);
|
|
41
|
-
await expect(loadConfig(dir)).resolves.toMatchObject({
|
|
42
|
-
integrations: ['@nest/xds-meta'],
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('rejects invalid integration package manifests', async () => {
|
|
47
|
-
const dir = path.join(tmpDir, 'bad');
|
|
48
|
-
fs.mkdirSync(dir);
|
|
49
|
-
const packageDir = path.join(dir, 'node_modules', '@bad', 'widgets');
|
|
50
|
-
fs.mkdirSync(packageDir, {recursive: true});
|
|
51
|
-
fs.writeFileSync(
|
|
52
|
-
path.join(dir, 'astryx.config.mjs'),
|
|
53
|
-
`export default { integrations: '@bad/widgets' };\n`,
|
|
54
|
-
);
|
|
55
|
-
fs.writeFileSync(
|
|
56
|
-
path.join(packageDir, 'package.json'),
|
|
57
|
-
JSON.stringify({
|
|
58
|
-
name: '@bad/widgets',
|
|
59
|
-
astryx: {integration: './astryx.integration.mjs'},
|
|
60
|
-
}),
|
|
61
|
-
);
|
|
62
|
-
fs.writeFileSync(
|
|
63
|
-
path.join(packageDir, 'astryx.integration.mjs'),
|
|
64
|
-
`export default { docs: './docs' };\n`,
|
|
65
|
-
);
|
|
66
|
-
await expect(loadConfig(dir)).rejects.toThrow(/name/);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('normalizes integration arrays', async () => {
|
|
70
|
-
const dir = path.join(tmpDir, 'two');
|
|
71
|
-
fs.mkdirSync(dir);
|
|
72
|
-
installIntegrationPackage(dir);
|
|
73
|
-
fs.writeFileSync(
|
|
74
|
-
path.join(dir, 'astryx.config.mjs'),
|
|
75
|
-
`export default { integrations: ['@nest/xds-meta', ''] };\n`,
|
|
76
|
-
);
|
|
77
|
-
await expect(loadConfig(dir)).resolves.toMatchObject({
|
|
78
|
-
integrations: ['@nest/xds-meta'],
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('rejects invalid config shapes', async () => {
|
|
83
|
-
const dir = path.join(tmpDir, 'invalid');
|
|
84
|
-
fs.mkdirSync(dir);
|
|
85
|
-
fs.writeFileSync(
|
|
86
|
-
path.join(dir, 'astryx.config.mjs'),
|
|
87
|
-
`export default { integrations: [42] };\n`,
|
|
88
|
-
);
|
|
89
|
-
await expect(loadConfig(dir)).rejects.toThrow(/integrations/);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Gap-report command JSON responses.
|
|
5
|
-
*
|
|
6
|
-
* Invocation -> type discriminator
|
|
7
|
-
* ------------------------------------------------------------------
|
|
8
|
-
* xds --json gap-report --list-categories -> gap-report.categories
|
|
9
|
-
* xds --json gap-report --component X --category Y --reason Z -> gap-report.file
|
|
10
|
-
* (invalid category) -> CLIError
|
|
11
|
-
* (interactive mode) -> CLIUnsupportedError (fallback)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/** xds --json gap-report --list-categories */
|
|
15
|
-
export interface GapReportCategoriesResponse {
|
|
16
|
-
type: 'gap-report.categories';
|
|
17
|
-
data: GapReportCategoryEntry[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface GapReportCategoryEntry {
|
|
21
|
-
value: string;
|
|
22
|
-
label: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** xds --json gap-report --component X --category Y --reason Z */
|
|
26
|
-
export interface GapReportFileResponse {
|
|
27
|
-
type: 'gap-report.file';
|
|
28
|
-
data: {filed: boolean; url: string | null};
|
|
29
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
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
|
-
}
|
/package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs
RENAMED
|
File without changes
|