@adia-ai/web-components 0.8.4 → 0.8.5
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 +18 -1
- package/USAGE.md +60 -25
- package/components/adia-mark/adia-mark.a2ui.json +123 -0
- package/components/adia-mark/adia-mark.class.js +64 -0
- package/components/adia-mark/adia-mark.css +48 -0
- package/components/adia-mark/adia-mark.d.ts +20 -0
- package/components/adia-mark/adia-mark.examples.md +26 -0
- package/components/adia-mark/adia-mark.js +17 -0
- package/components/adia-mark/adia-mark.test.js +69 -0
- package/components/adia-mark/adia-mark.yaml +121 -0
- package/components/agent-questions/agent-questions.a2ui.json +2 -1
- package/components/agent-questions/agent-questions.class.js +96 -53
- package/components/agent-questions/agent-questions.css +27 -106
- package/components/agent-questions/agent-questions.yaml +1 -0
- package/components/button/button.class.js +5 -1
- package/components/calendar-grid/calendar-grid.a2ui.json +3 -1
- package/components/calendar-grid/calendar-grid.class.js +11 -6
- package/components/calendar-grid/calendar-grid.css +42 -20
- package/components/calendar-grid/calendar-grid.yaml +5 -0
- package/components/calendar-picker/calendar-picker.a2ui.json +3 -1
- package/components/calendar-picker/calendar-picker.class.js +11 -6
- package/components/calendar-picker/calendar-picker.css +39 -19
- package/components/calendar-picker/calendar-picker.yaml +5 -0
- package/components/chart/chart.class.js +17 -14
- package/components/color-input/color-input.class.js +8 -5
- package/components/color-picker/color-picker.class.js +6 -3
- package/components/field/field.class.js +10 -7
- package/components/fields/fields.class.js +15 -12
- package/components/icon/icon.class.js +9 -5
- package/components/index.js +1 -0
- package/components/nav/nav.class.js +2 -1
- package/components/noodles/noodles.class.js +14 -10
- package/components/page/page.class.js +3 -2
- package/components/select/select.class.js +3 -2
- package/components/swatch/swatch.class.js +27 -24
- package/components/swiper/swiper.class.js +4 -1
- package/components/swiper/swiper.css +13 -4
- package/components/toolbar/toolbar.class.js +11 -6
- package/components/tree/tree.class.js +5 -2
- package/core/data-stream.js +21 -15
- package/core/element.js +36 -1
- package/core/element.test.js +67 -0
- package/core/icons-phosphor.js +86 -22
- package/core/icons.js +22 -8
- package/dist/theme-provider.min.js +2 -2
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +107 -102
- package/dist/web-components.sheet.js +1 -1
- package/package.json +1 -5
- package/styles/components.css +1 -0
- package/traits/error-shake/error-shake.js +23 -17
- package/traits/fade-presence/fade-presence.js +19 -15
- package/traits/success-checkmark/success-checkmark.js +21 -16
package/core/element.js
CHANGED
|
@@ -64,6 +64,26 @@ function installProps(el, props) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// A minimal no-op ElementInternals shim for environments with no real
|
|
68
|
+
// implementation (linkedom and other DOM-shim SSR passes — gh#285). Real
|
|
69
|
+
// form-participation/validation behavior is meaningless server-side (no
|
|
70
|
+
// live user interaction to validate); the shim exists so the ~12
|
|
71
|
+
// call sites across the framework that read `this.internals.setValidity(…)`
|
|
72
|
+
// / `.setFormValue(…)` / `.validity` etc. keep working as inert no-ops
|
|
73
|
+
// instead of throwing on a missing method. Surface matches exactly what
|
|
74
|
+
// the framework's own consumers call (grepped, not guessed).
|
|
75
|
+
const NOOP_INTERNALS = Object.freeze({
|
|
76
|
+
setFormValue() {},
|
|
77
|
+
setValidity() {},
|
|
78
|
+
checkValidity() { return true; },
|
|
79
|
+
reportValidity() { return true; },
|
|
80
|
+
get form() { return null; },
|
|
81
|
+
get labels() { return []; },
|
|
82
|
+
get validity() { return {}; },
|
|
83
|
+
get validationMessage() { return ''; },
|
|
84
|
+
get willValidate() { return false; },
|
|
85
|
+
});
|
|
86
|
+
|
|
67
87
|
function reflect(el, a, v, t) {
|
|
68
88
|
t === Boolean
|
|
69
89
|
? v ? el.setAttribute(a, '') : el.removeAttribute(a)
|
|
@@ -78,6 +98,11 @@ function adoptStyles(ctor) {
|
|
|
78
98
|
ctor._sa = true;
|
|
79
99
|
const sheets = ctor.styles;
|
|
80
100
|
if (!sheets) return;
|
|
101
|
+
// gh#285 — linkedom's document has no adoptedStyleSheets at all; SSR
|
|
102
|
+
// has no rendered stylesheet to adopt into anyway (styles matter for
|
|
103
|
+
// paint, which doesn't happen server-side), so skipping is a correct
|
|
104
|
+
// no-op, not a degraded feature.
|
|
105
|
+
if (!('adoptedStyleSheets' in document)) return;
|
|
81
106
|
const list = Array.isArray(sheets) ? sheets : [sheets];
|
|
82
107
|
document.adoptedStyleSheets = [...document.adoptedStyleSheets, ...list.filter(s => !document.adoptedStyleSheets.includes(s))];
|
|
83
108
|
}
|
|
@@ -114,7 +139,17 @@ export class UIElement extends HTMLElement {
|
|
|
114
139
|
|
|
115
140
|
constructor() {
|
|
116
141
|
super();
|
|
117
|
-
|
|
142
|
+
// gh#285 — linkedom (and other DOM-shim SSR passes) implement no
|
|
143
|
+
// ElementInternals; an unconditional attachInternals() call threw
|
|
144
|
+
// HERE, before ANY subclass code ran — the single highest-leverage
|
|
145
|
+
// crash site in the whole framework under SSR. Feature-detect and
|
|
146
|
+
// fall back to a no-op shim (form participation is meaningless
|
|
147
|
+
// server-side) rather than leaving `this.internals` undefined,
|
|
148
|
+
// which would just move the crash to every consumer's first
|
|
149
|
+
// `.setValidity(…)` call instead of fixing it.
|
|
150
|
+
this.internals = typeof this.attachInternals === 'function'
|
|
151
|
+
? this.attachInternals()
|
|
152
|
+
: NOOP_INTERNALS;
|
|
118
153
|
installProps(this, this.constructor.properties);
|
|
119
154
|
}
|
|
120
155
|
|
package/core/element.test.js
CHANGED
|
@@ -249,3 +249,70 @@ describe('UIElement — addTrait', () => {
|
|
|
249
249
|
expect(disconnects).toBe(1);
|
|
250
250
|
});
|
|
251
251
|
});
|
|
252
|
+
|
|
253
|
+
// gh#285 — SSR DOM shims (linkedom et al.) implement no ElementInternals
|
|
254
|
+
// and no document.adoptedStyleSheets. These tests simulate that absence
|
|
255
|
+
// directly (deleting the real APIs) rather than trusting a mock — the
|
|
256
|
+
// bug was an unconditional call crashing the CONSTRUCTOR, before any
|
|
257
|
+
// subclass code ran, so the only real proof is exercising construction
|
|
258
|
+
// with the API genuinely gone.
|
|
259
|
+
describe('UIElement — SSR browser-API absence (gh#285)', () => {
|
|
260
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
261
|
+
|
|
262
|
+
it('constructs without throwing when attachInternals does not exist', () => {
|
|
263
|
+
const original = HTMLElement.prototype.attachInternals;
|
|
264
|
+
delete HTMLElement.prototype.attachInternals;
|
|
265
|
+
try {
|
|
266
|
+
class El extends UIElement {}
|
|
267
|
+
const tag = registerTestElement(El);
|
|
268
|
+
expect(() => mount(tag)).not.toThrow();
|
|
269
|
+
} finally {
|
|
270
|
+
HTMLElement.prototype.attachInternals = original;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('the no-op internals shim answers every call site the framework actually makes', () => {
|
|
275
|
+
const original = HTMLElement.prototype.attachInternals;
|
|
276
|
+
delete HTMLElement.prototype.attachInternals;
|
|
277
|
+
let el;
|
|
278
|
+
try {
|
|
279
|
+
class El extends UIElement {}
|
|
280
|
+
const tag = registerTestElement(El);
|
|
281
|
+
el = mount(tag);
|
|
282
|
+
} finally {
|
|
283
|
+
HTMLElement.prototype.attachInternals = original;
|
|
284
|
+
}
|
|
285
|
+
expect(() => el.internals.setFormValue('x')).not.toThrow();
|
|
286
|
+
expect(() => el.internals.setValidity({})).not.toThrow();
|
|
287
|
+
expect(el.internals.checkValidity()).toBe(true);
|
|
288
|
+
expect(el.internals.reportValidity()).toBe(true);
|
|
289
|
+
expect(el.internals.form).toBeNull();
|
|
290
|
+
expect(el.internals.labels).toEqual([]);
|
|
291
|
+
expect(el.internals.validity).toEqual({});
|
|
292
|
+
expect(el.internals.validationMessage).toBe('');
|
|
293
|
+
expect(el.internals.willValidate).toBe(false);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('a real attachInternals is still used when the browser provides one (no regression)', () => {
|
|
297
|
+
class El extends UIElement {}
|
|
298
|
+
const tag = registerTestElement(El);
|
|
299
|
+
const el = mount(tag);
|
|
300
|
+
// happy-dom's real attachInternals — not the shim.
|
|
301
|
+
expect(el.internals).not.toBe(null);
|
|
302
|
+
expect(typeof el.internals.setFormValue).toBe('function');
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('adoptStyles no-ops instead of throwing when adoptedStyleSheets does not exist', () => {
|
|
306
|
+
const desc = Object.getOwnPropertyDescriptor(Document.prototype, 'adoptedStyleSheets');
|
|
307
|
+
delete Document.prototype.adoptedStyleSheets;
|
|
308
|
+
try {
|
|
309
|
+
class El extends UIElement {
|
|
310
|
+
static styles = ['/* fake sheet */'];
|
|
311
|
+
}
|
|
312
|
+
const tag = registerTestElement(El);
|
|
313
|
+
expect(() => mount(tag)).not.toThrow();
|
|
314
|
+
} finally {
|
|
315
|
+
if (desc) Object.defineProperty(Document.prototype, 'adoptedStyleSheets', desc);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
});
|
package/core/icons-phosphor.js
CHANGED
|
@@ -31,13 +31,66 @@
|
|
|
31
31
|
* import { installIconLoaders } from '@adia-ai/web-components/core/icons';
|
|
32
32
|
* installIconLoaders({
|
|
33
33
|
* regular: import.meta.glob(
|
|
34
|
-
* '
|
|
34
|
+
* '../node_modules/@phosphor-icons/core/assets/regular/{caret-right,moon,sun,x}.svg',
|
|
35
35
|
* { query: '?raw', import: 'default', eager: true }
|
|
36
36
|
* ),
|
|
37
37
|
* });
|
|
38
38
|
*
|
|
39
39
|
* Brace-list globs are statically analyzed; only the named files are
|
|
40
|
-
* emitted as chunks (or inlined when `eager: true`).
|
|
40
|
+
* emitted as chunks (or inlined when `eager: true`). Use the `../node_modules/...`
|
|
41
|
+
* form shown here, not `/node_modules/...` — see "Why the glob is entry-relative,
|
|
42
|
+
* not root-relative" below; the same reasoning applies to a hand-written
|
|
43
|
+
* scoped glob as to the auto-discovery globs this file installs by default.
|
|
44
|
+
*
|
|
45
|
+
* ## Why the glob is entry-relative, not root-relative
|
|
46
|
+
*
|
|
47
|
+
* `import.meta.glob` only accepts a small set of static forms (`/`-rooted,
|
|
48
|
+
* `./`, `../`, `**\/`, or a `#`-subpath with a literal `*`), and each resolves
|
|
49
|
+
* via a literal path join, not module resolution (confirmed against Vite 8's
|
|
50
|
+
* `toAbsoluteGlob`, gh#287). A `/`-rooted glob joins to Vite's CONFIGURED
|
|
51
|
+
* PROJECT ROOT — for a consumer app, that only reaches `@phosphor-icons/core`
|
|
52
|
+
* when it's ALSO hoisted to that exact root. Under pnpm's default
|
|
53
|
+
* (non-hoisted, symlinked) linking, a package you depend on only
|
|
54
|
+
* TRANSITIVELY — `@phosphor-icons/core` is a dependency of THIS package, not
|
|
55
|
+
* necessarily your app's — is linked only inside that package's own
|
|
56
|
+
* resolution scope, never flattened into your app's top-level `node_modules`.
|
|
57
|
+
* A root-rooted glob then silently matches zero files.
|
|
58
|
+
*
|
|
59
|
+
* A `../`-prefixed glob instead joins to THIS FILE'S OWN directory
|
|
60
|
+
* (`core/`), one level inside `@adia-ai/web-components` — so `../node_modules`
|
|
61
|
+
* reaches `@adia-ai/web-components`'s own local `node_modules`, which pnpm
|
|
62
|
+
* always populates with a package's own direct dependencies (a symlink into
|
|
63
|
+
* the pnpm store) regardless of whether your app also hoists them. This
|
|
64
|
+
* holds for the published package too — `core/icons-phosphor.js` ships at
|
|
65
|
+
* the same one-level depth (see `package.json`'s `files` field). Verified
|
|
66
|
+
* empirically against a real hoisting-gap install (a pnpm workspace where
|
|
67
|
+
* `@phosphor-icons/core` is declared only by a nested package, not the
|
|
68
|
+
* workspace root): the root-rooted form matches zero files; the
|
|
69
|
+
* entry-relative form matches the full set with real content.
|
|
70
|
+
*
|
|
71
|
+
* ## Vite dep-optimizer pre-bundling (gh#287, second independent failure mode)
|
|
72
|
+
*
|
|
73
|
+
* In DEV, Vite pre-bundles bare-specifier dependencies with esbuild
|
|
74
|
+
* (`optimizeDeps`) for faster cold starts, BEFORE its own plugin pipeline
|
|
75
|
+
* (which includes the glob transform) ever sees them. Confirmed empirically:
|
|
76
|
+
* when this package gets swept into that pre-bundling step, esbuild's scan
|
|
77
|
+
* transforms each `import.meta.glob(...)` call into a literal `Object.assign({})`
|
|
78
|
+
* — no exception, `hasViteGlob` stays `true`, but every weight's map is empty.
|
|
79
|
+
* This is indistinguishable from a genuine zero-match glob to the code below,
|
|
80
|
+
* so the same `totalIcons === 0` diagnostic fires — the fix differs, though:
|
|
81
|
+
* add this package to your Vite config's `optimizeDeps.exclude` so it's
|
|
82
|
+
* requested directly instead of pre-bundled (confirmed empirically to restore
|
|
83
|
+
* full auto-discovery with no code change):
|
|
84
|
+
*
|
|
85
|
+
* // vite.config.js
|
|
86
|
+
* export default defineConfig({
|
|
87
|
+
* optimizeDeps: { exclude: ['@adia-ai/web-components', '@adia-ai/web-modules'] },
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* If you can't control the Vite config (e.g. Astro, or another framework
|
|
91
|
+
* that manages it), fall back to the scoped, explicit-import recipe above —
|
|
92
|
+
* plain bare-specifier imports in your OWN first-party source are never
|
|
93
|
+
* swept into `optimizeDeps` in the first place.
|
|
41
94
|
*
|
|
42
95
|
* ## Vite glob detection
|
|
43
96
|
*
|
|
@@ -57,12 +110,12 @@ let weightModules;
|
|
|
57
110
|
let hasViteGlob = false;
|
|
58
111
|
try {
|
|
59
112
|
weightModules = {
|
|
60
|
-
regular: import.meta.glob('
|
|
61
|
-
thin: import.meta.glob('
|
|
62
|
-
light: import.meta.glob('
|
|
63
|
-
bold: import.meta.glob('
|
|
64
|
-
fill: import.meta.glob('
|
|
65
|
-
duotone: import.meta.glob('
|
|
113
|
+
regular: import.meta.glob('../node_modules/@phosphor-icons/core/assets/regular/*.svg', { query: '?raw', import: 'default' }),
|
|
114
|
+
thin: import.meta.glob('../node_modules/@phosphor-icons/core/assets/thin/*.svg', { query: '?raw', import: 'default' }),
|
|
115
|
+
light: import.meta.glob('../node_modules/@phosphor-icons/core/assets/light/*.svg', { query: '?raw', import: 'default' }),
|
|
116
|
+
bold: import.meta.glob('../node_modules/@phosphor-icons/core/assets/bold/*.svg', { query: '?raw', import: 'default' }),
|
|
117
|
+
fill: import.meta.glob('../node_modules/@phosphor-icons/core/assets/fill/*.svg', { query: '?raw', import: 'default' }),
|
|
118
|
+
duotone: import.meta.glob('../node_modules/@phosphor-icons/core/assets/duotone/*.svg', { query: '?raw', import: 'default' }),
|
|
66
119
|
};
|
|
67
120
|
hasViteGlob = true;
|
|
68
121
|
} catch (err) {
|
|
@@ -85,28 +138,39 @@ if (hasViteGlob) {
|
|
|
85
138
|
// FB-08: detect the silent-empty-glob case — `import.meta.glob` returns
|
|
86
139
|
// `{}` when zero files match (it does NOT throw). The previous behavior
|
|
87
140
|
// installed empty per-weight maps and the consumer saw an empty icon
|
|
88
|
-
// registry with no diagnostic.
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
141
|
+
// registry with no diagnostic. gh#287 names two independent causes, both
|
|
142
|
+
// producing this same empty-map symptom:
|
|
143
|
+
// 1. A packaging/bundler step re-nested this file at a different depth
|
|
144
|
+
// than it ships at (breaks the `../`-relative glob's one-level-inside
|
|
145
|
+
// assumption — see "Why the glob is entry-relative" above), a Yarn
|
|
146
|
+
// Berry PnP install (virtual/zip filesystem), or @phosphor-icons/core
|
|
147
|
+
// missing entirely.
|
|
148
|
+
// 2. Vite's dev-server `optimizeDeps` pre-bundled this package (see
|
|
149
|
+
// "Vite dep-optimizer pre-bundling" above) — confirmed empirically to
|
|
150
|
+
// transform the glob into a literal empty object, no exception.
|
|
93
151
|
const totalIcons = Object.values(weightModules).reduce(
|
|
94
152
|
(sum, weight) => sum + Object.keys(weight).length, 0
|
|
95
153
|
);
|
|
96
154
|
if (totalIcons === 0) {
|
|
97
155
|
console.warn(
|
|
98
156
|
`[icons-phosphor] No Phosphor icons matched the auto-install glob ` +
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
`
|
|
102
|
-
`
|
|
157
|
+
`\`../node_modules/@phosphor-icons/core/assets/<weight>/*.svg\` (resolved ` +
|
|
158
|
+
`relative to this file's own directory — hoisting-safe under pnpm, gh#287). ` +
|
|
159
|
+
`Two known causes: (1) this package got pre-bundled by Vite's dev-server ` +
|
|
160
|
+
`optimizeDeps, which empties the glob — add it to optimizeDeps.exclude in ` +
|
|
161
|
+
`your Vite config:\n` +
|
|
162
|
+
` optimizeDeps: { exclude: ['@adia-ai/web-components', '@adia-ai/web-modules'] }\n` +
|
|
163
|
+
`(2) @phosphor-icons/core is missing, or this file was re-nested to a ` +
|
|
164
|
+
`different depth by a packaging step (Yarn PnP, a custom bundler). If ` +
|
|
165
|
+
`neither fix applies, install loaders manually instead:\n` +
|
|
103
166
|
` import { installIconLoaders } from '@adia-ai/web-components/core/icons';\n` +
|
|
167
|
+
` import caretRight from '@phosphor-icons/core/assets/regular/caret-right.svg?raw';\n` +
|
|
104
168
|
` installIconLoaders({\n` +
|
|
105
|
-
` regular:
|
|
106
|
-
` '
|
|
107
|
-
`
|
|
108
|
-
`
|
|
109
|
-
`
|
|
169
|
+
` regular: {\n` +
|
|
170
|
+
` '/node_modules/@phosphor-icons/core/assets/regular/caret-right.svg': caretRight,\n` +
|
|
171
|
+
` },\n` +
|
|
172
|
+
` });\n` +
|
|
173
|
+
`See the JSDoc header of icons-phosphor.js for the full recipe.`
|
|
110
174
|
);
|
|
111
175
|
}
|
|
112
176
|
installIconLoaders(weightModules);
|
package/core/icons.js
CHANGED
|
@@ -33,17 +33,25 @@
|
|
|
33
33
|
* import '@adia-ai/web-components/core/icons-phosphor';
|
|
34
34
|
*
|
|
35
35
|
* 3. **Scoped registration (recommended for production bundle-size
|
|
36
|
-
* SLOs
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
36
|
+
* SLOs, and for Vite dev-servers that pre-bundle this package via
|
|
37
|
+
* `optimizeDeps` — see `icons-phosphor.js`'s JSDoc header, "Vite
|
|
38
|
+
* dep-optimizer pre-bundling", gh#287).** Skip `icons-phosphor.js`
|
|
39
|
+
* entirely and register only the icons you actually use, via plain
|
|
40
|
+
* bare-specifier imports in your OWN first-party source — never swept
|
|
41
|
+
* into `optimizeDeps`, unlike a glob written inside this package:
|
|
40
42
|
*
|
|
41
43
|
* import { installIconLoaders } from '@adia-ai/web-components/core/icons';
|
|
44
|
+
* import caretRight from '@phosphor-icons/core/assets/regular/caret-right.svg?raw';
|
|
45
|
+
* import caretUpDown from '@phosphor-icons/core/assets/regular/caret-up-down.svg?raw';
|
|
46
|
+
* import moon from '@phosphor-icons/core/assets/regular/moon.svg?raw';
|
|
47
|
+
* import sun from '@phosphor-icons/core/assets/regular/sun.svg?raw';
|
|
42
48
|
* installIconLoaders({
|
|
43
|
-
* regular:
|
|
44
|
-
* '/node_modules/@phosphor-icons/core/assets/regular/
|
|
45
|
-
*
|
|
46
|
-
*
|
|
49
|
+
* regular: {
|
|
50
|
+
* '/node_modules/@phosphor-icons/core/assets/regular/caret-right.svg': caretRight,
|
|
51
|
+
* '/node_modules/@phosphor-icons/core/assets/regular/caret-up-down.svg': caretUpDown,
|
|
52
|
+
* '/node_modules/@phosphor-icons/core/assets/regular/moon.svg': moon,
|
|
53
|
+
* '/node_modules/@phosphor-icons/core/assets/regular/sun.svg': sun,
|
|
54
|
+
* },
|
|
47
55
|
* });
|
|
48
56
|
*
|
|
49
57
|
* Or register single SVGs directly:
|
|
@@ -236,6 +244,12 @@ export function installIconLoaders(modules) {
|
|
|
236
244
|
* import { installIconLoadersForRegistered } from '@adia-ai/web-components/core/icons';
|
|
237
245
|
*
|
|
238
246
|
* // Build the Phosphor loader map from your bundler (Vite, Webpack, etc.).
|
|
247
|
+
* // NOTE: this glob only matches under a hoisted install (npm/yarn classic,
|
|
248
|
+
* // or pnpm with @phosphor-icons/core hoisted to your project root). Plain
|
|
249
|
+
* // pnpm links a transitive dependency like this one inside its own
|
|
250
|
+
* // resolution scope only — the glob silently matches zero files there.
|
|
251
|
+
* // Use the plain bare-specifier import recipe in this file's own JSDoc
|
|
252
|
+
* // header (path 3, above) instead if that's your install. See gh#287.
|
|
239
253
|
* const modules = import.meta.glob('/node_modules/@phosphor-icons/core/assets/regular/*.svg', { query: '?raw' });
|
|
240
254
|
*
|
|
241
255
|
* // Aggregate requiredIcons across all defined primitives + install.
|