@pure-ds/core 0.5.10 → 0.5.12

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.
@@ -1,5 +1,5 @@
1
- export { nt as startLive };
2
- declare function nt(n: any, t: any, { emitReady: e, applyResolvedTheme: a, setupSystemListenerIfNeeded: r }: {
1
+ export { it as startLive };
2
+ declare function it(n: any, t: any, { emitReady: e, applyResolvedTheme: a, setupSystemListenerIfNeeded: r }: {
3
3
  emitReady: any;
4
4
  applyResolvedTheme: any;
5
5
  setupSystemListenerIfNeeded: any;
@@ -604,8 +604,8 @@ declare function nt(n: any, t: any, { emitReady: e, applyResolvedTheme: a, setup
604
604
  };
605
605
  "__#private@#l"(t: any): number;
606
606
  "__#private@#c"(t: any, e: any): number;
607
- "__#private@#m"(t: any, e?: number): string;
608
607
  "__#private@#h"(t: any, e?: number): string;
608
+ "__#private@#m"(t: any, e?: number): string;
609
609
  "__#private@#z"(t: any, e: any, a?: number): string;
610
610
  "__#private@#M"(t: any, e: any, a: any): string;
611
611
  "__#private@#F"(t: any): {
@@ -718,10 +718,10 @@ declare function nt(n: any, t: any, { emitReady: e, applyResolvedTheme: a, setup
718
718
  externalPath: any;
719
719
  };
720
720
  "__#private@#D"(t: any): string;
721
- "__#private@#N"(t: any): string;
722
721
  "__#private@#P"(t: any): string;
723
- "__#private@#I"(t: any): string;
722
+ "__#private@#N"(t: any): string;
724
723
  "__#private@#U"(t: any): string;
724
+ "__#private@#I"(t: any): string;
725
725
  "__#private@#O"(t: any): string;
726
726
  "__#private@#H"(t: any): string;
727
727
  "__#private@#q"(t: any): string;
@@ -748,8 +748,8 @@ declare function nt(n: any, t: any, { emitReady: e, applyResolvedTheme: a, setup
748
748
  "__#private@#pe"(): string;
749
749
  "__#private@#ue"(): string;
750
750
  "__#private@#ge"(): string;
751
- "__#private@#me"(): string;
752
751
  "__#private@#he"(): string;
752
+ "__#private@#me"(): string;
753
753
  "__#private@#o"(t: any): {
754
754
  h: number;
755
755
  s: number;
@@ -1 +1 @@
1
- {"version":3,"file":"pds-live.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-live.js"],"names":[],"mappings":"AAyMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6NC;0BAlayB,oBAAoB"}
1
+ {"version":3,"file":"pds-live.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-live.js"],"names":[],"mappings":"AAwKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6NC;0BAjYyB,oBAAoB"}
@@ -48,6 +48,9 @@ export function resolveThemeAndApply({ manageTheme, themeStorageKey, applyResolv
48
48
  resolvedTheme: string;
49
49
  storedTheme: string;
50
50
  };
51
+ export function createSetTheme({ PDS, defaultStorageKey, setupSystemListenerIfNeeded, onApply, }?: {
52
+ defaultStorageKey?: string;
53
+ }): (theme: any, options?: {}) => Promise<any>;
51
54
  export function resolveRuntimeAssetRoot(config: any, { resolvePublicAssetURL }: {
52
55
  resolvePublicAssetURL: any;
53
56
  }): any;
@@ -1 +1 @@
1
- {"version":3,"file":"pds-start-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-start-helpers.js"],"names":[],"mappings":"AAmBA,sEAgCC;AAiBD,mDASC;AA6BD,8CAsBC;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuGC;AAGD;;;;;;;;EAmCC;AAED;;QASC;AAGD;;;;;GAmIC;AAnZM,qDAGI"}
1
+ {"version":3,"file":"pds-start-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-start-helpers.js"],"names":[],"mappings":"AAmBA,sEAgCC;AAiBD,mDASC;AA6BD,8CAsBC;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuGC;AAGD;;;;;;;;EAmCC;AAGD;;KAMiC,UAAK,EAAE,YAAY,kBAmDnD;AAED;;QASC;AAGD;;;;;GAmIC;AA/cM,qDAGI"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pure-ds/core",
3
3
  "shortname": "pds",
4
- "version": "0.5.10",
4
+ "version": "0.5.12",
5
5
  "description": "Pure Design System - Why develop a Design System when you can generate one?",
6
6
  "repository": {
7
7
  "type": "git",
@@ -42,7 +42,7 @@ async function writePackageJson(pkgPath, pkg) {
42
42
  await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
43
43
  }
44
44
 
45
- function buildIndexHtml() {
45
+ function buildIndexHtml({ version, generatedAt }) {
46
46
  return `<!doctype html>
47
47
  <html lang="en">
48
48
  <head>
@@ -62,15 +62,16 @@ function buildIndexHtml() {
62
62
  }
63
63
  </script>
64
64
 
65
+ <!-- Dev live-reload (safe in production, no-op without server) -->
66
+ <script type="module" src="/assets/js/dev-reload.js" defer></script>
67
+
65
68
  <!-- App Script -->
66
69
  <script type="module" src="/assets/js/app.js" defer></script>
67
70
  </head>
68
71
 
69
72
  <body class="container">
70
73
  <header class="stack-sm">
71
- <p class="badge">Pure Design System</p>
72
- <h1>Design systems, generated.</h1>
73
- <p class="text-muted">This starter is ready for your custom tokens, components, and brand.</p>
74
+ <p class="auto-gen">Auto-generated by PDS ${version} at ${generatedAt}</p>
74
75
  </header>
75
76
 
76
77
  <main></main>
@@ -83,46 +84,209 @@ function buildIndexHtml() {
83
84
  `;
84
85
  }
85
86
 
87
+ function buildDevReloadJs() {
88
+ return `const shouldConnect =
89
+ location.hostname === 'localhost' || location.hostname === '127.0.0.1';
90
+
91
+ if (shouldConnect) {
92
+ const reloadPort = 4174;
93
+ const endpoint = 'http://localhost:' + reloadPort + '/events';
94
+ const source = new EventSource(endpoint);
95
+
96
+ source.onmessage = (event) => {
97
+ if (event.data === 'reload') {
98
+ location.reload();
99
+ }
100
+ };
101
+
102
+ source.onerror = () => {
103
+ source.close();
104
+ };
105
+ }
106
+ `;
107
+ }
108
+
86
109
  function buildAppCss() {
87
110
  return `html:not(.pds-ready) {
88
111
  opacity: 0;
89
112
  }
90
113
 
91
114
  main {
92
- margin-top: var(--spacing-8);
115
+ margin: auto;
116
+ }
117
+
118
+ h1 {
119
+ background: linear-gradient(var(--gradient-angle, 135deg),
120
+ var(--color-primary-400),
121
+ var(--color-accent-400)
122
+ );
123
+ background-clip: text;
124
+ -webkit-background-clip: text;
125
+ color: transparent;
126
+ }
127
+
128
+ .container {
129
+ display: grid;
130
+ grid-template-rows: auto 1fr auto;
131
+ height: 100dvh;
132
+ padding: 0;
133
+ }
134
+
135
+ header, footer {
136
+ padding: var(--spacing-4);
137
+ }
138
+
139
+ footer {
140
+ text-align: center;
141
+ }
142
+
143
+ .auto-gen {
144
+ color: var(--color-text-muted);
145
+ font-size: var(--font-size-xs);
146
+ }
147
+
148
+ #settings-btn {
149
+ position: fixed;
150
+ top: var(--spacing-4);
151
+ right: var(--spacing-4);
152
+ }
153
+
154
+ .hero {
155
+ padding: var(--spacing-8);
156
+ zoom: 1.15;
157
+ text-align: center;
158
+ border: var(--border-width-medium) solid transparent;
159
+ background: linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
160
+ linear-gradient(var(--gradient-angle, 135deg), var(--color-primary-400), var(--color-accent-400)) border-box;
161
+ max-width: var(--max-w-lg);
162
+ border-radius: var(--radius-lg);
163
+ border-width: 3px;
164
+ }
165
+
166
+ .hero > div {
167
+ margin: var(--spacing-10) 0;
93
168
  }
94
169
  `;
95
170
  }
96
171
 
97
- function buildWcHome() {
98
- return `customElements.define(
99
- "wc-home",
172
+ function buildMyHome() {
173
+ return `/**
174
+ * @file my-home.js
175
+ * @description A simple home component for the app.
176
+ */
177
+ customElements.define(
178
+ "my-home",
100
179
  class extends HTMLElement {
101
180
  connectedCallback() {
102
181
  this.innerHTML = /*html*/ \`
103
- <article class="card text-center border-gradient surface-translucent-50">
104
- <header>
105
- <h1>Welcome to Pure Design System</h1>
106
- <h2 class="text-muted">Build on What Lasts</h2>
107
- </header>
108
- <div class="stack-lg">
182
+ <article class="hero">
183
+ <h1>Welcome to your new App</h1>
184
+ <div>
109
185
  <p>
110
- This is a demo of a web component using Pure Design System.
111
- It showcases the design tokens, components, and utilities provided by PDS.
186
+ This <code>&lt;my-home&gt;</code> Web Component is lazy-loaded and styled with Pure Design System.
187
+ </p>
188
+ <p>
189
+ You can start building your app by editing the files in <code>public/assets/my/</code> and <code>src/js/</code>.
112
190
  </p>
113
191
  </div>
114
- <nav class="flex justify-center gap-sm">
115
- <button class="btn-primary btn-lg" data-enhanced-btn-working="true">
116
- Get Started
117
- </button>
118
- <a href="https://pureweb.dev" class="btn btn-secondary btn-lg" data-enhanced-btn-working="true">
119
- Learn More
192
+ <nav>
193
+ <a target="_blank" href="https://github.com/Pure-Web-Foundation/pure-ds/blob/main/packages/pds-storybook/stories/GettingStarted.md" class="btn btn-primary btn-lg">
194
+ <pds-icon icon="rocket"></pds-icon> Get Started
195
+ </a>
196
+ <a target="_blank" href="https://puredesignsystem.z6.web.core.windows.net/storybook/" class="btn btn-secondary btn-lg">
197
+ <pds-icon icon="book-open"></pds-icon> Storybook
120
198
  </a>
121
199
  </nav>
122
200
  </article>
123
201
  \`;
124
202
  }
125
- }
203
+ },
204
+ );
205
+ `;
206
+ }
207
+
208
+ function buildMyTheme() {
209
+ return `/**
210
+ * my-theme Web Component - allows users to select the app theme (light, dark, system)
211
+ *
212
+ * Uses Pure Design System (PDS) for styling and theming.
213
+ */
214
+ customElements.define(
215
+ "my-theme",
216
+ class extends HTMLElement {
217
+ constructor() {
218
+ super();
219
+ this.attachShadow({ mode: "open" });
220
+ }
221
+
222
+ async connectedCallback() {
223
+ const componentStyles = PDS.createStylesheet(\`
224
+ :host {
225
+ display: block;
226
+ }
227
+ \`);
228
+
229
+ await PDS.adoptLayers(
230
+ this.shadowRoot,
231
+ ["tokens", "primitives", "components", "utilities"],
232
+ [componentStyles],
233
+ );
234
+
235
+ this.shadowRoot.innerHTML += /*html*/ \`
236
+ <form>
237
+ <fieldset role="radiogroup" aria-label="Theme" class="buttons">
238
+ <legend>Theme</legend>
239
+ <label>
240
+ <input type="radio" name="theme" value="system">
241
+ <span>
242
+ <pds-icon icon="moon-stars"></pds-icon>
243
+ System
244
+ </span>
245
+ </label>
246
+ <label>
247
+ <input type="radio" name="theme" value="light">
248
+ <span>
249
+ <pds-icon icon="sun"></pds-icon>
250
+ Light
251
+ </span>
252
+ </label>
253
+ <label>
254
+ <input type="radio" name="theme" value="dark">
255
+ <span>
256
+ <pds-icon icon="moon"></pds-icon>
257
+ Dark
258
+ </span>
259
+ </label>
260
+ </fieldset>
261
+ </form>\`;
262
+
263
+ this.#updateCheckedState();
264
+
265
+ this.shadowRoot.addEventListener("change", (e) => {
266
+ if (e.target.type === "radio" && e.target.name === "theme") {
267
+ PDS.setTheme(e.target.value, { persist: true });
268
+ PDS.toast(\`Theme changed to \${e.target.value}\`, { duration: 2000 });
269
+ }
270
+ });
271
+
272
+ const observer = new MutationObserver(() => {
273
+ this.#updateCheckedState();
274
+ });
275
+
276
+ observer.observe(document.documentElement, {
277
+ attributes: true,
278
+ attributeFilter: ["data-theme"],
279
+ });
280
+ }
281
+
282
+ #updateCheckedState() {
283
+ const currentTheme = PDS.theme || "system";
284
+ const radios = this.shadowRoot.querySelectorAll('input[type="radio"]');
285
+ radios.forEach((radio) => {
286
+ radio.checked = radio.value === currentTheme;
287
+ });
288
+ }
289
+ },
126
290
  );
127
291
  `;
128
292
  }
@@ -134,19 +298,132 @@ import { config } from '../../pds.config.js';
134
298
  await PDS.start(config);
135
299
  PDS.theme = 'light';
136
300
 
137
- await import('/assets/wc/wc-home.js');
138
-
139
301
  const main = document.querySelector('main');
140
- if (main && !main.querySelector('wc-home')) {
141
- main.innerHTML = '<wc-home></wc-home>';
302
+ if (main && !main.querySelector('my-home')) {
303
+ main.innerHTML = '<my-home></my-home>';
142
304
  }
305
+
306
+ const settingsBtn = document.createElement('button');
307
+ settingsBtn.id = 'settings-btn';
308
+ settingsBtn.className = 'icon-only btn-xs btn-outline';
309
+ settingsBtn.setAttribute('aria-label', 'Settings');
310
+ settingsBtn.innerHTML = '<pds-icon icon="gear"></pds-icon>';
311
+ document.body.appendChild(settingsBtn);
312
+
313
+ const drawer = document.createElement('pds-drawer');
314
+ drawer.setAttribute('position', 'right');
315
+ drawer.innerHTML = `
316
+ <div slot="drawer-header">Settings</div>
317
+ <div slot="drawer-content">
318
+ <my-theme></my-theme>
319
+ </div>
320
+ `;
321
+ document.body.appendChild(drawer);
322
+
323
+ settingsBtn.addEventListener('click', () => {
324
+ drawer.open = true;
325
+ });
326
+ `;
327
+ }
328
+
329
+ function buildPdsConfig() {
330
+ return `let defaultEnhancers = [];
331
+ if (typeof window !== "undefined") defaultEnhancers = PDS.defaultEnhancers;
332
+
333
+ export const config = {
334
+ mode: "static",
335
+ preset: "social-feed",
336
+
337
+ autoDefine: {
338
+ predefine: ["pds-icon", "pds-drawer", "pds-toaster"],
339
+
340
+ // Custom component paths
341
+ mapper: (tag) => {
342
+ if (tag.startsWith("my-")) return "/assets/my/\${tag}.js";
343
+
344
+ // Return nothing to use PDS default mapping
345
+ },
346
+
347
+ enhancers: [
348
+ ...defaultEnhancers,
349
+ {
350
+ selector: ".hero",
351
+ description: "Adds tooltip on hover",
352
+ run: (element) => {
353
+ let angle = 135;
354
+ const speed = 0.5;
355
+
356
+ function animate() {
357
+ angle = (angle + speed) % 360;
358
+ element.style.setProperty("--gradient-angle", \`\${angle}deg\`);
359
+ requestAnimationFrame(animate);
360
+ }
361
+
362
+ animate();
363
+ },
364
+ },
365
+ ],
366
+ },
367
+ };
143
368
  `;
144
369
  }
145
370
 
146
371
  function buildEsbuildDevCjs() {
147
372
  return `const esbuild = require('esbuild');
373
+ const http = require('http');
374
+
375
+ const reloadPort = 4174;
376
+ const reloadClients = new Set();
377
+
378
+ function startReloadServer() {
379
+ const server = http.createServer((req, res) => {
380
+ if (req.url !== '/events') {
381
+ res.writeHead(404);
382
+ res.end();
383
+ return;
384
+ }
385
+
386
+ res.writeHead(200, {
387
+ 'Content-Type': 'text/event-stream',
388
+ 'Cache-Control': 'no-cache',
389
+ Connection: 'keep-alive',
390
+ 'Access-Control-Allow-Origin': '*'
391
+ });
392
+
393
+ res.write('retry: 1000\n\n');
394
+ reloadClients.add(res);
395
+
396
+ req.on('close', () => {
397
+ reloadClients.delete(res);
398
+ });
399
+ });
400
+
401
+ server.listen(reloadPort, () => {
402
+ console.log('Live reload listening on http://localhost:' + reloadPort + '/events');
403
+ });
404
+ }
405
+
406
+ function notifyReload() {
407
+ for (const client of reloadClients) {
408
+ client.write('data: reload\n\n');
409
+ }
410
+ }
411
+
412
+ function liveReloadPlugin() {
413
+ return {
414
+ name: 'live-reload',
415
+ setup(build) {
416
+ build.onEnd((result) => {
417
+ if (!result.errors.length) {
418
+ notifyReload();
419
+ }
420
+ });
421
+ }
422
+ };
423
+ }
148
424
 
149
425
  async function start() {
426
+ startReloadServer();
150
427
  const ctx = await esbuild.context({
151
428
  entryPoints: ['src/js/app.js'],
152
429
  outdir: 'public/assets/js',
@@ -154,8 +431,9 @@ async function start() {
154
431
  format: 'esm',
155
432
  sourcemap: true,
156
433
  publicPath: '/assets/js',
157
- external: ['/assets/wc/*'],
158
- logLevel: 'info'
434
+ external: ['/assets/my/*'],
435
+ logLevel: 'info',
436
+ plugins: [liveReloadPlugin()]
159
437
  });
160
438
 
161
439
  await ctx.watch();
@@ -172,6 +450,59 @@ start().catch((err) => {
172
450
 
173
451
  function buildEsbuildDevEsm() {
174
452
  return `import esbuild from 'esbuild';
453
+ import http from 'http';
454
+
455
+ const reloadPort = 4174;
456
+ const reloadClients = new Set();
457
+
458
+ function startReloadServer() {
459
+ const server = http.createServer((req, res) => {
460
+ if (req.url !== '/events') {
461
+ res.writeHead(404);
462
+ res.end();
463
+ return;
464
+ }
465
+
466
+ res.writeHead(200, {
467
+ 'Content-Type': 'text/event-stream',
468
+ 'Cache-Control': 'no-cache',
469
+ Connection: 'keep-alive',
470
+ 'Access-Control-Allow-Origin': '*'
471
+ });
472
+
473
+ res.write('retry: 1000\n\n');
474
+ reloadClients.add(res);
475
+
476
+ req.on('close', () => {
477
+ reloadClients.delete(res);
478
+ });
479
+ });
480
+
481
+ server.listen(reloadPort, () => {
482
+ console.log('Live reload listening on http://localhost:' + reloadPort + '/events');
483
+ });
484
+ }
485
+
486
+ function notifyReload() {
487
+ for (const client of reloadClients) {
488
+ client.write('data: reload\n\n');
489
+ }
490
+ }
491
+
492
+ function liveReloadPlugin() {
493
+ return {
494
+ name: 'live-reload',
495
+ setup(build) {
496
+ build.onEnd((result) => {
497
+ if (!result.errors.length) {
498
+ notifyReload();
499
+ }
500
+ });
501
+ }
502
+ };
503
+ }
504
+
505
+ startReloadServer();
175
506
 
176
507
  const ctx = await esbuild.context({
177
508
  entryPoints: ['src/js/app.js'],
@@ -180,13 +511,13 @@ const ctx = await esbuild.context({
180
511
  format: 'esm',
181
512
  sourcemap: true,
182
513
  publicPath: '/assets/js',
183
- external: ['/assets/wc/*'],
184
- logLevel: 'info'
514
+ external: ['/assets/my/*'],
515
+ logLevel: 'info',
516
+ plugins: [liveReloadPlugin()]
185
517
  });
186
518
 
187
519
  await ctx.watch();
188
520
  const { host, port } = await ctx.serve({ servedir: 'public', port: 4173 });
189
- console.log('Dev server running at http://' + host + ':' + port);
190
521
  `;
191
522
  }
192
523
 
@@ -294,12 +625,27 @@ async function main() {
294
625
  await ensurePackageScripts(pkg, pkgPath);
295
626
  await ensureEsbuildDependency(pkg, pkgPath);
296
627
 
297
- await writeFileIfMissing(path.join(projectRoot, 'public', 'index.html'), buildIndexHtml());
628
+ const version = await getPdsCoreVersion();
629
+ const generatedAt = new Date().toLocaleString();
630
+
631
+ await writeFileIfMissing(
632
+ path.join(projectRoot, 'public', 'index.html'),
633
+ buildIndexHtml({ version, generatedAt })
634
+ );
298
635
  await writeFileIfMissing(path.join(projectRoot, 'public', 'assets', 'css', 'app.css'), buildAppCss());
299
636
  await writeFileIfMissing(path.join(projectRoot, 'src', 'js', 'app.js'), buildAppJs());
637
+ await writeFileIfMissing(path.join(projectRoot, 'pds.config.js'), buildPdsConfig());
638
+ await writeFileIfMissing(
639
+ path.join(projectRoot, 'public', 'assets', 'js', 'dev-reload.js'),
640
+ buildDevReloadJs()
641
+ );
642
+ await writeFileIfMissing(
643
+ path.join(projectRoot, 'public', 'assets', 'my', 'my-home.js'),
644
+ buildMyHome()
645
+ );
300
646
  await writeFileIfMissing(
301
- path.join(projectRoot, 'public', 'assets', 'wc', 'wc-home.js'),
302
- buildWcHome()
647
+ path.join(projectRoot, 'public', 'assets', 'my', 'my-theme.js'),
648
+ buildMyTheme()
303
649
  );
304
650
 
305
651
  const esbuildDevPath = path.join(projectRoot, 'esbuild-dev.js');