@astryxdesign/cli 0.7.11 → 0.7.12-canary.ccb4a6d

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.
Files changed (68) hide show
  1. package/api/build/kit/rank.mjs +21 -4
  2. package/api/build/kit/words.d.mts +1 -0
  3. package/api/build/kit/words.mjs +1 -1
  4. package/api/icon/_adapter.d.mts +3 -2
  5. package/api/icon/_adapter.mjs +8 -2
  6. package/api/icon/_authoring.d.mts +1 -0
  7. package/api/icon/_authoring.mjs +586 -66
  8. package/api/icon/_default-look.d.mts +155 -0
  9. package/api/icon/_default-look.mjs +474 -0
  10. package/api/icon/_records.d.mts +1 -1
  11. package/api/icon/_records.mjs +1 -0
  12. package/api/icon/add/add.mjs +224 -38
  13. package/api/icon/icon.type.d.mts +22 -2
  14. package/api/icon/icon.type.mjs +6 -2
  15. package/api/icon/iconAdd.doc.mjs +2 -2
  16. package/api/icon/iconNewDefinition.doc.mjs +3 -2
  17. package/api/icon/iconNewSet.doc.mjs +4 -4
  18. package/api/icon/search/search.mjs +10 -9
  19. package/api/integration/add-helpers.d.mts +11 -1
  20. package/api/integration/add-helpers.mjs +5 -2
  21. package/api/integration/authoring-checks.d.mts +0 -2
  22. package/api/integration/authoring-checks.mjs +1 -6
  23. package/api/logger.mjs +2 -1
  24. package/api/swizzle/_adapter.d.mts +1 -0
  25. package/api/swizzle/_adapter.mjs +4 -1
  26. package/api/swizzle/_moduleGraph.d.mts +171 -0
  27. package/api/swizzle/_moduleGraph.mjs +795 -0
  28. package/api/swizzle/copy/copy.d.mts +2 -43
  29. package/api/swizzle/copy/copy.mjs +195 -314
  30. package/api/swizzle/swizzle.d.mts +0 -2
  31. package/api/swizzle/swizzle.doc.mjs +9 -4
  32. package/api/swizzle/swizzle.mjs +3 -7
  33. package/api/swizzle/swizzle.type.d.mts +2 -1
  34. package/api/swizzle/swizzle.type.mjs +3 -2
  35. package/assets/discover/official-packages.json +20 -0
  36. package/assets/docs/tree/icon-sets.doc.mjs +11 -5
  37. package/assets/templates/blocks/components/Table/TableRowIndexTable.doc.mjs +1 -1
  38. package/assets/templates/blocks/components/Table/TableRowIndexTable.tsx +2 -2
  39. package/assets/templates/pages/course-detail/page.tsx +699 -0
  40. package/assets/templates/pages/course-detail/template.doc.mjs +37 -0
  41. package/assets/templates/pages/file-explorer/page.tsx +103 -79
  42. package/assets/templates/pages/table-grouped/page.tsx +160 -232
  43. package/assets/templates/pages/table-grouped/template.doc.mjs +0 -2
  44. package/assets/templates/pages/theme-showcase/page.tsx +724 -792
  45. package/assets/templates/pages/theme-showcase/template.doc.mjs +4 -5
  46. package/authoring/doctypes/template/type.ts +1 -0
  47. package/clients/cli/commands/experimental/icon.mjs +31 -10
  48. package/clients/cli/commands/experimental-icon-add.doc.mjs +1 -1
  49. package/clients/cli/commands/experimental-icon-new-definition.doc.mjs +2 -1
  50. package/clients/cli/commands/experimental-icon-new-set.doc.mjs +2 -2
  51. package/clients/cli/commands/swizzle.doc.mjs +8 -3
  52. package/clients/cli/commands/swizzle.mjs +21 -9
  53. package/foundation/discovery/component-loader.d.mts +1 -1
  54. package/foundation/discovery/doc-types.mjs +9 -2
  55. package/foundation/discovery/icon-ranking.d.mts +27 -3
  56. package/foundation/discovery/icon-ranking.mjs +125 -8
  57. package/foundation/discovery/icon-set-checks.mjs +44 -35
  58. package/foundation/discovery/icon-set-discovery.d.mts +13 -0
  59. package/foundation/discovery/icon-set-discovery.mjs +25 -0
  60. package/foundation/discovery/icon-set-writer.d.mts +238 -16
  61. package/foundation/discovery/icon-set-writer.mjs +676 -79
  62. package/foundation/discovery/module-exports.d.mts +3 -2
  63. package/foundation/discovery/module-exports.mjs +167 -37
  64. package/foundation/fs/paths.d.mts +2 -1
  65. package/foundation/fs/paths.mjs +3 -4
  66. package/foundation/text/shell-arg.d.mts +14 -0
  67. package/foundation/text/shell-arg.mjs +17 -0
  68. package/package.json +6 -6
