@vollowx/seele 0.12.10 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +34 -58
  2. package/package.json +6 -5
  3. package/src/all.js +5 -0
  4. package/src/base/autocomplete.js +1 -4
  5. package/src/base/dialog.js +32 -0
  6. package/src/base/input.js +2 -40
  7. package/src/base/list.js +1 -1
  8. package/src/base/menu.js +1 -9
  9. package/src/base/select.js +1 -1
  10. package/src/base/slider.js +2 -23
  11. package/src/base/tabs.js +1 -5
  12. package/src/m3/autocomplete/autocomplete-styles.css.js +1 -1
  13. package/src/m3/autocomplete/autocomplete.js +1 -20
  14. package/src/m3/badge/badge-styles.css.js +1 -1
  15. package/src/m3/badge/badge.js +1 -6
  16. package/src/m3/button/common-button-styles.css.js +1 -1
  17. package/src/m3/button/common-button-toggle.js +1 -9
  18. package/src/m3/button/common-button.js +1 -7
  19. package/src/m3/button/icon-button-styles.css.js +1 -1
  20. package/src/m3/button/icon-button-toggle.js +1 -7
  21. package/src/m3/button/icon-button.js +1 -6
  22. package/src/m3/button/shared-button-styles.css.js +1 -1
  23. package/src/m3/button/shared-button-toggle-styles.css.js +1 -1
  24. package/src/m3/button-group/standard-button-group-styles.css.js +2 -0
  25. package/src/m3/button-group/standard-button-group.js +130 -0
  26. package/src/m3/checkbox/checkbox-styles.css.js +1 -1
  27. package/src/m3/checkbox/checkbox.js +2 -12
  28. package/src/m3/dialog/dialog-styles.css.js +2 -0
  29. package/src/m3/dialog/dialog.js +215 -0
  30. package/src/m3/divider/divider-styles.css.js +1 -1
  31. package/src/m3/fab/fab-styles.css.js +1 -1
  32. package/src/m3/fab/fab.js +1 -7
  33. package/src/m3/field/field-styles.css.js +1 -1
  34. package/src/m3/field/field.js +3 -16
  35. package/src/m3/field/filled-field-styles.css.js +1 -1
  36. package/src/m3/field/filled-field.js +1 -15
  37. package/src/m3/field/outlined-field-styles.css.js +1 -1
  38. package/src/m3/field/outlined-field.js +2 -18
  39. package/src/m3/focus-ring/focus-ring-styles.css.js +1 -1
  40. package/src/m3/item/item.js +1 -12
  41. package/src/m3/list/list-item.js +1 -18
  42. package/src/m3/loading-indicator/loading-indicator-styles.css.js +2 -0
  43. package/src/m3/loading-indicator/loading-indicator.js +320 -0
  44. package/src/m3/menu/menu-styles.css.js +1 -1
  45. package/src/m3/ripple/ripple-styles.css.js +1 -1
  46. package/src/m3/select/filled-select.js +1 -26
  47. package/src/m3/select/outlined-select.js +1 -26
  48. package/src/m3/select/select-styles.css.js +1 -1
  49. package/src/m3/select/select.js +1 -22
  50. package/src/m3/slider/slider-styles.css.js +1 -1
  51. package/src/m3/slider/slider.js +5 -38
  52. package/src/m3/switch/switch-styles.css.js +1 -1
  53. package/src/m3/switch/switch.js +3 -22
  54. package/src/m3/system/base.css +0 -1
  55. package/src/m3/system/typography.css +5 -5
  56. package/src/m3/tab/tab-styles.css.js +1 -1
  57. package/src/m3/tab/tab.js +1 -9
  58. package/src/m3/tab/tabs-styles.css.js +1 -1
  59. package/src/m3/tab/tabs.js +1 -4
  60. package/src/m3/text-field/filled-text-field.js +1 -12
  61. package/src/m3/text-field/outlined-text-field.js +1 -14
  62. package/src/m3/text-field/text-field-styles.css.js +1 -1
  63. package/src/m3/toolbar/toolbar-styles.css.js +1 -1
  64. package/src/m3/toolbar/toolbar.js +1 -8
  65. package/src/m3/tooltip/tooltip-styles.css.js +1 -1
  66. package/src/win98/button/button-styles.css.js +2 -0
  67. package/src/win98/button/button.js +19 -0
  68. package/src/m3/system/motion.css +0 -30
