@vollowx/seele 0.14.1 → 0.14.3

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 (62) hide show
  1. package/README.md +5 -1
  2. package/custom-elements.json +195 -153
  3. package/package.json +4 -4
  4. package/src/all.d.ts +3 -1
  5. package/src/all.js +3 -1
  6. package/src/base/autocomplete.d.ts +1 -0
  7. package/src/base/autocomplete.js +17 -5
  8. package/src/base/composed-menu.d.ts +16 -0
  9. package/src/base/composed-menu.js +36 -0
  10. package/src/base/menu.js +26 -0
  11. package/src/base/popup-styles.css.js +1 -1
  12. package/src/base/popup.d.ts +22 -9
  13. package/src/base/popup.js +131 -83
  14. package/src/base/positioning.d.ts +2 -0
  15. package/src/base/positioning.js +23 -0
  16. package/src/base/progressbar.d.ts +13 -0
  17. package/src/base/progressbar.js +32 -0
  18. package/src/base/slider.d.ts +1 -2
  19. package/src/base/slider.js +1 -8
  20. package/src/base/tooltip-styles.css.js +2 -0
  21. package/src/base/tooltip.d.ts +9 -8
  22. package/src/base/tooltip.js +143 -56
  23. package/src/m3/autocomplete/autocomplete-styles.css.js +1 -1
  24. package/src/m3/autocomplete/autocomplete.js +1 -1
  25. package/src/m3/badge/badge-styles.css.js +1 -1
  26. package/src/m3/button/common-button-styles.css.js +1 -1
  27. package/src/m3/button/icon-button-styles.css.js +1 -1
  28. package/src/m3/button/shared-button-styles.css.js +1 -1
  29. package/src/m3/button/shared-button-toggle-styles.css.js +1 -1
  30. package/src/m3/button-group/connected-button-group-styles.css.js +1 -1
  31. package/src/m3/fab/fab-styles.css.js +1 -1
  32. package/src/m3/item/item-styles.css.js +1 -1
  33. package/src/m3/list/list-item-styles.css.js +1 -1
  34. package/src/m3/loading/loading-styles.css.js +2 -0
  35. package/src/m3/{loading-indicator/loading-indicator.d.ts → loading/loading.d.ts} +9 -3
  36. package/src/m3/{loading-indicator/loading-indicator.js → loading/loading.js} +15 -9
  37. package/src/m3/menu/composed-menu.d.ts +4 -9
  38. package/src/m3/menu/composed-menu.js +7 -27
  39. package/src/m3/menu/menu-styles.css.js +1 -1
  40. package/src/m3/navigation/navigation-rail-styles.css.js +1 -1
  41. package/src/m3/popup/popup-styles.css.js +1 -1
  42. package/src/m3/popup/popup.d.ts +1 -0
  43. package/src/m3/popup/popup.js +4 -0
  44. package/src/m3/progress/circular-progress-styles.css.js +2 -0
  45. package/src/m3/progress/circular-progress.d.ts +19 -0
  46. package/src/m3/progress/circular-progress.js +29 -0
  47. package/src/m3/progress/linear-progress-styles.css.js +2 -0
  48. package/src/m3/progress/linear-progress.d.ts +22 -0
  49. package/src/m3/progress/linear-progress.js +35 -0
  50. package/src/m3/radio/radio-styles.css.js +1 -1
  51. package/src/m3/select/select-styles.css.js +1 -1
  52. package/src/m3/slider/slider-styles.css.js +1 -1
  53. package/src/m3/slider/slider.d.ts +4 -1
  54. package/src/m3/slider/slider.js +22 -4
  55. package/src/m3/switch/switch-styles.css.js +1 -1
  56. package/src/m3/tab/tab-styles.css.js +1 -1
  57. package/src/m3/tooltip/tooltip-styles.css.js +1 -1
  58. package/src/m3/tooltip/tooltip.d.ts +0 -7
  59. package/src/m3/tooltip/tooltip.js +1 -8
  60. package/src/base/controllers/popover-controller.d.ts +0 -35
  61. package/src/base/controllers/popover-controller.js +0 -163
  62. package/src/m3/loading-indicator/loading-indicator-styles.css.js +0 -2
@@ -1,23 +1,32 @@
1
+ // References:
2
+ // - https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/
3
+ // - https://sarahmhigley.com/writing/tooltips-in-wcag-21/#best-practices-summary
1
4
  import { __decorate } from "tslib";
2
- import { LitElement, html } from 'lit';
3
- import { property, query } from 'lit/decorators.js';
5
+ import { LitElement, html, isServer } from 'lit';
6
+ import { property } from 'lit/decorators.js';
7
+ import { autoUpdate, computePosition, arrow, flip, offset, shift, } from '@floating-ui/dom';
4
8
  import { focusVisible } from '../core/focus.js';
5
9
  import { Attachable, handleControlChange } from './mixins/attachable.js';
6
10
  import { InternalsAttached, internals } from './mixins/internals-attached.js';
7
- import { PopoverController } from './controllers/popover-controller.js';
11
+ import { transformOriginFromArrow } from './positioning.js';
12
+ import { tooltipStyles } from './tooltip-styles.css.js';
8
13
  let lastHidingTime = 0;
14
+ let userSelectHolders = { count: 0, prevUserSelect: '' };
15
+ // To prevent text zoom bubbles in Safari. Ignore the `webkitUserSelect`s.
9
16
  const Base = Attachable(InternalsAttached(LitElement));
10
17
  /**
11
18
  * TODO: Check if $control controls a menu/popover and keep hidden when it is open.
19
+ * TODO: Allow adding a real arrow
12
20
  */
13
21
  export class Tooltip extends Base {
22
+ static { this.styles = [tooltipStyles]; }
14
23
  render() {
15
- return html `<slot @slotchange="${this.#handleSlotChange}"></slot>`;
24
+ return html `<slot></slot>`;
16
25
  }
17
- // Different from those in the popoverController, these timers are used to
18
- // manage the delay before showing/hiding the tooltip.
26
+ // Used to manage the delay before showing/hiding the tooltip.
19
27
  #openTimer;
20
28
  #closeTimer;
29
+ #holdingUserSelect;
21
30
  constructor() {
22
31
  super();
23
32
  this._delays = {
@@ -26,62 +35,75 @@ export class Tooltip extends Base {
26
35
  touch: { show: 700, hide: 1500 },
27
36
  recentlyShowed: 800,
28
37
  };
29
- this._durations = { show: 100, hide: 100 };
30
38
  this.align = 'top';
31
39
  this.offset = 4;
40
+ this.windowPadding = 8;
32
41
  this.forceInvisible = false;
33
- // Different from those in the popoverController, these timers are used to
34
- // manage the delay before showing/hiding the tooltip.
42
+ this.open = false;
43
+ // Used to manage the delay before showing/hiding the tooltip.
35
44
  this.#openTimer = null;
36
45
  this.#closeTimer = null;
37
- this.popoverController = new PopoverController(this, {
38
- popover: () => this,
39
- trigger: () => this.$control,
40
- positioning: {
41
- placement: () => this.align,
42
- strategy: () => 'absolute',
43
- offset: () => this.offset,
44
- windowPadding: () => 16,
45
- },
46
- durations: {
47
- open: () => this._durations.show,
48
- close: () => this._durations.hide,
49
- },
50
- onClickAway: () => {
51
- this.visible = false;
52
- },
53
- });
54
- this.#handleSlotChange = () => {
55
- if (!this.visible)
56
- this.$control.setAttribute('aria-label', this.textContent ?? '');
57
- };
46
+ this.#holdingUserSelect = false;
58
47
  this.#handleFocusIn = () => {
59
48
  if (!focusVisible)
60
49
  return;
61
- this.#show(this._delays.focus.show);
50
+ this.#scheduleShow(this._delays.focus.show, true);
62
51
  };
63
52
  this.#handleFocusOut = () => {
64
- this.#hide(this._delays.focus.hide);
53
+ this.#scheduleHide(this._delays.focus.hide);
65
54
  };
