@shortfuse/materialdesignweb 0.7.5 → 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 +487 -13
  22. package/components/List.js +6 -4
  23. package/components/ListItem.js +12 -12
  24. package/components/ListOption.js +25 -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 +45 -39
  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 -216
  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,19 +128,16 @@ 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 */
135
140
  onResizeObserved(entry) {
136
- super.onResizeObserved(entry);
137
141
  if (this.matches(':active')) return;
138
142
  this.resize();
139
143
  },
@@ -173,10 +177,8 @@ export default CustomElement
173
177
  // Custom
174
178
  control.setAttribute('input-prefix', '{inputPrefix}');
175
179
  control.setAttribute('input-suffix', '{inputSuffix}');
176
- control.setAttribute('minrows', '{minRows}');
177
180
  control.setAttribute('fixed', '{fixed}');
178
181
  control.setAttribute('icon', '{icon}');
179
- control.setAttribute('maxrows', '{maxRows}');
180
182
  },
181
183
  defaultValueAttrChanged(oldValue, newValue) {
182
184
  this.defaultValue = newValue;
@@ -186,14 +188,15 @@ export default CustomElement
186
188
  this.resize();
187
189
  },
188
190
  _lineHeightChanged(oldValue, newValue) {
189
- this.refs.label.style.setProperty('--line-height', newValue);
191
+ this.refs.shape.style.setProperty('--line-height', newValue);
190
192
  },
193
+ // Animate API does not override user-resize. Must use inline-styles
191
194
  minRowsChanged(oldValue, newValue) {
192
- this.refs.label.style.setProperty('--min-rows', `${newValue || 'none'}`);
195
+ this.refs.shape.style.setProperty('--min-rows', `${newValue || 'none'}`);
193
196
  this.resize();
194
197
  },
195
198
  maxRowsChanged(oldValue, newValue) {
196
- this.refs.label.style.setProperty('--max-rows', `${newValue || 'none'}`);
199
+ this.refs.shape.style.setProperty('--max-rows', `${newValue || 'none'}`);
197
200
  this.resize();
198
201
  },
199
202
  rowsChanged() {
@@ -210,6 +213,8 @@ export default CustomElement
210
213
  minlength: cloneAttributeCallback('minlength', 'control'),
211
214
  maxlength: cloneAttributeCallback('maxlength', 'control'),
212
215
  placeholder: cloneAttributeCallback('placeholder', 'control'),
216
+ minrows: cloneAttributeCallback('minrows', 'control'),
217
+ maxrows: cloneAttributeCallback('maxrows', 'control'),
213
218
  },
214
219
  })
215
220
  .css`
@@ -228,17 +233,21 @@ export default CustomElement
228
233
  --control__margin-bottom: 1px;
229
234
  }
230
235
 
231
- #label {
236
+ #shape {
232
237
  --max-rows: none;
233
238
  --line-height: var(--mdw-typescale__body-large__line-height);
234
- --expected-height: calc((var(--control__margin-top) + var(--control__padding-top) + var(--line-height) + var(--control__padding-bottom) + var(--control__margin-bottom)));
239
+ --expected-height: calc(var(--line-height)
240
+ + var(--control__margin-top)
241
+ + var(--control__padding-top)
242
+ + var(--control__padding-bottom)
243
+ + var(--control__margin-bottom));
235
244
  max-block-size: 100%;
236
245
  grid-row: 1 / 1;
237
246
  padding: 0;
238
247
  }
239
248
 
240
249
  @supports(height: 1lh) {
241
- #label {
250
+ #shape {
242
251
  --line-height: 1lh;
243
252
  }
244
253
  }
@@ -252,36 +261,33 @@ export default CustomElement
252
261
  overflow-y: auto;
253
262
  -webkit-overflow-scrolling: touch;
254
263
 
255
- box-sizing: border-box;
256
- 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 */
257
274
 
258
- min-block-size: var(--expected-height);
259
- /* Avoid clipping on resize */
260
- max-block-size: inherit;
261
- inline-size: 100% !important; /* !important to override user-agent resize */
262
275
  padding-inline: 16px;
263
- }
264
276
 
265
- #control[icon] {
266
- padding-inline-start: 0;
277
+ /* https://github.com/w3c/csswg-drafts/issues/7542 */
278
+ form-sizing: normal;
267
279
  }
268
280
 
269
281
  #control[minrows] {
270
- min-block-size: calc((var(--min-rows) * var(--line-height))
271
- + var(--control__margin-top)
272
- + var(--control__padding-top)
273
- + var(--control__padding-bottom)
274
- + var(--control__margin-bottom)
275
- );
282
+ min-block-size: calc((var(--min-rows) * var(--line-height)));
276
283
  }
277
284
 
278
285
  #control[maxrows] {
279
- max-block-size: calc((var(--max-rows) * var(--line-height))
280
- + var(--control__margin-top)
281
- + var(--control__padding-top)
282
- + var(--control__padding-bottom)
283
- + var(--control__margin-bottom)
284
- );
286
+ max-block-size: calc((var(--max-rows) * var(--line-height)));
287
+ }
288
+
289
+ #control[icon] {
290
+ padding-inline-start: 0;
285
291
  }
286
292
 
287
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