@shortfuse/materialdesignweb 0.7.6 → 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.
Files changed (114) hide show
  1. package/README.md +57 -68
  2. package/components/Badge.js +2 -2
  3. package/components/BottomAppBar.js +3 -5
  4. package/components/Box.js +33 -3
  5. package/components/Button.js +48 -21
  6. package/components/Button.md +9 -9
  7. package/components/Card.js +9 -16
  8. package/components/Checkbox.js +45 -36
  9. package/components/CheckboxIcon.js +2 -2
  10. package/components/Chip.js +1 -1
  11. package/components/Dialog.js +228 -359
  12. package/components/DialogActions.js +2 -2
  13. package/components/Divider.js +3 -3
  14. package/components/ExtendedFab.js +4 -8
  15. package/components/Fab.js +1 -2
  16. package/components/FilterChip.js +4 -4
  17. package/components/Headline.js +1 -1
  18. package/components/Icon.js +8 -8
  19. package/components/IconButton.js +9 -14
  20. package/components/Input.js +273 -1
  21. package/components/Layout.js +485 -16
  22. package/components/List.js +6 -4
  23. package/components/ListItem.js +12 -12
  24. package/components/ListOption.js +21 -5
  25. package/components/Listbox.js +239 -0
  26. package/components/Menu.js +77 -526
  27. package/components/MenuItem.js +12 -14
  28. package/components/Nav.js +0 -2
  29. package/components/NavBar.js +8 -79
  30. package/components/NavDrawer.js +12 -11
  31. package/components/NavDrawerItem.js +2 -1
  32. package/components/NavItem.js +18 -8
  33. package/components/NavRail.js +15 -7
  34. package/components/NavRailItem.js +3 -1
  35. package/components/Popup.js +20 -0
  36. package/components/Progress.js +24 -23
  37. package/components/Radio.js +42 -35
  38. package/components/RadioIcon.js +3 -3
  39. package/components/Ripple.js +2 -3
  40. package/components/Search.js +85 -0
  41. package/components/SegmentedButton.js +1 -10
  42. package/components/SegmentedButtonGroup.js +16 -10
  43. package/components/Select.js +4 -4
  44. package/components/Shape.js +1 -1
  45. package/components/Slider.js +43 -50
  46. package/components/Snackbar.js +4 -5
  47. package/components/Surface.js +3 -3
  48. package/components/Switch.js +55 -21
  49. package/components/SwitchIcon.js +10 -8
  50. package/components/Tab.js +11 -9
  51. package/components/TabContent.js +4 -3
  52. package/components/TabList.js +2 -2
  53. package/components/TabPanel.js +11 -8
  54. package/components/TextArea.js +38 -35
  55. package/components/Tooltip.js +2 -2
  56. package/components/TopAppBar.js +65 -147
  57. package/core/Composition.js +985 -628
  58. package/core/CompositionAdapter.js +315 -0
  59. package/core/CustomElement.js +153 -90
  60. package/core/DomAdapter.js +586 -0
  61. package/core/ICustomElement.d.ts +2 -2
  62. package/core/css.js +8 -7
  63. package/core/customTypes.js +53 -31
  64. package/{utils → core}/jsonMergePatch.js +36 -14
  65. package/core/observe.js +111 -57
  66. package/core/optimizations.js +23 -0
  67. package/core/template.js +17 -11
  68. package/core/test.js +126 -0
  69. package/core/typings.d.ts +11 -5
  70. package/core/uid.js +13 -0
  71. package/dist/index.min.js +83 -152
  72. package/dist/index.min.js.map +4 -4
  73. package/dist/meta.json +1 -1
  74. package/mixins/AriaReflectorMixin.js +1 -2
  75. package/mixins/AriaToolbarMixin.js +2 -3
  76. package/mixins/ControlMixin.js +25 -17
  77. package/mixins/DensityMixin.js +0 -1
  78. package/mixins/FlexableMixin.js +1 -2
  79. package/mixins/FormAssociatedMixin.js +13 -10
  80. package/mixins/InputMixin.js +2 -9
  81. package/mixins/KeyboardNavMixin.js +14 -1
  82. package/mixins/PopupMixin.js +757 -0
  83. package/mixins/RTLObserverMixin.js +0 -1
  84. package/mixins/ResizeObserverMixin.js +0 -1
  85. package/mixins/RippleMixin.js +3 -4
  86. package/mixins/ScrollListenerMixin.js +41 -32
  87. package/mixins/SemiStickyMixin.js +151 -0
  88. package/mixins/ShapeMixin.js +29 -24
  89. package/mixins/StateMixin.js +11 -6
  90. package/mixins/SurfaceMixin.js +3 -57
  91. package/mixins/TextFieldMixin.js +57 -65
  92. package/mixins/ThemableMixin.js +78 -156
  93. package/mixins/TooltipTriggerMixin.js +7 -13
  94. package/mixins/TouchTargetMixin.js +4 -3
  95. package/package.json +9 -5
  96. package/theming/index.js +1 -1
  97. package/theming/themableMixinLoader.js +12 -0
  98. package/utils/{hct → material-color}/blend.js +8 -10
  99. package/utils/{hct → material-color/hct}/Cam16.js +196 -69
  100. package/utils/{hct → material-color/hct}/Hct.js +61 -19
  101. package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
  102. package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
  103. package/utils/{hct → material-color}/helper.js +11 -18
  104. package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
  105. package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
  106. package/utils/material-color/scheme/Scheme.js +376 -0
  107. package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
  108. package/utils/popup.js +46 -25
  109. package/components/ListSelect.js +0 -220
  110. package/components/Option.js +0 -91
  111. package/components/Pane.js +0 -281
  112. package/core/identify.js +0 -40
  113. package/utils/hct/Scheme.js +0 -587
  114. /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
