@hirobius/design-system 0.19.1 → 0.21.0

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 (175) hide show
  1. package/AGENTS.md +123 -0
  2. package/CONSUMING.md +11 -6
  3. package/DESIGN.md +34 -21
  4. package/NOTICE.md +1 -1
  5. package/README.md +48 -13
  6. package/codemods/hds-prefix.mjs +231 -0
  7. package/codemods/jsx-fold.mjs +515 -0
  8. package/codemods/not-found-pattern.mjs +71 -0
  9. package/codemods/patterns-subpath.mjs +242 -81
  10. package/codemods/patterns-subpath.names.json +41 -15
  11. package/codemods/removed-0.20.json +194 -0
  12. package/codemods/tile-grid.mjs +283 -0
  13. package/codemods/unrewritable.mjs +291 -0
  14. package/dist/chunks/DemoStateContext-Cz5TmrYu.js +32 -0
  15. package/dist/chunks/empty-state-DNoThgfV.js +1227 -0
  16. package/dist/chunks/form-By82qZcC.js +66 -0
  17. package/dist/contexts.js +157 -78
  18. package/dist/fonts/geist-mono-400.woff2 +0 -0
  19. package/dist/fonts/satoshi-400.woff2 +0 -0
  20. package/dist/fonts/satoshi-500.woff2 +0 -0
  21. package/dist/fonts/satoshi-700.woff2 +0 -0
  22. package/dist/fonts.css +53 -0
  23. package/dist/form.js +1 -1
  24. package/dist/hirobius-ui.js +1600 -5354
  25. package/dist/manifest.js +12 -13
  26. package/dist/patterns.js +796 -510
  27. package/dist/styles.css +2 -2
  28. package/dist/tokens.css +1 -1
  29. package/dist/tokens.js +165 -65
  30. package/dist/types/src/app/components/alert-dialog.d.ts +5 -0
  31. package/dist/types/src/app/components/asset-img.d.ts +1 -0
  32. package/dist/types/src/app/components/avatar-group.d.ts +2 -2
  33. package/dist/types/src/app/components/badge.d.ts +8 -3
  34. package/dist/types/src/app/components/blockquote.d.ts +2 -2
  35. package/dist/types/src/app/components/box-sx.d.ts +110 -13
  36. package/dist/types/src/app/components/box.d.ts +6 -3
  37. package/dist/types/src/app/components/breadcrumb.d.ts +0 -5
  38. package/dist/types/src/app/components/button.d.ts +35 -4
  39. package/dist/types/src/app/components/card.d.ts +10 -10
  40. package/dist/types/src/app/components/combobox.d.ts +47 -11
  41. package/dist/types/src/app/components/container.d.ts +2 -2
  42. package/dist/types/src/app/components/data-table-section.d.ts +2 -1
  43. package/dist/types/src/app/components/destructive-section.d.ts +1 -0
  44. package/dist/types/src/app/components/dialog.d.ts +8 -1
  45. package/dist/types/src/app/components/disclosure.d.ts +1 -5
  46. package/dist/types/src/app/components/error-pattern.d.ts +6 -1
  47. package/dist/types/src/app/components/field.d.ts +1 -2
  48. package/dist/types/src/app/components/form-actions.d.ts +1 -0
  49. package/dist/types/src/app/components/form-control.d.ts +10 -0
  50. package/dist/types/src/app/components/grid.d.ts +15 -6
  51. package/dist/types/src/app/components/hds-tooltip.d.ts +12 -2
  52. package/dist/types/src/app/components/icon.d.ts +1 -0
  53. package/dist/types/src/app/components/inline-code.d.ts +1 -2
  54. package/dist/types/src/app/components/input.d.ts +8 -5
  55. package/dist/types/src/app/components/kbd.d.ts +2 -2
  56. package/dist/types/src/app/components/metadata-list.d.ts +2 -2
  57. package/dist/types/src/app/components/metric-tiles.d.ts +1 -0
  58. package/dist/types/src/app/components/page-header.d.ts +0 -2
  59. package/dist/types/src/app/components/popover.d.ts +8 -0
  60. package/dist/types/src/app/components/progress.d.ts +33 -6
  61. package/dist/types/src/app/components/segmented-control.d.ts +2 -26
  62. package/dist/types/src/app/components/select.d.ts +10 -1
  63. package/dist/types/src/app/components/skeleton.d.ts +3 -4
  64. package/dist/types/src/app/components/spinner.d.ts +1 -2
  65. package/dist/types/src/app/components/stack.d.ts +4 -1
  66. package/dist/types/src/app/components/stat.d.ts +5 -5
  67. package/dist/types/src/app/components/status-list-item.d.ts +1 -2
  68. package/dist/types/src/app/components/status-tile.d.ts +3 -2
  69. package/dist/types/src/app/components/surface.d.ts +2 -3
  70. package/dist/types/src/app/components/switcher.d.ts +1 -1
  71. package/dist/types/src/app/components/table.d.ts +6 -15
  72. package/dist/types/src/app/components/tag.d.ts +0 -6
  73. package/dist/types/src/app/components/text.d.ts +54 -8
  74. package/dist/types/src/app/components/textarea.d.ts +1 -2
  75. package/dist/types/src/app/components/timestamp.d.ts +1 -0
  76. package/dist/types/src/app/components/toast.d.ts +1 -2
  77. package/dist/types/src/app/components/tooltip.d.ts +1 -1
  78. package/dist/types/src/app/context/DemoStateContext.d.ts +1 -1
  79. package/dist/types/src/app/context/RouterContext.d.ts +5 -5
  80. package/dist/types/src/app/data/manifest-types.d.ts +10 -5
  81. package/dist/types/src/app/design-system/generated-token-refs.d.ts +45 -28
  82. package/dist/types/src/app/design-system/generated-token-values.d.ts +4 -0
  83. package/dist/types/src/app/design-system/tokens.d.ts +139 -18
  84. package/dist/types/src/icons.d.ts +1 -1
  85. package/dist/types/src/index.d.ts +76 -164
  86. package/dist/types/src/patterns.d.ts +20 -25
  87. package/dist/variables.css +47 -33
  88. package/docs/CONSUMING.md +80 -48
  89. package/hirobius.tokens.json +125 -88
  90. package/llms.txt +166 -59
  91. package/mcp/catalog.mjs +366 -0
  92. package/mcp/guide.mjs +315 -0
  93. package/mcp/hds-mcp.mjs +49 -0
  94. package/mcp/server.mjs +94 -0
  95. package/package.json +48 -27
  96. package/public/hds-manifest.json +2667 -6705
  97. package/public/llms/components.txt +45 -426
  98. package/public/llms/layout.txt +5 -5
  99. package/public/llms-full.txt +245 -506
  100. package/public/llms.txt +166 -59
  101. package/scripts/eslint-plugin-hds/index.d.mts +29 -0
  102. package/scripts/eslint-plugin-hds/index.mjs +55 -0
  103. package/scripts/eslint-plugin-hds/package.json +30 -0
  104. package/scripts/eslint-plugin-hds/rules/no-raw-controls.mjs +47 -0
  105. package/scripts/eslint-plugin-hds/rules/no-raw-hex.mjs +70 -0
  106. package/scripts/eslint-plugin-hds/rules/no-raw-px-spacing.mjs +125 -0
  107. package/scripts/eslint-plugin-hds/rules/prefer-hds-layout-primitive.mjs +54 -0
  108. package/scripts/eslint-plugin-hds/rules/sx-token-first.mjs +111 -0
  109. package/scripts/eslint-plugin-hds/rules/utils.mjs +66 -0
  110. package/src/app/data/component-api.json +1082 -2913
  111. package/dist/chunks/LanguageContext-BxdCwiFg.js +0 -95
  112. package/dist/chunks/TokenDisplayContext-DKYJMVWk.js +0 -26
  113. package/dist/chunks/activity-feed-BGQ6v3wc.js +0 -22040
  114. package/dist/chunks/form-COP3vK9_.js +0 -66
  115. package/dist/types/src/app/components/activity-feed.d.ts +0 -73
  116. package/dist/types/src/app/components/app-shell.d.ts +0 -40
  117. package/dist/types/src/app/components/aspect-ratio.d.ts +0 -25
  118. package/dist/types/src/app/components/bleed.d.ts +0 -39
  119. package/dist/types/src/app/components/button-group.d.ts +0 -22
  120. package/dist/types/src/app/components/calendar.d.ts +0 -22
  121. package/dist/types/src/app/components/carousel.d.ts +0 -26
  122. package/dist/types/src/app/components/center.d.ts +0 -36
  123. package/dist/types/src/app/components/cinematic-link.d.ts +0 -18
  124. package/dist/types/src/app/components/circular-progress.d.ts +0 -28
  125. package/dist/types/src/app/components/cluster.d.ts +0 -39
  126. package/dist/types/src/app/components/command-palette.d.ts +0 -46
  127. package/dist/types/src/app/components/component-instance-matrix.d.ts +0 -27
  128. package/dist/types/src/app/components/context-menu.d.ts +0 -78
  129. package/dist/types/src/app/components/cover.d.ts +0 -43
  130. package/dist/types/src/app/components/date-input.d.ts +0 -31
  131. package/dist/types/src/app/components/date-range-input.d.ts +0 -34
  132. package/dist/types/src/app/components/date-time-input.d.ts +0 -30
  133. package/dist/types/src/app/components/doc-link-card.d.ts +0 -32
  134. package/dist/types/src/app/components/error-boundary.d.ts +0 -25
  135. package/dist/types/src/app/components/file-input.d.ts +0 -30
  136. package/dist/types/src/app/components/foundation-swatch.d.ts +0 -45
  137. package/dist/types/src/app/components/frame.d.ts +0 -38
  138. package/dist/types/src/app/components/heading-stack.d.ts +0 -52
  139. package/dist/types/src/app/components/history-card.d.ts +0 -12
  140. package/dist/types/src/app/components/hover-card.d.ts +0 -46
  141. package/dist/types/src/app/components/icon-button.d.ts +0 -22
  142. package/dist/types/src/app/components/image-lightbox.d.ts +0 -14
  143. package/dist/types/src/app/components/input-group.d.ts +0 -23
  144. package/dist/types/src/app/components/multi-selector.d.ts +0 -40
  145. package/dist/types/src/app/components/nav-group.d.ts +0 -29
  146. package/dist/types/src/app/components/nav-item.d.ts +0 -33
  147. package/dist/types/src/app/components/not-found-pattern.d.ts +0 -1
  148. package/dist/types/src/app/components/overflow-list.d.ts +0 -21
  149. package/dist/types/src/app/components/selectable-card.d.ts +0 -29
  150. package/dist/types/src/app/components/side-nav.d.ts +0 -23
  151. package/dist/types/src/app/components/sketch.d.ts +0 -19
  152. package/dist/types/src/app/components/stacked-card-rail.d.ts +0 -32
  153. package/dist/types/src/app/components/status-dot.d.ts +0 -25
  154. package/dist/types/src/app/components/stepper-field.d.ts +0 -12
  155. package/dist/types/src/app/components/stepper.d.ts +0 -33
  156. package/dist/types/src/app/components/text-lockup.d.ts +0 -38
  157. package/dist/types/src/app/components/tile-grid.d.ts +0 -17
  158. package/dist/types/src/app/components/time-input.d.ts +0 -24
  159. package/dist/types/src/app/components/toggle-button.d.ts +0 -32
  160. package/dist/types/src/app/components/token.d.ts +0 -90
  161. package/dist/types/src/app/components/tokenUtils.d.ts +0 -38
  162. package/dist/types/src/app/components/tokenizer.d.ts +0 -24
  163. package/dist/types/src/app/components/toolbar.d.ts +0 -36
  164. package/dist/types/src/app/components/top-nav.d.ts +0 -23
  165. package/dist/types/src/app/components/tree-list.d.ts +0 -30
  166. package/dist/types/src/app/data/nav-model.d.ts +0 -39
  167. package/dist/types/src/app/hooks/useFocusVisible.d.ts +0 -9
  168. package/dist/types/src/app/layouts/CaseStudyLayout.d.ts +0 -20
  169. package/dist/types/src/app/layouts/DocLayout.d.ts +0 -14
  170. package/dist/types/src/app/layouts/EmbeddedDocLayoutContext.d.ts +0 -6
  171. package/dist/types/src/app/layouts/HdsDocsShell.d.ts +0 -72
  172. package/dist/types/src/app/layouts/HdsSystemDocLayout.d.ts +0 -14
  173. package/dist/types/src/app/lib/hds-search.d.ts +0 -45
  174. package/dist/types/src/app/lib/nav-active.d.ts +0 -16
  175. package/dist/types/src/app/lib/navLevels.d.ts +0 -4
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * hds-prefix codemod (hds#389 R1, follows hds#315)
4
+ *
5
+ * 0.20.0 removed the six `Hds*` aliases from the package root: HdsCheckbox,
6
+ * HdsRadio, HdsSelect, HdsSlider, HdsToggle and HdsTooltip. Each is the same
7
+ * component under its bare name. This rewrites the import specifier only, and
8
+ * keeps the name the file already uses:
9
+ *
10
+ * - `import { HdsCheckbox } from '@hirobius/design-system'` becomes
11
+ * `import { Checkbox as HdsCheckbox } from '@hirobius/design-system'`;
12
+ * - `HdsSelect as Pick` becomes `Select as Pick`; `type` modifiers stay;
13
+ * - `export { HdsToggle } from '…'` becomes `export { Toggle as HdsToggle } from '…'`,
14
+ * so the file's own export name does not change.
15
+ *
16
+ * No other text in the file changes: JSX, values, `typeof`, spreads, string
17
+ * keys, comments (including comments inside the import braces) and imports from
18
+ * any other module stay as written, so every reference still resolves to the
19
+ * same component. Renaming the local binding to the bare name afterwards is
20
+ * optional and a manual edit. Only named imports and re-exports whose source is
21
+ * exactly the package root are rewritten, and running it twice changes nothing.
22
+ *
23
+ * node codemods/hds-prefix.mjs [--root <dir>] [--check] [--dry-run]
24
+ *
25
+ * --root <dir> directory to scan (default: current directory)
26
+ * --check write nothing; exit 1 when a rewrite is needed, or when a root
27
+ * star re-export, or a namespace import or dynamic `import()`,
28
+ * `require()` or `vi.mock`/`jest.mock` of the root that reads an
29
+ * Hds* name off the module, or a file that cannot be read to its
30
+ * end (codemods/unrewritable.mjs), needs a manual look
31
+ * --dry-run write nothing; print each changed line before (-) and after (+), exit 0
32
+ */
33
+ import { readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from 'node:fs';
34
+ import { relative, resolve, join } from 'node:path';
35
+ import { fileURLToPath } from 'node:url';
36
+ import { findUnrewritable as findHidden, maskSource } from './unrewritable.mjs';
37
+
38
+ const ROOT_PKG = '@hirobius/design-system';
39
+ const EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts']);
40
+ const SKIP_DIRS = new Set([
41
+ 'node_modules',
42
+ 'dist',
43
+ 'build',
44
+ '.git',
45
+ '.next',
46
+ '.vercel',
47
+ 'coverage',
48
+ 'storybook-static',
49
+ ]);
50
+
51
+ /** The aliases 0.19.1 exported from the root, and the bare name each pointed at. */
52
+ export const RENAMES = Object.freeze({
53
+ HdsCheckbox: 'Checkbox',
54
+ HdsRadio: 'Radio',
55
+ HdsSelect: 'Select',
56
+ HdsSlider: 'Slider',
57
+ HdsToggle: 'Toggle',
58
+ HdsTooltip: 'Tooltip',
59
+ });
60
+
61
+ const ID = '[A-Za-z_$][\\w$]*';
62
+ // Matched on the masked source (codemods/unrewritable.mjs), where comments are
63
+ // blank and the specifier is a run of spaces between its quotes:
64
+ // at a line start or after `;`: import|export, type?, default?, { body }, from, quote.
65
+ const namedRe = () =>
66
+ new RegExp(
67
+ `(?:^|(?<=;))[ \\t]*(?:import|export)(?:\\s+type)?\\s*(?:${ID}\\s*,\\s*)?\\{([^}]*)\\}\\s*from\\s*(['"]) {${ROOT_PKG.length}}\\2`,
68
+ 'gm',
69
+ );
70
+ // One specifier, between commas: `type`? name, then `as alias`?
71
+ const specRe = new RegExp(`^(\\s*(?:type\\s+)?)(${ID})(\\s+as\\s+${ID})?\\s*$`);
72
+
73
+ /**
74
+ * Pure transform of one file's source: rewrites the Hds* specifiers of each
75
+ * named import or re-export from the package root, and nothing else.
76
+ * @param {string} source
77
+ * @param {Record<string, string>} [renames]
78
+ * @returns {{ source: string, changed: boolean, sites: number, renamed: string[],
79
+ * edits: { line: number, before: string, after: string }[] }}
80
+ */
81
+ export function transformSource(source, renames = RENAMES) {
82
+ const { code } = maskSource(source);
83
+ const renamed = new Set();
84
+ const changes = [];
85
+ let sites = 0;
86
+
87
+ for (const m of code.matchAll(namedRe())) {
88
+ const quoteAt = m.index + m[0].length - ROOT_PKG.length - 2;
89
+ if (!source.startsWith(ROOT_PKG, quoteAt + 1)) continue;
90
+ const bodyAt = m.index + m[0].indexOf('{') + 1;
91
+ let touched = false;
92
+ let at = bodyAt;
93
+ for (const spec of m[1].split(',')) {
94
+ const s = specRe.exec(spec);
95
+ const bare = s && Object.hasOwn(renames, s[2]) ? renames[s[2]] : undefined;
96
+ if (bare) {
97
+ const name = s[2];
98
+ const nameAt = at + s[1].length;
99
+ // Keep the name the file uses: `HdsCheckbox` -> `Checkbox as HdsCheckbox`.
100
+ changes.push({
101
+ start: nameAt,
102
+ end: nameAt + name.length,
103
+ text: s[3] ? bare : `${bare} as ${name}`,
104
+ });
105
+ renamed.add(name);
106
+ touched = true;
107
+ }
108
+ at += spec.length + 1;
109
+ }
110
+ if (touched) sites++;
111
+ }
112
+
113
+ let out = source;
114
+ for (const r of changes.sort((a, b) => b.start - a.start))
115
+ out = out.slice(0, r.start) + r.text + out.slice(r.end);
116
+
117
+ if (out === source) return { source, changed: false, sites: 0, renamed: [], edits: [] };
118
+ const before = source.split('\n');
119
+ const after = out.split('\n');
120
+ const edits = [];
121
+ before.forEach((line, i) => {
122
+ if (line !== after[i]) edits.push({ line: i + 1, before: line, after: after[i] });
123
+ });
124
+ return { source: out, changed: true, sites, renamed: [...renamed].sort(), edits };
125
+ }
126
+
127
+ /**
128
+ * What the codemod cannot rewrite (codemods/unrewritable.mjs): a star re-export
129
+ * of the root, whose importers are in other files; and a namespace import or a
130
+ * dynamic `import()`, `require()`, `vi.mock` or `jest.mock` of the root in a file
131
+ * that reads an Hds* name off something (`HDS.HdsSlider`, `m['HdsToggle']`,
132
+ * `const { HdsRadio } = …`). The alias binding the codemod writes is not a read.
133
+ */
134
+ export function findUnrewritable(source, renames = RENAMES) {
135
+ return findHidden(source, ROOT_PKG, Object.keys(renames));
136
+ }
137
+
138
+ function* walk(dir) {
139
+ for (const entry of readdirSync(dir)) {
140
+ if (SKIP_DIRS.has(entry)) continue;
141
+ const full = join(dir, entry);
142
+ const st = statSync(full);
143
+ if (st.isDirectory()) yield* walk(full);
144
+ else if (EXTS.has(full.slice(full.lastIndexOf('.')))) yield full;
145
+ }
146
+ }
147
+
148
+ /** Scan a directory. Writes only when `write` is true. */
149
+ export function runCodemod({ root, write = false, renames = RENAMES }) {
150
+ const files = [];
151
+ const manual = [];
152
+ const renamed = new Set();
153
+ let sites = 0;
154
+ for (const file of walk(root)) {
155
+ const src = readFileSync(file, 'utf8');
156
+ if (!src.includes(ROOT_PKG)) continue;
157
+ const r = transformSource(src, renames);
158
+ for (const stmt of findUnrewritable(r.source, renames))
159
+ manual.push({ file: relative(root, file), stmt });
160
+ if (!r.changed) continue;
161
+ files.push({ file: relative(root, file), sites: r.sites, renamed: r.renamed, edits: r.edits });
162
+ r.renamed.forEach((n) => renamed.add(n));
163
+ sites += r.sites;
164
+ if (write) writeFileSync(file, r.source);
165
+ }
166
+ return { files, sites, manual, names: [...renamed].sort() };
167
+ }
168
+
169
+ function main(argv) {
170
+ const args = { root: process.cwd(), check: false, dryRun: false };
171
+ for (let i = 0; i < argv.length; i++) {
172
+ if (argv[i] === '--root') args.root = resolve(argv[++i] ?? '');
173
+ else if (argv[i] === '--check') args.check = true;
174
+ else if (argv[i] === '--dry-run') args.dryRun = true;
175
+ else {
176
+ console.error(
177
+ `unknown argument: ${argv[i]}\nusage: hds-prefix [--root <dir>] [--check] [--dry-run]`,
178
+ );
179
+ return 2;
180
+ }
181
+ }
182
+ const write = !args.check && !args.dryRun;
183
+ const res = runCodemod({ root: args.root, write });
184
+ const names = res.names.map((n) => `${n} -> ${RENAMES[n]}`).join(', ') || 'none';
185
+ const summary = `${res.files.length} files, ${res.sites} import sites, ${res.names.length} names (${names})`;
186
+ // An unreadable file names its own fix; the rest need the bare names by hand.
187
+ const manualLines = res.manual.map(
188
+ (m) =>
189
+ ` ${m.file}: ${m.stmt}${m.stmt.startsWith('unreadable ') ? '' : ' (use the bare names by hand)'}`,
190
+ );
191
+ if (args.check) {
192
+ if (res.files.length > 0 || res.manual.length > 0) {
193
+ console.error(`hds-prefix: rewrite needed: ${summary}`);
194
+ for (const f of res.files) console.error(` ${f.file}: ${f.renamed.join(', ')}`);
195
+ for (const l of manualLines) console.error(l);
196
+ return 1;
197
+ }
198
+ console.log('hds-prefix: nothing to rewrite');
199
+ return 0;
200
+ }
201
+ console.log(`hds-prefix: ${write ? 'rewrote' : 'would rewrite'} ${summary}`);
202
+ for (const f of res.files) {
203
+ console.log(` ${f.file}: ${f.renamed.join(', ')}`);
204
+ if (args.dryRun)
205
+ for (const e of f.edits) {
206
+ console.log(`- ${e.before}`);
207
+ console.log(`+ ${e.after}`);
208
+ }
209
+ }
210
+ if (res.manual.length > 0) {
211
+ console.warn('hds-prefix: cannot rewrite these, do them by hand:');
212
+ for (const l of manualLines) console.warn(l);
213
+ }
214
+ return 0;
215
+ }
216
+
217
+ // Compare real paths: npm/yarn link the bin and pnpm links the package directory, so
218
+ // argv[1] is a symlink while import.meta.url is already resolved.
219
+ const isEntry = (() => {
220
+ try {
221
+ return (
222
+ !!process.argv[1] &&
223
+ realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))
224
+ );
225
+ } catch {
226
+ return false;
227
+ }
228
+ })();
229
+ if (isEntry) {
230
+ process.exit(main(process.argv.slice(2)));
231
+ }