@alacris/ui 0.7.0 → 0.8.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/README.md CHANGED
@@ -47,9 +47,9 @@ The published package is plain ESM. Point an import map at a pinned CDN build of
47
47
  {
48
48
  "imports": {
49
49
  "@alacris/core": "https://cdn.jsdelivr.net/npm/@alacris/core@0.11.5/dist/alacris.js",
50
- "@alacris/ui": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.7.0/src/index.js",
51
- "@alacris/ui/theme": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.7.0/src/theme/index.js",
52
- "@alacris/ui/components/": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.7.0/src/components/"
50
+ "@alacris/ui": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.8.1/src/index.js",
51
+ "@alacris/ui/theme": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.8.1/src/theme/index.js",
52
+ "@alacris/ui/components/": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.8.1/src/components/"
53
53
  }
54
54
  }
55
55
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alacris/ui",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Themeable design system for Alacris — Material defaults, sixty-nine custom elements, ESM-only, no build step.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -283,11 +283,12 @@ define('ui-search', {
283
283
  <input part="input" ref=${(el) => (input = el)}
284
284
  .value=${() => value() ?? ''}
285
285
  placeholder=${ph}
286
+ role="combobox"
286
287
  aria-label=${() => label() || 'Search'}
287
288
  aria-expanded=${() => String(open())}
288
289
  aria-controls=${() => (showPanel() ? 'suggestions' : null)}
289
290
  aria-autocomplete="list"
290
- aria-haspopup=${() => (isView() || slotted() ? 'true' : null)}
291
+ aria-haspopup=${() => (isView() ? 'dialog' : slotted() ? 'listbox' : null)}
291
292
  ?disabled=${disabled}
292
293
  @input=${onInput} @change=${commit} @keydown=${onKeydown}
293
294
  @focus=${onFocus}>
@@ -8,7 +8,8 @@
8
8
  //
9
9
  // Imperative (fire and forget; FIFO — one visible at a time):
10
10
  //
11
- // const { close, closed } = showSnackbar('Message archived', { action: 'Undo' });
11
+ // const { close, closed } = showSnackbar('Message archived', { action: 'Undo', onAction: undo });
12
+ // const { reason } = await closed // 'action' | 'timeout' | 'close' | 'method'
12
13
  //
13
14
  // The component requests closing by emitting `close` with a reason — the
14
15
  // PARENT flips `open`. `closed` fires after the exit animation finishes.
@@ -183,11 +184,15 @@ function serviceHost() {
183
184
  if (!serviceEl || !serviceEl.isConnected) {
184
185
  serviceEl = document.createElement('ui-snackbar');
185
186
  // The service is the "parent": it owns the open state.
186
- serviceEl.addEventListener('close', () => { serviceEl.open = false; });
187
+ serviceEl.addEventListener('close', (e) => {
188
+ if (current && !current.reason) current.reason = e.detail?.reason ?? 'close';
189
+ serviceEl.open = false;
190
+ });
191
+ serviceEl.addEventListener('action', () => current?.onAction?.());
187
192
  serviceEl.addEventListener('closed', () => {
188
193
  const done = current;
189
194
  current = null;
190
- done?.resolve();
195
+ done?.resolve({ reason: done.reason ?? 'close' });
191
196
  next();
192
197
  });
193
198
  document.body.append(serviceEl);
@@ -210,23 +215,25 @@ function next() {
210
215
  * showSnackbar(message, { action, duration, closeButton })
211
216
  *
212
217
  * Returns { close, closed }: `close()` dismisses this snackbar (or removes it
213
- * from the queue if it has not shown yet); `closed` resolves once it has fully
214
- * left the screen.
218
+ * from the queue if it has not shown yet); `closed` resolves with
219
+ * `{ reason }` ('action' | 'timeout' | 'close' | 'method') once it has fully
220
+ * left the screen. `onAction` runs when the action button is pressed.
215
221
  */
216
- export function showSnackbar(message, { action = '', duration = 4000, closeButton = false } = {}) {
222
+ export function showSnackbar(message, { action = '', duration = 4000, closeButton = false, onAction } = {}) {
217
223
  let resolve;
218
224
  const closed = new Promise((r) => { resolve = r; });
219
- const entry = { message, action, duration, closeButton, resolve };
225
+ const entry = { message, action, duration, closeButton, resolve, onAction, reason: null };
220
226
  queue.push(entry);
221
227
  next();
222
228
  return {
223
229
  closed,
224
230
  close() {
225
231
  if (current === entry) {
232
+ entry.reason ??= 'method';
226
233
  serviceEl.open = false; // exit animation → 'closed' → resolve + next
227
234
  } else {
228
235
  const i = queue.indexOf(entry);
229
- if (i > -1) { queue.splice(i, 1); entry.resolve(); }
236
+ if (i > -1) { queue.splice(i, 1); entry.resolve({ reason: 'method' }); }
230
237
  }
231
238
  },
232
239
  };