@@ -5,9 +5,9 @@ import ShapeMixin from '../mixins/ShapeMixin.js';
5
5
  import ThemableMixin from '../mixins/ThemableMixin.js';
6
6
 
7
7
  export default CustomElement
8
+ .extend()
8
9
  .mixin(ThemableMixin)
9
10
  .mixin(ShapeMixin)
10
- .extend()
11
11
  .observe({
12
12
  selected: 'boolean',
13
13
  icon: 'string',
@@ -41,7 +41,7 @@ export default CustomElement
41
41
  return _active ? `${color}-container` : '';
42
42
  },
43
43
  _iconInk({ disabled, selected, color }) {
44
- if (!selected) return 'surface-variant';
44
+ if (!selected) return 'surface-container-highest';
45
45
  if (disabled) return 'on-surface';
46
46
  return `on-${color}-container`;
47
47
  },
@@ -51,7 +51,7 @@ export default CustomElement
51
51
  return Boolean(icon || src || unselectedIcon || unselectedSrc);
52
52
  },
53
53
  })
54
- .html/* html */`
54
+ .html`
55
55
  <div id=thumb selected={checked} pressed={pressed} disabled={disabled}>
56
56
  <mdw-shape id=thumb-shape shape-style=full selected={checked} pressed={pressed} hovered={hovered} focused={focused} icon={hasIcon}
57
57
  color={_thumbColor} active={_active} ink={_thumbInk} disabled={disabled}></mdw-shape>
@@ -67,7 +67,7 @@ export default CustomElement
67
67
  track.id = 'track';
68
68
  track.setAttribute('selected', '{checked}');
69
69
  track.setAttribute('disabled', '{disabled}');
70
- outline.removeAttribute('_if');
70
+ outline.removeAttribute('mdw-if');
71
71
  outline.setAttribute('selected', '{checked}');
72
72
  outline.setAttribute('errored', '{errored}');
73
73
  outline.setAttribute('disabled', '{disabled}');
@@ -115,7 +115,7 @@ export default CustomElement
115
115
  position: absolute;
116
116
  inset: 0;
117
117
 
118
- background-color: rgb(var(--mdw-color__surface-variant));
118
+ background-color: rgb(var(--mdw-color__surface-container-highest));
119
119
  }
120
120
 
121
121
  #track[selected] {
@@ -206,7 +206,7 @@ export default CustomElement
206
206
 
207
207
  #thumb-shape:not([selected]) {
208
208
  --mdw-bg: var(--mdw-color__outline);
209
- --mdw-ink: var(--mdw-color__surface-variant);
209
+ --mdw-ink: var(--mdw-color__surface-container-highest);
210
210
  }
211
211
 
212
212
  #thumb-shape[selected] {
@@ -225,8 +225,10 @@ export default CustomElement
225
225
 
