@astryxdesign/cli 0.1.2-canary.1a4d5c5 → 0.1.2-canary.1ba0e77
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 +1 -0
- package/README.md +55 -49
- package/package.json +7 -7
- package/src/api/doctor.mjs +3 -3
- package/src/codemods/transforms/{v0.1.0 → v0.0.15}/drop-xds-prefix-imports.mjs +4 -15
- package/src/codemods/transforms/v0.0.15/index.mjs +13 -0
- package/src/codemods/transforms/v0.1.0/index.mjs +0 -46
- package/src/commands/agent-docs.mjs +1 -1
- package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +1 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +1 -0
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +4 -9
- package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +1 -0
- package/templates/pages/shell-side-nav/page.tsx +1 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -67
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -61
- package/src/codemods/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -104
- package/src/codemods/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +0 -77
- package/src/codemods/transforms/v0.1.0/migrate-xds-declare-module.mjs +0 -78
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.doc.mjs +0 -14
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.tsx +0 -46
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.doc.mjs +0 -14
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.tsx +0 -52
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.doc.mjs +0 -14
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.tsx +0 -43
- /package/src/codemods/transforms/{v0.1.0 → v0.0.15}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -62,7 +62,8 @@ Options:
|
|
|
62
62
|
| `upgrade` | Run codemods to migrate between versions |
|
|
63
63
|
| `theme build` | Compile a defineTheme file to production CSS and JS |
|
|
64
64
|
| `discover` | Discover external packages and components |
|
|
65
|
-
| `
|
|
65
|
+
| `gap-report` | Report a gap when a component doesn't meet your needs |
|
|
66
|
+
| `doctor` | Diagnose your XDS setup and report problems with fixes (CI-friendly via exit code) |
|
|
66
67
|
|
|
67
68
|
### Global options
|
|
68
69
|
|
|
@@ -160,6 +161,7 @@ if (isError(result)) {
|
|
|
160
161
|
| `ERR_INVALID_VERSION` | A `--from`/`--to` value was not a valid semver string. |
|
|
161
162
|
| `ERR_DEP_MISSING` | A required external dependency (e.g. jscodeshift) is missing. |
|
|
162
163
|
| `ERR_GH_CLI` | GitHub CLI (`gh`) is not installed or not authenticated. |
|
|
164
|
+
| `ERR_GAP_REPORT_FAILED` | Filing a gap report failed (disabled, or the integration errored). |
|
|
163
165
|
|
|
164
166
|
## Capability manifest (agent discovery)
|
|
165
167
|
|
|
@@ -170,7 +172,7 @@ discriminators each command can emit. Think of it as an OpenAPI spec for the CLI
|
|
|
170
172
|
|
|
171
173
|
```bash
|
|
172
174
|
astryx manifest --json # dedicated surface — type: "manifest"
|
|
173
|
-
|
|
175
|
+
xds --json # bare invocation — embeds the same payload under data.manifest
|
|
174
176
|
```
|
|
175
177
|
|
|
176
178
|
Shape:
|
|
@@ -180,7 +182,7 @@ Shape:
|
|
|
180
182
|
"apiVersion": 1,
|
|
181
183
|
"type": "manifest",
|
|
182
184
|
"data": {
|
|
183
|
-
"name": "
|
|
185
|
+
"name": "xds",
|
|
184
186
|
"version": "0.0.14",
|
|
185
187
|
"description": "Design system CLI — components, themes, and tooling",
|
|
186
188
|
"globalOptions": [
|
|
@@ -247,14 +249,14 @@ the `JSON_SUPPORTED` allowlist and a small declarative `RESPONSE_TYPES` map in
|
|
|
247
249
|
`src/lib/manifest.mjs`, guarded by a drift test (`manifest.test.mjs`) so adding a
|
|
248
250
|
command without describing it fails CI.
|
|
249
251
|
|
|
250
|
-
**Backwards-compat:** the bare `
|
|
252
|
+
**Backwards-compat:** the bare `xds --json` envelope keeps `type: "help"` and its
|
|
251
253
|
original shallow fields (`name`, `version`, `commands` as a `string[]` of names,
|
|
252
254
|
`jsonSupported`); the full structured manifest is additive under `data.manifest`.
|
|
253
255
|
For the standalone manifest envelope (`type: "manifest"`), use `astryx manifest --json`.
|
|
254
256
|
|
|
255
257
|
## Programmatic API
|
|
256
258
|
|
|
257
|
-
The same logic that powers `
|
|
259
|
+
The same logic that powers `xds --json` is available as importable, type-safe functions:
|
|
258
260
|
|
|
259
261
|
```typescript
|
|
260
262
|
import {
|
|
@@ -267,20 +269,20 @@ import {
|
|
|
267
269
|
AstryxError,
|
|
268
270
|
} from '@astryxdesign/cli/api';
|
|
269
271
|
|
|
270
|
-
// Same result as:
|
|
272
|
+
// Same result as: xds --json component Button
|
|
271
273
|
const btn = await component('Button');
|
|
272
274
|
btn.type; // 'component.detail'
|
|
273
275
|
btn.data.name; // 'Button' (typed as ComponentDoc)
|
|
274
276
|
|
|
275
|
-
// Same result as:
|
|
277
|
+
// Same result as: xds --json component --list
|
|
276
278
|
const list = await component(undefined, {list: true});
|
|
277
279
|
list.data; // Record<string, string[]>
|
|
278
280
|
|
|
279
|
-
// Same result as:
|
|
281
|
+
// Same result as: xds --json docs principles
|
|
280
282
|
const principles = await docs('principles');
|
|
281
|
-
principles.data.title; // 'Principles'
|
|
283
|
+
principles.data.title; // 'XDS Principles'
|
|
282
284
|
|
|
283
|
-
// Same result as:
|
|
285
|
+
// Same result as: xds --json hook useMediaQuery
|
|
284
286
|
const useMediaQuery = await hook('useMediaQuery');
|
|
285
287
|
useMediaQuery.data.params; // typed as HookParamDoc[]
|
|
286
288
|
|
|
@@ -294,7 +296,7 @@ try {
|
|
|
294
296
|
}
|
|
295
297
|
```
|
|
296
298
|
|
|
297
|
-
The CLI command handlers are thin wrappers around these functions: they parse args, call the API, then format the output (JSON or text). This guarantees that `@astryxdesign/cli/api` and `
|
|
299
|
+
The CLI command handlers are thin wrappers around these functions: they parse args, call the API, then format the output (JSON or text). This guarantees that `@astryxdesign/cli/api` and `xds --json` always return identical data.
|
|
298
300
|
|
|
299
301
|
### Consumer utilities
|
|
300
302
|
|
|
@@ -324,41 +326,43 @@ detail.data.name; // already narrowed
|
|
|
324
326
|
|
|
325
327
|
Every response has a `type` string that uniquely identifies it:
|
|
326
328
|
|
|
327
|
-
| Command
|
|
328
|
-
|
|
|
329
|
-
| `
|
|
330
|
-
| `
|
|
331
|
-
| `
|
|
332
|
-
| `
|
|
333
|
-
| `
|
|
334
|
-
| `
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
337
|
-
| `
|
|
338
|
-
| `
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
342
|
-
| `
|
|
343
|
-
| `
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
358
|
-
| `
|
|
359
|
-
| `
|
|
360
|
-
|
|
|
361
|
-
|
|
|
329
|
+
| Command | Type | Response |
|
|
330
|
+
| ---------------------------------------------- | --------------------------- | --------------------------------- |
|
|
331
|
+
| `xds --json component [--list]` | `component.list` | `ComponentListResponse` |
|
|
332
|
+
| `xds --json component --list --detail compact` | `component.brief` | `ComponentBriefResponse` |
|
|
333
|
+
| `xds --json component --list --detail full` | `component.full` | `ComponentFullResponse` |
|
|
334
|
+
| `xds --json component <name>` | `component.detail` | `ComponentDetailResponse` |
|
|
335
|
+
| `xds --json component <name> --props` | `component.detail.props` | `ComponentDetailPropsResponse` |
|
|
336
|
+
| `xds --json component <name> --source` | `component.detail.source` | `ComponentDetailSourceResponse` |
|
|
337
|
+
| `xds --json component <name> --showcase` | `component.detail.showcase` | `ComponentDetailShowcaseResponse` |
|
|
338
|
+
| `xds --json component <name> --blocks` | `component.detail.blocks` | `ComponentDetailBlocksResponse` |
|
|
339
|
+
| `xds --json discover` | `discover.list` | `DiscoverListResponse` |
|
|
340
|
+
| `xds --json discover @scope/name` | `discover.detail` | `DiscoverDetailResponse` |
|
|
341
|
+
| `xds --json discover @scope/name/Comp` | `discover.detail.doc` | `DiscoverDetailDocResponse` |
|
|
342
|
+
| `xds --json discover <search>` | `discover.search` | `DiscoverSearchResponse` |
|
|
343
|
+
| `xds --json docs` | `docs.list` | `DocsListResponse` |
|
|
344
|
+
| `xds --json docs <topic>` | `docs.detail` | `DocsDetailResponse` |
|
|
345
|
+
| `xds --json docs <topic> <section>` | `docs.detail.section` | `DocsDetailSectionResponse` |
|
|
346
|
+
| `xds --json template [--list]` | `template.list` | `TemplateListResponse` |
|
|
347
|
+
| `xds --json template <name>` | `template.show` | `TemplateShowResponse` |
|
|
348
|
+
| `xds --json template <name> --skeleton` | `template.skeleton` | `TemplateSkeletonResponse` |
|
|
349
|
+
| `xds --json template <name> [path]` | `template.copy` | `TemplateCopyResponse` |
|
|
350
|
+
| `xds --json hook [--list]` | `hook.list` | `HookListResponse` |
|
|
351
|
+
| `xds --json hook --list --detail compact` | `hook.brief` | `HookBriefResponse` |
|
|
352
|
+
| `xds --json hook --list --detail full` | `hook.full` | `HookFullResponse` |
|
|
353
|
+
| `xds --json hook <name>` | `hook.detail` | `HookDetailResponse` |
|
|
354
|
+
| `xds --json hook <name> --params` | `hook.detail.params` | `HookDetailParamsResponse` |
|
|
355
|
+
| `xds --json search <query>` | `search` | `SearchResponse` |
|
|
356
|
+
| `xds --json swizzle [--list]` | `swizzle.list` | `SwizzleListResponse` |
|
|
357
|
+
| `xds --json swizzle <component>` | `swizzle.copy` | `SwizzleCopyResponse` |
|
|
358
|
+
| `xds --json theme build <file>` | `theme.build` | `ThemeBuildResponse` |
|
|
359
|
+
| `xds --json upgrade --list` | `upgrade.list` | `UpgradeListResponse` |
|
|
360
|
+
| `xds --json upgrade [--apply]` | `upgrade.run` | `UpgradeRunResponse` |
|
|
361
|
+
| `xds --json gap-report --list-categories` | `gap-report.categories` | `GapReportCategoriesResponse` |
|
|
362
|
+
| `xds --json gap-report --component X ...` | `gap-report.file` | `GapReportFileResponse` |
|
|
363
|
+
| `xds --json doctor` | `doctor` | `DoctorResponse` |
|
|
364
|
+
| any error | — | `CLIError` |
|
|
365
|
+
| unsupported command | — | `CLIUnsupportedError` |
|
|
362
366
|
|
|
363
367
|
## Doctor
|
|
364
368
|
|
|
@@ -379,7 +383,7 @@ astryx doctor — diagnosing your setup
|
|
|
379
383
|
@astryxdesign/core v0.0.14 is in step with @astryxdesign/cli v0.0.14.
|
|
380
384
|
⚠ Theme packages
|
|
381
385
|
No @astryxdesign/theme-* packages are installed.
|
|
382
|
-
→ fix: Install a theme, e.g. `npm install @astryxdesign/theme-neutral`, then import its CSS or set
|
|
386
|
+
→ fix: Install a theme, e.g. `npm install @astryxdesign/theme-neutral`, then import its CSS or set xds.theme.
|
|
383
387
|
ℹ astryx.config.mjs
|
|
384
388
|
No astryx.config.mjs found — using defaults.
|
|
385
389
|
ℹ AI agent docs
|
|
@@ -404,7 +408,7 @@ No failures — but review the ⚠ warnings above when you can.
|
|
|
404
408
|
| Version alignment | pass / warn / info | Installed `@astryxdesign/core` is in step with `@astryxdesign/cli` |
|
|
405
409
|
| Theme packages | pass / warn | An `@astryxdesign/theme-*` package is installed and a theme is wired |
|
|
406
410
|
| astryx.config.mjs | pass / fail / info | Config (if present) loads cleanly with a valid shape |
|
|
407
|
-
| AI agent docs | pass / warn / info | Agent docs exist and contain the
|
|
411
|
+
| AI agent docs | pass / warn / info | Agent docs exist and contain the XDS section markers |
|
|
408
412
|
| Peer dependencies | pass / warn / info | `@astryxdesign/core`'s peer deps (react, …) are installed |
|
|
409
413
|
| Package manager | info | Reports the detected package manager |
|
|
410
414
|
|
|
@@ -430,6 +434,8 @@ export default {
|
|
|
430
434
|
templates: {
|
|
431
435
|
get: async id => fetchTemplateFromAPI(id),
|
|
432
436
|
},
|
|
433
|
-
|
|
437
|
+
gapReport: {
|
|
438
|
+
url: 'https://your-api.com/gaps',
|
|
439
|
+
},
|
|
434
440
|
};
|
|
435
441
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.1.2-canary.
|
|
3
|
+
"version": "0.1.2-canary.1ba0e77",
|
|
4
4
|
"displayName": "CLI",
|
|
5
5
|
"description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"zod": "^4.4.3"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
79
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
80
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
78
|
+
"@astryxdesign/core": "0.1.2-canary.1ba0e77",
|
|
79
|
+
"@astryxdesign/lab": "0.1.2-canary.1ba0e77",
|
|
80
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.1ba0e77",
|
|
81
81
|
"gpt-tokenizer": "^2.0.0"
|
|
82
82
|
},
|
|
83
83
|
"peerDependenciesMeta": {
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@astryxdesign/core": "0.1.2-canary.
|
|
96
|
-
"@astryxdesign/lab": "0.1.2-canary.
|
|
97
|
-
"@astryxdesign/theme-neutral": "0.1.2-canary.
|
|
95
|
+
"@astryxdesign/core": "0.1.2-canary.1ba0e77",
|
|
96
|
+
"@astryxdesign/lab": "0.1.2-canary.1ba0e77",
|
|
97
|
+
"@astryxdesign/theme-neutral": "0.1.2-canary.1ba0e77",
|
|
98
98
|
"gpt-tokenizer": "^2.0.0"
|
|
99
99
|
},
|
|
100
100
|
"scripts": {
|
package/src/api/doctor.mjs
CHANGED
|
@@ -240,7 +240,7 @@ export function checkThemes(ctx) {
|
|
|
240
240
|
label: 'Theme packages',
|
|
241
241
|
status: 'warn',
|
|
242
242
|
message: 'No @astryxdesign/theme-* packages are installed.',
|
|
243
|
-
fix: 'Install a theme, e.g. `npm install @astryxdesign/theme-neutral`, then import its CSS or set
|
|
243
|
+
fix: 'Install a theme, e.g. `npm install @astryxdesign/theme-neutral`, then import its CSS or set xds.theme.',
|
|
244
244
|
};
|
|
245
245
|
}
|
|
246
246
|
|
|
@@ -354,7 +354,7 @@ export function checkAgentDocs(ctx) {
|
|
|
354
354
|
label: 'AI agent docs',
|
|
355
355
|
status: 'warn',
|
|
356
356
|
message: `Agent docs present (${present.join(', ')}) but no Astryx section markers found.`,
|
|
357
|
-
fix: 'Add the
|
|
357
|
+
fix: 'Add the XDS section to your agent docs with `astryx init --features agents`.',
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
360
|
|
|
@@ -362,7 +362,7 @@ export function checkAgentDocs(ctx) {
|
|
|
362
362
|
id: 'agent-docs',
|
|
363
363
|
label: 'AI agent docs',
|
|
364
364
|
status: 'pass',
|
|
365
|
-
message: `
|
|
365
|
+
message: `XDS agent docs section present in ${withMarkers.join(', ')}.`,
|
|
366
366
|
};
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -4,23 +4,12 @@
|
|
|
4
4
|
* @file Codemod: Drop the `XDS` prefix from @xds/core imports and their usages
|
|
5
5
|
*
|
|
6
6
|
* Part of the XDS-prefix migration (P2380608025). Rewrites consumer code from
|
|
7
|
-
* the prefixed names to
|
|
7
|
+
* the prefixed names to the bare compatibility aliases shipped in P1:
|
|
8
8
|
*
|
|
9
9
|
* XDSButton -> Button
|
|
10
10
|
* XDSButtonProps -> ButtonProps
|
|
11
11
|
* useXDSTheme -> useTheme
|
|
12
12
|
* useXDSToast -> useToast
|
|
13
|
-
* XDSIconRegistry-> IconRegistry
|
|
14
|
-
*
|
|
15
|
-
* Mandatory in v0.1.0: the prefixed compatibility aliases (which made both
|
|
16
|
-
* prefixed and bare names valid during the 0.0.x compat window) were dropped
|
|
17
|
-
* in v0.1.0, so the un-prefixing is now required for code to keep type-
|
|
18
|
-
* checking against @astryxdesign/core.
|
|
19
|
-
*
|
|
20
|
-
* Ordering: within the v0.1.0 manifest this runs BEFORE
|
|
21
|
-
* migrate-xds-module-specifiers so it still matches `@xds/core` imports (its
|
|
22
|
-
* source matcher) and un-prefixes the identifiers first; the specifier codemod
|
|
23
|
-
* then rewrites the module paths `@xds/*` -> `@astryxdesign/*`.
|
|
24
13
|
*
|
|
25
14
|
* Safety: this codemod ONLY renames identifiers that are imported from
|
|
26
15
|
* `@xds/core` (bare or subpath, e.g. `@xds/core/Button`). It tracks the local
|
|
@@ -47,9 +36,9 @@ export const meta = {
|
|
|
47
36
|
title: 'Drop XDS prefix from @xds/core imports (XDSButton -> Button)',
|
|
48
37
|
description:
|
|
49
38
|
'Rewrites @xds/core imports and their usages from the prefixed names ' +
|
|
50
|
-
'(XDSButton, useXDSTheme,
|
|
51
|
-
'
|
|
52
|
-
'
|
|
39
|
+
'(XDSButton, useXDSTheme, XDSButtonProps) to the bare compatibility ' +
|
|
40
|
+
'aliases (Button, useTheme, ButtonProps). Only renames bindings imported ' +
|
|
41
|
+
'from @xds/core, leaving unrelated identifiers untouched.',
|
|
53
42
|
pr: '#2880',
|
|
54
43
|
};
|
|
55
44
|
|
|
@@ -34,6 +34,10 @@ import migrateSelectorChildrenToRenderOption, {
|
|
|
34
34
|
meta as migrateSelectorChildrenToRenderOptionMeta,
|
|
35
35
|
} from './migrate-selector-children-to-render-option.mjs';
|
|
36
36
|
|
|
37
|
+
import dropXdsPrefixImports, {
|
|
38
|
+
meta as dropXdsPrefixImportsMeta,
|
|
39
|
+
} from './drop-xds-prefix-imports.mjs';
|
|
40
|
+
|
|
37
41
|
export default [
|
|
38
42
|
{
|
|
39
43
|
name: 'rename-date-picker-to-input',
|
|
@@ -71,4 +75,13 @@ export default [
|
|
|
71
75
|
transform: migrateSelectorChildrenToRenderOption,
|
|
72
76
|
meta: migrateSelectorChildrenToRenderOptionMeta,
|
|
73
77
|
},
|
|
78
|
+
{
|
|
79
|
+
// XDS-prefix migration (P2380608025). Optional + not tied to a version
|
|
80
|
+
// bump: consumers run it explicitly during their migration, e.g.
|
|
81
|
+
// astryx upgrade --codemod drop-xds-prefix-imports --codemod-only --apply
|
|
82
|
+
name: 'drop-xds-prefix-imports',
|
|
83
|
+
transform: dropXdsPrefixImports,
|
|
84
|
+
meta: dropXdsPrefixImportsMeta,
|
|
85
|
+
optional: true,
|
|
86
|
+
},
|
|
74
87
|
];
|
|
@@ -6,60 +6,14 @@
|
|
|
6
6
|
* Lists all codemods for the v0.1.0 release in the order they should run.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import dropXdsPrefixImports, {
|
|
10
|
-
meta as dropXdsPrefixImportsMeta,
|
|
11
|
-
} from './drop-xds-prefix-imports.mjs';
|
|
12
|
-
|
|
13
9
|
import migrateXdsModuleSpecifiers, {
|
|
14
10
|
meta as migrateXdsModuleSpecifiersMeta,
|
|
15
11
|
} from './migrate-xds-module-specifiers.mjs';
|
|
16
12
|
|
|
17
|
-
import migrateXdsDeclareModule, {
|
|
18
|
-
meta as migrateXdsDeclareModuleMeta,
|
|
19
|
-
} from './migrate-xds-declare-module.mjs';
|
|
20
|
-
|
|
21
|
-
import migrateXdsCssSurfaces, {
|
|
22
|
-
meta as migrateXdsCssSurfacesMeta,
|
|
23
|
-
} from './migrate-xds-css-surfaces.mjs';
|
|
24
|
-
|
|
25
13
|
export default [
|
|
26
|
-
{
|
|
27
|
-
// XDS-prefix migration (P2380608025). Mandatory in v0.1.0: the release
|
|
28
|
-
// dropped the prefixed compatibility aliases (useXDSTheme, XDSButton,
|
|
29
|
-
// XDSIconRegistry, ...), so consumers upgrading from 0.0.x MUST rewrite
|
|
30
|
-
// prefixed imports to their bare names.
|
|
31
|
-
//
|
|
32
|
-
// Ordered BEFORE migrate-xds-module-specifiers so it sees `@xds/core`
|
|
33
|
-
// imports (its source matcher) and un-prefixes the identifiers first;
|
|
34
|
-
// the specifier codemod then rewrites the paths to `@astryxdesign/core`.
|
|
35
|
-
// The runner preserves this array order (see runner.mjs).
|
|
36
|
-
name: 'drop-xds-prefix-imports',
|
|
37
|
-
transform: dropXdsPrefixImports,
|
|
38
|
-
meta: dropXdsPrefixImportsMeta,
|
|
39
|
-
},
|
|
40
14
|
{
|
|
41
15
|
name: 'migrate-xds-module-specifiers',
|
|
42
16
|
transform: migrateXdsModuleSpecifiers,
|
|
43
17
|
meta: migrateXdsModuleSpecifiersMeta,
|
|
44
18
|
},
|
|
45
|
-
{
|
|
46
|
-
// Cleans up TypeScript `declare module "@xds/core/..."` augmentations,
|
|
47
|
-
// which reference the package by string specifier and so are dead after
|
|
48
|
-
// the scope rename. Mandatory in v0.1.0. Ordered AFTER the specifier
|
|
49
|
-
// codemod: it uses the same @xds -> @astryxdesign mapping and repairs an
|
|
50
|
-
// adjacent surface the specifier codemod does not visit (module-decl ids
|
|
51
|
-
// are not import/export/require sources).
|
|
52
|
-
name: 'migrate-xds-declare-module',
|
|
53
|
-
transform: migrateXdsDeclareModule,
|
|
54
|
-
meta: migrateXdsDeclareModuleMeta,
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
// Rewrites consumer CSS surfaces broken by the v0.1.0 DOM-namespace rename
|
|
58
|
-
// (core no longer dual-emits `xds-*`): the `.xds-*` class-selector prefix,
|
|
59
|
-
// `[data-xds-*]` attribute selectors, and `@layer xds-*` layer names all
|
|
60
|
-
// become their `astryx-*` forms. Mandatory in v0.1.0.
|
|
61
|
-
name: 'migrate-xds-css-surfaces',
|
|
62
|
-
transform: migrateXdsCssSurfaces,
|
|
63
|
-
meta: migrateXdsCssSurfacesMeta,
|
|
64
|
-
},
|
|
65
19
|
];
|
|
@@ -207,7 +207,7 @@ export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPre
|
|
|
207
207
|
.sort();
|
|
208
208
|
if (topics.length > 0) lines.push(` docs <topic> ${topics.join(', ')}`);
|
|
209
209
|
}
|
|
210
|
-
lines.push(' swizzle <Name> eject component source
|
|
210
|
+
lines.push(' swizzle <Name> eject component source (--gap reports why)');
|
|
211
211
|
lines.push(' upgrade --apply run after any @astryxdesign/core bump');
|
|
212
212
|
lines.push(MARKER_END);
|
|
213
213
|
|
|
@@ -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', '
|
|
13
|
+
componentsUsed: ['HoverCard', 'Icon', 'Layout', 'Text'],
|
|
14
14
|
};
|
|
@@ -5,14 +5,12 @@
|
|
|
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';
|
|
9
8
|
import {Text} from '@astryxdesign/core/Text';
|
|
10
9
|
import {LinkIcon} from '@heroicons/react/24/outline';
|
|
11
10
|
|
|
12
11
|
export default function HoverCardInteractiveContent() {
|
|
13
12
|
return (
|
|
14
|
-
<Text type="body">
|
|
15
|
-
Read more in the{' '}
|
|
13
|
+
<Text type="body">Read more in the{' '}
|
|
16
14
|
<HoverCard
|
|
17
15
|
placement="below"
|
|
18
16
|
content={
|
|
@@ -32,11 +30,8 @@ export default function HoverCardInteractiveContent() {
|
|
|
32
30
|
</HStack>
|
|
33
31
|
</VStack>
|
|
34
32
|
}>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</HoverCard>
|
|
39
|
-
.
|
|
40
|
-
</Text>
|
|
33
|
+
Getting Started Guide
|
|
34
|
+
</HoverCard>.
|
|
35
|
+
</Text>
|
|
41
36
|
);
|
|
42
37
|
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
4
|
-
|
|
5
|
-
async function applyTransform(source, filePath = 'test.css') {
|
|
6
|
-
const {default: transform} = await import('../migrate-xds-css-surfaces.mjs');
|
|
7
|
-
// api.jscodeshift is unused by this CSS codemod, but the runner still
|
|
8
|
-
// passes it — mirror that shape.
|
|
9
|
-
const jscodeshift = (await import('jscodeshift')).default;
|
|
10
|
-
const api = {jscodeshift, stats: () => {}, report: () => {}};
|
|
11
|
-
const file = {source, path: filePath};
|
|
12
|
-
const result = transform(file, api);
|
|
13
|
-
return result ?? source;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
describe('migrate-xds-css-surfaces', () => {
|
|
17
|
-
it('rewrites the .xds- class-selector prefix', async () => {
|
|
18
|
-
const input = '.xds-heading { color: red; }';
|
|
19
|
-
const output = await applyTransform(input);
|
|
20
|
-
expect(output).toBe('.astryx-heading { color: red; }');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('rewrites the [data-xds-theme] attribute selector', async () => {
|
|
24
|
-
const input = '[data-xds-theme="dark"] .xds-card { background: black; }';
|
|
25
|
-
const output = await applyTransform(input);
|
|
26
|
-
expect(output).toContain('[data-astryx-theme="dark"]');
|
|
27
|
-
expect(output).toContain('.astryx-card');
|
|
28
|
-
expect(output).not.toContain('xds-');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('rewrites data-xds-theme-prose and data-xds-media attribute selectors', async () => {
|
|
32
|
-
const input =
|
|
33
|
-
'[data-xds-theme-prose] {} [data-xds-media="print"] {}';
|
|
34
|
-
const output = await applyTransform(input);
|
|
35
|
-
expect(output).toContain('[data-astryx-theme-prose]');
|
|
36
|
-
expect(output).toContain('[data-astryx-media="print"]');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('rewrites @layer xds-theme and @layer xds-base', async () => {
|
|
40
|
-
const input = '@layer xds-theme, xds-base;\n@layer xds-theme { a { color: red; } }';
|
|
41
|
-
const output = await applyTransform(input);
|
|
42
|
-
expect(output).toContain('astryx-theme');
|
|
43
|
-
expect(output).toContain('astryx-base');
|
|
44
|
-
expect(output).not.toContain('xds-theme');
|
|
45
|
-
expect(output).not.toContain('xds-base');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('does NOT rewrite a bare "xds" in a comment or value', async () => {
|
|
49
|
-
const input = '/* xds tokens live here */\n.card { content: "xds"; }';
|
|
50
|
-
const output = await applyTransform(input);
|
|
51
|
-
expect(output).toBe(input);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('does NOT rewrite a class-like word missing the leading dot', async () => {
|
|
55
|
-
// e.g. inside a JS-ish string or a comment fragment — not a class selector.
|
|
56
|
-
const input = '/* use xds-heading in markup */';
|
|
57
|
-
const output = await applyTransform(input);
|
|
58
|
-
expect(output).toBe(input);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('leaves already-migrated CSS unchanged', async () => {
|
|
62
|
-
const input =
|
|
63
|
-
'@layer astryx-theme { [data-astryx-theme="dark"] .astryx-card {} }';
|
|
64
|
-
const output = await applyTransform(input);
|
|
65
|
-
expect(output).toBe(input);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
4
|
-
|
|
5
|
-
async function applyTransform(source, filePath = 'test.d.ts') {
|
|
6
|
-
const {default: transform} = await import('../migrate-xds-declare-module.mjs');
|
|
7
|
-
const jscodeshift = (await import('jscodeshift')).default;
|
|
8
|
-
const j = jscodeshift.withParser('tsx');
|
|
9
|
-
const api = {jscodeshift: j, stats: () => {}, report: () => {}};
|
|
10
|
-
const file = {source, path: filePath};
|
|
11
|
-
const result = transform(file, api);
|
|
12
|
-
return result ?? source;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe('migrate-xds-declare-module', () => {
|
|
16
|
-
it('renames a subpath declare module', async () => {
|
|
17
|
-
const input = [
|
|
18
|
-
"declare module '@xds/core/Heading' {",
|
|
19
|
-
' export const HeadingLevelMap: Record<string, number>;',
|
|
20
|
-
'}',
|
|
21
|
-
].join('\n');
|
|
22
|
-
|
|
23
|
-
const output = await applyTransform(input);
|
|
24
|
-
expect(output).toMatch(/declare module ['"]@astryxdesign\/core\/Heading['"]/);
|
|
25
|
-
expect(output).not.toContain('@xds/core');
|
|
26
|
-
// The augmentation body identifier is untouched.
|
|
27
|
-
expect(output).toContain('HeadingLevelMap');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('renames a bare @xds/core declare module', async () => {
|
|
31
|
-
const input = "declare module '@xds/core' {\n const x: number;\n}";
|
|
32
|
-
const output = await applyTransform(input);
|
|
33
|
-
expect(output).toMatch(/declare module ['"]@astryxdesign\/core['"]/);
|
|
34
|
-
expect(output).not.toContain('@xds/core');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('renames @xds/lab declare module using the shared map', async () => {
|
|
38
|
-
const input = "declare module '@xds/lab/Thing' {\n const y: number;\n}";
|
|
39
|
-
const output = await applyTransform(input);
|
|
40
|
-
expect(output).toMatch(/declare module ['"]@astryxdesign\/lab\/Thing['"]/);
|
|
41
|
-
expect(output).not.toContain('@xds/lab');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('leaves non-xds declare modules alone', async () => {
|
|
45
|
-
const input = "declare module 'react' {\n const z: number;\n}";
|
|
46
|
-
const output = await applyTransform(input);
|
|
47
|
-
expect(output).toBe(input);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('leaves an already-migrated declare module unchanged', async () => {
|
|
51
|
-
const input = "declare module '@astryxdesign/core/Heading' {\n const a: number;\n}";
|
|
52
|
-
const output = await applyTransform(input);
|
|
53
|
-
expect(output).toBe(input);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('does not touch namespace declarations (Identifier id)', async () => {
|
|
57
|
-
const input = 'declare namespace XDSCore {\n const b: number;\n}';
|
|
58
|
-
const output = await applyTransform(input, 'test.ts');
|
|
59
|
-
expect(output).toBe(input);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* End-to-end test proving the v0.1.0 manifest ordering: the prefix-drop
|
|
7
|
-
* codemod runs BEFORE migrate-xds-module-specifiers, so a prefixed identifier
|
|
8
|
-
* imported from `@xds/core` is un-prefixed AND the module path is rewritten to
|
|
9
|
-
* `@astryxdesign/core` in a single upgrade pass.
|
|
10
|
-
*/
|
|
11
|
-
async function applyManifestInOrder(source, filePath = 'test.tsx') {
|
|
12
|
-
const {default: manifest} = await import('../index.mjs');
|
|
13
|
-
const jscodeshift = (await import('jscodeshift')).default;
|
|
14
|
-
const j = jscodeshift.withParser('tsx');
|
|
15
|
-
const api = {jscodeshift: j, stats: () => {}, report: () => {}};
|
|
16
|
-
|
|
17
|
-
let current = source;
|
|
18
|
-
for (const {transform} of manifest) {
|
|
19
|
-
const file = {source: current, path: filePath};
|
|
20
|
-
const result = transform(file, api);
|
|
21
|
-
current = result ?? current;
|
|
22
|
-
}
|
|
23
|
-
return current;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe('v0.1.0 codemod manifest ordering', () => {
|
|
27
|
-
it('runs drop-xds-prefix-imports before migrate-xds-module-specifiers', async () => {
|
|
28
|
-
const {default: manifest} = await import('../index.mjs');
|
|
29
|
-
const names = manifest.map(entry => entry.name);
|
|
30
|
-
const prefixDropIdx = names.indexOf('drop-xds-prefix-imports');
|
|
31
|
-
const specifierIdx = names.indexOf('migrate-xds-module-specifiers');
|
|
32
|
-
expect(prefixDropIdx).toBeGreaterThanOrEqual(0);
|
|
33
|
-
expect(specifierIdx).toBeGreaterThanOrEqual(0);
|
|
34
|
-
expect(prefixDropIdx).toBeLessThan(specifierIdx);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('drop-xds-prefix-imports is mandatory (not optional) in v0.1.0', async () => {
|
|
38
|
-
const {default: manifest} = await import('../index.mjs');
|
|
39
|
-
const entry = manifest.find(e => e.name === 'drop-xds-prefix-imports');
|
|
40
|
-
expect(entry).toBeDefined();
|
|
41
|
-
expect(entry.optional).toBeFalsy();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('orders declare-module and CSS codemods after migrate-xds-module-specifiers', async () => {
|
|
45
|
-
const {default: manifest} = await import('../index.mjs');
|
|
46
|
-
const names = manifest.map(entry => entry.name);
|
|
47
|
-
expect(names).toEqual([
|
|
48
|
-
'drop-xds-prefix-imports',
|
|
49
|
-
'migrate-xds-module-specifiers',
|
|
50
|
-
'migrate-xds-declare-module',
|
|
51
|
-
'migrate-xds-css-surfaces',
|
|
52
|
-
]);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('marks migrate-xds-declare-module and migrate-xds-css-surfaces mandatory', async () => {
|
|
56
|
-
const {default: manifest} = await import('../index.mjs');
|
|
57
|
-
for (const name of [
|
|
58
|
-
'migrate-xds-declare-module',
|
|
59
|
-
'migrate-xds-css-surfaces',
|
|
60
|
-
]) {
|
|
61
|
-
const entry = manifest.find(e => e.name === name);
|
|
62
|
-
expect(entry, name).toBeDefined();
|
|
63
|
-
expect(entry.optional).toBeFalsy();
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('un-prefixes useXDSTheme from @xds/core/theme AND renames the scope to @astryxdesign', async () => {
|
|
68
|
-
const input = [
|
|
69
|
-
"import {useXDSTheme} from '@xds/core/theme';",
|
|
70
|
-
'',
|
|
71
|
-
'function App() {',
|
|
72
|
-
' const theme = useXDSTheme();',
|
|
73
|
-
' return theme;',
|
|
74
|
-
'}',
|
|
75
|
-
].join('\n');
|
|
76
|
-
|
|
77
|
-
const output = await applyManifestInOrder(input);
|
|
78
|
-
|
|
79
|
-
expect(output).toMatch(/import\s*\{useTheme\}\s*from\s*['"]@astryxdesign\/core\/theme['"]/);
|
|
80
|
-
expect(output).toContain('const theme = useTheme();');
|
|
81
|
-
// The prefixed name and old scope must be fully gone.
|
|
82
|
-
expect(output).not.toContain('useXDSTheme');
|
|
83
|
-
expect(output).not.toContain('@xds/core');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('un-prefixes XDSButton and XDSIconRegistry alongside the scope rename', async () => {
|
|
87
|
-
const input = [
|
|
88
|
-
"import {XDSButton, XDSIconRegistry} from '@xds/core';",
|
|
89
|
-
'',
|
|
90
|
-
'const registry = new XDSIconRegistry();',
|
|
91
|
-
'const el = <XDSButton />;',
|
|
92
|
-
].join('\n');
|
|
93
|
-
|
|
94
|
-
const output = await applyManifestInOrder(input);
|
|
95
|
-
|
|
96
|
-
expect(output).toMatch(/from\s*['"]@astryxdesign\/core['"]/);
|
|
97
|
-
expect(output).toContain('Button');
|
|
98
|
-
expect(output).toContain('IconRegistry');
|
|
99
|
-
expect(output).toContain('new IconRegistry()');
|
|
100
|
-
expect(output).not.toContain('XDSButton');
|
|
101
|
-
expect(output).not.toContain('XDSIconRegistry');
|
|
102
|
-
expect(output).not.toContain('@xds/core');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Codemod: migrate XDS CSS surfaces to their Astryx equivalents
|
|
5
|
-
*
|
|
6
|
-
* The v0.1.0 release renamed the DOM namespace emitted by @astryxdesign/core
|
|
7
|
-
* from `xds-*` to `astryx-*` and dropped the dual-emit compatibility (core no
|
|
8
|
-
* longer emits the legacy `xds-*` classes or `data-xds-*` attributes). Any
|
|
9
|
-
* consumer CSS that targeted those surfaces is now broken.
|
|
10
|
-
*
|
|
11
|
-
* This transform performs precise, targeted string replacements on CSS/SCSS
|
|
12
|
-
* files for the documented surfaces only:
|
|
13
|
-
*
|
|
14
|
-
* .xds-* (class-name prefix in selectors — matched only
|
|
15
|
-
* after a `.` so it is a class selector)
|
|
16
|
-
* [data-xds-theme (theme attribute selector)
|
|
17
|
-
* [data-xds-theme-prose (prose-theme attribute selector)
|
|
18
|
-
* [data-xds-media (media attribute selector)
|
|
19
|
-
* @layer xds-theme (cascade layer name — incl. comma-separated
|
|
20
|
-
* @layer xds-base `@layer a, b;` statement lists and nested blocks)
|
|
21
|
-
*
|
|
22
|
-
* It deliberately does NOT blindly replace every `xds` substring: a bare
|
|
23
|
-
* `xds` in a comment, a custom-property value, or an unrelated identifier is
|
|
24
|
-
* left untouched. CSS has no meaningful AST for this class of edit, so this is
|
|
25
|
-
* a plain string transform — `api.jscodeshift` is available but unused.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
export const meta = {
|
|
29
|
-
title: 'Migrate .xds-* / [data-xds-*] / @layer xds-* CSS surfaces to astryx',
|
|
30
|
-
description:
|
|
31
|
-
'Rewrites the documented XDS CSS surfaces to their Astryx equivalents: ' +
|
|
32
|
-
'the `.xds-*` class-selector prefix, `[data-xds-theme]` / ' +
|
|
33
|
-
'`[data-xds-theme-prose]` / `[data-xds-media]` attribute selectors, and ' +
|
|
34
|
-
'`@layer xds-theme` / `@layer xds-base` cascade-layer names all become ' +
|
|
35
|
-
'their `astryx-*` / `data-astryx-*` forms.',
|
|
36
|
-
pr: '#3092',
|
|
37
|
-
fileExtensions: ['.css', '.scss'],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// The XDS cascade-layer names we own. A `@layer` prelude can name several
|
|
41
|
-
// layers in a comma-separated list (`@layer a, b;`), so we can't anchor every
|
|
42
|
-
// occurrence to the `@layer` keyword. We instead rewrite these exact layer
|
|
43
|
-
// tokens within a `@layer ...` prelude (up to the next `{` or `;`).
|
|
44
|
-
const XDS_LAYER_NAMES = new Map([
|
|
45
|
-
['xds-theme', 'astryx-theme'],
|
|
46
|
-
['xds-base', 'astryx-base'],
|
|
47
|
-
]);
|
|
48
|
-
|
|
49
|
-
function rewriteLayerPrelude(prelude) {
|
|
50
|
-
return prelude.replace(/\bxds-(?:theme|base)\b/g, name =>
|
|
51
|
-
XDS_LAYER_NAMES.get(name) ?? name,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Ordered, non-overlapping replacements. Each pattern is intentionally narrow
|
|
56
|
-
// so we never touch a bare `xds` substring outside these surfaces.
|
|
57
|
-
const REPLACEMENTS = [
|
|
58
|
-
// Class-name prefix: only when preceded by a `.` (a class selector).
|
|
59
|
-
{re: /\.xds-/g, to: '.astryx-'},
|
|
60
|
-
// Attribute selectors: any `[data-xds-` opener (theme, theme-prose, media).
|
|
61
|
-
{re: /\[data-xds-/g, to: '[data-astryx-'},
|
|
62
|
-
// Cascade-layer preludes: `@layer <names>` up to the block `{` or `;`.
|
|
63
|
-
// Rewrite only the recognized xds-* layer tokens inside the prelude.
|
|
64
|
-
{re: /@layer\b[^{;]*/g, to: match => rewriteLayerPrelude(match)},
|
|
65
|
-
];
|
|
66
|
-
|
|
67
|
-
export default function transformer(file /*, api */) {
|
|
68
|
-
const source = file.source;
|
|
69
|
-
if (typeof source !== 'string') return undefined;
|
|
70
|
-
|
|
71
|
-
let next = source;
|
|
72
|
-
for (const {re, to} of REPLACEMENTS) {
|
|
73
|
-
next = next.replace(re, to);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return next === source ? undefined : next;
|
|
77
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Codemod: migrate `declare module "@xds/..."` augmentations to
|
|
5
|
-
* `@astryxdesign/...`
|
|
6
|
-
*
|
|
7
|
-
* The v0.1.0 release moved the public package scope from @xds to
|
|
8
|
-
* @astryxdesign. TypeScript module augmentations (`declare module "@xds/core"
|
|
9
|
-
* { ... }`) reference the package by its string specifier, so they are dead
|
|
10
|
-
* after the scope rename: TypeScript resolves the augmentation against a
|
|
11
|
-
* module that no longer exists.
|
|
12
|
-
*
|
|
13
|
-
* This transform rewrites the augmented module string on `TSModuleDeclaration`
|
|
14
|
-
* nodes whose `id` is a StringLiteral matching a renamed @xds package (or one
|
|
15
|
-
* of its subpaths). It only touches the module path — identifiers *inside* the
|
|
16
|
-
* augmentation (e.g. an augmented interface name) are a separate concern
|
|
17
|
-
* handled by drop-xds-prefix-imports.
|
|
18
|
-
*
|
|
19
|
-
* Ordered AFTER migrate-xds-module-specifiers in the v0.1.0 manifest: it uses
|
|
20
|
-
* the same PACKAGE_RENAMES mapping and cleans up the module-augmentation
|
|
21
|
-
* surface alongside the import/export/require specifier rename.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
export const meta = {
|
|
25
|
-
title: 'Migrate declare-module augmentations from @xds/* to @astryxdesign/*',
|
|
26
|
-
description:
|
|
27
|
-
'Rewrites the module specifier on TypeScript `declare module "@xds/..."` ' +
|
|
28
|
-
'augmentations to the @astryxdesign/* packages used by Astryx v0.1.0. ' +
|
|
29
|
-
'Only the augmented module path is changed; identifiers inside the ' +
|
|
30
|
-
'augmentation are left untouched.',
|
|
31
|
-
pr: '#3092',
|
|
32
|
-
fileExtensions: ['.ts', '.d.ts', '.tsx'],
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const PACKAGE_RENAMES = new Map([
|
|
36
|
-
['@xds/build', '@astryxdesign/build'],
|
|
37
|
-
['@xds/cli', '@astryxdesign/cli'],
|
|
38
|
-
['@xds/core', '@astryxdesign/core'],
|
|
39
|
-
['@xds/lab', '@astryxdesign/lab'],
|
|
40
|
-
['@xds/theme-butter', '@astryxdesign/theme-butter'],
|
|
41
|
-
['@xds/theme-chocolate', '@astryxdesign/theme-chocolate'],
|
|
42
|
-
['@xds/theme-daily', '@astryxdesign/theme-neutral'],
|
|
43
|
-
['@xds/theme-default', '@astryxdesign/theme-neutral'],
|
|
44
|
-
['@xds/theme-gothic', '@astryxdesign/theme-gothic'],
|
|
45
|
-
['@xds/theme-matcha', '@astryxdesign/theme-matcha'],
|
|
46
|
-
['@xds/theme-neutral', '@astryxdesign/theme-neutral'],
|
|
47
|
-
['@xds/theme-stone', '@astryxdesign/theme-stone'],
|
|
48
|
-
['@xds/theme-y2k', '@astryxdesign/theme-y2k'],
|
|
49
|
-
]);
|
|
50
|
-
|
|
51
|
-
function renamePackageSpecifier(value) {
|
|
52
|
-
if (typeof value !== 'string') return value;
|
|
53
|
-
for (const [from, to] of PACKAGE_RENAMES) {
|
|
54
|
-
if (value === from) return to;
|
|
55
|
-
if (value.startsWith(from + '/')) return to + value.slice(from.length);
|
|
56
|
-
}
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default function transformer(file, api) {
|
|
61
|
-
const j = api.jscodeshift;
|
|
62
|
-
const root = j(file.source);
|
|
63
|
-
let hasChanges = false;
|
|
64
|
-
|
|
65
|
-
root.find(j.TSModuleDeclaration).forEach(path => {
|
|
66
|
-
const id = path.node.id;
|
|
67
|
-
// Module augmentations name the module with a string literal id; a
|
|
68
|
-
// `namespace Foo {}` uses an Identifier id, which we ignore.
|
|
69
|
-
if (!id || (id.type !== 'StringLiteral' && id.type !== 'Literal')) return;
|
|
70
|
-
if (typeof id.value !== 'string') return;
|
|
71
|
-
const next = renamePackageSpecifier(id.value);
|
|
72
|
-
if (next === id.value) return;
|
|
73
|
-
id.value = next;
|
|
74
|
-
hasChanges = true;
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
return hasChanges ? root.toSource() : undefined;
|
|
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: '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
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -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: '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
|
-
};
|
|
@@ -1,52 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -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: '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
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
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
|
-
}
|
/package/src/codemods/transforms/{v0.1.0 → v0.0.15}/__tests__/drop-xds-prefix-imports.test.mjs
RENAMED
|
File without changes
|