vanilla-jui 1.4.0 → 1.4.2

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 (71) hide show
  1. package/dist/index.d.ts +8 -21
  2. package/dist/index.js +1 -1
  3. package/dist/index.umd.js +1 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +1 -1
  6. package/src/components/accordion.ts +7 -10
  7. package/src/components/drop.ts +5 -15
  8. package/src/components/offcanvas.ts +5 -44
  9. package/src/components/parabola.ts +2 -2
  10. package/src/components/tabs.ts +5 -25
  11. package/src/components/theme.ts +25 -22
  12. package/src/components/toast.ts +34 -19
  13. package/src/components/tooltip.ts +3 -9
  14. package/src/core/Component.ts +1 -1
  15. package/src/css/accordion.css +1 -46
  16. package/src/css/avatar.css +7 -33
  17. package/src/css/badge.css +11 -59
  18. package/src/css/breadcrumb.css +9 -32
  19. package/src/css/button.css +23 -224
  20. package/src/css/components.css +1 -0
  21. package/src/css/content.css +147 -151
  22. package/src/css/drop.css +8 -8
  23. package/src/css/editor.css +16 -0
  24. package/src/css/flow.css +1 -1
  25. package/src/css/form.css +27 -14
  26. package/src/css/icon.css +3 -24
  27. package/src/css/index.css +4 -1
  28. package/src/css/layout.css +2 -2
  29. package/src/css/loading.css +88 -24
  30. package/src/css/menu.css +29 -32
  31. package/src/css/modal.css +15 -44
  32. package/src/css/offcanvas.css +14 -40
  33. package/src/css/pagination.css +4 -4
  34. package/src/css/popup.css +4 -4
  35. package/src/css/status.css +2 -3
  36. package/src/css/swiper.css +35 -50
  37. package/src/css/table.css +20 -20
  38. package/src/css/tabs.css +11 -34
  39. package/src/css/tag.css +16 -77
  40. package/src/css/theme-palette.css +10 -17
  41. package/src/css/themes/default/accordion.css +62 -0
  42. package/src/css/themes/default/avatar.css +55 -0
  43. package/src/css/themes/default/badge.css +63 -0
  44. package/src/css/themes/default/breadcrumb.css +28 -0
  45. package/src/css/themes/default/button.css +204 -0
  46. package/src/css/themes/default/content.css +59 -0
  47. package/src/css/themes/default/drop.css +11 -0
  48. package/src/css/themes/default/editor.css +10 -0
  49. package/src/css/themes/default/index.css +23 -0
  50. package/src/css/themes/default/loading.css +23 -0
  51. package/src/css/themes/default/menu.css +15 -0
  52. package/src/css/themes/default/modal.css +40 -0
  53. package/src/css/themes/default/offcanvas.css +13 -0
  54. package/src/css/themes/default/pagination.css +8 -0
  55. package/src/css/themes/default/popup.css +7 -0
  56. package/src/css/themes/default/swiper.css +35 -0
  57. package/src/css/themes/default/table.css +18 -0
  58. package/src/css/themes/default/tabs.css +37 -0
  59. package/src/css/themes/default/tag.css +85 -0
  60. package/src/css/themes/default/theme-palette.css +12 -0
  61. package/src/css/themes/default/tip.css +49 -0
  62. package/src/css/themes/default/toast.css +70 -0
  63. package/src/css/themes/default/toolbar.css +34 -0
  64. package/src/css/themes/default/tooltip.css +14 -0
  65. package/src/css/themes/index.css +1 -0
  66. package/src/css/tip.css +20 -39
  67. package/src/css/toast.css +29 -89
  68. package/src/css/tokens.css +7 -2
  69. package/src/css/toolbar.css +29 -48
  70. package/src/css/tooltip.css +10 -10
  71. package/src/locales/index.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-jui",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "private": false,
5
5
  "description": "A lightweight vanilla JavaScript UI plugin library.",