66
55
  this.#handlePointerEnter = (e) => {
67
56
  const evt = e;
68
57
  if (evt.pointerType === 'touch')
69
58
  return;
70
- this.#show(this._delays.mouse.show);
59
+ this.#scheduleShow(this._delays.mouse.show, true);
71
60
  };
72
61
  this.#handlePointerLeave = (e) => {
73
62
  const evt = e;
74
63
  if (evt.pointerType === 'touch')
75
64
  return;
76
- this.#hide(this._delays.mouse.hide);
65
+ this.#scheduleHide(this._delays.mouse.hide);
77
66
  };
78
67
  this.#handleTouchStart = () => {
79
- this.#show(this._delays.touch.show);
68
+ this.#editUserSelect();
69
+ this.#scheduleShow(this._delays.touch.show);
80
70
  };
81
71
  this.#handleTouchEnd = () => {
82
- this.#hide(this._delays.touch.hide);
72
+ this.#restoreUserSelect();
73
+ this.#scheduleHide(this._delays.touch.hide);
74
+ };
75
+ this.#handleGlobalPointerUp = (event) => {
76
+ const trigger = this.$control;
77
+ const path = event.composedPath();
78
+ if (trigger && path.includes(trigger))
79
+ return;
80
+ if (path.includes(this))
81
+ return;
82
+ this.open = false;
83
+ };
84
+ this.#handleGlobalKeyDown = (event) => {
85
+ if (event.key === 'Escape')
86
+ this.open = false;
83
87
  };
88
+ this.#dummyArrow = isServer ? null : document.createElement('div');
84
89
  this[internals].role = 'tooltip';
90
+ if (!this.hasAttribute('popover'))
91
+ this.setAttribute('popover', 'manual');
92
+ }
93
+ disconnectedCallback() {
94
+ this._cleanup();
95
+ window.removeEventListener('pointerup', this.#handleGlobalPointerUp);
96
+ window.removeEventListener('keydown', this.#handleGlobalKeyDown);
97
+ this.#restoreUserSelect();
98
+ super.disconnectedCallback();
99
+ }
100
+ updated(changedProperties) {
101
+ if (!changedProperties.has('open'))
102
+ return;
103
+ if (this.open)
104
+ this.#show();
105
+ else
106
+ this.#hide();
85
107
  }
86
108
  [handleControlChange](prev = null, next = null) {
87
109
  const eventHandlers = {
@@ -97,50 +119,115 @@ export class Tooltip extends Base {
97
119
  next?.addEventListener(key, eventHandlers[key]);
98
120
  });
99
121
  if (prev)
100
- prev.removeAttribute('aria-label');
122
+ prev.ariaDescribedByElements = [];
101
123
  if (next)
102
- next.setAttribute('aria-label', this.textContent ?? '');
103
- }
104
- set visible(value) {
105
- if (value) {
106
- this.popoverController.animateOpen();
107
- }
108
- else {
109
- this.popoverController.animateClose();
110
- }
124
+ next.ariaDescribedByElements = [this];
111
125
  }
112
- #handleSlotChange;
113
126
  #handleFocusIn;
114
127
  #handleFocusOut;
115
128
  #handlePointerEnter;
116
129
  #handlePointerLeave;
117
130
  #handleTouchStart;
118
131
  #handleTouchEnd;
119
- #show(delay) {
132
+ #handleGlobalPointerUp;
133
+ #handleGlobalKeyDown;
134
+ #scheduleShow(delay, allowInstantShow = false) {
120
135
  clearTimeout(this.#closeTimer);
121
136
  this.#openTimer = setTimeout(() => {
122
- this.visible = true;
123
- }, Math.max(Date.now() - lastHidingTime < this._delays.recentlyShowed ? 0 : delay));
137
+ this.open = true;
138
+ }, allowInstantShow &&
139
+ Date.now() - lastHidingTime < this._delays.recentlyShowed
140
+ ? 0
141
+ : delay);
124
142
  }
125
- #hide(delay) {
126
- if (this.popoverController.open) {
143
+ #scheduleHide(delay) {
144
+ if (this.open) {
127
145
  lastHidingTime = Date.now();
128
146
  }
129
147
  clearTimeout(this.#openTimer);
130
148
  this.#closeTimer = setTimeout(() => {
131
- this.visible = false;
149
+ this.open = false;
132
150
  }, delay);
133
151
  }