package/README.md CHANGED
@@ -1,82 +1,54 @@
1
- # Standard Extensible Elements
1
+ # seele
2
2
 
3
3
  [![npm package](https://img.shields.io/npm/v/%40vollowx%2Fseele)](https://www.npmjs.com/package/@vollowx/seele)
4
4
  [![builds.sr.ht status](https://builds.sr.ht/~lucaz/seele.svg)](https://builds.sr.ht/~lucaz/seele?)
5
5
  [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/@vollowx/seele)
6
6
 
7
- Seele (**S**tandard **E**xtensible **Ele**ments) is a extensible
8
- [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
9
- library with a focus on accessibility and keyboard-control.
7
+ [https://tideover.cc/seele/](https://tideover.cc/seele/)
8
+ [docs/](https://tideover.cc/seele/docs/)
9
+
10
+ seele (**S**tandard **E**xtensible **Ele**ments) is a extensible
11
+ [Web Components][web-comps] library with a focus on accessibility and
12
+ keyboard-control.
10
13
 
11
14
  It also provides styled components in the following design guideline(s):
12
15
 
13
16
  - [Material You Expressive](https://m3.material.io/)
17
+ - Windows 98, most styles are from [98.css](https://jdan.github.io/98.css/)
14
18
 
15
- Documentations and demos are at [tideover.cc/seele/](https://tideover.cc/seele/).
16
-
17
- ## Installation
18
-
19
- Seele is published on [npm](https://www.npmjs.com/package/@vollowx/seele),
20
- install with your preferred package manager:
21
-
22
- ```sh
23
- bun add @vollowx/seele
24
- yarn add @vollowx/seele
25
- npm install @vollowx/seele
26
- ```
27
-
28
- ## Quickstart
19
+ ![seele components screenshot](./preview.png)
29
20
 
30
- ### Importing
21
+ ## Features
31
22
 
32
- You can import the entire library or import as needed.
23
+ What's the differences comparing to other projects?
33
24
 
34
- ```javascript
35
- // Import all components
36
- import '@vollowx/seele';
25
+ - Accessible and keyboard-accessible - all components are based on the
26
+ [APG Patterns][apg-patterns]
27
+ - Flexible - seele provides not only the styled components, but also the base
28
+ ones and the mix-ins that compose them, allowing you to write your components
29
+ easily
30
+ - Up-to-date - seele uses new Web features as much as possible, (see the README),
31
+ meaning that its size is relatively small and the compatibility is not the
32
+ best
37
33
 
38
- // Or import specific components (recommended)
39
- // They all follow such path: @/catagory/group/component.js
40
- import '@vollowx/seele/m3/button/common-button.js';
41
- import '@vollowx/seele/m3/checkbox/checkbox.js';
42
- ```
34
+ ## Getting started
43
35
 
44
- ### Using
36
+ Check out [Overview](./docs/00-Overview.md).
45
37
 
46
- Once imported, the components can be used just like standard HTML elements.
38
+ ## Documentations
47
39
 
48
- ```html
49
- <md-button variant="filled">Filled Button</md-button>
50
- <md-button variant="outlined">Outlined Button</md-button>
40
+ - Previous [documentations and demos](https://tideover.cc/seele/docs/), being replaced
41
+ - [Documentations](./docs/00-Overview.md)
51
42
 
52
- <label>
53
- <md-checkbox checked></md-checkbox>
54
- Labelled Checkbox
55
- </label>
56
- ```
43
+ ## Download
57
44
 
58
- ### Theming
59
-
60
- Seele components use CSS variables for styling. To include the systems, add
61
- this to your style files.
62
-
63
- ```css
64
- @import '@vollowx/seele/m3/systems/base.css';
65
- /* This includes basic system variables like motion system and typography system */
66
- @import '@vollowx/seele/m3/systems/defaults.css';
67
- /* (Optional) This includes basic styling for body, selection and links */
68
-
69
- /*
70
- * Note that there is no default color system since the way you implement theme
71
- * switching and color changing varies.
72
- *
73
- * You can still find some references in dev/shared.css
74
- */
75
- ```
45
+ - [npm package](https://www.npmjs.com/package/@vollowx/seele)
46
+ - [The source at SourceHut](https://sr.ht/~lucaz/seele)
47
+ - [The source at GitHub](https://github.com/vollowx/seele)
76
48
 
77
49
  ## Browser Support
78
50
 
79
- Seele relies on the folling modern web standards:
51
+ seele relies on the following modern web standards:
80
52
 
81
53
  - [`ElementInternals`](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), Baseline 2023
82
54
  - [Constructable Stylesheets](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet), Baseline 2024, C[^1] 90, F 126
@@ -98,6 +70,10 @@ these following web features might be used and require higher browser versions:
98
70
 
99
71
  ## Other Information
100
72
 
101
- - [Roadmap](./ROADMAP.md)
73
+ - [Roadmap](./docs/01-Roadmap.md)
102
74
  - [Contributing](./CONTRIBUTING.md)
103
75
  - [License (Apache-2.0)](./LICENSE)
76
+
77
+ [web-comps]: https://developer.mozilla.org/en-US/docs/Web/API/Web_components
78
+ [apg-patterns]: https://www.w3.org/WAI/ARIA/apg/patterns/
79
+ [lit]: https://lit.dev/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vollowx/seele",
3
- "version": "0.12.10",
3
+ "version": "0.13.1",
4
4
  "description": "A extensible Web Components library, with Material Design 3 components pre-provided.",
5
5
  "author": "vollowx",
6
6
  "license": "Apache-2.0",
@@ -46,16 +46,17 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "@custom-elements-manifest/analyzer": "^0.11.0",
49
- "@swc/core": "^1.15.43",
49
+ "@swc/core": "^1.15.46",
50
50
  "@types/bun": "^1.3.14",
51
51
  "@web/dev-server": "^0.4.6",
52
52
  "@web/dev-server-esbuild": "^1.0.5",
53
53
  "chokidar": "^5.0.0",
54
- "lightningcss": "^1.32.0",
55
- "prettier": "^3.9.1"
54
+ "lightningcss": "^1.33.0",
55
+ "minify-html-literals": "^1.3.5",
56
+ "prettier": "^3.9.6"
56
57
  },
57
58
  "dependencies": {
58
- "@floating-ui/dom": "^1.7.6",
59
+ "@floating-ui/dom": "^1.8.0",
59
60
  "@swc/helpers": "^0.5.23",
60
61
  "lit": "^3.3.3"
61
62
  }
package/src/all.js CHANGED
@@ -5,13 +5,17 @@ export { M3Button } from './m3/button/common-button.js';
5
5
  export { M3ButtonToggle } from './m3/button/common-button-toggle.js';
6
6
  export { M3IconButton } from './m3/button/icon-button.js';
7
7
  export { M3IconButtonToggle } from './m3/button/icon-button-toggle.js';
8
+ export { M3StandardButtonGroup } from './m3/button-group/standard-button-group.js';
9
+ // export { M3ConnectedButtonGroup } from './m3/button-group/connected-button-group.js';
8
10
  export { M3Checkbox } from './m3/checkbox/checkbox.js';
11
+ export { M3Dialog } from './m3/dialog/dialog.js';
9
12
  export { M3Divider } from './m3/divider/divider.js';
10
13
  export { M3Fab } from './m3/fab/fab.js';
11
14
  export { M3FocusRing } from './m3/focus-ring/focus-ring.js';
12
15
  export { M3Item } from './m3/item/item.js';
13
16
  export { M3List } from './m3/list/list.js';
14
17
  export { M3ListItem } from './m3/list/list-item.js';
18
+ export { M3LoadingIndicator } from './m3/loading-indicator/loading-indicator.js';
15
19
  export { M3Menu } from './m3/menu/menu.js';
16
20
  export { M3MenuItem } from './m3/menu/menu-item.js';
17
21
  export { M3Ripple } from './m3/ripple/ripple.js';
@@ -27,3 +31,4 @@ export { M3FilledTextField } from './m3/text-field/filled-text-field.js';
27
31
  export { M3OutlinedTextField } from './m3/text-field/outlined-text-field.js';
28
32
  export { M3Toolbar } from './m3/toolbar/toolbar.js';
29
33
  export { M3Tooltip } from './m3/tooltip/tooltip.js';
34
+ export { Win98Button } from './win98/button/button.js';
@@ -11,10 +11,7 @@ const Base = FocusDelegated(InternalsAttached(LitElement));
11
11
  return this.inputSlotElements[0];
12
12
  }
13
13
  render() {
14
- return html`
15
- <slot name="input" @slotchange=${this.handleInputSlotChange}></slot>
16
- ${this.renderMenu()}
17
- `;
14
+ return html`<slot name="input" @slotchange="${this.handleInputSlotChange}"></slot>${this.renderMenu()}`;
18
15
  }
19
16
  /**
20
17
  * Example content:
@@ -0,0 +1,32 @@
1
+ import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
2
+ import { LitElement } from 'lit';
3
+ import { query } from 'lit/decorators.js';
4
+ /**
5
+ * @csspart dialog
6
+ *
7
+ * Example `render()`:
8
+ *
9
+ * ```
10
+ * <dialog
11
+ * part="dialog"
12
+ * @cancel="${this._handleCancel}">
13
+ * <slot></slot>
14
+ * </dialog>
15
+ * ```
16
+ */ export class Dialog extends LitElement {
17
+ show() {
18
+ this.$dialog.showModal();
19
+ }
20
+ close() {
21
+ this.$dialog.close();
22
+ }
23
+ constructor(...args){
24
+ super(...args), this._handleCancel = (e)=>{
25
+ e.preventDefault();
26
+ this.close();
27
+ };
28
+ }
29
+ }
30
+ _ts_decorate([
31
+ query('dialog')
32
+ ], Dialog.prototype, "$dialog", void 0);
package/src/base/input.js CHANGED
@@ -16,47 +16,9 @@ export class Input extends Base {
16
16
  const minLength = this.minLength > -1 ? this.minLength : nothing;
17
17
  const maxLength = this.maxLength > -1 ? this.maxLength : nothing;
18
18
  if (isTextarea) {
19
- return html`
20
- <textarea
21
- part="input"
22
- .value=${live(this.value)}
23
- placeholder=${this.placeholder || nothing}
24
- ?required=${this.required}
25
- ?readonly=${this.readOnly}
26
- ?disabled=${this.disabled}
27
- minlength=${minLength}
28
- maxlength=${maxLength}
29
- autocomplete=${this.autocomplete || nothing}
30
- @input=${this.handleInput}
31
- @change=${this.handleChange}
32
- @focus=${this.handleFocus}
33
- @blur=${this.handleBlur}
34
- ></textarea>
35
- `;
19
+ return html`<textarea part="input" .value="${live(this.value)}" placeholder="${this.placeholder || nothing}" ?required="${this.required}" ?readonly="${this.readOnly}" ?disabled="${this.disabled}" minlength="${minLength}" maxlength="${maxLength}" autocomplete="${this.autocomplete || nothing}" @input="${this.handleInput}" @change="${this.handleChange}" @focus="${this.handleFocus}" @blur="${this.handleBlur}"></textarea>`;
36
20
  }
37
- return html`
38
- <input
39
- part="input"
40
- type=${this.type}
41
- .value=${live(this.value)}
42
- placeholder=${this.placeholder || nothing}
43
- ?required=${this.required}
44
- ?readonly=${this.readOnly}
45
- ?disabled=${this.disabled}
46
- ?multiple=${this.multiple}
47
- min=${this.min || nothing}
48
- max=${this.max || nothing}
49
- step=${this.step || nothing}
50
- minlength=${minLength}
51
- maxlength=${maxLength}
52
- pattern=${this.pattern || nothing}
53
- autocomplete=${this.autocomplete || nothing}
54
- @input=${this.handleInput}
55
- @change=${this.handleChange}
56
- @focus=${this.handleFocus}
57
- @blur=${this.handleBlur}
58
- />
59
- `;
21
+ return html`<input part="input" type="${this.type}" .value="${live(this.value)}" placeholder="${this.placeholder || nothing}" ?required="${this.required}" ?readonly="${this.readOnly}" ?disabled="${this.disabled}" ?multiple="${this.multiple}" min="${this.min || nothing}" max="${this.max || nothing}" step="${this.step || nothing}" minlength="${minLength}" maxlength="${maxLength}" pattern="${this.pattern || nothing}" autocomplete="${this.autocomplete || nothing}" @input="${this.handleInput}" @change="${this.handleChange}" @focus="${this.handleFocus}" @blur="${this.handleBlur}">`;
60
22
  }
61
23
  updated(changedProperties) {
62
24
  super.updated(changedProperties);
package/src/base/list.js CHANGED
@@ -17,7 +17,7 @@ const Base = InternalsAttached(LitElement);
17
17
  return this.listController.items || [];
18
18
  }
19
19
  render() {
20
- return html` ${this.renderItemSlot()} `;
20
+ return html`${this.renderItemSlot()}`;
21
21
  }
22
22
  renderItemSlot() {
23
23
  return html`<slot part="items"></slot>`;
package/src/base/menu.js CHANGED
@@ -21,15 +21,7 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
21
21
  return this.listController.items || [];
22
22
  }
23
23
  render() {
24
- return html`<div
25
- part="menu"
26
- role="${this.type}"
27
- tabindex="${this.tabIndex}"
28
- @keydown=${this.#handleKeyDown.bind(this)}
29
- @focusout=${this.#handleFocusOut.bind(this)}
30
- >
31
- ${this.renderItemSlot()}
32
- </div>`;
24
+ return html`<div part="menu" role="${this.type}" tabindex="${this.tabIndex}" @keydown="${this.#handleKeyDown.bind(this)}" @focusout="${this.#handleFocusOut.bind(this)}">${this.renderItemSlot()}</div>`;
33
25
  }
34
26
  renderItemSlot() {
35
27
  return html`<slot part="items"></slot>`;
@@ -94,7 +94,7 @@ const Base = FormAssociated(FocusDelegated(InternalsAttached(LitElement)));
94
94
  return html``;
95
95
  }
96
96
  renderFieldContent() {
97
- return html`<span part="value">${this.displayText || html`&nbsp;`}</span>`;
97
+ return html`<span part="value">${this.displayText || html` `}</span>`;
98
98
  }
99
99
  constructor(){
100
100
  super(), // Form-related
@@ -43,31 +43,10 @@ export class Slider extends Base {
43
43
  }
44
44
  renderInput({ start, value, ariaLabel, ariaValueText, ariaMin, ariaMax }) {
45
45
  const name = start ? `start` : `end`;
46
- return html`<input
47
- type="range"
48
- class="${classMap({
46
+ return html`<input type="range" class="${classMap({
49
47
  start,
50
48
  end: !start
51
- })}"
52
- @focus=${this.handleFocus}
53
- @pointerdown=${this.handleDown}
54
- @pointerup=${this.handleUp}
55
- @keydown=${this.handleKeydown}
56
- @keyup=${this.handleKeyup}
57
- @input=${this.handleInput}
58
- @change=${this.handleChange}
59
- id=${name}
60
- .disabled=${this.disabled}
61
- .min=${String(this.min)}
62
- aria-valuemin=${ariaMin}
63
- .max=${String(this.max)}
64
- aria-valuemax=${ariaMax}
65
- .step=${String(this.step)}
66
- .value=${String(value)}
67
- .tabIndex=${start ? 1 : 0}
68
- aria-label=${ariaLabel || nothing}
69
- aria-valuetext=${ariaValueText}
70
- />`;
49
+ })}" @focus="${this.handleFocus}" @pointerdown="${this.handleDown}" @pointerup="${this.handleUp}" @keydown="${this.handleKeydown}" @keyup="${this.handleKeyup}" @input="${this.handleInput}" @change="${this.handleChange}" id="${name}" .disabled="${this.disabled}" .min="${String(this.min)}" aria-valuemin="${ariaMin}" .max="${String(this.max)}" aria-valuemax="${ariaMax}" .step="${String(this.step)}" .value="${String(value)}" .tabIndex="${start ? 1 : 0}" aria-label="${ariaLabel || nothing}" aria-valuetext="${ariaValueText}">`;
71
50
  }
72
51
  constructor(){
73
52
  super(), this.min = 0, this.max = 100, this.valueLabel = '', this.valueLabelStart = '', this.valueLabelEnd = '', this.ariaLabelStart = '', this.ariaValueTextStart = '', this.ariaLabelEnd = '', this.ariaValueTextEnd = '', this.step = 1, this.ticks = false, this.labeled = false, this.range = false, this.startOnTop = false, this.handlesOverlapping = false, this.isRedispatchingEvent = false, // @TODO: Delegate ARIA attributes to inputs, automatically convert from
package/src/base/tabs.js CHANGED
@@ -12,11 +12,7 @@ import { internals } from './mixins/internals-attached.js';
12
12
  return this.parentNode instanceof ShadowRoot ? this.parentNode.host : this.parentElement;
13
13
  }
14
14
  render() {
15
- return html`
16
- <div part="tablist" role="tablist">
17
- <slot @slotchange=${this.#handleSlotChange}></slot>
18
- </div>
19
- `;
15
+ return html`<div part="tablist" role="tablist"><slot @slotchange="${this.#handleSlotChange}"></slot></div>`;
20
16
  }
21
17
  connectedCallback() {
22
18
  super.connectedCallback();
@@ -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=menu]{--md-menu-max-height:300px;min-width:100%}`;
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:0;width:100%}[part=menu]{--md-menu-max-height:300px;min-width:100%}`;
@@ -10,26 +10,7 @@ export class M3Autocomplete extends Autocomplete {
10
10
  ];
11
11
  }
12
12
  renderMenu() {
13
- return html`
14
- <md-menu
15
- part="menu"
16
- id="menu"
17
- type="listbox"
18
- data-tabindex="-1"
19
- ?quick="${this.quick}"
20
- .offset=${this.offset}
21
- .align=${this.align}
22
- .alignStrategy=${this.alignStrategy}
23
- ?keep-open-select=${this.keepOpenSelect}
24
- no-focus-control
25
- ?open=${this.open}
26
- @open="${()=>this.open = true}"
27
- @close="${()=>this.open = false}"
28
- @select=${this.handleMenuSelect}
29
- >
30
- <slot @slotchange=${this.handleItemsSlotChange}></slot>
31
- </md-menu>
32
- `;
13
+ return html`<md-menu part="menu" id="menu" type="listbox" data-tabindex="-1" ?quick="${this.quick}" .offset="${this.offset}" .align="${this.align}" .alignStrategy="${this.alignStrategy}" ?keep-open-select="${this.keepOpenSelect}" no-focus-control ?open="${this.open}" @open="${()=>this.open = true}" @close="${()=>this.open = false}" @select="${this.handleMenuSelect}"><slot @slotchange="${this.handleItemsSlotChange}"></slot></md-menu>`;
33
14
  }
34
15
  }
35
16
  M3Autocomplete = _ts_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-std-effects-fast-duration) var(--md-sys-motion-std-effects-fast), color var(--md-sys-motion-std-effects-fast-duration) var(--md-sys-motion-std-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);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([hidden]) [part~=badge],:host([value="0"]:not([show-zero])) [part~=badge]{--md-badge-scale:0}:host([circle]){--md-badge-offset:14%}:host(:not([left])[dir=rtl]) [part~=badge],:host([left]:not([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(:not([left])[dir=rtl][bottom]) [part~=badge],:host([left][bottom]:not([dir=rtl])) [part~=badge]{transform:scale(var(--md-badge-scale)) translate(-50%,50%);transform-origin:0 100%}`;
@@ -9,12 +9,7 @@ export class M3Badge extends LitElement {
9
9
  ];
10
10
  }
11
11
  render() {
12
- return html`
13
- <div part="root">
14
- <slot></slot>
15
- <span part="badge">${this.#getDisplayValue()}</span>
16
- </div>
17
- `;
12
+ return html`<div part="root"><slot></slot><span part="badge">${this.#getDisplayValue()}</span></div>`;
18
13
  }
19
14
  #getDisplayValue() {
20
15
  const value = this.value;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const commonButtonStyles = css`@layer common-button{: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);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);min-width:64px;padding-inline:var(--_padding);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);gap:8px}:host([size=xsmall]){--_padding:12px;gap:4px}:host([size=medium]){--_padding:24px;font:var(--md-sys-typography-title-medium);gap:8px}:host([size=large]){--_padding:48px;font:var(--md-sys-typography-headline-small);gap:12px}:host([size=xlarge]){--_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)}[part~=icon]{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 common-button{block-size:1em;font-size:var(--_icon-size);inline-size:1em}`;
@@ -19,15 +19,7 @@ export class M3ButtonToggle extends ToggleButton {
19
19
  ];
20
20
  }
21
21
  render() {
22
- return html`
23
- <md-focus-ring></md-focus-ring>
24
- <md-ripple></md-ripple>
25
- <span part="target"></span>
26
- <slot part="icon unchecked" name="icon" aria-hidden="true"></slot>
27
- <slot part="icon checked" name="icon-checked" aria-hidden="true"></slot>
28
- <slot part="label unchecked"></slot>
29
- <slot part="label checked" name="checked"></slot>
30
- `;
22
+ return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon unchecked" name="icon" aria-hidden="true"></slot><slot part="icon checked" name="icon-checked" aria-hidden="true"></slot><slot part="label unchecked"></slot><slot part="label checked" name="checked"></slot>`;
31
23
  }
32
24
  constructor(...args){
33
25
  super(...args), this.size = 'small', this.shape = 'rounded', this.color = 'primary', this.variant = 'filled', /**
@@ -17,13 +17,7 @@ export class M3Button extends Button {
17
17
  ];
18
18
  }
19
19
  render() {
20
- return html`
21
- <md-focus-ring></md-focus-ring>
22
- <md-ripple></md-ripple>
23
- <span part="target"></span>
24
- <slot part="icon" name="icon" aria-hidden="true"></slot>
25
- <slot part="label"></slot>
26
- `;
20
+ return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon" name="icon" aria-hidden="true"></slot><slot part="label"></slot>`;
27
21
  }
28
22
  constructor(...args){
29
23
  super(...args), this.size = 'small', this.shape = 'rounded', this.color = 'primary', this.variant = 'filled', /**
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const iconButtonStyles = css`@layer icon-button{:host{--_wn:32px;--_ww:52px;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);transition:border-radius var(--md-sys-motion-std-effects-slow-duration) var(--md-sys-motion-std-effects-slow);width:var(--_h)}:host([size=xsmall]){--_wn:28px;--_ww:40px}:host([size=medium]){--_wn:48px;--_ww:72px}:host([size=large]){--_wn:64px;--_ww:128px}:host([size=xlarge]){--_wn:104px;--_ww:184px}:host([width=narrow]){width:var(--_wn)}:host([width=wide]){width: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``;
@@ -19,13 +19,7 @@ export class M3IconButtonToggle extends ToggleButton {
19
19
  ];
20
20
  }
21
21
  render() {
22
- return html`
23
- <md-focus-ring></md-focus-ring>
24
- <md-ripple enterbehavior="always"></md-ripple>
25
- <span part="target"></span>
26
- <slot part="icon unchecked"></slot>
27
- <slot part="icon checked" name="checked"></slot>
28
- `;
22
+ return html`<md-focus-ring></md-focus-ring><md-ripple enterbehavior="always"></md-ripple><span part="target"></span><slot part="icon unchecked"></slot><slot part="icon checked" name="checked"></slot>`;
29
23
  }
30
24
  constructor(...args){
31
25
  super(...args), this.size = 'small', this.color = 'primary', this.variant = 'text', this.width = 'standard';
@@ -17,12 +17,7 @@ export class M3IconButton extends Button {
17
17
  ];
18
18
  }
19
19
  render() {
20
- return html`
21
- <md-focus-ring></md-focus-ring>
22
- <md-ripple></md-ripple>
23
- <span part="target"></span>
24
- <slot part="icon"></slot>
25
- `;
20
+ return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon"></slot>`;
26
21
  }
27
22
  constructor(...args){
28
23
  super(...args), this.size = 'small', this.color = 'primary', this.variant = 'text', this.width = 'standard';
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const sharedButtonStyles = css`@layer common-button,icon-button;@layer shared{:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_icon-size:20px;--_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;height:var(--_h);-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}:host([size=medium]){--_h:56px;--_icon-size:24px;--_rad-sq:16px;--_rad-pr:12px}:host([size=large]){--_h:96px;--_icon-size:32px;--_rad-sq:28px;--_rad-pr:16px}:host([size=xlarge]){--_h:136px;--_icon-size:40px;--_rad-sq:28px;--_rad-pr: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(--_outline-color) var(--_outline-opacity,100%), transparent);box-shadow:none;border-style:solid;border-width:1px}: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)}}@layer shared-toggle,override;@layer active{:host(:active){--md-focus-ring-shape:var(--_rad-pr);border-radius:var(--_rad-pr)}}@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%;--_outline-color:var(--md-sys-color-on-surface);--_outline-opacity:10%;box-shadow:none;pointer-events:none}}`;
2
+ export const sharedButtonStyles = css``;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const sharedButtonToggleStyles = css`@layer shared-toggle{: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))){--_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}}`;
2
+ export const sharedButtonToggleStyles = css``;
@@ -0,0 +1,2 @@
1
+ import { css } from 'lit';
2
+ export const standardButtonGroupStyles = css`:host{gap:8px;display:inline-flex}`;