@astryxdesign/cli 0.1.1 → 0.1.2-canary.043f3fd
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 +50 -0
- package/docs/theme.doc.mjs +2 -2
- package/docs/working-with-ai.doc.mjs +6 -6
- package/package.json +31 -8
- package/src/api/component.mjs +253 -12
- package/src/api/discover.mjs +87 -28
- package/src/api/doctor.mjs +7 -22
- package/src/api/index.mjs +1 -0
- package/src/api/layout.mjs +302 -0
- package/src/api/layout.test.mjs +241 -0
- package/src/api/template-integration.test.mjs +225 -0
- package/src/api/template.mjs +421 -122
- package/src/api/template.test.mjs +2 -0
- package/src/api/theme-add.mjs +182 -0
- 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 +2 -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 +2 -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__/v0.1.0-ordering.test.mjs +81 -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 +15 -6
- package/src/codemods/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +120 -0
- package/src/codemods/transforms/v0.1.2/index.mjs +19 -0
- package/src/codemods/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +136 -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/build-theme.import-path.test.mjs +22 -2
- package/src/commands/build-theme.mjs +185 -16
- 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/init.mjs +34 -8
- package/src/commands/init.next-steps.test.mjs +46 -0
- package/src/commands/json-contract.test.mjs +0 -32
- package/src/commands/layout.mjs +139 -0
- package/src/commands/swizzle.mjs +241 -224
- 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 -239
- package/src/commands/validate-integration.mjs +110 -0
- package/src/commands/validate-integration.test.mjs +124 -0
- package/src/config.mjs +18 -0
- package/src/config.test.mjs +100 -0
- package/src/index.mjs +13 -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 +105 -0
- package/src/lib/error-codes.mjs +18 -12
- package/src/lib/integration-warnings.mjs +62 -0
- package/src/lib/integration-warnings.test.mjs +102 -0
- package/src/lib/integrations.mjs +132 -0
- package/src/lib/integrations.test.mjs +135 -0
- package/src/lib/levenshtein.mjs +29 -0
- package/src/lib/manifest.mjs +15 -2
- package/src/lib/module-loader.mjs +80 -0
- package/src/lib/module-loader.test.mjs +106 -0
- package/src/lib/package-scanner.mjs +31 -7
- package/src/lib/project.mjs +502 -0
- package/src/lib/project.test.mjs +308 -0
- package/src/lib/string-utils.mjs +5 -14
- package/src/lib/xle/browser.d.ts +100 -0
- package/src/lib/xle/browser.mjs +120 -0
- package/src/lib/xle/expand.mjs +622 -0
- package/src/lib/xle/parse.mjs +581 -0
- package/src/lib/xle/print.mjs +174 -0
- package/src/lib/xle/registry-core.mjs +170 -0
- package/src/lib/xle/registry.mjs +237 -0
- package/src/lib/xle/splice.mjs +137 -0
- package/src/lib/xle/validate.mjs +356 -0
- package/src/lib/xle/xle.test.mjs +333 -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 +70 -0
- 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 -252
- package/src/utils/interactive.mjs +2 -2
- package/templates/blocks/components/Card/ClickableCardWithNestedButton.doc.mjs +1 -1
- package/templates/blocks/components/Card/SelectableCardMulti.doc.mjs +1 -1
- package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerWithProgress.tsx +1 -1
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonShowcase.tsx +3 -3
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
- package/templates/blocks/components/DateInput/DateInputDateRange.doc.mjs +2 -2
- 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/FileInput/FileInputShowcase.tsx +4 -2
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +9 -4
- package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +14 -0
- package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.tsx +43 -0
- package/templates/blocks/components/MultiSelector/MultiSelectorShowcase.tsx +6 -2
- package/templates/blocks/components/NumberInput/NumberInputShowcase.tsx +6 -2
- package/templates/blocks/components/Outline/OutlineShowcase.doc.mjs +15 -0
- package/templates/blocks/components/Outline/OutlineShowcase.tsx +22 -0
- package/templates/blocks/components/RadioList/RadioListShowcase.tsx +8 -1
- package/templates/blocks/components/SegmentedControl/SegmentedControlShowcase.tsx +3 -1
- package/templates/blocks/components/Selector/SelectorShowcase.tsx +4 -1
- package/templates/blocks/components/Slider/SliderShowcase.tsx +10 -1
- package/templates/blocks/components/Tab/TabShowcase.tsx +3 -1
- package/templates/blocks/components/Tab/TabWithSelectedIcon.doc.mjs +13 -0
- package/templates/blocks/components/Tab/TabWithSelectedIcon.tsx +39 -0
- package/templates/blocks/components/TabList/TabListShowcase.tsx +3 -1
- package/templates/blocks/components/TabMenu/TabMenuShowcase.tsx +3 -1
- package/templates/blocks/components/Table/ColumnResizeHookUsage.doc.mjs +14 -0
- package/templates/blocks/components/Table/ColumnResizeHookUsage.tsx +59 -0
- package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +14 -0
- package/templates/blocks/components/Table/StickyColumnsHookUsage.tsx +104 -0
- package/templates/blocks/components/Text/TextColors.tsx +20 -5
- package/templates/blocks/components/TextArea/TextAreaShowcase.tsx +4 -2
- package/templates/blocks/components/TextInput/TextInputShowcase.tsx +4 -2
- package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +11 -6
- package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +43 -7
- package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +40 -3
- package/templates/blocks/components/Thumbnail/ThumbnailShowcase.tsx +6 -5
- package/templates/blocks/components/Thumbnail/ThumbnailStates.tsx +11 -6
- package/templates/blocks/components/Timestamp/TimestampColors.tsx +2 -2
- package/templates/blocks/components/ToggleButton/ToggleButtonGroup.doc.mjs +1 -1
- package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +8 -6
- package/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +2 -2
- package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +23 -14
- package/templates/blocks/components/Typeahead/TypeaheadShowcase.tsx +6 -2
- 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 +242 -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/templates/pages/theme-showcase/page.tsx +8 -19
- package/templates/themes/butter/butterTheme.ts +916 -0
- package/templates/themes/butter/icons.tsx +77 -0
- package/templates/themes/chocolate/chocolateTheme.ts +230 -0
- package/templates/themes/chocolate/icons.tsx +77 -0
- package/templates/themes/gothic/gothicTheme.ts +657 -0
- package/templates/themes/gothic/icons.tsx +77 -0
- package/templates/themes/manifest.json +90 -0
- package/templates/themes/matcha/icons.tsx +67 -0
- package/templates/themes/matcha/matchaTheme.ts +247 -0
- package/templates/themes/neutral/icons.tsx +77 -0
- package/templates/themes/neutral/neutralTheme.ts +603 -0
- package/templates/themes/stone/icons.tsx +77 -0
- package/templates/themes/stone/stoneTheme.ts +652 -0
- package/templates/themes/y2k/icons.tsx +67 -0
- package/templates/themes/y2k/y2kTheme.ts +617 -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 -456
- package/src/commands/gap-report.test.mjs +0 -163
- package/src/commands/swizzle-gap-safety.test.mjs +0 -273
- package/src/lib/config.mjs +0 -86
- package/src/lib/config.test.mjs +0 -42
- package/src/types/gap-report.d.ts +0 -29
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.doc.mjs +0 -14
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +0 -57
- /package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
|
@@ -19,7 +19,7 @@ export default function ChatDictationButtonShowcase() {
|
|
|
19
19
|
const dictation = useChatDictation({
|
|
20
20
|
inputRef,
|
|
21
21
|
hasSounds: true,
|
|
22
|
-
onResult:
|
|
22
|
+
onResult: text => {
|
|
23
23
|
console.log('Dictation result:', text);
|
|
24
24
|
},
|
|
25
25
|
});
|
|
@@ -31,7 +31,7 @@ export default function ChatDictationButtonShowcase() {
|
|
|
31
31
|
input.
|
|
32
32
|
</Text>
|
|
33
33
|
<ChatComposer
|
|
34
|
-
onSubmit={
|
|
34
|
+
onSubmit={v => console.log('Submit:', v)}
|
|
35
35
|
input={<ChatComposerInput handleRef={inputRef} />}
|
|
36
36
|
sendActions={<ChatDictationButton dictation={dictation} />}
|
|
37
37
|
/>
|
|
@@ -63,7 +63,7 @@ export default function ChatDictationButtonShowcase() {
|
|
|
63
63
|
</HStack>
|
|
64
64
|
)}
|
|
65
65
|
{!dictation.isSupported && (
|
|
66
|
-
<Text type="supporting" color="
|
|
66
|
+
<Text type="supporting" color="accent">
|
|
67
67
|
SpeechRecognition is not supported in this browser.
|
|
68
68
|
</Text>
|
|
69
69
|
)}
|
|
@@ -0,0 +1,15 @@
|
|
|
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: 'CommandPaletteEmpty',
|
|
7
|
+
name: 'CommandPaletteEmpty',
|
|
8
|
+
displayName: 'Command Palette Empty',
|
|
9
|
+
description:
|
|
10
|
+
'Command palette empty state shown when no commands are available.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
isShowcase: true,
|
|
13
|
+
aspectRatio: 4 / 3,
|
|
14
|
+
componentsUsed: ['CommandPalette', 'CommandPaletteEmpty', 'Text'],
|
|
15
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useMemo} from 'react';
|
|
6
|
+
import {CommandPalette} from '@astryxdesign/core/CommandPalette';
|
|
7
|
+
import {Text} from '@astryxdesign/core/Text';
|
|
8
|
+
import {createStaticSource} from '@astryxdesign/core/Typeahead';
|
|
9
|
+
|
|
10
|
+
export default function CommandPaletteEmptyShowcase() {
|
|
11
|
+
const emptySource = useMemo(() => createStaticSource([]), []);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<CommandPalette
|
|
15
|
+
isOpen
|
|
16
|
+
isInline
|
|
17
|
+
onOpenChange={() => {}}
|
|
18
|
+
searchSource={emptySource}
|
|
19
|
+
emptyBootstrapText={
|
|
20
|
+
<Text type="supporting" color="secondary">
|
|
21
|
+
No commands available yet
|
|
22
|
+
</Text>
|
|
23
|
+
}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
export const doc = {
|
|
5
5
|
type: 'block',
|
|
6
6
|
exampleFor: 'DateInput',
|
|
7
|
-
name: 'DateInput —
|
|
8
|
-
displayName: 'DateInput —
|
|
7
|
+
name: 'DateInput — Min/Max Constraints',
|
|
8
|
+
displayName: 'DateInput — Min/Max Constraints',
|
|
9
9
|
description:
|
|
10
10
|
'Date input constrained to a min/max window. Use when only certain dates are valid, like booking availability or a fiscal quarter.',
|
|
11
11
|
isReady: true,
|
|
@@ -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: 'DateRangeInput',
|
|
7
|
+
name: 'DateRangeInput — With Presets',
|
|
8
|
+
displayName: 'DateRangeInput — With Presets',
|
|
9
|
+
description:
|
|
10
|
+
'Date range picker with quick-select presets for common periods. Use for analytics dashboards, report filters, or any context where users frequently select standard time windows.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['DateRangeInput', 'Layout', 'Text'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
6
|
+
import {DateRangeInput} from '@astryxdesign/core/DateRangeInput';
|
|
7
|
+
import type {DateRange} from '@astryxdesign/core/DateRangeInput';
|
|
8
|
+
import type {ISODateString} from '@astryxdesign/core/Calendar';
|
|
9
|
+
import {Stack} from '@astryxdesign/core/Layout';
|
|
10
|
+
import {Text} from '@astryxdesign/core/Text';
|
|
11
|
+
|
|
12
|
+
function daysAgo(n: number): ISODateString {
|
|
13
|
+
const d = new Date();
|
|
14
|
+
d.setDate(d.getDate() - n);
|
|
15
|
+
return d.toISOString().slice(0, 10) as ISODateString;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function today(): ISODateString {
|
|
19
|
+
return new Date().toISOString().slice(0, 10) as ISODateString;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const presets = [
|
|
23
|
+
{label: 'Last 7 days', getRange: () => ({start: daysAgo(7), end: today()})},
|
|
24
|
+
{label: 'Last 14 days', getRange: () => ({start: daysAgo(14), end: today()})},
|
|
25
|
+
{label: 'Last 30 days', getRange: () => ({start: daysAgo(30), end: today()})},
|
|
26
|
+
{label: 'Last 90 days', getRange: () => ({start: daysAgo(90), end: today()})},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default function DateRangeInputWithPresets() {
|
|
30
|
+
const [range, setRange] = useState<DateRange | null>(null);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Stack direction="vertical" gap={4} width="100%" style={{maxWidth: 400}}>
|
|
34
|
+
<Text type="supporting" color="secondary">
|
|
35
|
+
{range ? `${range.start} → ${range.end}` : 'No range selected'}
|
|
36
|
+
</Text>
|
|
37
|
+
<DateRangeInput
|
|
38
|
+
label="Report period"
|
|
39
|
+
description="Use a preset or pick a custom range"
|
|
40
|
+
value={range}
|
|
41
|
+
onChange={setRange}
|
|
42
|
+
presets={presets}
|
|
43
|
+
/>
|
|
44
|
+
</Stack>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -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: 'DateRangeInput',
|
|
7
|
+
name: 'DateRangeInput — Validation',
|
|
8
|
+
displayName: 'DateRangeInput — Validation',
|
|
9
|
+
description:
|
|
10
|
+
'Date range input in all three status states: error, warning, and success. Use to surface booking conflicts, flag high-demand periods, or confirm an available range.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['DateRangeInput', 'Layout'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
6
|
+
import {DateRangeInput} from '@astryxdesign/core/DateRangeInput';
|
|
7
|
+
import type {DateRange} from '@astryxdesign/core/DateRangeInput';
|
|
8
|
+
import {Stack} from '@astryxdesign/core/Layout';
|
|
9
|
+
|
|
10
|
+
export default function DateRangeInputWithValidation() {
|
|
11
|
+
const [errorRange, setErrorRange] = useState<DateRange | null>({
|
|
12
|
+
start: '2026-01-01',
|
|
13
|
+
end: '2026-01-31',
|
|
14
|
+
});
|
|
15
|
+
const [warningRange, setWarningRange] = useState<DateRange | null>({
|
|
16
|
+
start: '2026-06-01',
|
|
17
|
+
end: '2026-06-30',
|
|
18
|
+
});
|
|
19
|
+
const [successRange, setSuccessRange] = useState<DateRange | null>({
|
|
20
|
+
start: '2026-03-01',
|
|
21
|
+
end: '2026-03-31',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Stack direction="vertical" gap={4} width="100%" style={{maxWidth: 400}}>
|
|
26
|
+
<DateRangeInput
|
|
27
|
+
label="Booking period"
|
|
28
|
+
value={errorRange}
|
|
29
|
+
onChange={setErrorRange}
|
|
30
|
+
status={{
|
|
31
|
+
type: 'error',
|
|
32
|
+
message: 'Selected dates are no longer available',
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
<DateRangeInput
|
|
36
|
+
label="Preferred period"
|
|
37
|
+
value={warningRange}
|
|
38
|
+
onChange={setWarningRange}
|
|
39
|
+
status={{
|
|
40
|
+
type: 'warning',
|
|
41
|
+
message: 'High demand — limited availability',
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
<DateRangeInput
|
|
45
|
+
label="Confirmed period"
|
|
46
|
+
value={successRange}
|
|
47
|
+
onChange={setSuccessRange}
|
|
48
|
+
status={{type: 'success', message: 'Dates confirmed and available'}}
|
|
49
|
+
/>
|
|
50
|
+
</Stack>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -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: 'DateTimeInput',
|
|
7
|
+
name: 'DateTimeInput — Validation',
|
|
8
|
+
displayName: 'DateTimeInput — Validation',
|
|
9
|
+
description:
|
|
10
|
+
'DateTimeInput in all three status states: error, warning, and success. Use to surface scheduling conflicts, caution the user about edge cases, or confirm a valid datetime.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['DateTimeInput', 'Layout'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
6
|
+
import {DateTimeInput} from '@astryxdesign/core/DateTimeInput';
|
|
7
|
+
import type {ISODateTimeString} from '@astryxdesign/core/DateTimeInput';
|
|
8
|
+
import {Stack} from '@astryxdesign/core/Layout';
|
|
9
|
+
|
|
10
|
+
export default function DateTimeInputWithValidation() {
|
|
11
|
+
const [errorVal, setErrorVal] = useState<ISODateTimeString | undefined>(
|
|
12
|
+
'2026-01-25T09:00' as ISODateTimeString,
|
|
13
|
+
);
|
|
14
|
+
const [warningVal, setWarningVal] = useState<ISODateTimeString | undefined>(
|
|
15
|
+
'2026-12-25T14:00' as ISODateTimeString,
|
|
16
|
+
);
|
|
17
|
+
const [successVal, setSuccessVal] = useState<ISODateTimeString | undefined>(
|
|
18
|
+
'2026-03-10T10:30' as ISODateTimeString,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Stack direction="vertical" gap={4} width="100%" style={{maxWidth: 400}}>
|
|
23
|
+
<DateTimeInput
|
|
24
|
+
label="Meeting time"
|
|
25
|
+
value={errorVal}
|
|
26
|
+
onChange={setErrorVal}
|
|
27
|
+
status={{type: 'error', message: 'This time slot is already booked'}}
|
|
28
|
+
/>
|
|
29
|
+
<DateTimeInput
|
|
30
|
+
label="Preferred time"
|
|
31
|
+
value={warningVal}
|
|
32
|
+
onChange={setWarningVal}
|
|
33
|
+
status={{type: 'warning', message: 'This falls outside business hours'}}
|
|
34
|
+
/>
|
|
35
|
+
<DateTimeInput
|
|
36
|
+
label="Start time"
|
|
37
|
+
value={successVal}
|
|
38
|
+
onChange={setSuccessVal}
|
|
39
|
+
status={{type: 'success', message: 'Time confirmed'}}
|
|
40
|
+
/>
|
|
41
|
+
</Stack>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {FileInput} from '@astryxdesign/core/FileInput';
|
|
6
7
|
|
|
7
8
|
export default function FileInputShowcase() {
|
|
9
|
+
const [value, setValue] = useState<File | File[] | null>(null);
|
|
8
10
|
return (
|
|
9
11
|
<div style={{width: 350}}>
|
|
10
12
|
<FileInput
|
|
11
13
|
label="Upload file"
|
|
12
|
-
value={
|
|
13
|
-
onChange={
|
|
14
|
+
value={value}
|
|
15
|
+
onChange={setValue}
|
|
14
16
|
placeholder="Drag files here or click to browse"
|
|
15
17
|
/>
|
|
16
18
|
</div>
|
|
@@ -10,5 +10,5 @@ export const doc = {
|
|
|
10
10
|
'Shows a page summary when hovering a link: title, description, and URL. Use for documentation links, article references, or any URL where a preview helps the user decide whether to click.',
|
|
11
11
|
isReady: true,
|
|
12
12
|
aspectRatio: 16 / 9,
|
|
13
|
-
componentsUsed: ['HoverCard', 'Icon', 'Layout', 'Text'],
|
|
13
|
+
componentsUsed: ['HoverCard', 'Icon', 'Layout', 'Link', 'Text'],
|
|
14
14
|
};
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
import {HoverCard} from '@astryxdesign/core/HoverCard';
|
|
6
6
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
7
7
|
import {VStack, HStack} from '@astryxdesign/core/Layout';
|
|
8
|
+
import {Link} from '@astryxdesign/core/Link';
|
|
8
9
|
import {Text} from '@astryxdesign/core/Text';
|
|
9
10
|
import {LinkIcon} from '@heroicons/react/24/outline';
|
|
10
11
|
|
|
11
12
|
export default function HoverCardInteractiveContent() {
|
|
12
13
|
return (
|
|
13
|
-
<Text type="body">
|
|
14
|
+
<Text type="body">
|
|
15
|
+
Read more in the{' '}
|
|
14
16
|
<HoverCard
|
|
15
17
|
placement="below"
|
|
16
18
|
content={
|
|
@@ -30,8 +32,11 @@ export default function HoverCardInteractiveContent() {
|
|
|
30
32
|
</HStack>
|
|
31
33
|
</VStack>
|
|
32
34
|
}>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
<Link href="#" hasUnderline>
|
|
36
|
+
Getting Started Guide
|
|
37
|
+
</Link>
|
|
38
|
+
</HoverCard>
|
|
39
|
+
.
|
|
40
|
+
</Text>
|
|
36
41
|
);
|
|
37
42
|
}
|
|
@@ -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: 'LinkProvider',
|
|
7
|
+
name: 'Link Provider — Custom Link Component',
|
|
8
|
+
displayName: 'Link Provider — Custom Link Component',
|
|
9
|
+
description:
|
|
10
|
+
'Routes every Astryx link through a custom component that intercepts the click, the hook frameworks like Next.js use for client-side navigation. Click the link to see the custom handler fire instead of a full-page load.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
aspectRatio: 4 / 3,
|
|
13
|
+
componentsUsed: ['LinkProvider', 'Link'],
|
|
14
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import type {AnchorHTMLAttributes} from 'react';
|
|
6
|
+
import {Link, LinkProvider} from '@astryxdesign/core/Link';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A stand-in for a framework router link (e.g. Next.js `Link` or React
|
|
10
|
+
* Router `Link`). Instead of letting the browser do a full-page navigation,
|
|
11
|
+
* it intercepts the click and hands the destination to a custom handler —
|
|
12
|
+
* the same hook real routers use for client-side navigation. Here it just
|
|
13
|
+
* announces the target so the behavior swap is observable in the preview.
|
|
14
|
+
*/
|
|
15
|
+
function RouterLink({
|
|
16
|
+
href,
|
|
17
|
+
onClick,
|
|
18
|
+
children,
|
|
19
|
+
...props
|
|
20
|
+
}: AnchorHTMLAttributes<HTMLAnchorElement>) {
|
|
21
|
+
return (
|
|
22
|
+
<a
|
|
23
|
+
href={href}
|
|
24
|
+
onClick={e => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
onClick?.(e);
|
|
27
|
+
alert(`RouterLink intercepted navigation to: ${href}`);
|
|
28
|
+
}}
|
|
29
|
+
{...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</a>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default function LinkProviderCustomLink() {
|
|
36
|
+
return (
|
|
37
|
+
<LinkProvider component={RouterLink}>
|
|
38
|
+
<Link href="/dashboard" isStandalone>
|
|
39
|
+
Go to dashboard
|
|
40
|
+
</Link>
|
|
41
|
+
</LinkProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
3
6
|
import {MultiSelector} from '@astryxdesign/core/MultiSelector';
|
|
4
7
|
|
|
5
8
|
export default function MultiSelectorShowcase() {
|
|
9
|
+
const [value, setValue] = useState<string[]>([]);
|
|
6
10
|
return (
|
|
7
11
|
<div style={{width: 300}}>
|
|
8
12
|
<MultiSelector
|
|
9
13
|
label="Columns"
|
|
10
14
|
options={['Name', 'Email', 'Role', 'Status', 'Created']}
|
|
11
|
-
value={
|
|
12
|
-
onChange={
|
|
15
|
+
value={value}
|
|
16
|
+
onChange={setValue}
|
|
13
17
|
placeholder="Select columns..."
|
|
14
18
|
/>
|
|
15
19
|
</div>
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
3
6
|
import {NumberInput} from '@astryxdesign/core/NumberInput';
|
|
4
7
|
|
|
5
8
|
export default function NumberInputShowcase() {
|
|
9
|
+
const [value, setValue] = useState<number | null>(0);
|
|
6
10
|
return (
|
|
7
11
|
<div style={{width: 300}}>
|
|
8
12
|
<NumberInput
|
|
9
13
|
label="Quantity"
|
|
10
14
|
placeholder="Enter quantity"
|
|
11
|
-
value={
|
|
12
|
-
onChange={
|
|
15
|
+
value={value}
|
|
16
|
+
onChange={setValue}
|
|
13
17
|
/>
|
|
14
18
|
</div>
|
|
15
19
|
);
|
|
@@ -0,0 +1,15 @@
|
|
|
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: 'Outline',
|
|
7
|
+
name: 'Outline',
|
|
8
|
+
displayName: 'Outline',
|
|
9
|
+
description:
|
|
10
|
+
'A document outline with the active section highlighted by the sliding indicator track.',
|
|
11
|
+
isReady: true,
|
|
12
|
+
aspectRatio: 16 / 9,
|
|
13
|
+
isShowcase: true,
|
|
14
|
+
componentsUsed: ['Outline'],
|
|
15
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {Outline} from '@astryxdesign/core/Outline';
|
|
6
|
+
import type {OutlineItem} from '@astryxdesign/core/Outline';
|
|
7
|
+
|
|
8
|
+
const items: OutlineItem[] = [
|
|
9
|
+
{id: 'showcase-overview', label: 'Overview', level: 2},
|
|
10
|
+
{id: 'showcase-installation', label: 'Installation', level: 2},
|
|
11
|
+
{id: 'showcase-theming', label: 'Theming', level: 2},
|
|
12
|
+
{id: 'showcase-tokens', label: 'Tokens', level: 3},
|
|
13
|
+
{id: 'showcase-accessibility', label: 'Accessibility', level: 2},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export default function OutlineShowcase() {
|
|
17
|
+
return (
|
|
18
|
+
<div style={{width: 240}}>
|
|
19
|
+
<Outline items={items} activeId="showcase-theming" />
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
3
6
|
import {RadioList, RadioListItem} from '@astryxdesign/core/RadioList';
|
|
4
7
|
|
|
5
8
|
export default function RadioListShowcase() {
|
|
9
|
+
const [value, setValue] = useState('');
|
|
6
10
|
return (
|
|
7
|
-
<RadioList
|
|
11
|
+
<RadioList
|
|
12
|
+
label="Notification preference"
|
|
13
|
+
value={value}
|
|
14
|
+
onChange={setValue}>
|
|
8
15
|
<RadioListItem label="Email" value="email" />
|
|
9
16
|
<RadioListItem label="SMS" value="sms" />
|
|
10
17
|
<RadioListItem label="Push notification" value="push" />
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {
|
|
6
7
|
SegmentedControl,
|
|
7
8
|
SegmentedControlItem,
|
|
8
9
|
} from '@astryxdesign/core/SegmentedControl';
|
|
9
10
|
|
|
10
11
|
export default function SegmentedControlShowcase() {
|
|
12
|
+
const [value, setValue] = useState('grid');
|
|
11
13
|
return (
|
|
12
|
-
<SegmentedControl value=
|
|
14
|
+
<SegmentedControl value={value} onChange={setValue} label="View mode">
|
|
13
15
|
<SegmentedControlItem value="grid" label="Grid" />
|
|
14
16
|
<SegmentedControlItem value="list" label="List" />
|
|
15
17
|
<SegmentedControlItem value="table" label="Table" />
|
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {Selector} from '@astryxdesign/core/Selector';
|
|
6
7
|
|
|
7
8
|
export default function SelectorShowcase() {
|
|
9
|
+
const [value, setValue] = useState<string | undefined>();
|
|
8
10
|
return (
|
|
9
11
|
<Selector
|
|
10
12
|
style={{width: 300}}
|
|
11
13
|
label="Fruit"
|
|
12
14
|
options={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}
|
|
13
15
|
placeholder="Select a fruit..."
|
|
14
|
-
|
|
16
|
+
value={value}
|
|
17
|
+
onChange={setValue}
|
|
15
18
|
/>
|
|
16
19
|
);
|
|
17
20
|
}
|
|
@@ -2,8 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {Slider} from '@astryxdesign/core/Slider';
|
|
6
7
|
|
|
7
8
|
export default function SliderShowcase() {
|
|
8
|
-
|
|
9
|
+
const [value, setValue] = useState(50);
|
|
10
|
+
return (
|
|
11
|
+
<Slider
|
|
12
|
+
label="Volume"
|
|
13
|
+
value={value}
|
|
14
|
+
onChange={setValue}
|
|
15
|
+
style={{width: 300}}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
9
18
|
}
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
6
7
|
import {Badge} from '@astryxdesign/core/Badge';
|
|
7
8
|
|
|
8
9
|
export default function TabShowcase() {
|
|
10
|
+
const [value, setValue] = useState('inbox');
|
|
9
11
|
return (
|
|
10
|
-
<TabList value=
|
|
12
|
+
<TabList value={value} onChange={setValue}>
|
|
11
13
|
<Tab
|
|
12
14
|
value="inbox"
|
|
13
15
|
label="Inbox"
|
|
@@ -0,0 +1,13 @@
|
|
|
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: 'Tab',
|
|
7
|
+
name: 'Tab — Selected Icon',
|
|
8
|
+
displayName: 'Tab — Selected Icon',
|
|
9
|
+
description: 'A tab that changes its icon when selected.',
|
|
10
|
+
isReady: true,
|
|
11
|
+
aspectRatio: 4 / 3,
|
|
12
|
+
componentsUsed: ['TabList', 'Tab'],
|
|
13
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {useState} from 'react';
|
|
6
|
+
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
7
|
+
|
|
8
|
+
const StarIcon = (
|
|
9
|
+
<svg
|
|
10
|
+
viewBox="0 0 16 16"
|
|
11
|
+
fill="none"
|
|
12
|
+
stroke="currentColor"
|
|
13
|
+
width="100%"
|
|
14
|
+
height="100%">
|
|
15
|
+
<path d="m8 1.5 2 4.1 4.5.7-3.3 3.2.8 4.5-4-2.1L4 14l.8-4.5-3.3-3.2 4.5-.7L8 1.5Z" />
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const SelectedStarIcon = (
|
|
20
|
+
<svg viewBox="0 0 16 16" fill="currentColor" width="100%" height="100%">
|
|
21
|
+
<path d="m8 1.5 2 4.1 4.5.7-3.3 3.2.8 4.5-4-2.1L4 14l.8-4.5-3.3-3.2 4.5-.7L8 1.5Z" />
|
|
22
|
+
</svg>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export default function TabWithSelectedIcon() {
|
|
26
|
+
const [value, setValue] = useState('favorites');
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<TabList value={value} onChange={setValue}>
|
|
30
|
+
<Tab
|
|
31
|
+
value="favorites"
|
|
32
|
+
label="Favorites"
|
|
33
|
+
icon={StarIcon}
|
|
34
|
+
selectedIcon={SelectedStarIcon}
|
|
35
|
+
/>
|
|
36
|
+
<Tab value="recent" label="Recent" />
|
|
37
|
+
</TabList>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
6
7
|
|
|
7
8
|
export default function TabListShowcase() {
|
|
9
|
+
const [value, setValue] = useState('home');
|
|
8
10
|
return (
|
|
9
|
-
<TabList value=
|
|
11
|
+
<TabList value={value} onChange={setValue}>
|
|
10
12
|
<Tab value="home" label="Home" />
|
|
11
13
|
<Tab value="projects" label="Projects" />
|
|
12
14
|
<Tab value="settings" label="Settings" />
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import {useState} from 'react';
|
|
5
6
|
import {TabList, Tab, TabMenu} from '@astryxdesign/core/TabList';
|
|
6
7
|
|
|
7
8
|
export default function TabMenuShowcase() {
|
|
9
|
+
const [value, setValue] = useState('settings');
|
|
8
10
|
return (
|
|
9
|
-
<TabList value=
|
|
11
|
+
<TabList value={value} onChange={setValue}>
|
|
10
12
|
<Tab value="overview" label="Overview" />
|
|
11
13
|
<Tab value="activity" label="Activity" />
|
|
12
14
|
<TabMenu
|