152
+ async #show() {
153
+ setTimeout(() => {
154
+ if (this.open)
155
+ window.addEventListener('pointerup', this.#handleGlobalPointerUp);
156
+ }, 0);
157
+ window.addEventListener('keydown', this.#handleGlobalKeyDown);
158
+ const trigger = this.$control;
159
+ if (this.isConnected && !this.matches(':popover-open'))
160
+ this.showPopover({ source: trigger ?? undefined });
161
+ if (trigger) {
162
+ this._cleanup();
163
+ this.#cleanupAutoUpdate = autoUpdate(trigger, this, () => this.reposition());
164
+ await this.reposition();
165
+ }
166
+ }
167
+ #hide() {
168
+ window.removeEventListener('pointerup', this.#handleGlobalPointerUp);
169
+ window.removeEventListener('keydown', this.#handleGlobalKeyDown);
170
+ this._cleanup();
171
+ this.#restoreUserSelect();
172
+ if (this.matches(':popover-open'))
173
+ this.hidePopover();
174
+ }
175
+ #editUserSelect() {
176
+ if (!userSelectHolders.count) {
177
+ userSelectHolders.prevUserSelect = document.body.style.webkitUserSelect;
178
+ document.body.style.webkitUserSelect = 'none';
179
+ }
180
+ ++userSelectHolders.count;
181
+ this.#holdingUserSelect = true;
182
+ }
183
+ #restoreUserSelect() {
184
+ if (!this.#holdingUserSelect)
185
+ return;
186
+ this.#holdingUserSelect = false;
187
+ userSelectHolders.count = Math.max(0, userSelectHolders.count - 1);
188
+ if (!userSelectHolders.count)
189
+ document.body.style.webkitUserSelect = userSelectHolders.prevUserSelect;
190
+ }
191
+ #cleanupAutoUpdate;
192
+ #dummyArrow;
193
+ async reposition() {
194
+ const trigger = this.$control;
195
+ if (!trigger)
196
+ return Promise.resolve();
197
+ return computePosition(trigger, this, {
198
+ placement: this.align,
199
+ strategy: 'absolute',
200
+ middleware: [
201
+ offset(this.offset),
202
+ flip({ padding: this.windowPadding }),
203
+ shift({ padding: this.windowPadding, crossAxis: true }),
204
+ arrow({ element: this.#dummyArrow }),
205
+ ],
206
+ }).then(({ x, y, placement, middlewareData }) => {
207
+ Object.assign(this.style, {
208
+ left: `${x}px`,
209
+ top: `${y}px`,
210
+ transformOrigin: transformOriginFromArrow(placement, middlewareData.arrow),
211
+ });
212
+ });
213
+ }
214
+ _cleanup() {
215
+ this.#cleanupAutoUpdate?.();
216
+ this.#cleanupAutoUpdate = undefined;
217
+ }
134
218
  }
135
219
  __decorate([
136
220
  property({ reflect: true })
137
221
  ], Tooltip.prototype, "align", void 0);
138
222
  __decorate([
139
- property({ type: Number, reflect: true })
223
+ property({ type: Number })
140
224
  ], Tooltip.prototype, "offset", void 0);
225
+ __decorate([
226
+ property({ type: Number, attribute: 'window-padding' })
227
+ ], Tooltip.prototype, "windowPadding", void 0);
141
228
  __decorate([
142
229
  property({ type: Boolean, reflect: true, attribute: 'force-invisible' })
143
230
  ], Tooltip.prototype, "forceInvisible", void 0);
144
231
  __decorate([
145
- query('slot')
146
- ], Tooltip.prototype, "$slot", void 0);
232
+ property({ type: Boolean, reflect: true })
233
+ ], Tooltip.prototype, "open", void 0);
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const autocompleteStyles = css`:host{-webkit-user-select:none;user-select:none;min-width:210px;display:inline-block;position:relative}::slotted([slot=input]){cursor:pointer;outline:none;width:100%}[part=popup]{--md-menu-max-height:300px;min-width:inherit}`;
2
+ export const autocompleteStyles = css`:host{-webkit-user-select:none;user-select:none;width:300px;display:inline-block;position:relative}::slotted([slot=input]){cursor:pointer;outline:none;width:100%}[part=popup]{width:inherit}[part=menu]{max-height:400px}`;
@@ -11,7 +11,7 @@ import { autocompleteStyles } from './autocomplete-styles.css.js';
11
11
  let M3Autocomplete = class M3Autocomplete extends Autocomplete {
12
12
  static { this.styles = [autocompleteStyles]; }
13
13
  renderMenu() {
14
- return html `<md-popup part="popup" role="presentation" no-focus-control quick .open="${this.open}" @toggle="${(e) => (this.open = e.newState === 'open')}"><md-menu part="menu" id="menu" type="listbox" tabindex="-1" @action="${this.handleMenuAction}"><slot @slotchange="${this.handleItemsSlotChange}"></slot></md-menu></md-popup>`;
14
+ return html `<md-popup part="popup" role="presentation" no-focus-control quick .open="${this.open}" @toggle="${(e) => (this.open = e.newState === 'open')}"><md-menu part="menu" id="menu" role="listbox" tabindex="-1" @action="${this.handleMenuAction}"><slot @slotchange="${this.handleItemsSlotChange}"></slot></md-menu></md-popup>`;
15
15
  }
16
16
  };
