@machfivetechchicago/machvive-neodigm55-ux 0.1.0 → 0.1.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@machfivetechchicago/machvive-neodigm55-ux",
3
- "version": "0.1.0",
4
- "description": "Neodigm 55 as dependency-free Web Components \u2014 a page-level choreographer that moves colour and attention across every themed element, plus the components it conducts.",
3
+ "version": "0.1.1",
4
+ "description": "Neodigm 55 as dependency-free Web Components — a page-level choreographer that moves colour and attention across every themed element, plus the components it conducts.",
5
5
  "keywords": [
6
6
  "web-components",
7
7
  "webcomponents",
@@ -50,10 +50,17 @@ const STYLES = `
50
50
 
51
51
  max-width: min(92vw, 560px);
52
52
  box-sizing: border-box;
53
- padding: 14px 20px;
53
+ /* Clips the progress bar to the rounded corners. */
54
+ overflow: hidden;
55
+ padding: 18px;
54
56
  border-radius: 8px;
55
- font: 15px/1.45 system-ui, sans-serif;
57
+ /* The original's type, white on every theme but the two light ones below.
58
+ A faint shadow keeps it legible at the light end of the gradient. */
59
+ font: 18px/1.4 'Helvetica', 'Helvetica Neue', sans-serif;
60
+ text-shadow: 0 1px 2px rgb(0 0 0 / .35);
56
61
  text-align: center;
62
+ user-select: none;
63
+ -webkit-user-select: none;
57
64
  box-shadow: 0 6px 24px rgb(0 0 0 / .28);
58
65
 
59
66
  /* The unthemed default, for a page that imported the toast but never called
@@ -61,21 +68,46 @@ const STYLES = `
61
68
  night-deep here would mean the two drift apart the first time anyone edits
62
69
  the palette, and nothing would fail. Both sides are declared so the toast
63
70
  never inherits a page colour it cannot guarantee contrast against. */
64
- background: var(--n55-night-deep, #2b2b2b);
65
- color: var(--n55-white, #fff);
71
+ background: linear-gradient(45deg, var(--n55-night, #2b2b2b), var(--n55-night-deep, #2b2b2b));
72
+ color: #fff;
66
73
  }
67
74
 
68
75
  :host([open]) {
69
76
  opacity: 1;
70
77
  visibility: visible;
71
78
  transform: translateX(-50%) translateY(0);
79
+ animation: n55-toast-in .5s ease-in-out;
72
80
  }
73
81
 
82
+ /* From the original's toast_bottom: rise from below the fold, overshoot,
83
+ settle back. Entry only — leaving is the plain transition above. */
84
+ @keyframes n55-toast-in {
85
+ 0% { transform: translateX(-50%) translateY(136px); }
86
+ 80% { transform: translateX(-50%) translateY(-6px); }
87
+ 100% { transform: translateX(-50%) translateY(0); }
88
+ }
89
+
90
+ /* Time remaining, filling left to right across the top over the toast's own
91
+ duration, which #next() writes onto it. The original fixed this at 5.2s
92
+ whatever the toast's duration. Like the original it runs dark to light,
93
+ the reverse of the background; each theme's colours are set below. */
94
+ .bar {
95
+ position: absolute;
96
+ inset-block-start: 0;
97
+ inset-inline-start: 0;
98
+ block-size: 3px;
99
+ inline-size: 0;
100
+ background: linear-gradient(90deg, var(--n55-night-deep, #2b2b2b), var(--n55-night, #2b2b2b));
101
+ animation: n55-toast-bar linear forwards;
102
+ }
103
+ @keyframes n55-toast-bar { to { inline-size: 100%; } }
104
+
74
105
  /* A visitor who asked for less motion still gets the toast — it carries
75
106
  information — but it appears rather than slides. */
76
107
  @media (prefers-reduced-motion: reduce) {
77
108
  :host { transition: opacity .01s linear; transform: translateX(-50%); }
78
- :host([open]) { transform: translateX(-50%); }
109
+ :host([open]) { transform: translateX(-50%); animation: none; }
110
+ .bar { display: none; }
79
111
  }
80
112
 
81
113
  :host([hidden]) { display: none; }
@@ -85,13 +117,18 @@ const STYLES = `
85
117
  and silently missed here. */
86
118
  ${Object.keys(THEMES).map((name) => `
87
119
  :host([${THEME_ATTR}="${name}"]) {
88
- background: var(--n55-${name});
89
- color: var(--n55-${name}-deep);
120
+ background: linear-gradient(45deg, var(--n55-${name}), var(--n55-${name}-deep));
121
+ }
122
+ :host([${THEME_ATTR}="${name}"]) .bar {
123
+ background: linear-gradient(90deg, var(--n55-${name}-deep), var(--n55-${name}));
90
124
  }`).join('')}
91
125
 
92
- /* ghost and white are light backgrounds; their -deep value is the readable ink. */
126
+ /* white and ghost start from pure white, where white text would vanish. The
127
+ original never styled a toast for either; dark ink is the readable choice. */
93
128
  :host([${THEME_ATTR}="white"]),
94
- :host([${THEME_ATTR}="ghost"]) { color: #1a1a1a; }
129
+ :host([${THEME_ATTR}="ghost"]) { color: #1a1a1a; text-shadow: none; }
130
+ /* white's two colours are both white, so its bar would vanish too. */
131
+ :host([${THEME_ATTR}="white"]) .bar { background: currentColor; }
95
132
 
96
133
  .msg { margin: 0; }
97
134
  .msg b { font-weight: 600; }
@@ -197,6 +234,7 @@ export class NeodigmToast extends HTMLElement {
197
234
  this.#showing = true;
198
235
 
199
236
  this.#render(entry.message);
237
+ this.#progress(entry.duration);
200
238
  if (entry.theme) this.setAttribute(THEME_ATTR, entry.theme);
201
239
  this.setAttribute('open', '');
202
240
  this.dispatchEvent(new CustomEvent('neodigm-toast-show', {
@@ -218,6 +256,21 @@ export class NeodigmToast extends HTMLElement {
218
256
  this.#timer = setTimeout(() => this.#next(), gap);
219
257
  }
220
258
 
259
+ /**
260
+ * Replaces the progress bar with a fresh one, which is what restarts its CSS
261
+ * animation for each queued message. Left out entirely when motion is off: a
262
+ * moving bar is motion, and the toast still closes on time without it.
263
+ */
264
+ #progress(duration) {
265
+ this.shadowRoot.querySelector('.bar')?.remove();
266
+ if (!motionAllowed()) return;
267
+ const bar = this.ownerDocument.createElement('span');
268
+ bar.className = 'bar';
269
+ bar.setAttribute('part', 'progress');
270
+ bar.style.animationDuration = `${duration}ms`;
271
+ this.shadowRoot.append(bar);
272
+ }
273
+
221
274
  /**
222
275
  * Writes the message.
223
276
  *