@vollowx/seele 0.7.1 → 0.8.0

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@vollowx/seele",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "Standard Extensible Elements. A web components library that can be styled and extended freely, pre-providing components in Material Design 3.",
5
5
  "author": "vollowx",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@ export class Checkbox extends Base {
20
20
  this.#handleClick = (e) => {
21
21
  e.stopPropagation();
22
22
  e.preventDefault();
23
- this.#toggleChecked();
23
+ this.toggleChecked();
24
24
  };
25
25
  this.#handleKeyDown = (e) => {
26
26
  if (e.key === ' ') {
@@ -32,7 +32,7 @@ export class Checkbox extends Base {
32
32
  if (e.key === ' ') {
33
33
  e.preventDefault();
34
34
  e.stopPropagation();
35
- this.#toggleChecked();
35
+ this.toggleChecked();
36
36
  }
37
37
  };
38
38
  this[internals].role = 'checkbox';
@@ -95,7 +95,7 @@ export class Checkbox extends Base {
95
95
  #handleClick;
96
96
  #handleKeyDown;
97
97
  #handleKeyUp;
98
- #toggleChecked() {
98
+ toggleChecked() {
99
99
  if (this.disabled)
100
100
  return;
101
101
  this.checked = !this.checked;
package/src/base/menu.js CHANGED
@@ -106,7 +106,7 @@ export class Menu extends Base {
106
106
  this.$control.ariaExpanded = 'true';
107
107
  }
108
108
  this.popoverController.animateOpen().then(() => {
109
- this.focus({ preventScroll: true });
109
+ this.focus();
110
110
  this.listController.focusFirstItem();
111
111
  });
112
112
  }
@@ -117,7 +117,7 @@ export class Menu extends Base {
117
117
  }
118
118
  this.popoverController.animateClose().then(() => {
119
119
  if (this.$lastFocused) {
120
- this.$lastFocused.focus({ preventScroll: true });
120
+ this.$lastFocused.focus();
121
121
  this.$lastFocused = null;
122
122
  }
123
123
  });
@@ -14,13 +14,49 @@ export class Switch extends Base {
14
14
  constructor() {
15
15
  super();
16
16
  this.checked = false;
17
+ /**
18
+ * **Drag-and-drop to the other side**
19
+ *
20
+ * *`checked` is supposed to be changed once*
21
+ *
22
+ * 1. `pointerdown`: _ignoreClick = false
23
+ * 2. `pointermove`: _ignoreClick = true
24
+ * 3. `pointerup`: `checked` changed
25
+ * 4. `click`: ignored, _ignoreClick = false
26
+ *
27
+ * **Drag-and-drop to the other side, then click**
28
+ *
29
+ * *`checked` is supposed to be changed twice*
30
+ *
31
+ * 1. `pointerdown`: _ignoreClick = false
32
+ * 2. `pointermove`: _ignoreClick = true
33
+ * 3. `pointerup`: `checked` changed(1)
34
+ * 4. `click`: ignored, _ignoreClick = false
35
+ * 5. `click`: `checked` changed(2)
36
+ *
37
+ * **Drag-and-drop to the other side, then click the label**
38
+ *
39
+ * *`checked` is supposed to be changed twice*
40
+ *
41
+ * 1. `pointerdown`: _ignoreClick = false
42
+ * 2. `pointermove`: _ignoreClick = true
43
+ * 3. `pointerup`: `checked` changed(1)
44
+ * 4. `click` on label: _ignoreClick = false
45
+ * 5. `click` on switch: `checked` changed(2)
46
+ */
17
47
  this._ignoreClick = false;
48
+ this.#handleLabelClick = () => {
49
+ this._ignoreClick = false;
50
+ };
18
51
  this.#handleClick = (e) => {
19
52
  e.stopPropagation();
20
53
  e.preventDefault();
21
- if (this._ignoreClick)
54
+ if (this._ignoreClick) {
55
+ console.log('ignoring click from', e.target);
56
+ this._ignoreClick = false;
22
57
  return;
23
- this.#toggleChecked();
58
+ }
59
+ this.toggleChecked();
24
60
  };
25
61
  this.#handleKeyDown = (e) => {
26
62
  if (e.key !== ' ' && e.key !== 'Enter')
@@ -28,13 +64,13 @@ export class Switch extends Base {
28
64
  e.preventDefault();
29
65
  e.stopPropagation();
30
66
  if (e.key === 'Enter')
31
- this.#toggleChecked();
67
+ this.toggleChecked();
32
68
  };
33
69
  this.#handleKeyUp = (e) => {
34
70
  if (e.key === ' ') {
35
71
  e.preventDefault();
36
72
  e.stopPropagation();
37
- this.#toggleChecked();
73
+ this.toggleChecked();
38
74
  }
39
75
  };
40
76
  this[internals].role = 'switch';
@@ -46,12 +82,18 @@ export class Switch extends Base {
46
82
  this.addEventListener('click', this.#handleClick);
47
83
  this.addEventListener('keydown', this.#handleKeyDown);
48
84
  this.addEventListener('keyup', this.#handleKeyUp);
85
+ this.labels.forEach((label) => {
86
+ label.addEventListener('click', this.#handleLabelClick);
87
+ });
49
88
  }
50
89
  disconnectedCallback() {
51
90
  super.disconnectedCallback();
52
91
  this.removeEventListener('click', this.#handleClick);
53
92
  this.removeEventListener('keydown', this.#handleKeyDown);
54
93
  this.removeEventListener('keyup', this.#handleKeyUp);
94
+ this.labels.forEach((label) => {
95
+ label.removeEventListener('click', this.#handleLabelClick);
96
+ });
55
97
  }
56
98
  updated(changed) {
57
99
  if (changed.has('checked') || changed.has('disabled')) {
@@ -67,10 +109,11 @@ export class Switch extends Base {
67
109
  this[internals].ariaDisabled = this.disabled ? 'true' : 'false';
68
110
  this[internals].setFormValue(this.checked ? 'on' : null);
69
111
  }
112
+ #handleLabelClick;
70
113
  #handleClick;
71
114
  #handleKeyDown;
72
115
  #handleKeyUp;
73
- #toggleChecked() {
116
+ toggleChecked() {
74
117
  if (this.disabled)
75
118
  return;
76
119
  this.checked = !this.checked;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const commonButtonStyles = css `:host{--md-focus-ring-shape:calc(var(--_h)/2);background-color:color-mix(in srgb,var(--_background-color)var(--_background-opacity,100%),transparent);border-radius:calc(var(--_h)/2);color:color-mix(in srgb,var(--_text-color)var(--_text-opacity,100%),transparent);font:var(--md-sys-typography-label-large);gap:var(--_gap);height:var(--_h);min-width:64px;padding-inline:var(--_pad);transition:box-shadow var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow),border-radius var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow)}:host([trailingicon]){flex-direction:row-reverse}:host([variant=elevated]){--_background-color:var(--md-sys-color-surface-container-low);--_text-color:var(--_color);box-shadow:var(--md-sys-elevation-shadow-1)}:host([variant=outlined]){padding-inline:calc(var(--_pad) - 1px)}:host([variant=text]){padding-inline:12px;--_background-color:transparent!important}@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)}}:host(:disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:10%;--_text-color:var(--md-sys-color-on-surface);--_text-opacity:38%;box-shadow:none;cursor:default;pointer-events:none}:host([variant=outlined]:disabled){--_background-color:var(--md-sys-color-outline)!important}[part~=icon]{fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}`;
2
+ export const commonButtonStyles = css `:host{--md-focus-ring-shape:calc(var(--_h)/2);background-color:color-mix(in srgb,var(--_background-color)var(--_background-opacity,100%),transparent);border-radius:calc(var(--_h)/2);color:color-mix(in srgb,var(--_text-color)var(--_text-opacity,100%),transparent);font:var(--md-sys-typography-label-large);gap:var(--_gap);height:var(--_h);min-width:64px;padding-inline:var(--_pad);transition:box-shadow var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow),border-radius var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow)}:host([trailingicon]){flex-direction:row-reverse}:host([variant=elevated]){--_background-color:var(--md-sys-color-surface-container-low);--_text-color:var(--_color);box-shadow:var(--md-sys-elevation-shadow-1)}:host([variant=outlined]){padding-inline:calc(var(--_pad) - 1px)}:host([variant=text]){padding-inline:calc(var(--_pad)/2)}@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)}}: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%;--_outline-color:var(--md-sys-color-on-surface);--_outline-opacity:10%;box-shadow:none;pointer-events:none}[part=icon]{fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}`;
@@ -7,8 +7,8 @@ import '../focus-ring.js';
7
7
  import '../ripple.js';
8
8
  import { targetStyles } from '../target-styles.css.js';
9
9
  import { sharedButtonStyles } from './shared-button-styles.css.js';
10
+ import { sharedButtonToggleStyles } from './shared-button-toggle-styles.css.js';
10
11
  import { commonButtonStyles } from './common-button-styles.css.js';
11
- import { commonButtonToggleStyles } from './common-button-toggle-styles.css.js';
12
12
  /**
13
13
  * @tag md-button-toggle
14
14
  *
@@ -26,7 +26,7 @@ let M3ButtonToggle = class M3ButtonToggle extends Switch {
26
26
  targetStyles,
27
27
  sharedButtonStyles,
28
28
  commonButtonStyles,
29
- commonButtonToggleStyles,
29
+ sharedButtonToggleStyles,
30
30
  ]; }
31
31
  constructor() {
32
32
  super();
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const iconButtonStyles = css `:host{--_icon-size:24px;background-color:color-mix(in srgb,var(--_background-color)var(--_background-opacity,100%),transparent);border-radius:calc(var(--_h)/2);color:color-mix(in srgb,var(--_text-color)var(--_text-opacity,100%),transparent);height:var(--_h);transition:border-radius var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow);width:var(--_h)}:host([variant=text]){--_text-color:var(--md-sys-color-on-surface-variant)}:host([width=narrow]){width:var(--_w_narrow)}:host([width=wide]){width:var(--_w_wide)}:host(:disabled){--_text-opacity:38%;cursor:default;pointer-events:none;--_text-color:var(--md-sys-color-on-surface)!important}:host([variant=filled]:disabled),:host([variant=tonal]:disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:10%}:host([variant=outlined]:disabled){--_outline-color:var(--md-sys-color-on-surface);--_outline-opacity:10%}::slotted(*){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}`;
2
+ export const iconButtonStyles = css `:host{--_icon-size:24px;background-color:color-mix(in srgb,var(--_background-color)var(--_background-opacity,100%),transparent);border-radius:calc(var(--_h)/2);color:color-mix(in srgb,var(--_text-color)var(--_text-opacity,100%),transparent);height:var(--_h);transition:border-radius var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow);width:var(--_h)}:host([variant=text]){--_color:var(--md-sys-color-on-surface-variant)}:host([variant=text]:state(checked):not(:disabled)){--_text-color:var(--md-sys-color-primary)}:host([width=narrow]){width:var(--_w_narrow)}:host([width=wide]){width:var(--_w_wide)}: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%;--_outline-color:var(--md-sys-color-on-surface);--_outline-opacity:10%;pointer-events:none}::slotted(*){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}`;
@@ -7,8 +7,8 @@ import '../focus-ring.js';
7
7
  import '../ripple.js';
8
8
  import { targetStyles } from '../target-styles.css.js';
9
9
  import { sharedButtonStyles } from './shared-button-styles.css.js';
10
+ import { sharedButtonToggleStyles } from './shared-button-toggle-styles.css.js';
10
11
  import { iconButtonStyles } from './icon-button-styles.css.js';
11
- import { iconButtonToggleStyles } from './icon-button-toggle-styles.css.js';
12
12
  /**
13
13
  * @tag md-icon-button-toggle
14
14
  *
@@ -23,7 +23,7 @@ let M3IconButtonToggle = class M3IconButtonToggle extends Switch {
23
23
  targetStyles,
24
24
  sharedButtonStyles,
25
25
  iconButtonStyles,
26
- iconButtonToggleStyles,
26
+ sharedButtonToggleStyles,
27
27
  ]; }
28
28
  constructor() {
29
29
  super();
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const sharedButtonStyles = css `:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_w_narrow:32px;--_w_wide:52px;--_icon-size:20px;--_pad:16px;--_gap:8px;--_rad-sq:12px;--_rad-pr:8px;--_text-color:var(--_on-color);--_background-color:var(--_color);--_outline-color:var(--md-sys-color-outline-variant);box-sizing:border-box;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;vertical-align:top;outline:0;justify-content:center;align-items:center;display:inline-flex;position:relative}:host([size=xsmall]){--_h:32px;--_w_narrow:28px;--_w_wide:40px;--_pad:12px;--_gap:4px}:host([size=medium]){--_h:56px;--_w_narrow:48px;--_w_wide:72px;--_icon-size:24px;--_pad:24px;--_gap:8px;--_rad-sq:16px;--_rad-pr:12px;font:var(--md-sys-typography-title-medium)}:host([size=large]){--_h:96px;--_w_narrow:64px;--_w_wide:128px;--_icon-size:32px;--_pad:48px;--_gap:12px;--_rad-sq:28px;--_rad-pr:16px;font:var(--md-sys-typography-headline-small)}:host([size=xlarge]){--_h:136px;--_w_narrow:104px;--_w_wide:184px;--_icon-size:40px;--_pad:64px;--_gap:16px;--_rad-sq:28px;--_rad-pr:16px;font:var(--md-sys-typography-headline-medium)}: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(--_outline-color)var(--_outline-opacity,100%),transparent);box-shadow:none;border-style:solid;border-width:1px}:host([variant=text]){--_background-color:transparent;--_text-color:var(--_color)}:host([shape=square]),:host(:state(checked)){--md-focus-ring-shape:var(--_rad-sq);border-radius:var(--_rad-sq)}:host(:active){--md-focus-ring-shape:var(--_rad-pr);border-radius:var(--_rad-pr)}:host(:state(checked)) [part~=unchecked],:host(:not(:state(checked))) [part~=checked]{display:none}`;
2
+ export const sharedButtonStyles = css `:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_w_narrow:32px;--_w_wide:52px;--_icon-size:20px;--_pad:16px;--_gap:8px;--_rad-sq:12px;--_rad-pr:8px;--_text-color:var(--_on-color);--_background-color:var(--_color);--_outline-color:var(--md-sys-color-outline-variant);box-sizing:border-box;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;vertical-align:top;outline:0;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}:host([size=xsmall]){--_h:32px;--_w_narrow:28px;--_w_wide:40px;--_pad:12px;--_gap:4px}:host([size=medium]){--_h:56px;--_w_narrow:48px;--_w_wide:72px;--_icon-size:24px;--_pad:24px;--_gap:8px;--_rad-sq:16px;--_rad-pr:12px;font:var(--md-sys-typography-title-medium)}:host([size=large]){--_h:96px;--_w_narrow:64px;--_w_wide:128px;--_icon-size:32px;--_pad:48px;--_gap:12px;--_rad-sq:28px;--_rad-pr:16px;font:var(--md-sys-typography-headline-small)}:host([size=xlarge]){--_h:136px;--_w_narrow:104px;--_w_wide:184px;--_icon-size:40px;--_pad:64px;--_gap:16px;--_rad-sq:28px;--_rad-pr:16px;font:var(--md-sys-typography-headline-medium)}: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(--_outline-color)var(--_outline-opacity,100%),transparent);box-shadow:none;border-style:solid;border-width:1px}:host([variant=outlined]:disabled){--_background-color:var(--md-sys-color-outline)}:host([variant=text]){--_text-color:var(--_color);--_background-color:transparent!important}:host([shape=square]){--md-focus-ring-shape:var(--_rad-sq);border-radius:var(--_rad-sq)}:host(:active){--md-focus-ring-shape:var(--_rad-pr);border-radius:var(--_rad-pr)}`;
@@ -0,0 +1,2 @@
1
+ import { css } from 'lit';
2
+ export const sharedButtonToggleStyles = css `:host{transition:box-shadow var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow),border-radius var(--md-sys-motion-std-effects-slow-duration)var(--md-sys-motion-std-effects-slow),background-color var(--md-sys-motion-exp-effects-fast-duration)var(--md-sys-motion-exp-effects-fast),color var(--md-sys-motion-exp-effects-fast-duration)var(--md-sys-motion-exp-effects-fast)}:host(:state(checked)){--md-focus-ring-shape:var(--_rad-sq);border-radius:var(--_rad-sq)}:host(:state(checked)) [part~=unchecked],:host(:not(:state(checked))) [part~=checked]{display:none}:host([variant=filled]:not(:state(checked)):not(:disabled)){--_background-color:var(--md-sys-color-surface-container);--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=tonal]:not(:state(checked)):not(:disabled)){--_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}`;
@@ -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);-webkit-user-select:none;user-select:none;flex:1;align-items:center;gap:8px;min-height:48px;padding:0 12px;display:flex;position:relative}[name=container]{border-radius:inherit}[name=container]::slotted(*){position:absolute;inset:0}`;
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;overflow:hidden}: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}`;
package/src/m3/item.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html } from 'lit';
3
- import { customElement } from 'lit/decorators.js';
3
+ import { customElement, property } from 'lit/decorators.js';
4
4
  import { Item } from '../base/item.js';
5
5
  import { itemStyles } from './item-styles.css.js';
6
6
  /**
@@ -24,6 +24,10 @@ import { itemStyles } from './item-styles.css.js';
24
24
  * @slot end - end content
25
25
  */
26
26
  let M3Item = class M3Item extends Item {
27
+ constructor() {
28
+ super(...arguments);
29
+ this.multiline = false;
30
+ }
27
31
  static { this.styles = [itemStyles]; }
28
32
  render() {
29
33
  return html `
@@ -31,7 +35,7 @@ let M3Item = class M3Item extends Item {
31
35
  <slot name="start"></slot>
32
36
  <div class="text">
33
37
  <slot name="overline"></slot>
34
- <slot></slot>
38
+ <slot class="default-slot"></slot>
35
39
  <slot name="headline"></slot>
36
40
  <slot name="supporting-text"></slot>
37
41
  </div>
@@ -40,6 +44,9 @@ let M3Item = class M3Item extends Item {
40
44
  `;
41
45
  }
42
46
  };
47
+ __decorate([
48
+ property({ type: Boolean, reflect: true })
49
+ ], M3Item.prototype, "multiline", void 0);
43
50
  M3Item = __decorate([
44
51
  customElement('md-item')
45
52
  ], M3Item);
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const menuPartStyles = css `[part=menu]{background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);box-sizing:border-box;color:var(--md-sys-color-on-surface);height:inherit;max-height:inherit;max-width:inherit;min-width:inherit;opacity:0;z-index:1000;border-radius:16px;padding:4px;inset:auto;overflow-y:auto;transform:scaleY(.4)}:host(:state(closed)) [part=menu]{display:none}:host(:state(opening)) [part=menu]{opacity:1;transition:opacity 67ms,transform var(--md-sys-motion-exp-effects-slow-duration)var(--md-sys-motion-exp-effects-slow);display:block;transform:scaleY(1)}:host(:state(opened)) [part=menu]{opacity:1;display:block;transform:scaleY(1)}:host(:state(closing)) [part=menu]{opacity:0;transition:opacity var(--md-sys-motion-exp-effects-default-duration),transform var(--md-sys-motion-exp-effects-default-duration)var(--md-sys-motion-exp-effects-default);transform:scaleY(.4)}[part=items]{opacity:0;flex-direction:column;gap:2px;display:flex}:host(:state(opening)) [part=items]{opacity:1;transition:opacity 67ms linear 67ms}:host(:state(opened)) [part=items]{opacity:1}:host(:state(closing)) [part=items]{opacity:0;transition:opacity 67ms}`;
2
+ export const menuPartStyles = css `[part=menu]{background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);box-sizing:border-box;color:var(--md-sys-color-on-surface);height:inherit;max-height:inherit;max-width:inherit;min-width:inherit;opacity:0;-webkit-user-select:none;user-select:none;z-index:1000;border-radius:16px;padding:4px;inset:auto;overflow-y:auto;transform:scaleY(.4)}:host(:state(closed)) [part=menu]{display:none}:host(:state(opening)) [part=menu]{opacity:1;transition:opacity 67ms,transform var(--md-sys-motion-exp-effects-slow-duration)var(--md-sys-motion-exp-effects-slow);display:block;transform:scaleY(1)}:host(:state(opened)) [part=menu]{opacity:1;display:block;transform:scaleY(1)}:host(:state(closing)) [part=menu]{opacity:0;transition:opacity var(--md-sys-motion-exp-effects-default-duration),transform var(--md-sys-motion-exp-effects-default-duration)var(--md-sys-motion-exp-effects-default);transform:scaleY(.4)}[part=items]{opacity:0;flex-direction:column;gap:2px;display:flex}:host(:state(opening)) [part=items]{opacity:1;transition:opacity 67ms linear 67ms}:host(:state(opened)) [part=items]{opacity:1}:host(:state(closing)) [part=items]{opacity:0;transition:opacity 67ms}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const menuStyles = css `:host{outline:0;min-width:112px;display:block}`;
2
+ export const menuStyles = css `:host{outline:0;min-width:112px;display:contents}:host([alignstrategy=fixed]){position:fixed}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const selectStyles = css `:host{min-width:210px;display:inline-block;position:relative}[part=field]{cursor:pointer;outline:none;width:100%}[part=value]{font:var(--md-sys-typography-body-large);height:1.5em}[part=menu]{max-height:var(--md-select-menu-max-height,300px);min-width:100%}`;
2
+ export const selectStyles = css `:host{-webkit-user-select:none;user-select:none;min-width:210px;display:inline-block;position:relative}[part=field]{cursor:pointer;outline:none;width:100%}[part=value]{font:var(--md-sys-typography-body-large);height:1.5em}[part=menu]{max-height:var(--md-select-menu-max-height,300px);min-width:100%}`;
package/src/m3/switch.js CHANGED
@@ -1,15 +1,14 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html } from 'lit';
3
- import { customElement, property } from 'lit/decorators.js';
3
+ import { customElement, property, query } from 'lit/decorators.js';
4
4
  import { Switch } from '../base/switch.js';
5
5
  import './focus-ring.js';
6
- import './ripple.js';
7
6
  import { switchStyles } from './switch-styles.css.js';
8
7
  import { targetStyles } from './target-styles.css.js';
9
8
  // FIXME: Drag-and-drop breaks the support for working with `<label>`. Temporarily disabled.
10
- // function isRTL() {
11
- // return document.documentElement.dir === 'rtl';
12
- // }
9
+ function isRTL() {
10
+ return document.documentElement.dir === 'rtl';
11
+ }
13
12
  /**
14
13
  * @tag md-switch
15
14
  *
@@ -19,73 +18,44 @@ import { targetStyles } from './target-styles.css.js';
19
18
  let M3Switch = class M3Switch extends Switch {
20
19
  constructor() {
21
20
  super(...arguments);
22
- // /** @type {M3Ripple} */
23
- // @query('md-ripple') $ripple;
24
- // /** @type {HTMLSpanElement} */
25
- // @query('[part~="thumb"]') $thumb;
26
- // connectedCallback() {
27
- // super.connectedCallback();
28
- // this.$ripple.attach(this);
29
- // this.addEventListener('pointerdown', this.#boundPointerDown);
30
- // this.addEventListener('pointerup', this.#boundPointerUp);
31
- // }
32
- // disconnectedCallback() {
33
- // super.disconnectedCallback();
34
- // this.removeEventListener('pointerdown', this.#boundPointerDown);
35
- // this.removeEventListener('pointerup', this.#boundPointerUp);
36
- // }
37
21
  this.icons = false;
38
22
  this.checkedIconOnly = false;
39
- // #pointerDownX = 0;
40
- //
41
- // #boundPointerDown = this.#handlePointerDown.bind(this);
42
- // #boundPointerMove = this.#handlePointerMove.bind(this);
43
- // #boundPointerUp = this.#handlePointerUp.bind(this);
44
- // /** @param {PointerEvent} e */
45
- // #handlePointerDown(e) {
46
- // this._ignoreClick = false;
47
- //
48
- // if (e.button !== 0) return;
49
- // this.#pointerDownX = e.clientX;
50
- // this.setPointerCapture(e.pointerId);
51
- // this.addEventListener('pointermove', this.#boundPointerMove);
52
- // }
53
- // /** @param {PointerEvent} e */
54
- // #handlePointerMove(e) {
55
- // this._ignoreClick = true;
56
- //
57
- // const diff = (isRTL() ? -1 : 1) * (e.clientX - this.#pointerDownX);
58
- // const limitedDiff = this.checked
59
- // ? Math.min(0, Math.max(-20, diff))
60
- // : Math.min(20, Math.max(0, diff));
61
- // this.$thumb.style.setProperty(
62
- // '--_thumb-diff-pointer',
63
- // `${2 * limitedDiff}px`
64
- // );
65
- // // Thumb loses its `:active` status before pointer up event
66
- // this.$thumb.style.setProperty('--_thumb-diameter', '28px');
67
- // this.$thumb.style.transitionDuration = '0s';
68
- // }
69
- // /** @param {PointerEvent} e */
70
- // #handlePointerUp(e) {
71
- // this.removeEventListener('pointermove', this.#boundPointerMove);
72
- // this.releasePointerCapture(e.pointerId);
73
- //
74
- // const trackRect = this.getBoundingClientRect();
75
- // const thumbRect = this.$thumb.getBoundingClientRect();
76
- // const diff =
77
- // thumbRect.left +
78
- // thumbRect.width / 2 -
79
- // trackRect.left -
80
- // trackRect.width / 2;
81
- // const shouldBeChecked = (diff >= 0 && !isRTL()) || (diff < 0 && isRTL());
82
- //
83
- // this.$thumb.style.setProperty('--_thumb-diff-pointer', '');
84
- // this.$thumb.style.setProperty('--_thumb-diameter', '');
85
- // this.$thumb.style.transitionDuration = '';
86
- //
87
- // if (this.checked != shouldBeChecked) this.__toggleStatus();
88
- // }
23
+ this.#pointerDownX = 0;
24
+ this.#handlePointerDown = (e) => {
25
+ this._ignoreClick = false;
26
+ if (e.button !== 0)
27
+ return;
28
+ this.#pointerDownX = e.clientX;
29
+ this.setPointerCapture(e.pointerId);
30
+ this.addEventListener('pointermove', this.#handlePointerMove);
31
+ };
32
+ this.#handlePointerMove = (e) => {
33
+ const diff = (isRTL() ? -1 : 1) * (e.clientX - this.#pointerDownX);
34
+ this._ignoreClick = true;
35
+ const limitedDiff = this.checked
36
+ ? Math.min(0, Math.max(-20, diff))
37
+ : Math.min(20, Math.max(0, diff));
38
+ this.$thumb.style.setProperty('--_thumb-diff-pointer', `${2 * limitedDiff}px`);
39
+ // Thumb loses its `:active` status before pointer up event
40
+ this.$thumb.style.setProperty('--_thumb-diameter', '28px');
41
+ this.$thumb.style.transitionDuration = '0s';
42
+ };
43
+ this.#handlePointerUp = (e) => {
44
+ this.removeEventListener('pointermove', this.#handlePointerMove);
45
+ this.releasePointerCapture(e.pointerId);
46
+ const trackRect = this.getBoundingClientRect();
47
+ const thumbRect = this.$thumb.getBoundingClientRect();
48
+ const diff = thumbRect.left +
49
+ thumbRect.width / 2 -
50
+ trackRect.left -
51
+ trackRect.width / 2;
52
+ const shouldBeChecked = (diff >= 0 && !isRTL()) || (diff < 0 && isRTL());
53
+ this.$thumb.style.setProperty('--_thumb-diff-pointer', '');
54
+ this.$thumb.style.setProperty('--_thumb-diameter', '');
55
+ this.$thumb.style.transitionDuration = '';
56
+ if (this.checked != shouldBeChecked)
57
+ this.toggleChecked();
58
+ };
89
59
  }
90
60
  static { this.styles = [targetStyles, switchStyles]; }
91
61
  render() {
@@ -116,7 +86,30 @@ let M3Switch = class M3Switch extends Switch {
116
86
  </svg>
117
87
  `;
118
88
  }
89
+ connectedCallback() {
90
+ super.connectedCallback();
91
+ this.updateComplete.then(() => {
92
+ this.$ripple.attach(this);
93
+ });
94
+ this.addEventListener('pointerdown', this.#handlePointerDown);
95
+ this.addEventListener('pointerup', this.#handlePointerUp);
96
+ }
97
+ disconnectedCallback() {
98
+ super.disconnectedCallback();
99
+ this.removeEventListener('pointerdown', this.#handlePointerDown);
100
+ this.removeEventListener('pointerup', this.#handlePointerUp);
101
+ }
102
+ #pointerDownX;
103
+ #handlePointerDown;
104
+ #handlePointerMove;
105
+ #handlePointerUp;
119
106
  };
107
+ __decorate([
108
+ query('md-ripple')
109
+ ], M3Switch.prototype, "$ripple", void 0);
110
+ __decorate([
111
+ query('[part~="thumb"]')
112
+ ], M3Switch.prototype, "$thumb", void 0);
120
113
  __decorate([
121
114
  property({ type: Boolean, reflect: true })
122
115
  ], M3Switch.prototype, "icons", void 0);
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const toolbarStyles = css `:host{--_padding:16px;--_gap:32px;--_container-color:var(--md-sys-color-surface-container);--_on-color:var(--md-sys-color-on-surface);background-color:color-mix(in srgb,var(--_container-color)var(--_container-opacity,100%),transparent);box-sizing:border-box;color:color-mix(in srgb,var(--_on-color)var(--_on-opacity,100%),transparent);align-items:center;width:100%;height:64px;display:flex}:host([type=floating]){--_padding:8px;--_gap:4px;--_container-color:var(--md-sys-color-surface-container-high);box-shadow:none;background:0 0;width:fit-content;max-width:calc(100% - 32px)}:host([type=floating][orientation=vertical]){flex-direction:column;align-items:stretch;width:56px;min-height:auto}[part=container]{box-sizing:border-box;align-items:center;gap:var(--_gap);height:56px;padding:0 var(--_padding);flex:auto;justify-content:space-between;width:100%;display:flex}:host([type=floating]) [part=container]{background-color:color-mix(in srgb,var(--_container-color)var(--_container-opacity,100%),transparent);border-radius:var(--md-toolbar-shape,28px);box-shadow:var(--md-toolbar-shadow,var(--md-sys-elevation-shadow-3));width:fit-content}[part=fab-slot]{justify-content:flex-end;align-items:center;display:flex}:host(:not([orientation=vertical])) ::slotted([slot=fab]){margin-inline-start:8px}:host([orientation=vertical]) ::slotted([slot=fab]){margin-block-start:8px}:host([type=floating][orientation=vertical]) [part=container]{height:fit-content;padding:var(--_padding)0;flex-direction:column;width:100%}::slotted(md-icon-button),::slotted(md-icon-button-toggle){--md-focus-ring-shape:calc(var(--_h)/2);border-radius:calc(var(--_h)/2)}::slotted(md-icon-button-toggle[variant=tonal]:not(:state(checked))){--_background-color:transparent}:host([color=vibrant]){--_container-color:var(--md-sys-color-primary-container);--_on-color:var(--md-sys-color-on-primary-container)}:host([color=vibrant]) ::slotted(md-icon-button[variant=text]),:host([color=vibrant]) ::slotted(md-icon-button-toggle[variant=tonal]){--_text-color:var(--md-sys-color-on-primary-container)}:host([color=vibrant]) ::slotted(md-icon-button-toggle[variant=tonal]:state(checked)){--_background-color:var(--md-sys-color-surface-container);--_text-color:var(--md-sys-color-on-surface)}`;
2
+ export const toolbarStyles = css `:host{--_padding:16px;--_gap:32px;--_container-color:var(--md-sys-color-surface-container);--_on-color:var(--md-sys-color-on-surface);background-color:color-mix(in srgb,var(--_container-color)var(--_container-opacity,100%),transparent);box-sizing:border-box;color:color-mix(in srgb,var(--_on-color)var(--_on-opacity,100%),transparent);align-items:center;width:100%;height:64px;display:flex}:host([type=floating]){--_padding:8px;--_gap:4px;--_container-color:var(--md-sys-color-surface-container-high);box-shadow:none;background:0 0;width:fit-content;max-width:calc(100% - 32px)}:host([type=floating][orientation=vertical]){flex-direction:column;align-items:stretch;width:56px;min-height:auto}[part=container]{box-sizing:border-box;align-items:center;gap:var(--_gap);height:56px;padding:0 var(--_padding);flex:auto;justify-content:space-between;width:100%;display:flex}:host([type=floating]) [part=container]{background-color:color-mix(in srgb,var(--_container-color)var(--_container-opacity,100%),transparent);border-radius:var(--md-toolbar-shape,28px);box-shadow:var(--md-toolbar-shadow,var(--md-sys-elevation-shadow-3));width:fit-content}[part=fab-slot]{justify-content:flex-end;align-items:center;display:flex}:host(:not([orientation=vertical])) ::slotted([slot=fab]){margin-inline-start:8px}:host([orientation=vertical]) ::slotted([slot=fab]){margin-block-start:8px}:host([type=floating][orientation=vertical]) [part=container]{height:fit-content;padding:var(--_padding)0;flex-direction:column;width:100%}::slotted(md-button),::slotted(md-button-toggle),::slotted(md-icon-button),::slotted(md-icon-button-toggle){--md-focus-ring-shape:calc(var(--_h)/2);border-radius:calc(var(--_h)/2)}::slotted(md-button-toggle[variant=tonal]:not(:state(checked))),::slotted(md-icon-button-toggle[variant=tonal]:not(:state(checked))){--_background-color:transparent}:host([color=vibrant]){--_container-color:var(--md-sys-color-primary-container);--_on-color:var(--md-sys-color-on-primary-container)}:host([color=vibrant]) ::slotted(md-icon-button[variant=text]),:host([color=vibrant]) ::slotted(md-icon-button-toggle[variant=tonal]){--_text-color:var(--md-sys-color-on-primary-container)}:host([color=vibrant]) ::slotted(md-icon-button-toggle[variant=tonal]:state(checked)){--_background-color:var(--md-sys-color-surface-container);--_text-color:var(--md-sys-color-on-surface)}`;
@@ -1,2 +0,0 @@
1
- import { css } from 'lit';
2
- export const commonButtonToggleStyles = css `: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);--_outline-color:var(--md-sys-color-inverse-surface);--_text-color:var(--md-sys-color-inverse-on-surface)}`;
@@ -1,2 +0,0 @@
1
- import { css } from 'lit';
2
- export const iconButtonToggleStyles = css `:host([variant=text]:state(checked)){--_text-color:var(--md-sys-color-primary)}: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);--_outline-color:var(--md-sys-color-inverse-surface);--_text-color:var(--md-sys-color-inverse-on-surface)}: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-width:0}`;