17
17
  M3Autocomplete = __decorate([
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const badgeStyles = css`:host{--md-badge-offset:0}[part~=root]{vertical-align:middle;flex-shrink:0;display:inline-flex;position:relative}[part~=badge]{--md-badge-scale:1;top:var(--md-badge-offset);right:var(--md-badge-offset);box-sizing:border-box;font:var(--md-sys-typography-label-small);z-index:1;background-color:var(--md-sys-color-error);min-width:16px;height:16px;color:var(--md-sys-color-on-error);transform:scale(var(--md-badge-scale)) translate(50%, -50%);transform-origin:100% 0;transition:transform var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);pointer-events:none;border-radius:8px;flex-flow:wrap;justify-content:center;align-items:center;padding:0 2.5px;display:flex;position:absolute}:host([small]) [part~=badge]{--md-badge-scale:.375;color:#0000}:host([hidden]){display:hidden}:host([value="0"]:not([show-zero])) [part~=badge],:host([hidden]) [part~=badge]{--md-badge-scale:0}:host([circle]){--md-badge-offset:14%}:host([left]:not([dir=rtl])) [part~=badge],:host(:not([left])[dir=rtl]) [part~=badge]{right:auto;left:var(--md-badge-offset);transform:scale(var(--md-badge-scale)) translate(-50%, -50%);transform-origin:0 0}:host([bottom]) [part~=badge]{top:auto;bottom:var(--md-badge-offset);transform:scale(var(--md-badge-scale)) translate(50%, 50%);transform-origin:100% 100%}:host([left][bottom]:not([dir=rtl])) [part~=badge],:host(:not([left])[dir=rtl][bottom]) [part~=badge]{transform:scale(var(--md-badge-scale)) translate(-50%, 50%);transform-origin:0 100%}`;
2
+ export const badgeStyles = css`:host{--md-badge-offset:0}[part~=root]{vertical-align:middle;flex-shrink:0;display:inline-flex;position:relative}[part~=badge]{--md-badge-scale:1;top:var(--md-badge-offset);right:var(--md-badge-offset);box-sizing:border-box;font:var(--md-sys-typography-label-small);background-color:var(--md-sys-color-error);min-width:16px;height:16px;color:var(--md-sys-color-on-error);transform:scale(var(--md-badge-scale)) translate(50%, -50%);transform-origin:100% 0;transition:transform var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);pointer-events:none;border-radius:8px;flex-flow:wrap;justify-content:center;align-items:center;padding:0 2.5px;display:flex;position:absolute}:host([small]) [part~=badge]{--md-badge-scale:.375;color:#0000}:host([hidden]){display:hidden}:host([value="0"]:not([show-zero])) [part~=badge],:host([hidden]) [part~=badge]{--md-badge-scale:0}:host([circle]){--md-badge-offset:14%}:host([left]:not([dir=rtl])) [part~=badge],:host(:not([left])[dir=rtl]) [part~=badge]{right:auto;left:var(--md-badge-offset);transform:scale(var(--md-badge-scale)) translate(-50%, -50%);transform-origin:0 0}:host([bottom]) [part~=badge]{top:auto;bottom:var(--md-badge-offset);transform:scale(var(--md-badge-scale)) translate(50%, 50%);transform-origin:100% 100%}:host([left][bottom]:not([dir=rtl])) [part~=badge],:host(:not([left])[dir=rtl][bottom]) [part~=badge]{transform:scale(var(--md-badge-scale)) translate(-50%, 50%);transform-origin:0 100%}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const commonButtonStyles = css`@layer main{:host{--_padding:16px;--md-focus-ring-shape:calc(var(--_h) / 2);background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);font:var(--md-sys-typography-label-large);min-inline-size:64px;padding-inline:var(--_padding);transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);justify-content:center;align-items:center;gap:8px;display:inline-flex}:host([size=xs]){--_padding:12px;gap:4px}:host([size=m]){--_padding:24px;font:var(--md-sys-typography-title-medium);gap:8px}:host([size=l]){--_padding:48px;font:var(--md-sys-typography-headline-small);gap:12px}:host([size=xl]){--_padding:64px;font:var(--md-sys-typography-headline-medium);gap:16px}:host([trailing-icon]){flex-direction:row-reverse}:host([variant=outlined]){padding-inline:calc(var(--_padding) - 1px)}:host([variant=text]){padding-inline:calc(var(--_padding) / 4 * 3)}::slotted([slot=icon]),::slotted([slot=icon-checked]){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([variant=elevated]){--_background-color:var(--md-sys-color-surface-container-low);--_text-color:var(--_color);box-shadow:var(--md-sys-elevation-shadow-1)}@media (hover:hover) and (pointer:fine){:host([variant=filled]:hover:not(:active)),:host([variant=tonal]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-1)}:host([variant=elevated]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-2)}}}`;
2
+ export const commonButtonStyles = css`@layer main{:host{--_padding:16px;--md-focus-ring-shape:calc(var(--_h) / 2);font:var(--md-sys-typography-label-large);min-inline-size:64px;padding-inline:var(--_padding);transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);justify-content:center;align-items:center;gap:8px;display:inline-flex}:host([size=xs]){--_padding:12px;gap:4px}:host([size=m]){--_padding:24px;font:var(--md-sys-typography-title-medium);gap:8px}:host([size=l]){--_padding:48px;font:var(--md-sys-typography-headline-small);gap:12px}:host([size=xl]){--_padding:64px;font:var(--md-sys-typography-headline-medium);gap:16px}:host([trailing-icon]){flex-direction:row-reverse}:host([variant=outlined]){padding-inline:calc(var(--_padding) - 1px)}:host([variant=text]){padding-inline:calc(var(--_padding) / 4 * 3)}::slotted([slot=icon]),::slotted([slot=icon-checked]){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([variant=elevated]){background-color:var(--md-sys-color-surface-container-low);color:var(--_color);box-shadow:var(--md-sys-elevation-shadow-1)}@media (hover:hover) and (pointer:fine){:host([variant=filled]:hover:not(:active)),:host([variant=tonal]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-1)}:host([variant=elevated]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-2)}}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const iconButtonStyles = css`@layer main{:host{--_wn:32px;--_ww:52px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);inline-size:var(--_h);place-items:center;display:inline-grid}:host([size=xs]){--_wn:28px;--_ww:40px}:host([size=m]){--_wn:48px;--_ww:72px}:host([size=l]){--_wn:64px;--_ww:128px}:host([size=xl]){--_wn:104px;--_ww:184px}:host([width=narrow]){inline-size:var(--_wn)}:host([width=wide]){inline-size:var(--_ww)}::slotted(*){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([size=small]){--_icon-size:24px}:host([variant=text]){--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=text]:state(checked)){--_text-color:var(--_color)}}`;
2
+ export const iconButtonStyles = css`@layer main{:host{--_wn:32px;--_ww:52px;transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);inline-size:var(--_h);place-items:center;display:inline-grid}:host([size=xs]){--_wn:28px;--_ww:40px}:host([size=m]){--_wn:48px;--_ww:72px}:host([size=l]){--_wn:64px;--_ww:128px}:host([size=xl]){--_wn:104px;--_ww:184px}:host([width=narrow]){inline-size:var(--_wn)}:host([width=wide]){inline-size:var(--_ww)}::slotted(*){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([size=small]){--_icon-size:24px}:host([variant=text]){color:var(--md-sys-color-on-surface-variant)}:host([variant=text]:state(checked)){color:var(--_color)}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const sharedButtonStyles = css`@layer main;@layer shared{:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_icon-size:20px;--_rs:12px;--_rp:8px;--_text-color:var(--_on-color);--_background-color:var(--_color);box-sizing:border-box;cursor:pointer;block-size:var(--_h);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;vertical-align:top;border-start-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));border-start-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));outline:0;flex-shrink:0;position:relative}:host([notransition]){transition:none!important}md-ripple,md-focus-ring{position:absolute}:host([size=xs]){--_h:32px}:host([size=m]){--_h:56px;--_icon-size:24px;--_rs:16px;--_rp:12px}:host([size=l]){--_h:96px;--_icon-size:32px;--_rs:28px;--_rp:16px}:host([size=xl]){--_h:136px;--_icon-size:40px;--_rs:28px;--_rp:16px}:host([color=secondary]){--_on-color:var(--md-sys-color-on-secondary);--_color:var(--md-sys-color-secondary)}:host([color=tertiary]){--_on-color:var(--md-sys-color-on-tertiary);--_color:var(--md-sys-color-tertiary)}:host([variant=tonal]){--_background-color:var(--md-sys-color-secondary-container);--_text-color:var(--md-sys-color-on-secondary-container)}:host([variant=outlined]){--_background-color:transparent;--_text-color:var(--md-sys-color-on-surface-variant);--md-focus-ring-offset:3px;border-color:color-mix(in srgb, var(--md-sys-color-outline-variant) 100%, transparent);border-style:solid;border-width:1px;& md-ripple{inset:-1px}}:host([variant=text]){--_text-color:var(--_color);--_background-color:transparent!important}:host([square]){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}@media (forced-colors:active){:host{forced-color-adjust:none;color:buttontext;background:buttonface;border:1px solid buttonborder}}}@layer shared-toggle,override;@layer active{:host(:active),:host(:state(active)){--md-focus-ring-shape:var(--_rp);border-radius:var(--_rp)}}@layer disabled{:host([variant=outlined]:disabled){--_background-color:var(--md-sys-color-outline)}:host(:disabled),:host([variant=outlined]:state(checked):disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:10%;--_text-color:var(--md-sys-color-on-surface);--_text-opacity:38%;border-color:color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);box-shadow:none;pointer-events:none}@media (forced-colors:active){:host(:disabled){color:graytext;border-color:graytext}}}`;
2
+ export const sharedButtonStyles = css`@layer main;@layer shared{:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_icon-size:20px;--_rs:12px;--_rp:8px;color:var(--_on-color);background-color:var(--_color);box-sizing:border-box;cursor:pointer;block-size:var(--_h);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;vertical-align:top;border-start-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));border-start-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));outline:0;flex-shrink:0;position:relative}:host([notransition]){transition:none!important}md-ripple,md-focus-ring{position:absolute}:host([size=xs]){--_h:32px}:host([size=m]){--_h:56px;--_icon-size:24px;--_rs:16px;--_rp:12px}:host([size=l]){--_h:96px;--_icon-size:32px;--_rs:28px;--_rp:16px}:host([size=xl]){--_h:136px;--_icon-size:40px;--_rs:28px;--_rp:16px}:host([color=secondary]){--_on-color:var(--md-sys-color-on-secondary);--_color:var(--md-sys-color-secondary)}:host([color=tertiary]){--_on-color:var(--md-sys-color-on-tertiary);--_color:var(--md-sys-color-tertiary)}:host([variant=tonal]){background-color:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}:host([variant=outlined]){--md-focus-ring-offset:3px;color:var(--md-sys-color-on-surface-variant);border-color:var(--md-sys-color-outline-variant);background-color:#0000;border-style:solid;border-width:1px;& md-ripple{inset:-1px}}:host([variant=text]){color:var(--_color);background-color:#0000}:host([square]){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}@media (forced-colors:active){:host{forced-color-adjust:none;color:buttontext;background:buttonface;border:1px solid buttonborder}}}@layer shared-toggle,override;@layer active{:host(:active),:host(:state(active)){--md-focus-ring-shape:var(--_rp);border-radius:var(--_rp)}}@layer disabled{:host([variant=outlined]:disabled){background-color:oklch(from var(--md-sys-color-outline) l c h / 10%)}:host(:disabled),:host([variant=outlined]:state(checked):disabled){background-color:oklch(from var(--md-sys-color-on-surface) l c h / 10%);color:oklch(from var(--md-sys-color-on-surface) l c h / 38%);border-color:oklch(from var(--md-sys-color-on-surface) l c h / 10%);box-shadow:none;pointer-events:none}@media (forced-colors:active){:host(:disabled){color:graytext;border-color:graytext}}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const sharedButtonToggleStyles = css`@layer shared-toggle{:host{transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast)}:host(:state(checked)){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}:host(:state(checked)) [part~=unchecked],:host(:not(:state(checked))) [part~=checked]{display:none}:host([variant=filled]:not(:state(checked))){--_background-color:var(--md-sys-color-surface-container);--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=tonal]:not(:state(checked))){--_background-color:var(--md-sys-color-surface-container-highest);--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=outlined]:state(checked)){--_background-color:var(--md-sys-color-inverse-surface);--_text-color:var(--md-sys-color-inverse-on-surface);border-width:0}@media (forced-colors:active){:host(:state(checked)){color:highlighttext;background:highlight}}}`;
2
+ export const sharedButtonToggleStyles = css`@layer shared-toggle{:host{transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast)}:host(:state(checked)){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}:host(:state(checked)) [part~=unchecked],:host(:not(:state(checked))) [part~=checked]{display:none}:host([variant=filled]:not(:state(checked))){background-color:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface-variant)}:host([variant=tonal]:not(:state(checked))){background-color:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface-variant)}:host([variant=outlined]:state(checked)){background-color:var(--md-sys-color-inverse-surface);color:var(--md-sys-color-inverse-on-surface);border-width:0}@media (forced-colors:active){:host(:state(checked)){color:highlighttext;background:highlight}}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const connectedButtonGroupStyles = css`:host{gap:2px;display:inline-flex}::slotted(*){flex:1}::slotted(:not(:first-child)[size=xs]){--_inner-left-radius:4px}::slotted(:not(:last-child)[size=xs]){--_inner-right-radius:4px}::slotted(:not(:first-child)){--_inner-left-radius:8px}::slotted(:not(:last-child)){--_inner-right-radius:8px}::slotted(:not(:first-child)[size=l]){--_inner-left-radius:16px}::slotted(:not(:last-child)[size=l]){--_inner-right-radius:16px}::slotted(:not(:first-child)[size=xl]){--_inner-left-radius:20px}::slotted(:not(:last-child)[size=xl]){--_inner-right-radius:20px}::slotted(:first-child:state(checked):not(:active,[square])){border-start-start-radius:calc(var(--_h) / 2);border-end-start-radius:calc(var(--_h) / 2)}::slotted(:last-child:state(checked):not(:active,[square])){border-start-end-radius:calc(var(--_h) / 2);border-end-end-radius:calc(var(--_h) / 2)}`;
2
+ export const connectedButtonGroupStyles = css`:host{gap:2px;display:inline-flex}::slotted(*){flex:1}::slotted(:not(:first-child)[size=xs]){--_inner-left-radius:4px}::slotted(:not(:last-child)[size=xs]){--_inner-right-radius:4px}::slotted(:not(:first-child)){--_inner-left-radius:8px}::slotted(:not(:last-child)){--_inner-right-radius:8px}::slotted(:not(:first-child)[size=l]){--_inner-left-radius:16px}::slotted(:not(:last-child)[size=l]){--_inner-right-radius:16px}::slotted(:not(:first-child)[size=xl]){--_inner-left-radius:20px}::slotted(:not(:last-child)[size=xl]){--_inner-right-radius:20px}::slotted(:first-child:not([square])){border-start-start-radius:calc(var(--_h) / 2);border-end-start-radius:calc(var(--_h) / 2)}::slotted(:last-child:not([square])){border-start-end-radius:calc(var(--_h) / 2);border-end-end-radius:calc(var(--_h) / 2)}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const fabStyles = css`:host{--md-focus-ring-shape:var(--_border-radius);--_text-color:var(--md-sys-color-on-primary);--_background-color:var(--md-sys-color-primary);--_size:56px;--_border-radius:16px;--_icon-size:24px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);border-radius:var(--_border-radius);box-shadow:var(--md-sys-elevation-shadow-3);box-sizing:border-box;color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);cursor:pointer;font:var(--md-sys-typography-label-large);height:var(--_size);min-width:var(--_size);padding-inline:calc((var(--_size) - var(--_icon-size)) / 2);-webkit-tap-highlight-color:transparent;transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);-webkit-user-select:none;user-select:none;vertical-align:middle;outline:0;justify-content:center;align-items:center;gap:8px;display:inline-flex;position:relative}md-ripple,md-focus-ring{position:absolute}:host([size=m]){--_size:80px;--_border-radius:20px;--_icon-size:28px}:host([size=l]){--_size:96px;--_border-radius:28px;--_icon-size:36px}:host([color=primary-container]){--_text-color:var(--md-sys-color-on-primary-container);--_background-color:var(--md-sys-color-primary-container)}:host([color=secondary-container]){--_text-color:var(--md-sys-color-on-secondary-container);--_background-color:var(--md-sys-color-secondary-container)}:host([color=tertiary-container]){--_text-color:var(--md-sys-color-on-tertiary-container);--_background-color:var(--md-sys-color-tertiary-container)}:host([color=secondary]){--_text-color:var(--md-sys-color-on-secondary);--_background-color:var(--md-sys-color-secondary)}:host([color=tertiary]){--_text-color:var(--md-sys-color-on-tertiary);--_background-color:var(--md-sys-color-tertiary)}:host([color=surface]){--_text-color:var(--md-sys-color-primary);--_background-color:var(--md-sys-color-surface-container-high)}:host(:disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:12%;--_text-color:var(--md-sys-color-on-surface);--_text-opacity:38%;box-shadow:none;pointer-events:none}@media (hover:hover) and (pointer:fine){:host(:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-4)}}::slotted(:not([slot=label])){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}::slotted([slot=label]){margin-inline:4px}@media (forced-colors:active){:host{forced-color-adjust:none;color:buttontext;background:buttonface;border:1px solid buttonborder}}`;
2
+ export const fabStyles = css`:host{--md-focus-ring-shape:var(--_border-radius);--_size:56px;--_border-radius:16px;--_icon-size:24px;background-color:var(--md-sys-color-primary);border-radius:var(--_border-radius);box-shadow:var(--md-sys-elevation-shadow-3);box-sizing:border-box;color:var(--md-sys-color-on-primary);cursor:pointer;font:var(--md-sys-typography-label-large);height:var(--_size);min-width:var(--_size);padding-inline:calc((var(--_size) - var(--_icon-size)) / 2);-webkit-tap-highlight-color:transparent;transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);-webkit-user-select:none;user-select:none;vertical-align:middle;outline:0;justify-content:center;align-items:center;gap:8px;display:inline-flex;position:relative}md-ripple,md-focus-ring{position:absolute}:host([size=m]){--_size:80px;--_border-radius:20px;--_icon-size:28px}:host([size=l]){--_size:96px;--_border-radius:28px;--_icon-size:36px}:host([color=primary-container]){color:var(--md-sys-color-on-primary-container);background-color:var(--md-sys-color-primary-container)}:host([color=secondary-container]){color:var(--md-sys-color-on-secondary-container);background-color:var(--md-sys-color-secondary-container)}:host([color=tertiary-container]){color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container)}:host([color=secondary]){color:var(--md-sys-color-on-secondary);background-color:var(--md-sys-color-secondary)}:host([color=tertiary]){color:var(--md-sys-color-on-tertiary);background-color:var(--md-sys-color-tertiary)}:host([color=surface]){color:var(--md-sys-color-primary);background-color:var(--md-sys-color-surface-container-high)}:host(:disabled){background-color:oklch(from var(--md-sys-color-on-surface) l c h / 10%);color:oklch(from var(--md-sys-color-on-surface) l c h / 38%);box-shadow:none;pointer-events:none}@media (hover:hover) and (pointer:fine){:host(:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-4)}}::slotted(:not([slot=label])){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}::slotted([slot=label]){margin-inline:4px}@media (forced-colors:active){:host{forced-color-adjust:none;color:buttontext;background:buttonface;border:1px solid buttonborder}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const itemStyles = css`:host{border-radius:inherit;box-sizing:border-box;font:var(--md-sys-typography-body-large);text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex:1;align-items:center;gap:16px;min-height:48px;padding:12px;display:flex;position:relative}:host([multiline]){min-height:72px}[name=container]{border-radius:inherit}[name=container]::slotted(*){position:absolute;inset:0}.default-slot{display:inline}.default-slot,.text ::slotted(*){text-overflow:ellipsis;overflow:hidden}.text{flex-direction:column;flex:1;display:flex;overflow:hidden}[name=overline]{font:var(--md-sys-typography-label-small)}[name=supporting-text]{color:var(--md-item-supporting-text-color,var(--md-sys-color-on-surface-variant));font:var(--md-sys-typography-body-medium)}`;
2
+ export const itemStyles = css`:host{border-radius:inherit;box-sizing:border-box;font:var(--md-sys-typography-body-large);min-height:calc(48px + 4px * var(--md-sys-spacing-density,0));padding:calc(12px + 2px * var(--md-sys-spacing-density,0)) 12px;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex:1;align-items:center;gap:16px;display:flex;position:relative}:host([multiline]){min-height:72px}[name=container]{border-radius:inherit}[name=container]::slotted(*){position:absolute;inset:0}.default-slot{display:inline}.default-slot,.text ::slotted(*){text-overflow:ellipsis;overflow:hidden}.text{flex-direction:column;flex:1;display:flex;overflow:hidden}[name=overline]{font:var(--md-sys-typography-label-small)}[name=supporting-text]{color:var(--md-item-supporting-text-color,var(--md-sys-color-on-surface-variant));font:var(--md-sys-typography-body-medium)}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const listItemStyles = css`:host{--md-focus-ring-shape:12px;--md-focus-ring-inward-offset:-3px;background-color:var(--_background,transparent);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;border-radius:4px;outline:0;display:flex}:host(:not([hidden]):first-of-type){border-radius:12px 12px 4px 4px}:host(:not([hidden]):last-of-type){border-radius:4px 4px 12px 12px}:host(:state(selected)){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-radius:12px}:host(:disabled){cursor:default;opacity:.3;pointer-events:none}md-item,md-item div[slot=container]{border-radius:inherit}@media (forced-colors:active){:host{forced-color-adjust:none;color:canvastext}:host(:hover),:host(:state(selected)){color:highlighttext;background:highlight}}`;
2
+ export const listItemStyles = css`:host{--md-focus-ring-shape:12px;--md-focus-ring-inward-offset:-3px;background-color:var(--_background,transparent);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;border-radius:4px;outline:0;display:flex}:host(:not([hidden],:state(selected)):first-of-type){border-radius:12px 12px 4px 4px}:host(:not([hidden],:state(selected)):last-of-type){border-radius:4px 4px 12px 12px}:host(:state(selected)){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-radius:12px}:host(:disabled){cursor:default;opacity:.3;pointer-events:none}md-item,md-item div[slot=container]{border-radius:inherit}md-ripple:before{transition:none}md-ripple::part(ripple){display:none}@media (forced-colors:active){:host{forced-color-adjust:none;color:canvastext}:host(:hover),:host(:state(selected)){color:highlighttext;background:highlight}}`;
@@ -0,0 +1,2 @@
1
+ import { css } from 'lit';
2
+ export const loadingStyles = css`:host{aspect-ratio:1;background-color:var(--md-sys-color-surface);border-radius:9999px;place-items:center;width:48px;display:grid}:host([contained]){background-color:var(--md-sys-color-primary-container)}canvas{width:82%;height:82%;display:block}`;
@@ -1,5 +1,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 brahmkshatriya
4
+ * Modifications Copyright 2026 Lucas X. Zhao
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
1
7
  import { LitElement } from 'lit';
2
- declare const M3LoadingIndicator_base: Constructor<import("../../base/mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
8
+ declare const M3Loading_base: Constructor<import("../../base/mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
3
9
  /**
4
10
  * @tag md-loading
5
11
  *
@@ -8,7 +14,7 @@ declare const M3LoadingIndicator_base: Constructor<import("../../base/mixins/int
8
14
  * pulls the color once per second
9
15
  * NOTE: the pantagon is completely not following the shape system
10
16
  */
11
- export declare class M3LoadingIndicator extends M3LoadingIndicator_base {
17
+ export declare class M3Loading extends M3Loading_base {
12
18
  #private;
13
19
  contained: boolean;
14
20
  $canvas: HTMLCanvasElement;
@@ -20,7 +26,7 @@ export declare class M3LoadingIndicator extends M3LoadingIndicator_base {
20
26
  }
21
27
  declare global {
22
28
  interface HTMLElementTagNameMap {
23
- 'md-loading': M3LoadingIndicator;
29
+ 'md-loading': M3Loading;
24
30
  }
25
31
  }
26
32
  export {};
@@ -1,9 +1,15 @@
1
- // Origin: https://github.com/brahmkshatriya/material-osc/blob/main/assets/loading-shape-morph-demo.html
1
+ /**
2
+ * @license
3
+ * Copyright 2026 brahmkshatriya
4
+ * Modifications Copyright 2026 Lucas X. Zhao
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
2
7
  import { __decorate } from "tslib";
8
+ // Origin: https://github.com/brahmkshatriya/material-osc/blob/main/assets/loading-shape-morph-demo.html
3
9
  import { LitElement, html } from 'lit';
4
10
  import { customElement, property, query } from 'lit/decorators.js';
5
11
  import { InternalsAttached, internals } from '../../base/mixins/internals-attached.js';
6
- import { loadingIndicatorStyles } from './loading-indicator-styles.css.js';
12
+ import { loadingStyles } from './loading-styles.css.js';
7
13
  const STEP_MS = 650;
8
14
  const FULL_ROTATION_MS = 4666;
9
15
  const QUARTER_ROTATION = 90;
@@ -19,8 +25,8 @@ const CENTER = CANVAS_SIZE / 2;
19
25
  * pulls the color once per second
20
26
  * NOTE: the pantagon is completely not following the shape system
21
27
  */
22
- let M3LoadingIndicator = class M3LoadingIndicator extends InternalsAttached(LitElement) {
23
- static { this.styles = [loadingIndicatorStyles]; }
28
+ let M3Loading = class M3Loading extends InternalsAttached(LitElement) {
29
+ static { this.styles = [loadingStyles]; }
24
30
  render() {
25
31
  return html `<canvas width="${CANVAS_SIZE}" height="${CANVAS_SIZE}" aria-hidden="true"></canvas>`;
26
32
  }
@@ -102,14 +108,14 @@ let M3LoadingIndicator = class M3LoadingIndicator extends InternalsAttached(LitE
102
108
  };
103
109
  __decorate([
104
110
  property({ type: Boolean, reflect: true })
105
- ], M3LoadingIndicator.prototype, "contained", void 0);
111
+ ], M3Loading.prototype, "contained", void 0);
106
112
  __decorate([
107
113
  query('canvas')
108
- ], M3LoadingIndicator.prototype, "$canvas", void 0);
109
- M3LoadingIndicator = __decorate([
114
+ ], M3Loading.prototype, "$canvas", void 0);
115
+ M3Loading = __decorate([
110
116
  customElement('md-loading')
111
- ], M3LoadingIndicator);
112
- export { M3LoadingIndicator };
117
+ ], M3Loading);
118
+ export { M3Loading };
113
119
  const lerp = (a, b, t) => a + (b - a) * t;
114
120
  const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
115
121
  const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
@@ -1,16 +1,11 @@
1
- import { handleControlChange } from '../../base/mixins/attachable.js';
2
- import { Popup } from '../../base/popup.js';
3
- import { M3Menu } from './menu.js';
1
+ import { ComposedMenu } from '../../base/composed-menu.js';
2
+ import './menu.js';
4
3
  /**
5
- * TODO: consider adding ariaLabel that is passed to the menu
4
+ * @tag md-composed-menu
6
5
  */
7
- export declare class M3ComposedMenu extends Popup {
6
+ export declare class M3ComposedMenu extends ComposedMenu {
8
7
  vibrant: boolean;
9
- $menu: M3Menu;
10
8
  static styles: any[];
11
- render(): import("lit-html").TemplateResult<1>;
12
- constructor();
13
- [handleControlChange](prev: HTMLElement | null, next: HTMLElement | null): void;
14
9
  }
15
10
  declare global {
16
11
  interface HTMLElementTagNameMap {
@@ -1,41 +1,21 @@
1
1
  import { __decorate } from "tslib";
2
- import { html } from 'lit';
3
- import { property, customElement, query } from 'lit/decorators.js';
4
- import { ensureReady } from '../../core/ensure-ready.js';
5
- import { internals } from '../../base/mixins/internals-attached.js';
6
- import { handleControlChange } from '../../base/mixins/attachable.js';
7
- import { Popup } from '../../base/popup.js';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import { ComposedMenu } from '../../base/composed-menu.js';
4
+ import './menu.js';
8
5
  import { popupStyles } from '../popup/popup-styles.css.js';
9
6
  /**
10
- * TODO: consider adding ariaLabel that is passed to the menu
7
+ * @tag md-composed-menu
11
8
  */
12
- let M3ComposedMenu = class M3ComposedMenu extends Popup {
13
- static { this.styles = [...super.styles, popupStyles]; }
14
- render() {
15
- return html `<md-menu><slot></slot></md-menu>`;
16
- }
9
+ let M3ComposedMenu = class M3ComposedMenu extends ComposedMenu {
17
10
  constructor() {
18
- super();
11
+ super(...arguments);
19
12
  this.vibrant = false;
20
- this[internals].role = 'application';
21
- }
22
- [handleControlChange](prev, next) {
23
- if (next) {
24
- next.ariaHasPopup = 'menu';
25
- ensureReady(this.$menu).then(() => {
26
- next.ariaControlsElements = [this.$menu];
27
- this.$menu[internals].ariaLabelledByElements = [this.$control];
28
- });
29
- }
30
- super[handleControlChange](prev, next);
31
13
  }
14
+ static { this.styles = [...super.styles, popupStyles]; }
32
15
  };
33
16
  __decorate([
34
17
  property({ type: Boolean, reflect: true })
35
18
  ], M3ComposedMenu.prototype, "vibrant", void 0);
36
- __decorate([
37
- query('md-menu')
38
- ], M3ComposedMenu.prototype, "$menu", void 0);
39
19
  M3ComposedMenu = __decorate([
40
20
  customElement('md-composed-menu')
41
21
  ], M3ComposedMenu);
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const menuStyles = css`:host{box-sizing:border-box;height:inherit;max-height:300px;width:inherit;-webkit-user-select:none;user-select:none;outline:0;padding:4px;scroll-padding-block:4px;display:block;overflow-y:auto}[part=items]{flex-direction:column;gap:2px;display:flex}::slotted(md-divider){margin-block:6px}@media (forced-colors:active){:host{border:1px solid canvastext}}`;
2
+ export const menuStyles = css`:host{box-sizing:border-box;height:inherit;max-height:calc(100dvh - 16px);min-width:inherit;width:inherit;-webkit-user-select:none;user-select:none;outline:0;padding:4px;scroll-padding-block:4px;display:block;overflow-y:auto}[part=items]{flex-direction:column;gap:2px;display:flex}::slotted(md-divider){margin-block:6px}@media (forced-colors:active){:host{border:1px solid canvastext}}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const navigationRailStyles = css`:host{background-color:var(--md-sys-color-surface-container);box-sizing:border-box;-webkit-user-select:none;user-select:none;z-index:10;flex-shrink:0;grid-template-rows:min-content auto;justify-content:space-between;gap:40px;width:96px;height:100%;padding-block:20px;display:grid;overflow:visible}.actions{z-index:10;place-self:center;display:grid;position:sticky;top:-44px}::slotted(md-fab){box-shadow:none}.items{grid-template-areas:"stack";display:grid}slot:not([name]){flex-direction:column;grid-area:stack;gap:8px;padding:0;list-style:none;display:flex;position:relative}::slotted([end]){margin-block-start:auto}`;
2
+ export const navigationRailStyles = css`:host{background-color:var(--md-sys-color-surface-container);box-sizing:border-box;-webkit-user-select:none;user-select:none;flex-shrink:0;grid-template-rows:min-content auto;justify-content:space-between;gap:40px;width:96px;height:100%;padding-block:20px;display:grid;overflow:visible}.actions{place-self:center;display:grid;position:sticky;top:-44px}::slotted(md-fab){box-shadow:none}.items{grid-template-areas:"stack";display:grid}slot:not([name]){flex-direction:column;grid-area:stack;gap:8px;padding:0;list-style:none;display:flex;position:relative}::slotted([end]){margin-block-start:auto}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const popupStyles = css`:host{--_fast:var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);--_d:var(--md-sys-motion-spatial-default-duration);--_default:var(--_d) var(--md-sys-motion-spatial-default);background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);color:var(--md-sys-color-on-surface);opacity:0;transition:opacity var(--md-sys-motion-effects-fast-duration), transform var(--_fast), border-radius var(--_fast), display var(--_d) allow-discrete, overlay var(--_d) allow-discrete;border-radius:16px/46px;transform:scaleY(.35)}:host([strategy=fixed]){position:fixed}:host([vibrant]){--md-divider-color:var(--md-sys-color-tertiary);--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);& ::slotted([selected]){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary);background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}}slot{opacity:0;transition:opacity 67ms;display:block}:host(:popover-open){opacity:1;transition:opacity 67ms linear, transform var(--_default), border-radius var(--_default);border-radius:16px;transform:scaleY(1);& slot{opacity:1;transition:opacity 67ms linear 67ms}}@starting-style{:host(:popover-open){opacity:0;border-radius:16px/46px;transform:scaleY(.35);& slot{opacity:0}}}`;
2
+ export const popupStyles = css`:host{--_f:var(--md-sys-motion-spatial-fast-duration);--_fast:var(--_f) var(--md-sys-motion-spatial-fast);--_default:var(--md-sys-motion-spatial-default-duration) var(--md-sys-motion-spatial-default);background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);color:var(--md-sys-color-on-surface);opacity:0;transition:opacity .15s linear, transform var(--_fast), border-radius var(--_fast), display var(--_f) allow-discrete, overlay var(--_f) allow-discrete;border-radius:16px/32px;transform:scaleY(.5)}:host([quick]),:host([quick]) slot{transition:none!important}:host([vibrant]){--md-divider-color:var(--md-sys-color-tertiary);--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);& ::slotted([selected]){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary);background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}}slot{opacity:0;transition:opacity 67ms;display:block}:host(:popover-open){opacity:1;transition:opacity 83ms linear, transform var(--_default), border-radius var(--_default);border-radius:16px;transform:scaleY(1);& slot{opacity:1;transition:opacity 67ms linear 67ms}}@starting-style{:host(:popover-open){opacity:0;border-radius:16px/32px;transform:scaleY(.5);& slot{opacity:0}}}`;
@@ -1,5 +1,6 @@
1
1
  import { Popup } from '../../base/popup.js';
2
2
  export declare class M3Popup extends Popup {
3
+ quick: boolean;
3
4
  vibrant: boolean;
4
5
  static styles: any[];
5
6
  }
@@ -5,10 +5,14 @@ import { popupStyles } from './popup-styles.css.js';
5
5
  let M3Popup = class M3Popup extends Popup {
6
6
  constructor() {
7
7
  super(...arguments);
8
+ this.quick = false;
8
9
  this.vibrant = false;
9
10
  }
10
11
  static { this.styles = [...super.styles, popupStyles]; }
11
12
  };
13
+ __decorate([
14
+ property({ type: Boolean, reflect: true })
15
+ ], M3Popup.prototype, "quick", void 0);
12
16
  __decorate([
13
17
  property({ type: Boolean, reflect: true })
14
18
  ], M3Popup.prototype, "vibrant", void 0);
@@ -0,0 +1,2 @@
1
+ import { css } from 'lit';
2
+ export const circularProgressStyles = css`:host{--_size:var(--md-circular-progress-size,40px);--_thickness:var(--md-circular-progress-thickness,4px);--_gap:var(--md-circular-progress-gap,4px);--_value:0;height:var(--_size);width:var(--_size);display:inline-flex;position:relative;overflow:hidden}[part=container]{width:100%;height:100%;position:absolute;transform:rotate(-90deg)}svg{fill:#0000;width:100%;height:100%}[part~=track]{stroke:var(--md-sys-color-secondary-container);stroke-width:var(--_thickness);stroke-linecap:round;cx:calc(var(--_size) / 2);cy:calc(var(--_size) / 2);r:calc((var(--_size) - var(--_thickness)) / 2);stroke-dasharray:min((1 - var(--_value)) * (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) - var(--_gap) - var(--_thickness), 6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap) - var(--_gap) - 2 * var(--_thickness)) calc(6.28319 * (var(--_size) - var(--_thickness)) / 2 - min((1 - var(--_value)) * (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) - var(--_gap) - var(--_thickness), 6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap) - var(--_gap) - 2 * var(--_thickness)));stroke-dashoffset:calc(min((1 - var(--_value)) * (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) - var(--_gap) - var(--_thickness), 6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap) - var(--_gap) - 2 * var(--_thickness)) + var(--_gap) + var(--_thickness));transition:stroke-dasharray .5s cubic-bezier(0,0,.2,1),stroke-dashoffset .5s cubic-bezier(0,0,.2,1),stroke-width .25s cubic-bezier(.4,0,.6,1)}[part=active]{stroke:var(--md-sys-color-primary);stroke-width:var(--_thickness);stroke-linecap:round;cx:calc(var(--_size) / 2);cy:calc(var(--_size) / 2);r:calc((var(--_size) - var(--_thickness)) / 2);stroke-dasharray:calc(var(--_value) * (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) - var(--_thickness)) calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - var(--_value) * (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) + var(--_thickness));transition:stroke-dasharray .5s cubic-bezier(0,0,.2,1),stroke-width .25s cubic-bezier(.4,0,.6,1)}:host([indeterminate]){animation:6s linear infinite rotate;& [part=container]{animation:6s infinite container-rotate}& [part=track]{animation:6s infinite track-grow}& [part=active]{animation:6s infinite active-grow}}@keyframes rotate{0%{transform:rotate(-90deg)}to{transform:rotate(990deg)}}@keyframes container-rotate{0%{transform:rotate(0)}8.33333%{transform:rotate(90deg)}25%{transform:rotate(90deg)}33.3333%{transform:rotate(180deg)}50%{transform:rotate(180deg)}58.3333%{transform:rotate(270deg)}75%{transform:rotate(270deg)}83.3333%{transform:rotate(360deg)}to{transform:rotate(360deg)}}@keyframes track-grow{0%{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 - var(--_gap) - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 + var(--_gap) + var(--_thickness));stroke-dashoffset:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 - var(--_gap) - var(--_thickness) + var(--_gap) + var(--_thickness))}50%{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .13 - var(--_gap) - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .13 + var(--_gap) + var(--_thickness));stroke-dashoffset:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .13 - var(--_gap) - var(--_thickness) + var(--_gap) + var(--_thickness))}to{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 - var(--_gap) - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 + var(--_gap) + var(--_thickness));stroke-dashoffset:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .84 - var(--_gap) - var(--_thickness) + var(--_gap) + var(--_thickness))}}@keyframes active-grow{0%{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .16 - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .16 + var(--_thickness))}50%{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .87 - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .87 + var(--_thickness))}to{stroke-dasharray:calc((6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .16 - var(--_thickness)), calc((var(--_size) - var(--_thickness)) * 6.28319 / 2 - (6.28319 * (var(--_size) - var(--_thickness)) / 2 - var(--_gap)) * .16 + var(--_thickness))}}`;
@@ -0,0 +1,19 @@
1
+ import { ProgressBar } from '../../base/progressbar.js';
2
+ /**
3
+ * TODO: wavy?
4
+ *
5
+ * @tag md-circular-progress
6
+ *
7
+ * @csspart container
8
+ * @csspart track
9
+ * @csspart active
10
+ */
11
+ export declare class M3CircularProgress extends ProgressBar {
12
+ static styles: any[];
13
+ render(): import("lit-html").TemplateResult<1>;
14
+ }
15
+ declare global {
16
+ interface HTMLElementTagNameMap {
17
+ 'md-circular-progress': M3CircularProgress;
18
+ }
19
+ }