226
226
  .icon {
227
227
  position: absolute;
228
- inset-block-start: 50%;
229
- inset-inline-start: 50%;
228
+ /* stylelint-disable-next-line liberty/use-logical-spec */
229
+ top: 50%;
230
+ /* stylelint-disable-next-line liberty/use-logical-spec */
231
+ left: 50%;
230
232
 
231
233
  opacity: 0;
232
234
  transform: translateX(-50%) translateY(-50%);
package/components/Tab.js CHANGED
@@ -9,11 +9,11 @@ import ShapeMixin from '../mixins/ShapeMixin.js';
9
9
  import StateMixin from '../mixins/StateMixin.js';
10
10
 
11
11
  export default CustomElement
12
+ .extend()
12
13
  .mixin(ShapeMixin)
13
14
  .mixin(StateMixin)
14
15
  .mixin(RippleMixin)
15
16
  .mixin(ScrollListenerMixin)
16
- .extend()
17
17
  .define({
18
18
  stateTargetElement() { return this.refs.anchor; },
19
19
  /**
@@ -21,9 +21,8 @@ export default CustomElement
21
21
  * Default to 24.
22
22
  */
23
23
  labelMetrics() {
24
- const slot = this.refs.slot;
25
- let target = this.refs.slot;
26
- if (!slot.clientWidth) target = this.refs.icon;
24
+ const { slot, icon } = this.refs;
25
+ const target = slot.clientWidth ? slot : icon;
27
26
  return {
28
27
  width: target.clientWidth,
29
28
  left: target.offsetLeft,
@@ -47,7 +46,7 @@ export default CustomElement
47
46
  this.refs.anchor.focus(options);
48
47
  },
49
48
  })
50
- .html/* html */`
49
+ .html`
51
50
  <a id=anchor role=tab
52
51
  aria-label={ariaLabel}
53
52
  aria-controls=${({ href }) => (href?.startsWith('#') ? href.slice(1) : null)}
@@ -55,7 +54,7 @@ export default CustomElement
55
54
  aria-disabled=${({ disabledState }) => `${disabledState}`}
56
55
  disabled={disabledState}
57
56
  href=${({ href }) => href ?? '#'}>
58
- <mdw-icon _if=${(data) => data.icon || data.src} id=icon aria-hidden=true src={src} active={active}>{icon}</mdw-icon>
57
+ <mdw-icon mdw-if=${(data) => data.icon || data.src} id=icon aria-hidden=true src={src} active={active}>{icon}</mdw-icon>
59
58
  <slot id=slot></slot>
60
59
  </a>
61
60
  `
@@ -88,9 +87,12 @@ export default CustomElement
88
87
  return;
89
88
  }
90
89
  if (href.startsWith('#')) {
91
- /** @type {HTMLElement} */
92
- const el = document.querySelector(href);
93
- if (!el) { console.warn('Unknown element', href); }
90
+ const root = /** @type {HTMLElement} */ this.getRootNode();
91
+ const el = root.querySelector(href);
92
+ if (!el) {
93
+ console.warn('Unknown element', href);
94
+ return;
95
+ }
94
96
  event.preventDefault();
95
97
  el.scrollIntoView({ block: 'nearest', inline: 'start' });
96
98
  }
@@ -5,8 +5,8 @@ import ResizeObserverMixin from '../mixins/ResizeObserverMixin.js';
5
5
  import TabPanel from './TabPanel.js';
6
6
 
7
7
  export default CustomElement
8
- .mixin(ResizeObserverMixin)
9
8
  .extend()
9
+ .mixin(ResizeObserverMixin)
10
10
  .set({
11
11
  /** @type {InstanceType<TabPanel>[]} */
12
12
  _panelNodes: [],
@@ -87,11 +87,12 @@ export default CustomElement
87
87
  },
88
88
  },
89
89
  })
90
- .html/* html */`<slot id=slot></slot>`
90
+ .html`<slot id=slot></slot>`
91
91
  .methods({
92
92
  onResizeObserved() {
93
93
  this._panelMetrics = null;
94
- // Resize should not change panel visibility
94
+ this.updatePanels();
95
+ // Resize should not change panel visibility (Chrome Bug?)
95
96
  },
96
97
  updatePanels() {
97
98
  const start = this.scrollLeft;
@@ -10,12 +10,12 @@ import ThemableMixin from '../mixins/ThemableMixin.js';
10
10
  import Tab from './Tab.js';
11
11
 
12
12
  export default CustomElement
13
+ .extend()
13
14
  .mixin(ThemableMixin)
14
15
  .mixin(KeyboardNavMixin)
15
16
  .mixin(ResizeObserverMixin)
16
17
  .mixin(RTLObserverMixin)
17
18
  .mixin(ShapeMixin)
18
- .extend()
19
19
  .set({
20
20
  /** @type {WeakRef<HTMLElement>} */
21
21
  _tabContentRef: null,
@@ -257,7 +257,7 @@ export default CustomElement
257
257
  .set({
258
258
  ariaRole: 'tablist',
259
259
  })
260
- .html/* html */`
260
+ .html`
261
261
  <slot id=slot ink={ink} type-style={typeStyle}></slot>
262
262
  <div id=indicator aria-hidden=true style={_indicatorStyle} active={active} secondary={secondary}>
263
263
  <div id=indicator-start class=indicator-piece></div>
@@ -3,8 +3,8 @@ import AriaReflectorMixin from '../mixins/AriaReflectorMixin.js';
3
3
  import Box from './Box.js';
4
4
 
5
5
  export default Box
6
- .mixin(AriaReflectorMixin)
7
6
  .extend()
7
+ .mixin(AriaReflectorMixin)
8
8
  .set({
9
9
  _ariaRole: 'tabpanel',
10
10
  })
@@ -17,21 +17,24 @@ export default Box
17
17
  },
18
18
  peeking: 'boolean',
19
19
  })
20
- .css/* css */`
20
+ .css`
21
21
  :host {
22
+ overflow-y: auto;
22
23
  scroll-snap-align: center;
23
- min-inline-size: 100%;
24
- max-inline-size: 100%;
24
+
25
25
  min-block-size: 100%;
26
26
  max-block-size: 100%;
27
- overflow-y: auto;
28
- will-change: visibility;
27
+ min-inline-size: 100%;
28
+ max-inline-size: 100%;
29
29
 
30
- visibility: hidden;
30
+ visibility: hidden;
31
+
32
+ will-change: visibility;
31
33
  }
34
+
32
35
  :host(:is([active],[peeking])) {
33
36
  /* Safari bug: Visiblity not changing without !important or layout reflow */
34
- visibility: visible !important;;
37
+ visibility: visible !important;
35
38
  }
36
39
  `
37
40
  .autoRegister('mdw-tab-panel');
@@ -12,15 +12,16 @@ const DOMString = { nullParser: String, value: '' };
12
12
  * -implements {HTMLTextAreaElement}
13
13
  */
14
14
  export default CustomElement
15
+ .extend()
15
16
  .mixin(ThemableMixin)
16
17
  .mixin(StateMixin)
17
18
  .mixin(ControlMixin)
18
19
  .mixin(TextFieldMixin)
19
20
  .mixin(ResizeObserverMixin)
20
- .extend()
21
21
  .set({
22
22
  supportsCSSLineHeightUnit: CSS.supports('height', '1lh'),
23
23
  type: 'textarea',
24
+ _resizing: false,
24
25
  })
25
26
  .overrides({
26
27
  controlTagName: 'textarea',
@@ -81,11 +82,11 @@ export default CustomElement
81
82
 
82
83
  })
83
84
  .methods({
84
-
85
- /** @return {number} */
86
85
  resize() {
86
+ if (this._resizing) return;
87
+ this._resizing = true;
87
88
  const textarea = this._textarea;
88
- textarea.style.removeProperty('height');
89
+ let userHeight = textarea.style.getPropertyValue('height');
89
90
 
90
91
  // if (this.placeholder) textarea.removeAttribute('placeholder');
91
92
 
@@ -100,7 +101,12 @@ export default CustomElement
100
101
  textarea.rows = this.maxRows;
101
102
  }
102
103
  if (!this.fixed) {
103
- while (textarea.scrollHeight > textarea.clientHeight) {
104
+ // Auto-grow
105
+ while (textarea.clientHeight < textarea.scrollHeight) {
106
+ if (userHeight) {
107
+ textarea.style.removeProperty('height');
108
+ userHeight = null;
109
+ }
104
110
  if (this.maxRows && textarea.rows === this.maxRows) break;
105
111
  const lastClientHeight = textarea.clientHeight;
106
112
  textarea.rows++;
@@ -109,7 +115,8 @@ export default CustomElement
109
115
  break;
110
116
  }
111
117
  }
112
- while (textarea.scrollHeight === textarea.clientHeight) {
118
+ // Auto-shrink
119
+ while (!userHeight && textarea.clientHeight >= textarea.scrollHeight) {
113
120
  if (textarea.rows === 1) break;
114
121
  if (this.minRows > 1 && textarea.rows === this.minRows) break;
115
122
  const lastClientHeight = textarea.clientHeight;
@@ -121,14 +128,12 @@ export default CustomElement
121
128
  }
122
129
  }
123
130
  }
124
-
125
131
  if (textarea.selectionEnd === textarea.value.length) {
126
132
  textarea.scrollTop = textarea.scrollHeight;
127
133
  }
128
-
129
134
  this.rows = textarea.rows;
135
+ this._resizing = false;
130
136
  // if (this.placeholder) textarea.setAttribute('placeholder', this.placeholder);
131
- return this.rows;
132
137
  },
133
138
 
134
139
  /** @param {ResizeObserverEntry} entry */
@@ -183,14 +188,15 @@ export default CustomElement
183
188
  this.resize();
184
189
  },
185
190
  _lineHeightChanged(oldValue, newValue) {
186
- this.refs.label.style.setProperty('--line-height', newValue);
191
+ this.refs.shape.style.setProperty('--line-height', newValue);
187
192
  },
193
+ // Animate API does not override user-resize. Must use inline-styles
188
194
  minRowsChanged(oldValue, newValue) {
189
- this.refs.label.style.setProperty('--min-rows', `${newValue || 'none'}`);
195
+ this.refs.shape.style.setProperty('--min-rows', `${newValue || 'none'}`);
190
196
  this.resize();
191
197
  },
192
198
  maxRowsChanged(oldValue, newValue) {
193
- this.refs.label.style.setProperty('--max-rows', `${newValue || 'none'}`);
199
+ this.refs.shape.style.setProperty('--max-rows', `${newValue || 'none'}`);
194
200
  this.resize();
195
201
  },
196
202
  rowsChanged() {
@@ -227,7 +233,7 @@ export default CustomElement
227
233
  --control__margin-bottom: 1px;
228
234
  }
229
235
 
230
- #label {
236
+ #shape {
231
237
  --max-rows: none;
232
238
  --line-height: var(--mdw-typescale__body-large__line-height);
233
239
  --expected-height: calc(var(--line-height)
@@ -241,7 +247,7 @@ export default CustomElement
241
247
  }
242
248
 
243
249
  @supports(height: 1lh) {
244
- #label {
250
+ #shape {
245
251
  --line-height: 1lh;
246
252
  }
247
253
  }
@@ -255,36 +261,33 @@ export default CustomElement
255
261
  overflow-y: auto;
256
262
  -webkit-overflow-scrolling: touch;
257
263
 
258
- box-sizing: border-box;
259
- block-size: 100%;
264
+ box-sizing: content-box;
265
+ block-size: min-content;
266
+
267
+ min-block-size: var(--line-height);
268
+ /* Avoid clipping on manual resize */
269
+ max-block-size: calc(100% - (var(--control__margin-top)
270
+ + var(--control__padding-top)
271
+ + var(--control__padding-bottom)
272
+ + var(--control__margin-bottom)));
273
+ inline-size: calc(100% - 32px) !important; /* !important to override user-agent resize */
260
274
 
261
- min-block-size: var(--expected-height);
262
- /* Avoid clipping on resize */
263
- max-block-size: inherit;
264
- inline-size: 100% !important; /* !important to override user-agent resize */
265
275
  padding-inline: 16px;
266
- }
267
276
 