6
6
  "keywords": [
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  bindAttr,
3
- bindClass,
4
3
  createDeepStore,
5
4
  createRoot,
6
5
  flushSync,
@@ -36,7 +35,6 @@ export interface AccordionClassNames {
36
35
  arrow: string;
37
36
  panel: string;
38
37
  content: string;
39
- active: string;
40
38
  }
41
39
 
42
40
  export type AccordionClassNameConfig = Partial<AccordionClassNames>;
@@ -107,7 +105,6 @@ const DEFAULT_CLASS_NAMES: AccordionClassNames = {
107
105
  arrow: 'header-arrow',
108
106
  panel: 'accordion-panel',
109
107
  content: 'panel-content',
110
- active: 'is-active',
111
108
  };
112
109
 
113
110
  const ACCORDION_ITEMS_RULE = {
@@ -316,18 +313,18 @@ export class Accordion extends Component<
316
313
  this.bindingsDispose = createRoot((dispose) => {
317
314
  this.dom.headers.forEach((header) => {
318
315
  const name = header.dataset.accordionHeader || '';
319
- bindClass(header, this.props.className.active, () =>
320
- this.state.activeNames.includes(name)
321
- );
316
+ // bindClass(header, this.props.className.active, () =>
317
+ // this.state.activeNames.includes(name)
318
+ // );
322
319
  bindAttr(header, 'aria-expanded', () =>
323
- this.state.activeNames.includes(name)
320
+ this.state.activeNames.includes(name) ? 'true' : 'false'
324
321
  );
325
322
  });
326
323
  this.dom.panels.forEach((panel, i) => {
327
324
  const name = this.dom.headers[i]?.dataset.accordionHeader || '';
328
- bindClass(panel, this.props.className.active, () =>
329
- this.state.activeNames.includes(name)
330
- );
325
+ // bindClass(panel, this.props.className.active, () =>
326
+ // this.state.activeNames.includes(name)
327
+ // );
331
328
  bindAttr(panel, 'aria-hidden', () =>
332
329
  this.state.activeNames.includes(name) ? 'false' : 'true'
333
330
  );
@@ -30,7 +30,6 @@ export type DropPosition =
30
30
  export interface DropClassNames {
31
31
  root: string;
32
32
  container: string;
33
- active: string;
34
33
  }
35
34
 
36
35
  export type DropClassNameConfig = Partial<DropClassNames>;
@@ -48,7 +47,6 @@ export interface DropProps extends Record<string, unknown> {
48
47
  content?: RenderableContent<Drop>;
49
48
  className?: DropClassNameConfig;
50
49
  id?: string | null;
51
- containerClassName?: string | null;
52
50
  delay?: number | DropDelay;
53
51
  hoverIntent?: boolean;
54
52
  onShown?: ((drop: Drop) => void | Promise<void>) | null;
@@ -63,7 +61,6 @@ interface ResolvedDropProps extends Record<string, unknown> {
63
61
  content: RenderableContent<Drop>;
64
62
  className: DropClassNames;
65
63
  id: string;
66
- containerClassName: string | null;
67
64
  delay: number | DropDelay;
68
65
  hoverIntent: boolean;
69
66
  onShown: NonNullable<DropProps['onShown']> | null;
@@ -88,7 +85,6 @@ interface HoverIntentData {
88
85
  const DEFAULT_CLASS_NAMES: DropClassNames = {
89
86
  root: 'j-drop',
90
87
  container: 'drop-container',
91
- active: 'is-active',
92
88
  };
93
89
 
94
90
  const DROP_PROPS_SCHEMA = {
@@ -140,7 +136,6 @@ const DROP_PROPS_SCHEMA = {
140
136
  return value;
141
137
  },
142
138
  },
143
- containerClassName: { default: null, types: ['string', 'null'] },
144
139
  delay: { default: 0, types: ['number', 'object'] },
145
140
  hoverIntent: { default: true, type: 'boolean' },
146
141
  onShown: { default: null, types: ['function', 'null'] },
@@ -157,7 +152,6 @@ function normalizeProps(input: DropProps): ResolvedDropProps {
157
152
  content: props.content as RenderableContent<Drop>,
158
153
  className: props.className as DropClassNames,
159
154
  id: props.id as string,
160
- containerClassName: props.containerClassName as string | null,
161
155
  delay: props.delay as number | DropDelay,
162
156
  hoverIntent: props.hoverIntent as boolean,
163
157
  onShown: props.onShown as ResolvedDropProps['onShown'],
@@ -165,12 +159,6 @@ function normalizeProps(input: DropProps): ResolvedDropProps {
165
159
  };
166
160
  }
167
161
 
168
- function joinClasses(
169
- ...classes: Array<string | null | undefined | false>
170
- ): string {
171
- return classes.filter(Boolean).join(' ');
172
- }
173
-
174
162
  function normalizeDelay(delay: number | DropDelay): Required<DropDelay> {
175
163
  if (typeof delay === 'number' && delay >= 0) {
176
164
  return { show: delay, hide: delay };
@@ -232,12 +220,12 @@ export class Drop {
232
220
  }
233
221
 
234
222
  private buildDrop(props: ResolvedDropProps): void {
235
- const { className, content, id, name, containerClassName } = props;
223
+ const { className, content, id, name } = props;
236
224
  const wrapper =
237
225
  isNode(content) && content.nodeType === Node.ELEMENT_NODE
238
226
  ? content
239
227
  : jsx('div', {
240
- className: joinClasses(className.container, containerClassName),
228
+ className: className.container,
241
229
  'data-drop-container': name || id,
242
230
  children: normalizeContentNodes(content, this),
243
231
  });
@@ -433,7 +421,9 @@ export class Drop {
433
421
  this.root.remove();
434
422
  }
435
423
 
436
- this.root.classList.toggle(this.props.className.active, visible);
424
+ this.root.setAttribute('aria-hidden', visible ? 'false' : 'true');
425
+ this.root.setAttribute('aria-expanded', visible ? 'true' : 'false');
426
+
437
427
  this.isVisible = visible;
438
428
  }
439
429
 
@@ -18,7 +18,7 @@ import {
18
18
  } from '../utilities/dom.ts';
19
19
 
20
20
  export type OffcanvasDirection = 'top' | 'right' | 'bottom' | 'left';
21
- export type OffcanvasAnimation = 'slide' | 'push' | 'none';
21
+ export type OffcanvasAnimation = 'slide' | 'none';
22
22
 
23
23
  export interface OffcanvasClassNames {
24
24
  root: string;
@@ -30,13 +30,7 @@ export interface OffcanvasClassNames {
30
30
  bottom: string;
31
31
  left: string;
32
32
  slide: string;
33
- push: string;
34
33
  none: string;
35
- pushBody: string;
36
- pushTop: string;
37
- pushRight: string;
38
- pushBottom: string;
39
- pushLeft: string;
40
34
  }
41
35
 
42
36
  export type OffcanvasClassNameConfig = Partial<OffcanvasClassNames>;
@@ -112,13 +106,7 @@ const DEFAULT_CLASS_NAMES: OffcanvasClassNames = {
112
106
  bottom: 'is-bottom',
113
107
  left: 'is-left',
114
108
  slide: 'is-slide',
115
- push: 'is-push',
116
109
  none: 'is-none',
117
- pushBody: 'offcanvas-push-body',
118
- pushTop: 'offcanvas-push-top',
119
- pushRight: 'offcanvas-push-right',
120
- pushBottom: 'offcanvas-push-bottom',
121
- pushLeft: 'offcanvas-push-left',
122
110
  };
123
111
 
124
112
  const OFFCANVAS_PROPS_SCHEMA = {
@@ -139,7 +127,7 @@ const OFFCANVAS_PROPS_SCHEMA = {
139
127
  animation: {
140
128
  default: 'slide',
141
129
  type: 'string',
142
- enum: ['slide', 'push', 'none'],
130
+ enum: ['slide', 'none'],
143
131
  },
144
132
  bgClose: { default: true, type: 'boolean' },
145
133
  escClose: { default: true, type: 'boolean' },
@@ -373,44 +361,31 @@ export class Offcanvas extends Component<
373
361
  }
374
362
 
375
363
  private renderPanel(): void {
376
- const { overlay, animation, direction, id, className } = this.props;
364
+ const { overlay, id, className } = this.props;
377
365
  const body = document.body;
378
366
 
379
367
  if (overlay && this._overlay) body.appendChild(this._overlay);
380
368
  if (this.dom.root) body.appendChild(this.dom.root);
381
369
 
382
370
  body.style.overflow = 'hidden';
383
- if (animation === 'push') {
384
- body.classList.add(className.pushBody);
385
- }
386
371
 
387
372
  timer.start(`oc-show-${id}`, 10, () => {
388
373
  if (!this.dom.root) return;
389
374
  this._overlay?.classList.add(className.active);
390
- if (animation === 'push') {
391
- body.classList.add(className[`push${capitalizeDirection(direction)}`]);
392
- }
393
375
  this.dom.root.classList.add(className.active);
394
376
  });
395
377
  }
396
378
 
397
379
  private removePanel(): void {
398
- const { animation, direction, id, className } = this.props;
380
+ const { id, className } = this.props;
399
381
  const body = document.body;
400
382
 
401
383
  this._overlay?.classList.remove(className.active);
402
384
  this.dom.root?.classList.remove(className.active);
403
385
 
404
- if (animation === 'push') {
405
- body.classList.remove(className[`push${capitalizeDirection(direction)}`]);
406
- }
407
-
408
386
  timer.start(`oc-remove-${id}`, 100, () => {
409
387
  this._overlay?.remove();
410
388
  this.dom.root?.remove();
411
- if (animation === 'push') {
412
- body.classList.remove(className.pushBody);
413
- }
414
389
  body.style.overflow = '';
415
390
  });
416
391
  }
@@ -458,7 +433,7 @@ export class Offcanvas extends Component<
458
433
  }
459
434
 
460
435
  onDestroy(): void {
461
- const { id, direction, className } = this.props;
436
+ const { id, className } = this.props;
462
437
 
463
438
  timer.cancel(`oc-show-${id}`);
464
439
  timer.cancel(`oc-remove-${id}`);
@@ -472,25 +447,11 @@ export class Offcanvas extends Component<
472
447
 
473
448
  const body = document.body;
474
449
  body.style.overflow = '';
475
- body.classList.remove(
476
- className.pushBody,
477
- className[`push${capitalizeDirection(direction)}`]
478
- );
479
450
 
480
451
  this._overlay = null;
481
452
  }
482
453
  }
483
454
 
484
- function capitalizeDirection(
485
- direction: OffcanvasDirection
486
- ): 'Top' | 'Right' | 'Bottom' | 'Left' {
487
- return `${direction[0].toUpperCase()}${direction.slice(1)}` as
488
- | 'Top'
489
- | 'Right'
490
- | 'Bottom'
491
- | 'Left';
492
- }
493
-
494
455
  export function createOffcanvas(options: OffcanvasProps = {}): Offcanvas {
495
456
  return new Offcanvas(options);
496
457
  }
@@ -53,8 +53,8 @@ interface ParabolaPath {
53
53
  }
54
54
 
55
55
  const DEFAULT_BALL: ParabolaBallOptions = {
56
- color: 'var(--primary, #3e63dd)',
57
- size: '10px',
56
+ color: 'var(--tone-solid)',
57
+ size: '12px',
58
58
  };
59
59
 
60
60
  const DEFAULT_CLASS_NAMES: ParabolaClassNames = {
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  bindAttr,
3
- bindClass,
4
3
  createDeepStore,
5
4
  createRoot,
6
5
  flushSync,
@@ -43,7 +42,6 @@ export interface TabsClassNames {
43
42
  tab: string;
44
43
  panelWrap: string;
45
44
  panel: string;
46
- active: string;
47
45
  disabled: string;
48
46
  dragging: string;
49
47
  }
@@ -163,7 +161,6 @@ const DEFAULT_CLASS_NAMES: TabsClassNames = {
163
161
  tab: 'tab-item',
164
162
  panelWrap: 'tab-panel',
165
163
  panel: 'panel-item',
166
- active: 'is-active',
167
164
  disabled: 'is-disabled',
168
165
  dragging: 'dragging',
169
166
  };
@@ -389,33 +386,16 @@ export class Tabs extends Component<ResolvedTabsProps, TabsState, TabsDOM> {
389
386
  this.bindingsDispose = createRoot((dispose) => {
390
387
  this.dom.tabs.forEach((tab, index) => {
391
388
  const name = tab.dataset.tabsTab || '';
392
- bindClass(
393
- tab,
394
- this.props.className.active,
395
- () => this.state.current.index === index
396
- );
397
- bindClass(tab, this.props.className.disabled, () =>
398
- this.state.disabled.names.includes(name)
399
- );
400
- bindAttr(
401
- tab,
402
- 'aria-selected',
403
- () => this.state.current.index === index
389
+ bindAttr(tab, 'aria-selected', () =>
390
+ this.state.current.index === index ? 'true' : 'false'
404
391
  );
405
392
  bindAttr(tab, 'aria-disabled', () =>
406
- this.state.disabled.names.includes(name)
393
+ this.state.disabled.names.includes(name) ? 'true' : 'false'
407
394
  );
408
395
  });
409
396
  this.dom.panels.forEach((panel, index) => {
410
- bindClass(
411
- panel,
412
- this.props.className.active,
413
- () => this.state.current.index === index
414
- );
415
- bindAttr(
416
- panel,
417
- 'aria-hidden',
418
- () => this.state.current.index !== index
397
+ bindAttr(panel, 'aria-hidden', () =>
398
+ this.state.current.index !== index ? 'true' : 'false'
419
399
  );
420
400
  });
421
401
  return dispose;
@@ -260,33 +260,36 @@ export class Theme {
260
260
  className: containerClass || className.panel,
261
261
  'data-theme-palette': 'root',
262
262
  children: [
263
- jsx('div', {
264
- className: className.closeWrap,
265
- 'data-theme-close-wrap': '',
266
- style: {
267
- display: 'flex',
268
- justifyContent: 'center',
269
- },
270
- children: jsx('button', {
271
- className: className.closeButton,
272
- 'data-action': 'close',
273
- children: this.translate('b'),
274
- }),
275
- }),
263
+ // jsx('div', {
264
+ // className: className.closeWrap,
265
+ // 'data-theme-close-wrap': '',
266
+ // style: {
267
+ // display: 'flex',
268
+ // justifyContent: 'center',
269
+ // },
270
+ // children: jsx('button', {
271
+ // className: className.closeButton,
272
+ // 'data-action': 'close',
273
+ // children: this.translate('b'),
274
+ // }),
275
+ // }),
276
276
  jsx('h3', {
277
277
  className: className.title,
278
278
  'data-theme-title': '',
279
- children: this.translate('t'),
280
- }),
281
- jsx('p', {
282
- className: className.description,
283
- 'data-theme-description': '',
284
279
  style: {
285
- marginTop: 0,
286
- fontSize: 'var(--text-sm, 0.875rem)',
280
+ margin: '0 0 1rem',
287
281
  },
288
- children: this.translate('d'),
282
+ children: this.translate('t'),
289
283
  }),
284
+ // jsx('p', {
285
+ // className: className.description,
286
+ // 'data-theme-description': '',
287
+ // style: {
288
+ // marginTop: 0,
289
+ // fontSize: 'var(--text-sm, 0.875rem)',
290
+ // },
291
+ // children: this.translate('d'),
292
+ // }),
290
293
  jsx('div', {
291
294
  className: className.container,
292
295
  'data-theme-container': '',
@@ -373,7 +376,7 @@ export class Theme {
373
376
  private defaultPanelConfig(): ThemePanelGroup[] {
374
377
  return [
375
378
  {
376
- title: this.translate('Theme'),
379
+ title: this.translate('Primary'),
377
380
  type: 'theme',
378
381
  buttons: [
379
382
  ['gray', this.translate('Gray')],
@@ -1,5 +1,7 @@
1
1
  import { jsx } from 'vanilla-signal';
2
+ import { t } from 'vanilla-signal-i18n';
2
3
 
4
+ import locales from '../locales/index.ts';
3
5
  import { randomId, timer, validateParam } from '../utilities/core.ts';
4
6
  import { q } from '../utilities/dom.ts';
5
7
  import { listen } from '../utilities/events.ts';
@@ -12,13 +14,12 @@ export interface ToastClassNames {
12
14
  toast: string;
13
15
  icon: string;
14
16
  message: string;
15
- shown: string;
16
17
  hidden: string;
17
18
  lite: string;
18
19
  action: string;
19
20
  actions: string;
20
21
  button: string;
21
- cancelButton: string;
22
+ closeButton: string;
22
23
  actionButton: string;
23
24
  info: string;
24
25
  success: string;
@@ -35,10 +36,11 @@ export interface ToastOptions {
35
36
 
36
37
  export interface ToastActionProps extends ToastOptions {
37
38
  text?: {
38
- cancel?: string;
39
+ close?: string;
39
40
  action?: string;
40
41
  };
41
42
  onAction?: () => void | Promise<void>;
43
+ onClose?: () => void | Promise<void>;
42
44
  }
43
45
 
44
46
  interface ResolvedToastOptions {
@@ -50,13 +52,12 @@ const DEFAULT_CLASS_NAMES: ToastClassNames = {
50
52
  toast: 'j-toast',
51
53
  icon: 'toast-icon',
52
54
  message: 'toast-message',
53
- shown: 'is-shown',
54
55
  hidden: 'is-hidden',
55
56
  lite: 'j-toast-lite',
56
57
  action: 'is-action',
57
58
  actions: 'toast-actions',
58
59
  button: 'j-button is-sm',
59
- cancelButton: 'is-ghost',
60
+ closeButton: 'is-ghost',
60
61
  actionButton: 'is-outline',
61
62
  info: 'is-info',
62
63
  success: 'is-success',
@@ -135,6 +136,8 @@ export class Toast {
135
136
  const toast = jsx('div', {
136
137
  className: joinClasses(className.toast, className[type]),
137
138
  'data-toast': id,
139
+ role: 'alert',
140
+ 'aria-atomic': 'true',
138
141
  children: [
139
142
  jsx('span', {
140
143
  className: className.icon,
@@ -152,7 +155,8 @@ export class Toast {
152
155
  Toast.classNames.set(toast, className);
153
156
  toastContainer.appendChild(toast);
154
157
 
155
- Toast.setTimer(id, 'show', () => toast.classList.add(className.shown), 10);
158
+ const v = type === 'error' ? 'assertive' : 'polite';
159
+ Toast.setTimer(id, 'show', () => toast.setAttribute('aria-live', v), 10);
156
160
 
157
161
  if (duration > 0) {
158
162
  Toast.setTimer(id, 'hide', () => Toast.hide(toast), duration);
@@ -207,12 +211,11 @@ export class Toast {
207
211
  static hide(toast: HTMLElement | null | undefined): void {
208
212
  if (!toast) return;
209
213
 
210
- const className = Toast.classNames.get(toast) || Toast.options.className;
211
214
  Toast.disposers.get(toast)?.();
212
215
  Toast.disposers.delete(toast);
213
216
 
214
- toast.classList.remove(className.shown);
215
- toast.classList.add(className.hidden);
217
+ toast.removeAttribute('aria-live');
218
+ toast.setAttribute('aria-hidden', 'true');
216
219
 
217
220
  const id = toast.dataset.toast || randomId();
218
221
  Toast.setTimer(
@@ -252,13 +255,19 @@ export class Toast {
252
255
  Toast.classNames.set(lite, className);
253
256
  document.body.appendChild(lite);
254
257
 
255
- Toast.setTimer(id, 'show', () => lite.classList.add(className.shown), 10);
258
+ Toast.setTimer(
259
+ id,
260
+ 'show',
261
+ () => lite.setAttribute('aria-live', 'polite'),
262
+ 10
263
+ );
264
+
256
265
  Toast.setTimer(
257
266
  id,
258
267
  'hide',
259
268
  () => {
260
- lite.classList.remove(className.shown);
261
- lite.classList.add(className.hidden);
269
+ lite.removeAttribute('aria-live');
270
+ lite.setAttribute('aria-hidden', 'true');
262
271
  Toast.setTimer(id, 'remove', () => lite.remove(), 300);
263
272
  },
264
273
  duration
@@ -269,7 +278,8 @@ export class Toast {
269
278
 
270
279
  static action(message = '', props: ToastActionProps = {}): HTMLElement {
271
280
  validateParam('message', message, 'string', 'Toast.action');
272
-
281
+ const c = t('Close', locales);
282
+ const a = t('Confirm', locales);
273
283
  const className = Toast.resolveClassNames(props);
274
284
  const toastContainer = Toast.getOrCreateContainer(className);
275
285
  const id = randomId();
@@ -288,15 +298,20 @@ export class Toast {
288
298
  'data-toast-actions': id,
289
299
  children: [
290
300
  jsx('button', {
291
- className: joinClasses(className.button, className.cancelButton),
292
- children: props.text?.cancel || 'cancel',
293
- 'data-action': 'cancel',
294
- onClick: () => Toast.hide(action),
301
+ className: joinClasses(className.button, className.closeButton),
302
+ children: props.text?.close || c,
303
+ 'data-action': 'close',
304
+ 'aria-label': props.text?.close || c,
305
+ onClick: async () => {
306
+ await props.onClose?.();
307
+ Toast.hide(action);
308
+ },
295
309
  }),
296
310
  jsx('button', {
297
311
  className: joinClasses(className.button, className.actionButton),
298
- children: props.text?.action || 'action',
312
+ children: props.text?.action || a,
299
313
  'data-action': 'toast-action',
314
+ 'aria-label': props.text?.action || a,
300
315
  onClick: async () => {
301
316
  await props.onAction?.();
302
317
  Toast.hide(action);
@@ -314,7 +329,7 @@ export class Toast {
314
329
  id,
315
330
  'show',
316
331
  () => {
317
- action.classList.add(className.shown);
332
+ action.setAttribute('aria-live', 'polite');
318
333
  q<HTMLButtonElement>('[data-action="toast-action"]', action)?.focus();
319
334
  },
320
335
  10
@@ -4,14 +4,13 @@ import { type ResolveSchema, resolveProps } from '../utilities/core.ts';
4
4
  import { type DOMReference } from '../utilities/dom.ts';
5
5
  import {
6
6
  Drop,
7
- type DropClassNameConfig,
8
7
  type DropDelay,
9
8
  type DropMode,
10
9
  type DropPosition,
11
10
  } from './drop.ts';
12
11
 
13
12
  export interface TooltipClassNames {
14
- root: string;
13
+ container: string;
15
14
  message: string;
16
15
  }
17
16
 
@@ -24,7 +23,6 @@ export interface TooltipProps extends Record<string, unknown> {
24
23
  offset?: number;
25
24
  message?: string;
26
25
  className?: TooltipClassNameConfig;
27
- dropClassName?: DropClassNameConfig;
28
26
  id?: string | null;
29
27
  delay?: number | DropDelay;
30
28
  hoverIntent?: boolean;
@@ -39,7 +37,6 @@ interface ResolvedTooltipProps extends Record<string, unknown> {
39
37
  offset: number;
40
38
  message: string;
41
39
  className: TooltipClassNames;
42
- dropClassName: DropClassNameConfig;
43
40
  id: string | null;
44
41
  delay: number | DropDelay;
45
42
  hoverIntent: boolean;
@@ -48,7 +45,7 @@ interface ResolvedTooltipProps extends Record<string, unknown> {
48
45
  }
49
46
 
50
47
  const DEFAULT_CLASS_NAMES: TooltipClassNames = {
51
- root: 'j-tooltip',
48
+ container: 'j-tooltip',
52
49
  message: 'tooltip-message',
53
50
  };
54
51
 
@@ -87,7 +84,6 @@ const TOOLTIP_OPTIONS_SCHEMA = {
87
84
  ...(value && typeof value === 'object' ? value : {}),
88
85
  }),
89
86
  },
90
- dropClassName: { default: {}, type: 'object' },
91
87
  id: { default: null, types: ['string', 'null'] },
92
88
  delay: { default: 100, types: ['number', 'object'] },
93
89
  hoverIntent: { default: true, type: 'boolean' },
@@ -104,7 +100,6 @@ function normalizeProps(input: TooltipProps): ResolvedTooltipProps {
104
100
  offset: props.offset as number,
105
101
  message: props.message as string,
106
102
  className: props.className as TooltipClassNames,
107
- dropClassName: props.dropClassName as DropClassNameConfig,
108
103
  id: props.id as string | null,
109
104
  delay: props.delay as number | DropDelay,
110
105
  hoverIntent: props.hoverIntent as boolean,
@@ -135,14 +130,13 @@ export class Tooltip {
135
130
  hoverIntent: settings.hoverIntent,
136
131
  onShown: settings.onShown,
137
132
  onHidden: settings.onHidden,
138
- className: settings.dropClassName,
139
133
  content: this.buildContent(settings),
140
134
  });
141
135
  }
142
136
 
143
137
  private buildContent(settings: ResolvedTooltipProps): HTMLElement {
144
138
  return jsx('div', {
145
- className: settings.className.root,
139
+ className: settings.className.container,
146
140
  'data-tooltip': settings.name || settings.id || '',
147
141
  children: jsx('div', {
148
142
  className: settings.className.message,
@@ -325,7 +325,7 @@ export default class Component<
325
325
  */
326
326
  destroy(): void {
327
327
  if (this.runtime.destroyed) return;
328
- this.runtime = { destroyed: true };
328
+ this.runtime.destroyed = true;
329
329
 
330
330
  if (typeof this.onDestroy === 'function') this.onDestroy();
331
331
  this.emit('destroy');