@astryxdesign/cli 0.7.2-canary.db3a2e7 → 0.7.2-canary.e26723d
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/README.md +7 -7
- package/api/build/help/help.mjs +1 -1
- package/api/component/_adapter.d.mts +41 -1
- package/api/component/_adapter.mjs +93 -7
- package/api/component/component.mjs +22 -5
- package/api/component/component.test.mjs +420 -167
- package/api/component/integration-export-name.test.mjs +644 -0
- package/api/component/list/list.mjs +42 -4
- package/api/docs/_adapter.mjs +207 -1
- package/api/docs/integrationDocs.test.mjs +124 -0
- package/api/doctor/theme-checks.mjs +1 -1
- package/api/gap-report/gap-report.mjs +67 -4
- package/api/init/run/run.mjs +2 -2
- package/api/integration/_adapter.d.mts +12 -0
- package/api/integration/_adapter.mjs +54 -0
- package/api/integration/add-contribution.component-names.test.mjs +66 -0
- package/api/integration/add-contribution.mjs +7 -3
- package/api/integration/authoring-checks.mjs +11 -2
- package/api/integration/authoring-checks.test.mjs +39 -0
- package/api/integration/authoring-checks.type.d.mts +9 -0
- package/api/integration/authoring-checks.type.mjs +14 -1
- package/api/integration/integrationComponentConflicts.doc.mjs +21 -5
- package/api/integration/pack-check.mjs +61 -107
- package/api/integration/pack-check.test.mjs +359 -0
- package/api/integration/validate-integration.test.mjs +11 -0
- package/api/search/search.d.mts +9 -0
- package/api/search/search.mjs +108 -16
- package/api/search/search.test.mjs +36 -0
- package/api/swizzle/copy/copy.mjs +28 -14
- package/api/template/template.test.mjs +120 -3
- package/api/theme/build/build.family.test.mjs +16 -0
- package/api/theme/build/build.mjs +81 -22
- package/api/theme/themeBuild.doc.mjs +3 -3
- package/assets/codemods/transforms/next/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
- package/assets/codemods/transforms/next/index.mjs +11 -1
- package/assets/codemods/transforms/next/migrate-list-edge-compensation-to-edge.mjs +198 -0
- package/assets/docs/README.md +10 -0
- package/assets/docs/author-a-theme.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +3 -3
- package/assets/docs/theme.doc.dense.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/theme.doc.zh.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +10 -0
- package/assets/docs/tree/check-the-props.doc.mjs +145 -0
- package/assets/docs/tree/checks.doc.mjs +4 -4
- package/assets/docs/tree/component-family.doc.mjs +5 -1
- package/assets/docs/tree/component-imports.doc.mjs +8 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/links.doc.mjs +2 -2
- package/assets/docs/tree/single-component.doc.mjs +3 -2
- package/assets/docs/tree/troubleshooting.doc.mjs +9 -1
- package/assets/docs/tree/type-scale.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +1 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +2 -1
- package/assets/docs/use-a-theme.doc.mjs +2 -2
- package/assets/docs/working-with-ai.doc.mjs +43 -4
- package/assets/templates/blocks/components/Drawer/DrawerForm.doc.mjs +24 -0
- package/assets/templates/blocks/components/Drawer/DrawerForm.tsx +62 -0
- package/assets/templates/blocks/components/Drawer/DrawerScrim.doc.mjs +22 -0
- package/assets/templates/blocks/components/Drawer/DrawerScrim.tsx +68 -0
- package/assets/templates/blocks/components/Drawer/DrawerShowcase.doc.mjs +22 -0
- package/assets/templates/blocks/components/Drawer/DrawerShowcase.tsx +41 -0
- package/assets/templates/blocks/components/Drawer/DrawerStart.doc.mjs +21 -0
- package/assets/templates/blocks/components/Drawer/DrawerStart.tsx +41 -0
- package/assets/templates/blocks/components/Drawer/DrawerWidths.doc.mjs +22 -0
- package/assets/templates/blocks/components/Drawer/DrawerWidths.tsx +54 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderShowcase.doc.mjs +15 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderShowcase.tsx +73 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderSubtitleEndContent.doc.mjs +22 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderSubtitleEndContent.tsx +49 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderWithCloseButton.doc.mjs +21 -0
- package/assets/templates/blocks/components/DrawerHeader/DrawerHeaderWithCloseButton.tsx +42 -0
- package/assets/templates/pages/detail-page/page.tsx +3 -3
- package/assets/templates/pages/table-inbox/page.tsx +10 -8
- package/assets/theme.template.ts +1 -1
- package/authoring/doctypes/base/type.ts +6 -0
- package/authoring/doctypes/component/component.doc.mjs +4 -4
- package/authoring/doctypes/component/type.ts +6 -3
- package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
- package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
- package/authoring/doctypes/template/parse.d.mts +6 -2
- package/authoring/doctypes/template/parse.mjs +3 -1
- package/authoring/doctypes/template/type.ts +22 -0
- package/authoring/index.d.ts +1 -0
- package/authoring/integration/integration.doc.mjs +8 -1
- package/authoring/integration/parse.test.mjs +10 -0
- package/authoring/integration/schema.d.mts +2 -0
- package/authoring/integration/schema.mjs +1 -0
- package/authoring/integration/type.ts +4 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +3 -1
- package/clients/cli/commands/build-theme.mjs +1 -1
- package/clients/cli/commands/build-theme.path-safety.test.mjs +84 -0
- package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
- package/clients/cli/commands/doctor-integration-components.doc.mjs +9 -3
- package/clients/cli/commands/doctor-integration.test.mjs +392 -0
- package/clients/cli/commands/doctor.mjs +74 -0
- package/clients/cli/commands/theme-build.doc.mjs +2 -2
- package/clients/cli/lib/component-format.mjs +5 -1
- package/foundation/config/project.mjs +82 -0
- package/foundation/discovery/authoring-self-docs.mjs +1 -0
- package/foundation/discovery/component-discovery.d.mts +190 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +864 -56
- package/foundation/discovery/component-discovery.test.mjs +96 -0
- package/foundation/discovery/component-replacement.mjs +18 -0
- package/foundation/discovery/component-replacement.test.mjs +40 -0
- package/foundation/discovery/doc-types.d.mts +157 -0
- package/foundation/discovery/doc-types.mjs +1224 -0
- package/foundation/discovery/doc-types.test.mjs +652 -0
- package/foundation/discovery/docs-discovery.d.mts +81 -0
- package/foundation/discovery/docs-discovery.mjs +57 -0
- package/foundation/discovery/module-exports.d.mts +27 -0
- package/foundation/discovery/module-exports.mjs +356 -31
- package/foundation/discovery/module-exports.test.mjs +172 -0
- package/foundation/discovery/package-tsconfig.d.mts +14 -0
- package/foundation/discovery/package-tsconfig.mjs +228 -0
- package/foundation/discovery/package-tsconfig.test.mjs +210 -0
- package/foundation/discovery/project-typescript.d.mts +23 -0
- package/foundation/discovery/project-typescript.mjs +61 -0
- package/foundation/discovery/prop-drift.d.mts +220 -0
- package/foundation/discovery/prop-drift.mjs +1765 -0
- package/foundation/discovery/prop-drift.test.mjs +1197 -0
- package/foundation/discovery/template-adapter.mjs +74 -5
- package/foundation/discovery/type-match.d.mts +53 -0
- package/foundation/discovery/type-match.mjs +660 -0
- package/foundation/discovery/type-match.test.mjs +169 -0
- package/foundation/discovery/type-text.d.mts +68 -0
- package/foundation/discovery/type-text.mjs +658 -0
- package/foundation/discovery/type-text.test.mjs +196 -0
- package/foundation/discovery/unresolved-references.d.mts +62 -0
- package/foundation/discovery/unresolved-references.mjs +790 -0
- package/foundation/discovery/unresolved-references.test.mjs +567 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +9 -1
- package/foundation/doc-compiler/inputs.mjs +23 -0
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/links.d.mts +9 -5
- package/foundation/doc-compiler/links.mjs +4 -2
- package/foundation/integrations/contribution-inventory.mjs +6 -1
- package/foundation/response/response-types.doc.mjs +1 -1
- package/foundation/xle/registry.mjs +4 -0
- package/foundation/xle/registry.test.mjs +28 -0
- package/package.json +10 -10
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Codemod: migrate List edgeCompensation to edge
|
|
5
|
+
*
|
|
6
|
+
* `edgeCompensation="inline"` on an imported `List` becomes `edge="outset"`,
|
|
7
|
+
* the value it already resolves to. List resolves
|
|
8
|
+
* `edge ?? (edgeCompensation === 'inline' ? 'outset' : 'padded')`, so `edge`
|
|
9
|
+
* wins only when it has a value. The deprecated prop is removed beside an
|
|
10
|
+
* `edge` string that no later spread can override; beside a computed `edge`,
|
|
11
|
+
* which may be undefined at runtime, it gets a TODO instead.
|
|
12
|
+
*
|
|
13
|
+
* Built on the shared `transformProp` helper, so it does not follow
|
|
14
|
+
* variables, helpers, wrappers, or types. Where a List writes
|
|
15
|
+
* `edgeCompensation` but the codemod cannot prove the result, it keeps the
|
|
16
|
+
* old prop and leaves a TODO instead of guessing: on a dynamic value, and
|
|
17
|
+
* wherever the List also spreads props. A spread before the old prop may
|
|
18
|
+
* carry an `edge` that wins today and that a new `edge` would override; one
|
|
19
|
+
* after it may override either prop. A spread onto a List that never writes
|
|
20
|
+
* `edgeCompensation` is not evidence of use, so it stays unchanged
|
|
21
|
+
* (`spec:AST-040` FR1): the deprecated prop keeps working through it, and
|
|
22
|
+
* its `@deprecated` type reports a typed use where the props are written.
|
|
23
|
+
* Comments are the codemod's only report channel (`api.report` is a stub),
|
|
24
|
+
* and each is added once, so a second run changes nothing.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import {transformProp} from '../../transform-prop.mjs';
|
|
28
|
+
|
|
29
|
+
export const meta = {
|
|
30
|
+
title: 'Migrate List edgeCompensation to edge',
|
|
31
|
+
description:
|
|
32
|
+
'Renames `edgeCompensation="inline"` to `edge="outset"` on List, and ' +
|
|
33
|
+
'drops `edgeCompensation` beside an `edge` string. Keeps the old prop ' +
|
|
34
|
+
'with a TODO where `edge` is computed or a later spread may override ' +
|
|
35
|
+
'it, on a dynamic value, and where the List also spreads props; the ' +
|
|
36
|
+
'deprecated prop still works there.',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const OLD_NAME = 'edgeCompensation';
|
|
40
|
+
const NEW_NAME = 'edge';
|
|
41
|
+
const CORE_IMPORT_RE = /^@(astryxdesign|xds)\/core(?:\/|$)/;
|
|
42
|
+
|
|
43
|
+
const COMPONENT_PROPS = new Map([['List', new Set([OLD_NAME])]]);
|
|
44
|
+
|
|
45
|
+
const DYNAMIC_COMMENT =
|
|
46
|
+
' TODO(astryx upgrade): edgeCompensation is deprecated. Replace ' +
|
|
47
|
+
'edgeCompensation="inline" with edge="outset" by hand; this value is ' +
|
|
48
|
+
'computed. ';
|
|
49
|
+
const BOTH_SET_COMMENT =
|
|
50
|
+
' TODO(astryx upgrade): edgeCompensation is deprecated. edge is also set ' +
|
|
51
|
+
'here, but it may be undefined, and then edgeCompensation still applies. ' +
|
|
52
|
+
'Make edge default to "outset" where edgeCompensation is "inline", then ' +
|
|
53
|
+
'remove edgeCompensation. ';
|
|
54
|
+
const SPREAD_COMMENT =
|
|
55
|
+
' TODO(astryx upgrade): edgeCompensation is deprecated, but this List ' +
|
|
56
|
+
'also spreads props that may set edge, so it was left unchanged. Replace ' +
|
|
57
|
+
'edgeCompensation="inline" with edge="outset" by hand, after checking ' +
|
|
58
|
+
'which edge the spread passes. ';
|
|
59
|
+
|
|
60
|
+
const TYPE_WRAPPERS = new Set([
|
|
61
|
+
'TSAsExpression',
|
|
62
|
+
'TSSatisfiesExpression',
|
|
63
|
+
'TSTypeAssertion',
|
|
64
|
+
'TSNonNullExpression',
|
|
65
|
+
'TypeCastExpression',
|
|
66
|
+
'ParenthesizedExpression',
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
/** @param {any} node */
|
|
70
|
+
function unwrap(node) {
|
|
71
|
+
let current = node;
|
|
72
|
+
while (current && TYPE_WRAPPERS.has(current.type)) {
|
|
73
|
+
current = current.expression;
|
|
74
|
+
}
|
|
75
|
+
return current;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** @param {any} node */
|
|
79
|
+
function isStringLiteral(node) {
|
|
80
|
+
const value = unwrap(node);
|
|
81
|
+
return (
|
|
82
|
+
value != null &&
|
|
83
|
+
(value.type === 'StringLiteral' || value.type === 'Literal') &&
|
|
84
|
+
typeof value.value === 'string'
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The value of a JSX attribute: the string of `edge="flush"`, or the
|
|
90
|
+
* expression inside `edge={...}`.
|
|
91
|
+
* @param {any} attribute
|
|
92
|
+
*/
|
|
93
|
+
function attributeValue(attribute) {
|
|
94
|
+
return attribute.value?.type === 'JSXExpressionContainer'
|
|
95
|
+
? attribute.value.expression
|
|
96
|
+
: attribute.value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** @param {any} node */
|
|
100
|
+
function isInlineLiteral(node) {
|
|
101
|
+
const value = unwrap(node);
|
|
102
|
+
return (
|
|
103
|
+
value != null &&
|
|
104
|
+
(value.type === 'StringLiteral' || value.type === 'Literal') &&
|
|
105
|
+
value.value === 'inline'
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Attach a comment to a node once, so re-running the codemod adds nothing.
|
|
111
|
+
* @param {any} j @param {any} node @param {string} text
|
|
112
|
+
*/
|
|
113
|
+
function addComment(j, node, text) {
|
|
114
|
+
node.comments ??= [];
|
|
115
|
+
if (node.comments.some((/** @type {any} */ c) => c.value === text)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
node.comments.push(j.commentBlock(text, true, false));
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** @param {any} attributes */
|
|
123
|
+
function firstSpread(attributes) {
|
|
124
|
+
return attributes.find(
|
|
125
|
+
(/** @type {any} */ attribute) => attribute.type === 'JSXSpreadAttribute',
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @param {import('../../../../authoring/codemod/type').AstryxCodemodFile} file
|
|
131
|
+
* @param {import('../../../../authoring/codemod/type').CodemodTransformApi} api
|
|
132
|
+
* @returns {string | null | undefined}
|
|
133
|
+
*/
|
|
134
|
+
export default function transformer(file, api) {
|
|
135
|
+
const j = api.jscodeshift;
|
|
136
|
+
const root = j(file.source);
|
|
137
|
+
let hasChanges = false;
|
|
138
|
+
|
|
139
|
+
transformProp(
|
|
140
|
+
root,
|
|
141
|
+
j,
|
|
142
|
+
{
|
|
143
|
+
matchesImport: source => CORE_IMPORT_RE.test(source),
|
|
144
|
+
components: COMPONENT_PROPS,
|
|
145
|
+
},
|
|
146
|
+
propPath => {
|
|
147
|
+
const opening = propPath.parent?.node;
|
|
148
|
+
const attributes = opening?.attributes ?? [];
|
|
149
|
+
const prop = propPath.node;
|
|
150
|
+
const edgeIndex = attributes.findIndex(
|
|
151
|
+
(/** @type {any} */ attribute) =>
|
|
152
|
+
attribute.type === 'JSXAttribute' &&
|
|
153
|
+
attribute.name?.name === NEW_NAME,
|
|
154
|
+
);
|
|
155
|
+
if (edgeIndex !== -1) {
|
|
156
|
+
// `edge` wins only when it has a value. A string that no later
|
|
157
|
+
// spread can override always does, so the old prop is inert and
|
|
158
|
+
// removing it changes nothing. A computed `edge` may be undefined,
|
|
159
|
+
// and then the old prop still decides.
|
|
160
|
+
const isProven =
|
|
161
|
+
isStringLiteral(attributeValue(attributes[edgeIndex])) &&
|
|
162
|
+
!attributes
|
|
163
|
+
.slice(edgeIndex + 1)
|
|
164
|
+
.some(
|
|
165
|
+
(/** @type {any} */ attribute) =>
|
|
166
|
+
attribute.type === 'JSXSpreadAttribute',
|
|
167
|
+
);
|
|
168
|
+
if (isProven) {
|
|
169
|
+
opening.attributes = attributes.filter(
|
|
170
|
+
(/** @type {any} */ attribute) => attribute !== prop,
|
|
171
|
+
);
|
|
172
|
+
hasChanges = true;
|
|
173
|
+
} else {
|
|
174
|
+
hasChanges = addComment(j, prop, BOTH_SET_COMMENT) || hasChanges;
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// With a spread on the element the rename cannot be proven: a spread
|
|
179
|
+
// before the old prop may carry an `edge` that wins today and that a
|
|
180
|
+
// new `edge` would override, and one after it may override either
|
|
181
|
+
// prop. The old prop keeps working, so it stays, with a TODO.
|
|
182
|
+
if (firstSpread(attributes)) {
|
|
183
|
+
hasChanges = addComment(j, prop, SPREAD_COMMENT) || hasChanges;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (isInlineLiteral(attributeValue(prop))) {
|
|
187
|
+
prop.name.name = NEW_NAME;
|
|
188
|
+
prop.value = j.stringLiteral('outset');
|
|
189
|
+
hasChanges = true;
|
|
190
|
+
} else {
|
|
191
|
+
hasChanges = addComment(j, prop, DYNAMIC_COMMENT) || hasChanges;
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (!hasChanges) return undefined;
|
|
197
|
+
return root.toSource({quote: 'single'});
|
|
198
|
+
}
|
package/assets/docs/README.md
CHANGED
|
@@ -51,6 +51,16 @@ The material is usually good; the finding is placement, not quality. It goes in
|
|
|
51
51
|
|
|
52
52
|
Worked example: a responsive-and-interaction readiness rubric is grading criteria → **Component-Audit-Rubric**, or **Component-Lifecycle** if it is a promotion gate.
|
|
53
53
|
|
|
54
|
+
## Imports in code samples
|
|
55
|
+
|
|
56
|
+
Import each Core export from the path `astryx component <Name>` prints: the
|
|
57
|
+
component's own entry when Core has one (`@astryxdesign/core/VStack`,
|
|
58
|
+
`@astryxdesign/core/Heading`), and `@astryxdesign/core/theme` for `Theme`,
|
|
59
|
+
`defineTheme` and the rest of the theme API. A reader copies one sample and then
|
|
60
|
+
reads `astryx component`, and two paths for one export read as two different
|
|
61
|
+
things. The no-build CDN page is the exception: its import map names only the
|
|
62
|
+
package root.
|
|
63
|
+
|
|
54
64
|
## Sections are read one at a time
|
|
55
65
|
|
|
56
66
|
`astryx docs <topic> --index` lists a topic's sections, and readers then open
|
|
@@ -120,7 +120,7 @@ export const docs = {
|
|
|
120
120
|
['ocean.variants.d.ts', "(Optional) Module augmentations for custom component prop values"],
|
|
121
121
|
]},
|
|
122
122
|
{type: 'prose', text: 'The `__built: true` flag tells Theme to skip runtime `<style>` injection; the CSS file handles it. Load the generated CSS wherever you load the module.'},
|
|
123
|
-
{type: 'code', lang: 'tsx', label: 'Using a custom built theme', code: "import {Theme} from '@astryxdesign/core';\nimport {oceanTheme} from './themes/ocean';\nimport './themes/ocean.css';\n\n<Theme theme={oceanTheme}>\n <App />\n</Theme>"},
|
|
123
|
+
{type: 'code', lang: 'tsx', label: 'Using a custom built theme', code: "import {Theme} from '@astryxdesign/core/theme';\nimport {oceanTheme} from './themes/ocean';\nimport './themes/ocean.css';\n\n<Theme theme={oceanTheme}>\n <App />\n</Theme>"},
|
|
124
124
|
{type: 'prose', text: "After upgrading Astryx, rerun `astryx theme build` for every custom prebuilt theme. Deploy the regenerated files together. The runtime intentionally trusts `__built: true` and will not repair stale CSS from an older build. The build also warns when the theme names font families it does not load. See {@link generic:font-setup} for the full recipe."},
|
|
125
125
|
{type: 'prose', text: 'For the runtime vs built tradeoff, see the Runtime vs Built section of {@link generic:use-a-theme}.'},
|
|
126
126
|
],
|
|
@@ -86,7 +86,7 @@ export const docs = {
|
|
|
86
86
|
type: 'code',
|
|
87
87
|
lang: 'tsx',
|
|
88
88
|
label: 'App root',
|
|
89
|
-
code: `import {Theme} from '@astryxdesign/core';
|
|
89
|
+
code: `import {Theme} from '@astryxdesign/core/theme';
|
|
90
90
|
import {themes, defaultThemeSlug} from './astryx-themes';
|
|
91
91
|
|
|
92
92
|
<Theme theme={themes[defaultThemeSlug]}><App /></Theme>`,
|
|
@@ -119,14 +119,14 @@ import {themes, defaultThemeSlug} from './astryx-themes';
|
|
|
119
119
|
content: [
|
|
120
120
|
{
|
|
121
121
|
type: 'prose',
|
|
122
|
-
text: '
|
|
122
|
+
text: 'Import each component from its own entry, the path `astryx component <Name>` prints. This keeps bundles small and makes intent clear.',
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
type: 'code',
|
|
126
126
|
lang: 'tsx',
|
|
127
127
|
label: 'app/page.tsx',
|
|
128
128
|
code: `import {Button} from '@astryxdesign/core/Button';
|
|
129
|
-
import {VStack} from '@astryxdesign/core/
|
|
129
|
+
import {VStack} from '@astryxdesign/core/VStack';
|
|
130
130
|
|
|
131
131
|
export default function Page() {
|
|
132
132
|
return (
|
|
@@ -9,7 +9,7 @@ export const docsDense = {
|
|
|
9
9
|
section: 'Wrap your app in a theme',
|
|
10
10
|
title: 'Quick start',
|
|
11
11
|
content: [
|
|
12
|
-
{type: 'prose', text: "Install a theme, wrap in `<Theme>` (`import {Theme} from '@astryxdesign/core'`). {@link generic:use-a-theme} for full guide."},
|
|
12
|
+
{type: 'prose', text: "Install a theme, wrap in `<Theme>` (`import {Theme} from '@astryxdesign/core/theme'`). {@link generic:use-a-theme} for full guide."},
|
|
13
13
|
],
|
|
14
14
|
},
|
|
15
15
|
{
|
|
@@ -23,7 +23,7 @@ export const docs = {
|
|
|
23
23
|
type: 'code',
|
|
24
24
|
lang: 'tsx',
|
|
25
25
|
label: 'Wire the generated module once',
|
|
26
|
-
code: "import {Theme} from '@astryxdesign/core';\nimport {themes, defaultThemeSlug} from './astryx-themes';\n\nfunction App() {\n return (\n <Theme theme={themes[defaultThemeSlug]}>\n <YourApp />\n </Theme>\n );\n}",
|
|
26
|
+
code: "import {Theme} from '@astryxdesign/core/theme';\nimport {themes, defaultThemeSlug} from './astryx-themes';\n\nfunction App() {\n return (\n <Theme theme={themes[defaultThemeSlug]}>\n <YourApp />\n </Theme>\n );\n}",
|
|
27
27
|
},
|
|
28
28
|
],
|
|
29
29
|
},
|
|
@@ -11,7 +11,7 @@ export const docsZh = {
|
|
|
11
11
|
content: [
|
|
12
12
|
{
|
|
13
13
|
type: 'prose',
|
|
14
|
-
text: "安装主题包,用 `<Theme>`(`import {Theme} from '@astryxdesign/core'`)包裹应用,选择浅色或深色模式。完整指南——可用主题、集成主题、深色模式、嵌套主题和生产构建——请参阅 {@link generic:use-a-theme}。",
|
|
14
|
+
text: "安装主题包,用 `<Theme>`(`import {Theme} from '@astryxdesign/core/theme'`)包裹应用,选择浅色或深色模式。完整指南——可用主题、集成主题、深色模式、嵌套主题和生产构建——请参阅 {@link generic:use-a-theme}。",
|
|
15
15
|
},
|
|
16
16
|
],
|
|
17
17
|
},
|
|
@@ -71,5 +71,15 @@ Declare component root ./components in astryx.integration.mjs.
|
|
|
71
71
|
},
|
|
72
72
|
],
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
id: 'document-an-existing-component',
|
|
76
|
+
title: 'Document a component you already have',
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: 'prose',
|
|
80
|
+
text: "To document a component your package already has, write its doc beside the source file and name the doc after that file, such as `acme-gallery.doc.mjs` beside `acme-gallery.tsx`. Set `name` to the export apps import, such as `name: 'AcmeGallery'`, and keep both files inside the components root that `astryx.integration.mjs` declares. The file does not have to be named after the component; {@link generic:component-imports} shows how apps then find it.",
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
74
84
|
],
|
|
75
85
|
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/components/describe-the-component/check-the-props`:
|
|
5
|
+
* compare each component doc's props table with the component's TypeScript
|
|
6
|
+
* props, read each finding, and fix the doc or the code.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
10
|
+
export const docs = {
|
|
11
|
+
type: 'generic',
|
|
12
|
+
name: 'check-the-props',
|
|
13
|
+
placement: {
|
|
14
|
+
parent: 'namespace:describe-the-component',
|
|
15
|
+
slot: 'guides',
|
|
16
|
+
order: 50,
|
|
17
|
+
},
|
|
18
|
+
title: 'Check the props table',
|
|
19
|
+
category: 'guide',
|
|
20
|
+
keywords: [
|
|
21
|
+
'props table',
|
|
22
|
+
'documented props',
|
|
23
|
+
'prop drift',
|
|
24
|
+
'props not compared',
|
|
25
|
+
],
|
|
26
|
+
description:
|
|
27
|
+
"Compare each props table with the component's TypeScript props, then fix the doc or the code.",
|
|
28
|
+
sections: [
|
|
29
|
+
{
|
|
30
|
+
id: 'run-the-props-check',
|
|
31
|
+
title: 'Run the props check',
|
|
32
|
+
content: [
|
|
33
|
+
{
|
|
34
|
+
type: 'prose',
|
|
35
|
+
text: "`doctor integration components` compares every props table in your component docs, hidden docs and every family entry included, with the props the component's TypeScript declares. Run it in your package after you change a component or its doc.",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'code',
|
|
39
|
+
lang: 'bash',
|
|
40
|
+
code: 'npx astryx doctor integration components',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'code',
|
|
44
|
+
lang: 'text',
|
|
45
|
+
code: `severity: [warn]
|
|
46
|
+
component: AcmeCarousel
|
|
47
|
+
prop: loop
|
|
48
|
+
kind: not_in_code
|
|
49
|
+
message: "loop" is documented, but AcmeCarousel's props have no "loop".
|
|
50
|
+
doc: components/AcmeCarousel.doc.mjs
|
|
51
|
+
source: components/AcmeCarousel.tsx
|
|
52
|
+
docType: boolean
|
|
53
|
+
|
|
54
|
+
1 prop(s) differ between the docs and the code in 1 of 1 component(s) compared (TypeScript 6.0.3). These are warnings: update the doc, or the code if the doc is right.`,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'list',
|
|
58
|
+
style: 'unordered',
|
|
59
|
+
items: [
|
|
60
|
+
"A doc's own `props` describe the export its `name` names. In a family doc, each entry describes its own export. A hook entry documents parameters and returns, so it is not compared.",
|
|
61
|
+
"It reads props with the `typescript` your package installs, and reads your package's `tsconfig.json` the way `tsc -p` does. Without TypeScript it prints `[skip] Props not compared` and the reason.",
|
|
62
|
+
'Every finding is a warning, so the exit code stays 0. Read them before you publish. With `--json`, they are in `data.propDrift.findings`.',
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'fix-each-finding',
|
|
69
|
+
title: 'Fix each finding',
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'prose',
|
|
73
|
+
text: "Each finding's `kind` says what differs. Fix the doc, or the code if the doc is right.",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'table',
|
|
77
|
+
headers: ['Kind', 'Means', 'Fix'],
|
|
78
|
+
rows: [
|
|
79
|
+
[
|
|
80
|
+
'`not_in_code`',
|
|
81
|
+
"The doc lists a prop the component's props do not have",
|
|
82
|
+
'Remove it from the doc, or add it to the code. A name an index signature takes, such as `data-*`, counts as present',
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
'`not_in_doc`',
|
|
86
|
+
"Your package declares a prop the doc does not list, or builds one with a mapped type, such as `Partial<Record<'sm' | 'md', string>>`",
|
|
87
|
+
'Document it. Props from React, the DOM, or another package are never asked for, and neither are props whose keys another package defines (`keyof CSSProperties`, behind an alias or not), `className`, `style`, `xstyle`, `data-testid`, `ref`, `key`, or a prop whose JSDoc has `@internal`. A deprecated prop is still a prop: document it until you remove it. A prop a mapped type builds from keys the check cannot trace (a template literal, say) is listed under `[info] Props not checked for a doc entry` instead',
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
'`required_mismatch`',
|
|
91
|
+
'`required` disagrees with the code',
|
|
92
|
+
'Set `required: true` exactly when every caller must pass the prop. One your `defaultProps` fills counts as optional, as it is to JSX callers, and so does one only some members of a union require, since a caller can leave it out: say in its description which variants need it. An entry that names several props (`value / onChange`) makes the same claim about each: give them separate entries when they differ',
|
|
93
|
+
],
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'when-a-component-is-not-compared',
|
|
100
|
+
title: 'When a component is not compared',
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: 'prose',
|
|
104
|
+
text: "When the check cannot read a component's props exactly, it lists the component under `[info] Props not compared`, with the reason, instead of reporting findings that might be wrong.",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'code',
|
|
108
|
+
lang: 'text',
|
|
109
|
+
code: `[info] Props not compared for 1 documented component(s):
|
|
110
|
+
|
|
111
|
+
component: AcmeCarousel
|
|
112
|
+
doc: components/AcmeCarousel.doc.mjs
|
|
113
|
+
reason: AcmeCarousel depends on \`@acme/motion\` (imported in AcmeCarousel.tsx), which the compiler could not resolve, usually a dependency that is not installed. Install the package's dependencies and run this check again`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
type: 'table',
|
|
117
|
+
headers: ['Reason', 'Fix'],
|
|
118
|
+
rows: [
|
|
119
|
+
[
|
|
120
|
+
'It depends on a package or file the compiler could not resolve',
|
|
121
|
+
"Install the package's dependencies, then run the check again",
|
|
122
|
+
],
|
|
123
|
+
[
|
|
124
|
+
"It depends on a type the compiler can't work out",
|
|
125
|
+
'Make the types compile with `npx tsc --noEmit`, then run the check again',
|
|
126
|
+
],
|
|
127
|
+
[
|
|
128
|
+
"The package's TypeScript config has an error",
|
|
129
|
+
'Fix `tsconfig.json` until `npx tsc -p .` reads it',
|
|
130
|
+
],
|
|
131
|
+
['Its props are typed `any`', 'Give the component a props type'],
|
|
132
|
+
[
|
|
133
|
+
'Some prop names come from a type parameter',
|
|
134
|
+
'Nothing to fix: a component that renders an element the caller picks takes props known only where it is used',
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
"The file has no export named by the doc's `name`",
|
|
138
|
+
'Change `name` or the export so they agree',
|
|
139
|
+
],
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
@@ -36,9 +36,9 @@ export const docs = {
|
|
|
36
36
|
],
|
|
37
37
|
[
|
|
38
38
|
'`npx astryx doctor integration components`',
|
|
39
|
-
|
|
39
|
+
"No component name clashes with a Core component, each `replaces` names one Core component, and each component doc's props match the component's TypeScript props",
|
|
40
40
|
'Core is not installed (`core_not_found`). In a package that declares the CLI range that turns replacement on, a `replaces` target is missing (`missing_component_replacement_target`) or invalid (`invalid_component_replacement`), or two components replace one Core component (`ambiguous_component_replacement`)',
|
|
41
|
-
'A name clashes with Core,
|
|
41
|
+
'A name clashes with Core, a component sets `replaces` in a package without that range (`inactive_component_replacement`, plus any missing, invalid, or duplicate `replaces` reported as a warning), or a documented prop differs from the code: it is missing there (`not_in_code`), the doc omits a prop the package declares (`not_in_doc`), or its `required` disagrees (`required_mismatch`). It reads props with your installed `typescript`; without it, it prints `[skip] Props not compared`',
|
|
42
42
|
],
|
|
43
43
|
[
|
|
44
44
|
'`npx astryx doctor integration templates`',
|
|
@@ -62,7 +62,7 @@ export const docs = {
|
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
type: 'prose',
|
|
65
|
-
text: 'Pass a package name, such as `npx astryx doctor integration validate @acme/astryx-widgets`, to check an installed copy from an app instead.',
|
|
65
|
+
text: 'Pass a package name, such as `npx astryx doctor integration validate @acme/astryx-widgets`, to check an installed copy from an app instead. To fix a props finding, see {@link generic:check-the-props}.',
|
|
66
66
|
},
|
|
67
67
|
],
|
|
68
68
|
},
|
|
@@ -105,7 +105,7 @@ export const docs = {
|
|
|
105
105
|
'It runs `npm pack` the way `npm publish` would, including your `prepack` script.',
|
|
106
106
|
'It checks that every contribution file is in the `.tgz` file. A root missing from `files` fails with `Add "templates" to "files" in package.json.`',
|
|
107
107
|
'It lists the components, templates, themes, docs, and codemods the temporary app sees, and compares them with your source.',
|
|
108
|
-
"It resolves each component's `import`, and each template's public import, the way Node does, and checks that the module exports the component, or a default export for a template.",
|
|
108
|
+
"It resolves each component's `import`, and each template's public import, the way Node does, and checks that the module exports the component under the name its doc documents, or a default export for a template. A type-only export does not count.",
|
|
109
109
|
'For each theme, it rebuilds the source, compares the built module and production CSS with the authored outputs, and proves the module, CSS, and optional font CSS exports resolve from the packed package.',
|
|
110
110
|
'It fails a package that needs an `@astryxdesign/cli` peer and lacks it: `>=0.6.6` for a template that sets `keywords`, and `>=0.6.4` for a template that sets `replaces`, a docs section, a placed guide, a doc section with an `id`, or a theme.',
|
|
111
111
|
],
|
|
@@ -95,7 +95,11 @@ export default {
|
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
97
|
type: 'prose',
|
|
98
|
-
text:
|
|
98
|
+
text: "The public module named by `import` must export every component or hook named by a full entry. Apps then list, search and open each component in the family by its own name. A full entry the module does not export is not listed, and `integration verify` does not report it: check the family with `astryx component --list`. When `import` names output your pack lifecycle builds (such as `dist`), the members are listed once that output exists, and `integration verify` compares them as they are listed after the pack builds it.",
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: 'prose',
|
|
102
|
+
text: "A member's source is the `.tsx` file in the family doc's folder, or below it, that declares it: the one the family's own file or the module `import` names reaches, else the one in that folder that declares the name, as when `import` names built output. A member that only a bundle or a file outside that folder declares is still listed, with no source for `--source` or `swizzle`. A member is not listed when a doc's file or a Core name your package replaces already has its name. A member that shares a name with Core opens with `--package`.",
|
|
99
103
|
},
|
|
100
104
|
],
|
|
101
105
|
},
|
|
@@ -35,6 +35,14 @@ export const docs = {
|
|
|
35
35
|
type: 'prose',
|
|
36
36
|
text: 'Add writes the entry only when package.json already has an `exports` map, so start every package with `"exports": {}`.',
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
type: 'prose',
|
|
40
|
+
text: 'A file does not have to be named after its component. When `Slides.tsx` exports `AcmeCarousel` and nothing named `Slides`, keep the doc beside it as `Slides.doc.mjs` and set its `name` to `AcmeCarousel`: apps list, search and open the component by that name, and `integration verify` checks that its import exports `AcmeCarousel`. A file that exports its own name keeps that name. A package that names its files in kebab case works the same way: `acme-gallery.doc.mjs` beside `acme-gallery.tsx` sets `name: \'AcmeGallery\'`.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'prose',
|
|
44
|
+
text: "The file name still opens the doc. A name that Core or another doc's file already has stays theirs, and so does a Core name your package replaces: with `Badge.doc.mjs` naming `AcmeBadge`, `astryx component Badge` opens Core's `Badge`, and `--package` with your package name reaches yours.",
|
|
45
|
+
},
|
|
38
46
|
],
|
|
39
47
|
},
|
|
40
48
|
{
|
|
@@ -37,7 +37,7 @@ export const docs = {
|
|
|
37
37
|
items: [
|
|
38
38
|
'Change the source and its `.doc.mjs` together.',
|
|
39
39
|
'Update the doc whenever the public name, import, behavior, props, defaults, examples, or accessibility requirements change.',
|
|
40
|
-
'`integration verify` checks the doc shape and packed import,
|
|
40
|
+
'`integration verify` checks the doc shape and packed import, and `doctor integration components` compares each props table with the component\'s TypeScript props ({@link generic:check-the-props}). Neither can prove the prose still matches the component.',
|
|
41
41
|
],
|
|
42
42
|
},
|
|
43
43
|
{
|
|
@@ -36,8 +36,8 @@ export const docs = {
|
|
|
36
36
|
type: 'list',
|
|
37
37
|
style: 'unordered',
|
|
38
38
|
items: [
|
|
39
|
-
'The kind is `generic` for a topic or guide, `namespace` for a docs section,
|
|
40
|
-
'
|
|
39
|
+
'The kind is `generic` for a topic or guide, `namespace` for a docs section, `command` or `function` for a CLI command or API function, `component` for a component, and `page` or `block` for a template.',
|
|
40
|
+
'Name a component by its export name and a template by its id. Its link reads as the command that opens it, such as `astryx component AcmeCarousel --package @acme/widgets`.',
|
|
41
41
|
'Inside backticks or a code block, link syntax prints as written.',
|
|
42
42
|
],
|
|
43
43
|
},
|
|
@@ -56,7 +56,7 @@ export default {
|
|
|
56
56
|
style: 'unordered',
|
|
57
57
|
items: [
|
|
58
58
|
'Keep `props` on the top-level doc. Private implementation helpers do not need entries.',
|
|
59
|
-
'
|
|
59
|
+
'Name the doc after the source file beside it, such as `AcmeCarousel.doc.mjs` beside `AcmeCarousel.tsx`, and change both in the same pull request.',
|
|
60
60
|
'If the module later exposes several related public exports, adapt this doc with {@link generic:component-family}.',
|
|
61
61
|
],
|
|
62
62
|
},
|
|
@@ -122,6 +122,7 @@ export default {
|
|
|
122
122
|
'Set `required: true` only when every caller must pass the prop.',
|
|
123
123
|
'Write `default` exactly as the value should appear in documentation.',
|
|
124
124
|
'Skip styling escape hatches such as `xstyle`, `className`, and `style`.',
|
|
125
|
+
'`npx astryx doctor integration components` lists a documented prop the code lacks, a public prop the doc misses, and a wrong `required`. See {@link generic:check-the-props}.',
|
|
125
126
|
],
|
|
126
127
|
},
|
|
127
128
|
],
|
|
@@ -157,7 +158,7 @@ export default {
|
|
|
157
158
|
{
|
|
158
159
|
type: 'code',
|
|
159
160
|
lang: 'bash',
|
|
160
|
-
code: 'npx astryx component AcmeCarousel\nnpx astryx integration verify',
|
|
161
|
+
code: 'npx astryx component AcmeCarousel\nnpx astryx doctor integration components\nnpx astryx integration verify',
|
|
161
162
|
},
|
|
162
163
|
],
|
|
163
164
|
},
|
|
@@ -67,7 +67,7 @@ export const docs = {
|
|
|
67
67
|
rows: [
|
|
68
68
|
[
|
|
69
69
|
'`component_export_missing`: `Component "AcmeCarousel" advertises import "@acme/astryx-widgets/components/AcmeCarousel", but that packed module does not export "AcmeCarousel".`',
|
|
70
|
-
"package.json has no `exports` map, or the module does not export the name. Keep `export function AcmeCarousel`, and add the entry: `npm pkg set 'exports[./components/AcmeCarousel]=./components/AcmeCarousel.tsx'`.",
|
|
70
|
+
"package.json has no `exports` map, or the module does not export the name. Keep `export function AcmeCarousel`, and add the entry: `npm pkg set 'exports[./components/AcmeCarousel]=./components/AcmeCarousel.tsx'`. When the quoted name is a file name, such as `acme-carousel`, set the doc's `name` to the component the file exports. A type-only export does not count.",
|
|
71
71
|
],
|
|
72
72
|
[
|
|
73
73
|
'`template_export_missing`: `Template "acme-dashboard" public import "@acme/astryx-widgets/templates/acme-dashboard" does not have a default export.`',
|
|
@@ -125,6 +125,14 @@ export const docs = {
|
|
|
125
125
|
type: 'table',
|
|
126
126
|
headers: ['Symptom', 'Fix'],
|
|
127
127
|
rows: [
|
|
128
|
+
[
|
|
129
|
+
'`Error: No component named "AcmeCarousel"` for a component your package documents.',
|
|
130
|
+
"Its doc still names its file. Set `name` to the export, such as `name: 'AcmeCarousel'` in `acme-carousel.doc.mjs`. A family member is listed only when the module its family doc imports exports it ({@link generic:component-family}).",
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
'`npx astryx component Dialog` opens Core\'s `Dialog`, not yours.',
|
|
134
|
+
"A name that Core, a legacy docs package, or another package's file already has stays theirs. Run `npx astryx component Dialog --package @acme/astryx-widgets`, or give your component a name of its own.",
|
|
135
|
+
],
|
|
128
136
|
[
|
|
129
137
|
'`Error: Template "dashboard" is ambiguous — narrow it with --type and/or --package.`',
|
|
130
138
|
"Your template id matches a Core id. Rename it, such as `acme-dashboard`, or set `replaces: 'dashboard'` to take its place. `npx astryx doctor integration templates` warns about this before you publish.",
|
|
@@ -76,7 +76,7 @@ export const docs = {
|
|
|
76
76
|
type: 'code',
|
|
77
77
|
lang: 'tsx',
|
|
78
78
|
label: 'Heading for document structure',
|
|
79
|
-
code: `import {Heading} from '@astryxdesign/core';
|
|
79
|
+
code: `import {Heading} from '@astryxdesign/core/Heading';
|
|
80
80
|
|
|
81
81
|
// Heading levels map to semantic tokens: level 1 → --text-heading-1-*
|
|
82
82
|
<Heading level={1}>Page Title</Heading>
|
|
@@ -96,7 +96,7 @@ export const docs = {
|
|
|
96
96
|
type: 'code',
|
|
97
97
|
lang: 'tsx',
|
|
98
98
|
label: 'Text for body, label, and display text',
|
|
99
|
-
code: `import {Text} from '@astryxdesign/core';
|
|
99
|
+
code: `import {Text} from '@astryxdesign/core/Text';
|
|
100
100
|
|
|
101
101
|
<Text type="body">Body text at the base scale.</Text>
|
|
102
102
|
<Text type="large">Emphasized body text.</Text>
|
|
@@ -121,7 +121,7 @@ export const docs = {
|
|
|
121
121
|
type: 'code',
|
|
122
122
|
lang: 'tsx',
|
|
123
123
|
label: 'Customizing the type scale via defineTheme',
|
|
124
|
-
code: `import {defineTheme} from '@astryxdesign/core';
|
|
124
|
+
code: `import {defineTheme} from '@astryxdesign/core/theme';
|
|
125
125
|
|
|
126
126
|
// Adjust the entire ramp holistically with base and ratio
|
|
127
127
|
const editorialTheme = defineTheme({
|
|
@@ -140,6 +140,7 @@ export const docs = {
|
|
|
140
140
|
'Published 0.6.3 and earlier reject a template that sets `replaces` or `keywords`, drop that template, and hide every doc topic your package ships. Published 0.6.4 and 0.6.5 still drop a template that sets `keywords`.',
|
|
141
141
|
'A stable CLI before 0.6.4 cannot read a docs section, a section `id`, or a theme folder that `integration add theme` writes. It can then hide every doc topic your package ships.',
|
|
142
142
|
'Stable 0.6.3 still loads your components, but 0.6.0 cannot read the component docs that `integration add component` writes: `component AcmeCarousel` fails there.',
|
|
143
|
+
'An app on an older CLI lists a component whose doc names another export of its file under the file name, and lists no family members, so `component AcmeCarousel` fails there.',
|
|
143
144
|
],
|
|
144
145
|
},
|
|
145
146
|
{
|
|
@@ -91,8 +91,9 @@ npx astryx template acme-stat-card src/features/account/StatusCard.tsx`,
|
|
|
91
91
|
lang: 'tsx',
|
|
92
92
|
code: `import {Button} from '@astryxdesign/core/Button';
|
|
93
93
|
import {Card} from '@astryxdesign/core/Card';
|
|
94
|
-
import {HStack
|
|
94
|
+
import {HStack} from '@astryxdesign/core/HStack';
|
|
95
95
|
import {Text} from '@astryxdesign/core/Text';
|
|
96
|
+
import {VStack} from '@astryxdesign/core/VStack';
|
|
96
97
|
import {AcmeStatusCard} from '@acme/astryx-widgets/components/AcmeStatusCard';
|
|
97
98
|
|
|
98
99
|
const metrics = [
|