268
- #control[icon] {
269
- padding-inline-start: 0;
277
+ /* https://github.com/w3c/csswg-drafts/issues/7542 */
278
+ form-sizing: normal;
270
279
  }
271
280
 
272
281
  #control[minrows] {
273
- min-block-size: calc((var(--min-rows) * var(--line-height))
274
- + var(--control__margin-top)
275
- + var(--control__padding-top)
276
- + var(--control__padding-bottom)
277
- + var(--control__margin-bottom)
278
- );
282
+ min-block-size: calc((var(--min-rows) * var(--line-height)));
279
283
  }
280
284
 
281
285
  #control[maxrows] {
282
- max-block-size: calc((var(--max-rows) * var(--line-height))
283
- + var(--control__margin-top)
284
- + var(--control__padding-top)
285
- + var(--control__padding-bottom)
286
- + var(--control__margin-bottom)
287
- );
286
+ max-block-size: calc((var(--max-rows) * var(--line-height)));
287
+ }
288
+
289
+ #control[icon] {
290
+ padding-inline-start: 0;
288
291
  }
289
292
 
290
293
  #control:is([icon], [input-prefix]) {
@@ -3,8 +3,8 @@ import AriaReflectorMixin from '../mixins/AriaReflectorMixin.js';
3
3
  import Surface from './Surface.js';
4
4
 
5
5
  export default Surface
6
- .mixin(AriaReflectorMixin)
7
6
  .extend()
7
+ .mixin(AriaReflectorMixin)
8
8
  .set({
9
9
  _ariaRole: 'tooltip',
10
10
  })
@@ -23,7 +23,7 @@ export default Surface
23
23
  :host {
24
24
  --mdw-shape__size: var(--mdw-shape__extra-small);
25
25
  --mdw-ink: var(--mdw-color__on-surface-variant);
26
- --mdw-shape__bg: rgb(var(--mdw-color__surface-variant));
26
+ --mdw-shape__bg: rgb(var(--mdw-color__surface-container));
27
27
  display: block;
28
28
  vertical-align: middle;
29
29