@astryxdesign/cli 0.1.6-canary.eb23da7 → 0.1.6-canary.eba4f34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -13
- package/src/api/template.mjs +27 -103
- package/src/api/validate-integration.mjs +8 -0
- package/src/lib/component-discovery.mjs +5 -15
- package/src/lib/component-loader.mjs +0 -53
- package/src/lib/config-schema.mjs +30 -0
- package/src/lib/xle/registry.mjs +5 -0
- package/templates/blocks/components/Avatar/AvatarGroup.tsx +7 -5
- package/templates/blocks/components/Avatar/AvatarShowcase.tsx +6 -4
- package/templates/blocks/components/Avatar/AvatarUserCard.tsx +5 -3
- package/templates/blocks/components/Avatar/AvatarWithImage.tsx +6 -8
- package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +5 -3
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputControlledInput.tsx +1 -1
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputDisabled.tsx +1 -1
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputMentionTrigger.tsx +1 -1
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputMultipleTriggers.tsx +1 -1
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputShowcase.tsx +1 -1
- package/templates/blocks/components/ChatComposerInput/ChatComposerInputSlashCommands.tsx +1 -1
- package/templates/pages/theme-showcase/page.tsx +7 -7
- package/templates/themes/neutral/neutralTheme.ts +32 -63
- package/docs/integration-authoring.md +0 -105
- package/docs/internationalization.doc.mjs +0 -243
- package/src/api/integration-block-exports.test.mjs +0 -240
- package/src/api/template-suffix.test.mjs +0 -246
- package/src/doc.mjs +0 -271
- package/src/doc.test.mjs +0 -383
- package/src/lib/component-discovery.importpath.test.mjs +0 -59
- package/src/types/doc.d.ts +0 -139
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenLiveRegion.doc.mjs +0 -14
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenLiveRegion.tsx +0 -41
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenShowcase.doc.mjs +0 -13
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenShowcase.tsx +0 -78
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenStructuralHeading.doc.mjs +0 -14
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenStructuralHeading.tsx +0 -38
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenSupplementaryContext.doc.mjs +0 -14
- package/templates/blocks/components/VisuallyHidden/VisuallyHiddenSupplementaryContext.tsx +0 -47
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Verifies that `.ts`-authored sources (hooks and other functions) are
|
|
5
|
-
* found by `findComponentSource`, so `resolveImportPath` derives a
|
|
6
|
-
* tree-shakeable subpath instead of falling back to the bare package root.
|
|
7
|
-
*
|
|
8
|
-
* Runs against the real packages/core source, not mocks.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import {describe, it, expect} from 'vitest';
|
|
12
|
-
import {
|
|
13
|
-
findComponentSource,
|
|
14
|
-
resolveImportPath,
|
|
15
|
-
} from './component-discovery.mjs';
|
|
16
|
-
import {findCoreDir} from '../utils/paths.mjs';
|
|
17
|
-
|
|
18
|
-
describe('findComponentSource resolves .ts-authored sources', () => {
|
|
19
|
-
const coreDir = findCoreDir();
|
|
20
|
-
|
|
21
|
-
it('finds a hook authored as a .ts file (not just .tsx)', () => {
|
|
22
|
-
const src = findComponentSource(coreDir, 'useMediaQuery');
|
|
23
|
-
expect(src).toBeTruthy();
|
|
24
|
-
expect(src.endsWith('useMediaQuery.ts')).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('still finds a component authored as .tsx', () => {
|
|
28
|
-
const src = findComponentSource(coreDir, 'Button');
|
|
29
|
-
expect(src).toBeTruthy();
|
|
30
|
-
expect(src.endsWith('.tsx')).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('resolveImportPath reproduces authored hook importPaths', () => {
|
|
35
|
-
const coreDir = findCoreDir();
|
|
36
|
-
|
|
37
|
-
// Representative sample of core hooks whose sources are `.ts` files. Before
|
|
38
|
-
// the `.ts` fix these fell back to bare `@astryxdesign/core`; the derived
|
|
39
|
-
// subpath must now match the value each hook's doc currently authors.
|
|
40
|
-
const cases = [
|
|
41
|
-
['useMediaQuery', '@astryxdesign/core/hooks'],
|
|
42
|
-
['useResizable', '@astryxdesign/core/Resizable'],
|
|
43
|
-
['useTheme', '@astryxdesign/core/theme'],
|
|
44
|
-
['useFocusTrap', '@astryxdesign/core/hooks'],
|
|
45
|
-
['useOverflow', '@astryxdesign/core/hooks'],
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
for (const [name, expected] of cases) {
|
|
49
|
-
it(`${name} derives ${expected}`, () => {
|
|
50
|
-
expect(resolveImportPath(coreDir, name)).toBe(expected);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
it('never falls back to the bare package root for a .ts hook', () => {
|
|
55
|
-
for (const [name] of cases) {
|
|
56
|
-
expect(resolveImportPath(coreDir, name)).not.toBe('@astryxdesign/core');
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
});
|
package/src/types/doc.d.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Authoring surface for Astryx docs, exported from `@astryxdesign/cli/doc`.
|
|
5
|
-
*
|
|
6
|
-
* A doc lives in a `{Name}.doc.{ts,mjs,js}` file. Authors default-export a
|
|
7
|
-
* factory result (`createComponentDoc`/`createFunctionDoc`/`createDoc`) —
|
|
8
|
-
* preferred — or, for the current loose docs, name-export `docs`. The doc's
|
|
9
|
-
* shape is validated at the load boundary against `ComponentDocSchema` (see
|
|
10
|
-
* `doc.mjs`), which accepts BOTH the new stamped formats and the legacy loose
|
|
11
|
-
* shape.
|
|
12
|
-
*
|
|
13
|
-
* The factories inject the `type` discriminant, so authors never write it. The
|
|
14
|
-
* inputs are kept as broad records so authoring never fails to typecheck when a
|
|
15
|
-
* richer core type surface is not resolvable; the precise per-field guidance
|
|
16
|
-
* lives on the doc types in `@astryxdesign/core/docs-types`.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Fields shared by every doc kind (component + function + generic).
|
|
21
|
-
*
|
|
22
|
-
* `group` vs `parent` are distinct:
|
|
23
|
-
* - `group` is a FLAT sidebar bucket label; many docs can share it and it is
|
|
24
|
-
* NOT an inheritance key.
|
|
25
|
-
* - `parent` is a DIRECTED inheritance/composition pointer — a doc naming the
|
|
26
|
-
* doc it belongs to (e.g. a sub-component naming its parent component). The
|
|
27
|
-
* legacy `subComponentOf` field is a synonym.
|
|
28
|
-
*
|
|
29
|
-
* `relatedDocs` is a single flat curated cross-reference list; it replaces the
|
|
30
|
-
* legacy split `relatedComponents` + `relatedHooks`.
|
|
31
|
-
*/
|
|
32
|
-
export interface AstryxBaseDocInput {
|
|
33
|
-
/** Name of the documented unit, without any prefix, PascalCase. Required. */
|
|
34
|
-
name: string;
|
|
35
|
-
/** Human-readable display name for gallery/sidebar. */
|
|
36
|
-
displayName?: string;
|
|
37
|
-
/** Short description. */
|
|
38
|
-
description?: string;
|
|
39
|
-
/** Usage documentation (description, best practices, anatomy, slotElements). */
|
|
40
|
-
usage?: unknown;
|
|
41
|
-
/** Flat sidebar grouping label (not an inheritance key). */
|
|
42
|
-
group?: string;
|
|
43
|
-
/** Overview-page functional category. */
|
|
44
|
-
category?: string;
|
|
45
|
-
/** CLI fuzzy-search keywords. */
|
|
46
|
-
keywords?: string[];
|
|
47
|
-
/** Directed inheritance/composition pointer to the doc this belongs to. */
|
|
48
|
-
parent?: string;
|
|
49
|
-
/** Flat curated cross-reference list of related doc names. */
|
|
50
|
-
relatedDocs?: string[];
|
|
51
|
-
/** Hide the whole doc from human-facing UI (stays importable/discoverable). */
|
|
52
|
-
hidden?: boolean;
|
|
53
|
-
/** Exclude from the categorized overview page (kept in sidebar/CLI). */
|
|
54
|
-
isHiddenFromOverview?: boolean;
|
|
55
|
-
/** Any additional fields the rich doc surface carries. */
|
|
56
|
-
[key: string]: unknown;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** A single documented prop (mirrors `PropDoc` from core docs-types). */
|
|
60
|
-
export interface AstryxPropInput {
|
|
61
|
-
name: string;
|
|
62
|
-
type: string;
|
|
63
|
-
description: string;
|
|
64
|
-
default?: string;
|
|
65
|
-
required?: boolean;
|
|
66
|
-
[key: string]: unknown;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** A single documented param (mirrors `HookParamDoc`). */
|
|
70
|
-
export interface AstryxParamInput {
|
|
71
|
-
name: string;
|
|
72
|
-
type: string;
|
|
73
|
-
description: string;
|
|
74
|
-
default?: string;
|
|
75
|
-
required?: boolean;
|
|
76
|
-
[key: string]: unknown;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** A single documented return field (mirrors `HookReturnDoc`). */
|
|
80
|
-
export interface AstryxReturnInput {
|
|
81
|
-
name: string;
|
|
82
|
-
type: string;
|
|
83
|
-
description: string;
|
|
84
|
-
[key: string]: unknown;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Input accepted by {@link createComponentDoc}. A component (or a family). The
|
|
89
|
-
* `type` discriminant is injected by the factory. `anatomy`/`slotElements` live
|
|
90
|
-
* inside `usage`; `importPath` is DERIVED (never authored).
|
|
91
|
-
*/
|
|
92
|
-
export interface AstryxComponentDocInput extends AstryxBaseDocInput {
|
|
93
|
-
/** All public props for the component. */
|
|
94
|
-
props: AstryxPropInput[];
|
|
95
|
-
/** Theming/selector-surface metadata. */
|
|
96
|
-
theming?: unknown;
|
|
97
|
-
/** Interactive-preview playground configuration. */
|
|
98
|
-
playground?: unknown;
|
|
99
|
-
/** Short code examples rendered after the props table. */
|
|
100
|
-
examples?: unknown[];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Input accepted by {@link createFunctionDoc}. Covers any function, including
|
|
105
|
-
* hooks: an inputs (`params`) + outputs (`returns`) surface. The `type`
|
|
106
|
-
* discriminant is injected by the factory; `importPath` is DERIVED.
|
|
107
|
-
*/
|
|
108
|
-
export interface AstryxFunctionDocInput extends AstryxBaseDocInput {
|
|
109
|
-
/** Function/hook parameters or options-object fields. */
|
|
110
|
-
params: AstryxParamInput[];
|
|
111
|
-
/** Return value documentation. One entry per field (or a single primitive). */
|
|
112
|
-
returns: AstryxReturnInput[];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Input accepted by {@link createDoc}. A generic reference/topic doc — just the
|
|
117
|
-
* shared base. The `type` discriminant is injected by the factory.
|
|
118
|
-
*/
|
|
119
|
-
export type AstryxGenericDocInput = AstryxBaseDocInput;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Back-compat alias. Previously `createDoc` accepted a broad component-doc
|
|
123
|
-
* record; the union of the three input kinds preserves that permissiveness for
|
|
124
|
-
* any code referring to the old name.
|
|
125
|
-
*/
|
|
126
|
-
export type AstryxComponentDoc =
|
|
127
|
-
AstryxComponentDocInput | AstryxFunctionDocInput | AstryxGenericDocInput;
|
|
128
|
-
|
|
129
|
-
export declare function createComponentDoc<T extends AstryxComponentDocInput>(
|
|
130
|
-
def: T,
|
|
131
|
-
): T & {type: 'component'};
|
|
132
|
-
|
|
133
|
-
export declare function createFunctionDoc<T extends AstryxFunctionDocInput>(
|
|
134
|
-
def: T,
|
|
135
|
-
): T & {type: 'function'};
|
|
136
|
-
|
|
137
|
-
export declare function createDoc<T extends AstryxGenericDocInput>(
|
|
138
|
-
def: T,
|
|
139
|
-
): T & {type: 'generic'};
|
|
@@ -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: 'VisuallyHidden',
|
|
7
|
-
name: 'VisuallyHidden — Live Region',
|
|
8
|
-
displayName: 'VisuallyHidden — Live Region',
|
|
9
|
-
description:
|
|
10
|
-
'A polite aria-live region announces visual-only state changes to assistive technology.',
|
|
11
|
-
isReady: true,
|
|
12
|
-
aspectRatio: 4 / 3,
|
|
13
|
-
componentsUsed: ['VisuallyHidden', 'Button', 'HStack', 'VStack', 'Text'],
|
|
14
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
'use client';
|
|
4
|
-
|
|
5
|
-
import {useState} from 'react';
|
|
6
|
-
import {VisuallyHidden} from '@astryxdesign/core/VisuallyHidden';
|
|
7
|
-
import {Button} from '@astryxdesign/core/Button';
|
|
8
|
-
import {HStack, VStack} from '@astryxdesign/core/Layout';
|
|
9
|
-
import {Text} from '@astryxdesign/core/Text';
|
|
10
|
-
|
|
11
|
-
const columns = ['Backlog', 'In progress', 'Done'] as const;
|
|
12
|
-
|
|
13
|
-
export default function VisuallyHiddenLiveRegion() {
|
|
14
|
-
const [column, setColumn] = useState(0);
|
|
15
|
-
const current = columns[column];
|
|
16
|
-
|
|
17
|
-
function move() {
|
|
18
|
-
setColumn(c => (c + 1) % columns.length);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<VStack gap={4} hAlign="start">
|
|
23
|
-
<Text type="supporting" color="secondary">
|
|
24
|
-
Drag-and-drop and other visual-only changes are silent to screen
|
|
25
|
-
readers. A live region narrates them.
|
|
26
|
-
</Text>
|
|
27
|
-
<HStack gap={3} vAlign="center">
|
|
28
|
-
<Button label="Move task" variant="secondary" onClick={move} />
|
|
29
|
-
<Text type="body">
|
|
30
|
-
Task is in{' '}
|
|
31
|
-
<Text as="span" weight="bold">
|
|
32
|
-
{current}
|
|
33
|
-
</Text>
|
|
34
|
-
</Text>
|
|
35
|
-
</HStack>
|
|
36
|
-
<VisuallyHidden as="div" aria-live="polite">
|
|
37
|
-
{`Task moved to ${current}`}
|
|
38
|
-
</VisuallyHidden>
|
|
39
|
-
</VStack>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,13 +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: 'VisuallyHidden',
|
|
7
|
-
name: 'VisuallyHidden',
|
|
8
|
-
displayName: 'VisuallyHidden',
|
|
9
|
-
isReady: true,
|
|
10
|
-
aspectRatio: 16 / 9,
|
|
11
|
-
isShowcase: true,
|
|
12
|
-
componentsUsed: ['VisuallyHidden', 'IconButton', 'Card', 'HStack', 'VStack', 'Text', 'Icon'],
|
|
13
|
-
};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
'use client';
|
|
4
|
-
|
|
5
|
-
import {VisuallyHidden} from '@astryxdesign/core/VisuallyHidden';
|
|
6
|
-
import {IconButton} from '@astryxdesign/core/IconButton';
|
|
7
|
-
import {Card} from '@astryxdesign/core/Card';
|
|
8
|
-
import {HStack, VStack} from '@astryxdesign/core/Layout';
|
|
9
|
-
import {Text} from '@astryxdesign/core/Text';
|
|
10
|
-
import {Icon} from '@astryxdesign/core/Icon';
|
|
11
|
-
import {
|
|
12
|
-
ArrowDownTrayIcon,
|
|
13
|
-
ShareIcon,
|
|
14
|
-
TrashIcon,
|
|
15
|
-
} from '@heroicons/react/24/outline';
|
|
16
|
-
import {SpeakerWaveIcon} from '@heroicons/react/24/solid';
|
|
17
|
-
|
|
18
|
-
const actions = [
|
|
19
|
-
{label: 'Download', icon: ArrowDownTrayIcon},
|
|
20
|
-
{label: 'Share', icon: ShareIcon},
|
|
21
|
-
{label: 'Delete', icon: TrashIcon},
|
|
22
|
-
] as const;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* VisuallyHidden is invisible by design, so this hero teaches the concept by
|
|
26
|
-
* contrast: the icon-only buttons are all a sighted user sees, while the
|
|
27
|
-
* caption spells out the accessible name each one exposes. A live
|
|
28
|
-
* <VisuallyHidden> region below announces the same names to assistive tech,
|
|
29
|
-
* so the demo genuinely exercises the component it documents.
|
|
30
|
-
*/
|
|
31
|
-
export default function VisuallyHiddenShowcase() {
|
|
32
|
-
return (
|
|
33
|
-
<VStack gap={5} hAlign="center">
|
|
34
|
-
<HStack gap={6} vAlign="stretch" wrap="wrap" hAlign="center">
|
|
35
|
-
<Card variant="muted">
|
|
36
|
-
<VStack gap={4} hAlign="center">
|
|
37
|
-
<Text type="supporting" color="secondary">
|
|
38
|
-
What you see
|
|
39
|
-
</Text>
|
|
40
|
-
<HStack gap={2}>
|
|
41
|
-
{actions.map(({label, icon}) => (
|
|
42
|
-
<IconButton
|
|
43
|
-
key={label}
|
|
44
|
-
label={label}
|
|
45
|
-
icon={<Icon icon={icon} />}
|
|
46
|
-
variant="ghost"
|
|
47
|
-
/>
|
|
48
|
-
))}
|
|
49
|
-
</HStack>
|
|
50
|
-
</VStack>
|
|
51
|
-
</Card>
|
|
52
|
-
|
|
53
|
-
<Card variant="muted">
|
|
54
|
-
<VStack gap={4} hAlign="start">
|
|
55
|
-
<HStack gap={2} vAlign="center">
|
|
56
|
-
<Icon icon={SpeakerWaveIcon} size="sm" />
|
|
57
|
-
<Text type="supporting" color="secondary">
|
|
58
|
-
What a screen reader hears
|
|
59
|
-
</Text>
|
|
60
|
-
</HStack>
|
|
61
|
-
<VStack gap={2}>
|
|
62
|
-
{actions.map(({label}) => (
|
|
63
|
-
<Text key={label} type="body">
|
|
64
|
-
{label}, button
|
|
65
|
-
</Text>
|
|
66
|
-
))}
|
|
67
|
-
</VStack>
|
|
68
|
-
</VStack>
|
|
69
|
-
</Card>
|
|
70
|
-
</HStack>
|
|
71
|
-
|
|
72
|
-
{/* A real live region: silent to sighted users, announced by AT. */}
|
|
73
|
-
<VisuallyHidden as="div" aria-live="polite">
|
|
74
|
-
Actions available: Download, Share, Delete.
|
|
75
|
-
</VisuallyHidden>
|
|
76
|
-
</VStack>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
@@ -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: 'VisuallyHidden',
|
|
7
|
-
name: 'VisuallyHidden — Structural Heading',
|
|
8
|
-
displayName: 'VisuallyHidden — Structural Heading',
|
|
9
|
-
description:
|
|
10
|
-
'Give a visually implicit section an accessible name so screen-reader users can navigate to it.',
|
|
11
|
-
isReady: true,
|
|
12
|
-
aspectRatio: 4 / 3,
|
|
13
|
-
componentsUsed: ['VisuallyHidden', 'Card', 'HStack', 'VStack', 'Text', 'Badge'],
|
|
14
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
'use client';
|
|
4
|
-
|
|
5
|
-
import {VisuallyHidden} from '@astryxdesign/core/VisuallyHidden';
|
|
6
|
-
import {Card} from '@astryxdesign/core/Card';
|
|
7
|
-
import {HStack, VStack} from '@astryxdesign/core/Layout';
|
|
8
|
-
import {Text} from '@astryxdesign/core/Text';
|
|
9
|
-
import {Badge} from '@astryxdesign/core/Badge';
|
|
10
|
-
|
|
11
|
-
const items = [
|
|
12
|
-
{name: 'astryx-core', status: 'Passing', variant: 'success'},
|
|
13
|
-
{name: 'astryx-charts', status: 'Failing', variant: 'error'},
|
|
14
|
-
{name: 'astryx-cli', status: 'Passing', variant: 'success'},
|
|
15
|
-
] as const;
|
|
16
|
-
|
|
17
|
-
export default function VisuallyHiddenStructuralHeading() {
|
|
18
|
-
return (
|
|
19
|
-
<VStack gap={3} hAlign="start">
|
|
20
|
-
<Text type="supporting" color="secondary">
|
|
21
|
-
The layout makes this group obvious to sighted users. A hidden heading
|
|
22
|
-
gives screen-reader users the same landmark to jump to.
|
|
23
|
-
</Text>
|
|
24
|
-
{/* No visible heading is needed here, but AT users navigate by heading. */}
|
|
25
|
-
<VisuallyHidden as="h2">Build status</VisuallyHidden>
|
|
26
|
-
<VStack gap={2}>
|
|
27
|
-
{items.map(({name, status, variant}) => (
|
|
28
|
-
<Card key={name} variant="muted" padding={3}>
|
|
29
|
-
<HStack gap={3} vAlign="center">
|
|
30
|
-
<Text type="body">{name}</Text>
|
|
31
|
-
<Badge label={status} variant={variant} />
|
|
32
|
-
</HStack>
|
|
33
|
-
</Card>
|
|
34
|
-
))}
|
|
35
|
-
</VStack>
|
|
36
|
-
</VStack>
|
|
37
|
-
);
|
|
38
|
-
}
|
package/templates/blocks/components/VisuallyHidden/VisuallyHiddenSupplementaryContext.doc.mjs
DELETED
|
@@ -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: 'VisuallyHidden',
|
|
7
|
-
name: 'VisuallyHidden — Supplementary Context',
|
|
8
|
-
displayName: 'VisuallyHidden — Supplementary Context',
|
|
9
|
-
description:
|
|
10
|
-
'Add screen-reader-only context to terse visual data, like spelling out what a trend arrow means.',
|
|
11
|
-
isReady: true,
|
|
12
|
-
aspectRatio: 4 / 3,
|
|
13
|
-
componentsUsed: ['VisuallyHidden', 'Card', 'HStack', 'VStack', 'Text', 'Icon'],
|
|
14
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
'use client';
|
|
4
|
-
|
|
5
|
-
import {VisuallyHidden} from '@astryxdesign/core/VisuallyHidden';
|
|
6
|
-
import {Card} from '@astryxdesign/core/Card';
|
|
7
|
-
import {HStack, VStack} from '@astryxdesign/core/Layout';
|
|
8
|
-
import {Text} from '@astryxdesign/core/Text';
|
|
9
|
-
import {Icon} from '@astryxdesign/core/Icon';
|
|
10
|
-
import {ArrowUpIcon, ArrowDownIcon} from '@heroicons/react/24/solid';
|
|
11
|
-
|
|
12
|
-
const stats = [
|
|
13
|
-
{label: 'Revenue', value: '$48.2k', delta: '+12%', direction: 'up'},
|
|
14
|
-
{label: 'Churn', value: '2.1%', delta: '-4%', direction: 'down'},
|
|
15
|
-
] as const;
|
|
16
|
-
|
|
17
|
-
export default function VisuallyHiddenSupplementaryContext() {
|
|
18
|
-
return (
|
|
19
|
-
<HStack gap={4} wrap="wrap">
|
|
20
|
-
{stats.map(({label, value, delta, direction}) => (
|
|
21
|
-
<Card key={label} variant="muted">
|
|
22
|
-
<VStack gap={1}>
|
|
23
|
-
<Text type="supporting" color="secondary">
|
|
24
|
-
{label}
|
|
25
|
-
</Text>
|
|
26
|
-
<Text type="display-3">{value}</Text>
|
|
27
|
-
<HStack gap={1} vAlign="center">
|
|
28
|
-
<Icon
|
|
29
|
-
icon={direction === 'up' ? ArrowUpIcon : ArrowDownIcon}
|
|
30
|
-
size="sm"
|
|
31
|
-
color={direction === 'up' ? 'accent' : 'secondary'}
|
|
32
|
-
/>
|
|
33
|
-
<Text type="body">
|
|
34
|
-
{delta}
|
|
35
|
-
{/* The arrow is decorative; spell out the trend for AT. */}
|
|
36
|
-
<VisuallyHidden>
|
|
37
|
-
{direction === 'up' ? ' increase' : ' decrease'} from last
|
|
38
|
-
month
|
|
39
|
-
</VisuallyHidden>
|
|
40
|
-
</Text>
|
|
41
|
-
</HStack>
|
|
42
|
-
</VStack>
|
|
43
|
-
</Card>
|
|
44
|
-
))}
|
|
45
|
-
</HStack>
|
|
46
|
-
);
|
|
47
|
-
}
|