@@ -9,16 +9,12 @@
9
9
  * - a component name -> api/swizzle/copy -> `swizzle.copy` receipt
10
10
  *
11
11
  * Errors throw AstryxError (stable code + suggestions). All human prose /
12
- * package-manager prefixing lives in the CLI renderer. Re-exports the copy
13
- * leaf's `rewriteImports` so existing importers keep this module as their entry
14
- * point (api/index.mjs, the CLI command, and the unit tests all import from
15
- * here).
12
+ * package-manager prefixing lives in the CLI renderer. api/index.mjs, the CLI
13
+ * command, and the unit tests import `swizzle` from here.
16
14
  */
17
15
 
18
16
  import {swizzleList} from './list/list.mjs';
19
- import {swizzleCopy, rewriteImports} from './copy/copy.mjs';
20
-
21
- export {rewriteImports};
17
+ import {swizzleCopy} from './copy/copy.mjs';
22
18
 
23
19
  /**
24
20
  * List swizzlable components, or copy one component's source for customization.
@@ -41,6 +41,7 @@ export type SwizzleCopyResponse = {
41
41
  filesCopied: number;
42
42
  files: string[];
43
43
  usesStyleX: boolean;
44
+ dependencies: Record<string, string>;
44
45
  feedback?: SwizzleFeedback | undefined;
45
46
  };
46
47
  };
@@ -62,7 +63,7 @@ export type SwizzleOptions = {
62
63
  */
63
64
  list?: boolean | undefined;
64
65
  /**
65
- * Overwrite existing files instead of erroring.
66
+ * Replace the component's existing files instead of erroring. A copy that carries a helper an earlier swizzle wrote never replaces it, except a changed private attribute owner module and the style modules it imports; swizzling the component whose folder holds the helper counts it as that component's own file.
66
67
  */
67
68
  overwrite?: boolean | undefined;
68
69
  };
@@ -34,8 +34,9 @@
34
34
  * @property {string} data.package Owner package the component source was copied from.
35
35
  * @property {string} data.outputDir
36
36
  * @property {number} data.filesCopied
37
- * @property {string[]} data.files Copied file names, relative to the component folder; owner modules and their unexported style modules copied beside it start with `../` (spec:AST-110 FR4).
37
+ * @property {string[]} data.files Copied file names, relative to the component folder; the internal modules copied beside it start with `../` (spec:AST-110 FR2).
38
38
  * @property {boolean} data.usesStyleX Whether any copied file uses StyleX (requires build-time setup).
39
+ * @property {Record<string, string>} data.dependencies Each npm package the copied files import, other than the owner package, with the version range the owner package declares (`*` when it declares none). The copy builds once the product installs them (spec:AST-110 FR1).
39
40
  * @property {SwizzleFeedback} [data.feedback]
40
41
  */
41
42
 
@@ -46,7 +47,7 @@
46
47
  * @property {string} [output] Output directory (must resolve inside cwd). Defaults to ./components/astryx.
47
48
  * @property {string} [package] Scope to a specific owning package when a name is ambiguous.
48
49
  * @property {boolean} [list] Force the list response even with a component argument.
49
- * @property {boolean} [overwrite] Overwrite existing files instead of erroring.
50
+ * @property {boolean} [overwrite] Replace the component's existing files instead of erroring. A copy that carries a helper an earlier swizzle wrote never replaces it, except a changed private attribute owner module and the style modules it imports; swizzling the component whose folder holds the helper counts it as that component's own file.
50
51
  */
51
52
 
52
53
  export {};
@@ -180,6 +180,14 @@
180
180
  "kind": "component",
181
181
  "name": "SVGIcon"
182
182
  },
183
+ {
184
+ "kind": "component",
185
+ "name": "TabBar"
186
+ },
187
+ {
188
+ "kind": "component",
189
+ "name": "TabBarItem"
190
+ },
183
191
  {
184
192
  "kind": "component",
185
193
  "name": "ThreeDBar"
@@ -283,6 +291,18 @@
283
291
  "kind": "component",
284
292
  "name": "RichTextEditor"
285
293
  },
294
+ {
295
+ "kind": "component",
296
+ "name": "RichTextEditorAutoLinkPlugin"
297
+ },
298
+ {
299
+ "kind": "component",
300
+ "name": "RichTextEditorToolbar"
301
+ },
302
+ {
303
+ "kind": "component",
304
+ "name": "RichTextView"
305
+ },
286
306
  {
287
307
  "kind": "template",
288
308
  "name": "RichTextEditorShowcase"
@@ -121,11 +121,11 @@ export const docs = {
121
121
  },
122
122
  {
123
123
  type: 'prose',
124
- text: "Every component the library exports becomes an icon (an alias of one component is recorded once), named `<Name>Icon`, with an id from its name (`Squares2X2Icon` is `squares-2x2`: a dimension stays one word). `map` is filled only where a definition's name is an icon's id (`delete` → icon `delete`), and the receipt lists those entries under Mapped by name: a library can draw another meaning under the same name (one library's `delete` is a backspace key), so check each. An icon whose id is only one of a definition's words (`trash` for `delete`) may mean something else in this library, so the receipt lists it under Suggestions, with the `experimental icon map <definition> <icon>` command for each, and writes nothing for it: check the meaning, then run the ones that fit. Run it again after a library release to refresh the icons that library supplies; `map` entries whose icon still exists are kept, and the receipt names any icon the library dropped, any icon `--exclude` left out, and the `map` entries each took with it. Icons you added from your own files or another library are left as they are. An icon you already have is known by the library export it re-exports, so it keeps its export name exactly, its `map` entries, variants, and words, even when a newer CLI spells its id differently or your `--exclude` lets a library prefix come off new ids; the receipt lists each changed id under `renamed`. A refresh with `--dry-run` writes nothing and prints the Mapped by name and Suggestions lists again; `--display-name` and `--description` on a refresh rewrite the descriptor. Variants added with `add --variant … --all` are kept too; run that `add` again to pick up icons the release added. `experimental icon --list` shows how many definitions the set maps.",
124
+ text: "Every component the library exports becomes an icon (an alias of one component is recorded once), named `<Name>Icon`, with an id from its name (`Squares2X2Icon` is `squares-2x2`: a dimension stays one word). `map` is filled only where a definition's name is an icon's id (`delete` → icon `delete`), and the receipt lists those entries under Mapped by name: a library can draw another meaning under the same name (one library's `delete` is a backspace key), so check each. An icon whose id is only one of a definition's words (`trash` for `delete`) may mean something else in this library, so the receipt lists it under Suggestions, with the `experimental icon map <definition> <icon>` command for each, and writes nothing for it: check the meaning, then run the ones that fit. Run it again after a library release to refresh the icons that library supplies; `map` entries whose icon still exists are kept, and the receipt names any icon the library dropped, any icon `--exclude` left out, and the `map` entries each took with it. Icons you added from your own files or another library are left as they are. Icons you added one file at a time from the same package (`--from <package>/dist/XIcon`) move to the root import when you refresh from the package root and the root exports the same icon; each keeps its id, export, `map` entries, variants, and words on that refresh and every later one, and the receipt lists it under `moved`. A library icon whose id or name a moved icon already has is left out. When another icon of the set already reads the same root export, the icon stays on its own file, and the receipt says why. An icon you already have is known by the library export it re-exports, so it keeps its export name exactly, its `map` entries, variants, and words, even when a newer CLI spells its id differently or your `--exclude` lets a library prefix come off new ids; the receipt lists each changed id under `renamed`. An id you chose that is not a spelling of the library name (`dismiss` for `XIcon`) is kept. A refresh with `--dry-run` writes nothing and prints the Mapped by name and Suggestions lists again; `--display-name` and `--description` on a refresh rewrite the descriptor. Variants added with `add --variant … --all` are kept too; run that `add` again to pick up icons the release added. `experimental icon --list` shows how many definitions the set maps.",
125
125
  },
126
126
  {
127
127
  type: 'prose',
128
- text: "With a package or package subpath, it also records the installed library and version as the data file's `source`, so `integration check` warns when your dependency moves to another version; copies the library's LICENSE (and NOTICE) files into the set directory; and sets the descriptor's `license` to the library's. A set you started without `--from` gets the same the first time a refresh records its source, unless you already changed `license`: a `license` you set is kept (the receipt names the library's), and every later refresh keeps it too. Your package.json `license` is never changed. Edit `license` when the artwork's license differs from the library's package license.",
128
+ text: "With a package or package subpath, it also records the installed library and version as the data file's `source`, so `integration check` warns when your dependency moves to another version; copies the library's LICENSE (and NOTICE) files into the set directory; and sets the descriptor's `license` to the library's. A set you started without `--from` gets the same the first time a refresh records its source, unless you already changed `license`: a `license` you set is kept (the receipt names the library's), and every later refresh keeps it too. Your package.json `license` is never changed. Edit `license` when the artwork's license differs from the library's package license. When the library ships no license file to copy, the receipt says so under `licenseNoticeMissing` and in its notes, and the CLI writes nothing: add a `NOTICE` file to the set directory (`icon-sets/<set>/NOTICE`) that names the library, its version, and its license. `integration check` accepts a file named `LICENSE`, `LICENCE`, `NOTICE`, or `COPYING`, in any case and with an optional suffix such as `NOTICE.md` or `LICENSE-MIT`, in the set directory or the package root; without one it reports `icon_license_notice_missing`.",
129
129
  },
130
130
  {
131
131
  type: 'prose',
@@ -139,7 +139,7 @@ astryx experimental icon add --variant solid --from @heroicons/react/24/solid --
139
139
  },
140
140
  {
141
141
  type: 'prose',
142
- text: "A library that redraws its artwork for small sizes (Heroicons' 20px mini and 16px micro) ships each of those as its own set in its own package (their export names match the 24px ones), not as variants: a variant's size comes from CSS. `--variants` lists the variants; `--default-variant` names the one each icon's own export draws (the first variant when omitted). `--all` adds the variant for every icon whose id an export of `--from` has (`TrashIcon` in the solid module becomes `TrashSolidIcon`, the solid variant of `trash`), and the receipt lists the icons the module has no export for. Running it again changes nothing.",
142
+ text: "A library that redraws its artwork for small sizes (Heroicons' 20px mini and 16px micro) ships each of those as its own set in its own package (their export names match the 24px ones), not as variants: a variant's size comes from CSS. `--variants` lists the variants; `--default-variant` names the one each icon's own export draws (when omitted, the look a library that names its looks draws; otherwise the set's current default, else, on a set without icons, the first variant; a set with icons changes it only with `--from`, and only in a library that names its looks). `--all` adds the variant for every icon whose id an export of `--from` has (`TrashIcon` in the solid module becomes `TrashSolidIcon`, the solid variant of `trash`), and the receipt lists the icons the module has no export for. Running it again changes nothing.",
143
143
  },
144
144
  {
145
145
  type: 'prose',
@@ -177,7 +177,7 @@ astryx experimental icon add --variant solid --from @heroicons/react/24/solid --
177
177
  },
178
178
  {
179
179
  type: 'prose',
180
- text: "An optional render test you can copy. Save it inside your package directory and run it there, since it imports your package by name through its `exports`, and install `react-dom` first (`npm install -D react-dom`). A library may add its own classes beside yours, so it checks the class list. A library that sets `width` and `height` attributes (24, say) still fills its box: CSS sizing, such as the `Icon` component's, overrides SVG size attributes.",
180
+ text: 'An optional render test you can copy. Save it inside your package directory and run it there, since it imports your package by name through its `exports`, and install `react-dom` first (`npm install -D react-dom`). A library may add its own classes beside yours, so it checks the class list. A component that writes its own `width` and `height` attributes (24, from a `size` prop, say) still fills its box when it passes `style` through to its svg: the `Icon` component and `themeIcons` size the svg with CSS, which overrides size attributes. The test checks that too.',
181
181
  },
182
182
  {
183
183
  type: 'code',
@@ -191,6 +191,8 @@ for (const [name, Icon] of Object.entries(icons)) {
191
191
  const html = renderToStaticMarkup(createElement(Icon, {className: 'x'}));
192
192
  if (!/class="([^"]* )?x( [^"]*)?"/.test(html)) throw new Error(\`\${name} drops className\`);
193
193
  if (!html.includes('currentColor')) throw new Error(\`\${name} has a fixed color\`);
194
+ const styled = renderToStaticMarkup(createElement(Icon, {style: {width: '1em'}}));
195
+ if (!styled.includes('width:1em')) throw new Error(\`\${name} drops style, so CSS cannot size it\`);
194
196
  }`,
195
197
  },
196
198
  ],
@@ -215,6 +217,10 @@ for (const [name, Icon] of Object.entries(icons)) {
215
217
  'A subpath per style',
216
218
  '`experimental icon add --variant solid --from @acme/glyph-library/solid --all` for every icon at once, or `experimental icon add Bin --from @acme/glyph-library/solid --id bin --variant solid` for one (the set must declare the variant: `new-set --variants`)',
217
219
  ],
220
+ [
221
+ 'Every look in its export names (`XOutline24WGHT500Icon`, `XFilled24WGHT500Icon`)',
222
+ "`experimental icon new-set meta --from @acme/vector-icons` wraps each glyph once as `x` (`XIcon`), in the look `--default-variant` names or the library's usual default (outline, the middle weight). For another look: `experimental icon new-set meta --variants outline,filled` declares it in place, then `experimental icon add --variant filled --from @acme/vector-icons --all`",
223
+ ],
218
224
  [
219
225
  'One file per icon, default export',
220
226
  '`experimental icon add Rocket --from @acme/glyph-library/rocket --default --definition rocket`',
@@ -262,7 +268,7 @@ export function adapt(data) {
262
268
  content: [
263
269
  {
264
270
  type: 'prose',
265
- text: 'The generated module also exports `themeIcons`: one entry per built-in definition in `map`, each an element of your own icon, hidden from assistive technology and sized `1em`. The CLI rewrites it on every `experimental icon add` and `experimental icon map`, so you never write it by hand, and `integration check` proves it matches `map`. A theme uses it in one line:',
271
+ text: "The generated module also exports `themeIcons`: one entry per built-in definition in `map`, each an element of your own icon, hidden from assistive technology and sized `1em` by its attributes and by CSS (its `style`), so it fills the theme's icon box even when your component writes its own size attributes. The CLI rewrites it on every `experimental icon add` and `experimental icon map`, so you never write it by hand, and `integration check` proves it matches `map`. A theme uses it in one line:",
266
272
  },
267
273
  {
268
274
  type: 'code',
@@ -7,7 +7,7 @@ export const doc = {
7
7
  name: 'useTableRowIndex — Numbered Rows',
8
8
  displayName: 'useTableRowIndex — Numbered Rows',
9
9
  description:
10
- 'A table with a prepended row-number column via useTableRowIndex. Numbering is monospaced, right-aligned, and follows the rendered data order.',
10
+ 'A table with a prepended row-number column via useTableRowIndex. Numbering is monospaced, right-aligned, and follows the rows the table renders.',
11
11
  isReady: true,
12
12
  aspectRatio: 16 / 9,
13
13
  componentsUsed: ['Table'],
@@ -32,8 +32,8 @@ const columns: TableColumn<Track>[] = [
32
32
  ];
33
33
 
34
34
  export default function TableRowIndexTable() {
35
- // Pass the rendered data array — numbering follows its order.
36
- const rowIndex = useTableRowIndex<Track>({data: tracks});
35
+ // Table gives each row its position, so numbering follows the rendered rows.
36
+ const rowIndex = useTableRowIndex<Track>();
37
37
 
38
38
  return (
39
39
  <Table