@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
@@ -0,0 +1,239 @@
1
+ import { constructHTMLOptionsCollectionProxy } from '../dom/HTMLOptionsCollectionProxy.js';
2
+ import FormAssociatedMixin from '../mixins/FormAssociatedMixin.js';
3
+ import KeyboardNavMixin from '../mixins/KeyboardNavMixin.js';
4
+ import StateMixin from '../mixins/StateMixin.js';
5
+
6
+ import List from './List.js';
7
+ import ListOption from './ListOption.js';
8
+
9
+ /** @implements {HTMLSelectElement} */
10
+ // @ts-expect-error Can't implement index signatures (use `item()`)
11
+ export default List
12
+ .extend()
13
+ .mixin(StateMixin)
14
+ .mixin(FormAssociatedMixin)
15
+ .mixin(KeyboardNavMixin)
16
+ .observe({
17
+ multiple: 'boolean',
18
+ size: { type: 'integer', empty: 0 },
19
+ })
20
+ .set({
21
+ _ariaRole: 'listbox',
22
+ delegatesFocus: true,
23
+ /** @type {HTMLCollectionOf<ListOption> & HTMLOptionsCollection} */
24
+ _optionsCollection: null,
25
+ /** @type {HTMLCollectionOf<ListOption>} */
26
+ _selectedOptionsCollection: null,
27
+ _handlingSelectedness: false,
28
+ })
29
+ .define({
30
+ options() {
31
+ if (!this._optionsCollection) {
32
+ this._optionsCollection = constructHTMLOptionsCollectionProxy({
33
+ host: this,
34
+ collection: this.getElementsByTagName(ListOption.elementName),
35
+ OptionConstructor: ListOption,
36
+ GroupConstructor: ListOption,
37
+ });
38
+ }
39
+ return this._optionsCollection;
40
+ },
41
+
42
+ /** @return {HTMLCollectionOf<ListOption>} */
43
+ selectedOptions() {
44
+ // eslint-disable-next-line no-return-assign
45
+ return (this._selectedOptionsCollection
46
+ ??= (
47
+ /** @type {HTMLCollectionOf<ListOption>} */
48
+ (this.getElementsByClassName('mdw-list-option__selected')))
49
+ );
50
+ },
51
+
52
+ type() { return 'select'; },
53
+
54
+ kbdNavQuery() { return ListOption.elementName; },
55
+
56
+ kbdNavFocusableWhenDisabled() { return true; },
57
+ })
58
+ .define({
59
+ length() { return this.options.length; },
60
+
61
+ selectedIndex: {
62
+ get() {
63
+ const [selectedItem] = this.selectedOptions;
64
+ if (!selectedItem) return -1;
65
+ return Array.prototype.indexOf.call(this.options, selectedItem);
66
+ },
67
+ set(value) {
68
+ const itemToSelect = this.options[value];
69
+ for (const option of this.options) {
70
+ option.selected = (option === itemToSelect);
71
+ }
72
+ this._value = this.value;
73
+ },
74
+ },
75
+ value: {
76
+ get() {
77
+ return this.selectedOptions[0]?.value ?? '';
78
+ },
79
+ /** @param {string} v */
80
+ set(v) {
81
+ let newValue = '';
82
+ const vString = `${v}`;
83
+ for (const option of this.options) {
84
+ if ((option.selected = (option.value === vString))) {
85
+ newValue = vString;
86
+ }
87
+ }
88
+ this._value = newValue;
89
+ },
90
+ },
91
+ add() { return this.options.add; },
92
+ })
93
+ .on({
94
+ disabledStateChanged(oldValue, newValue) {
95
+ this._kbdFocusable = !newValue;
96
+ this.tabIndex = newValue ? -1 : 0;
97
+ },
98
+ multipleChanged(oldValue, newValue) {
99
+ this.updateAriaProperty('ariaMultiSelectable', newValue ? 'true' : 'false');
100
+ },
101
+ _formResetChanged(oldValue, newValue) {
102
+ // TODO: Unset dirty
103
+ },
104
+ connected() {
105
+ if (!this.hasAttribute('tabindex')) {
106
+ this.tabIndex = 0;
107
+ }
108
+ },
109
+ })
110
+ .methods({
111
+ * _selectedOptionsGenerator() {
112
+ for (const el of this.options) {
113
+ if (!el.selected) continue;
114
+ yield el;
115
+ }
116
+ },
117
+ * [Symbol.iterator]() {
118
+ for (const el of this.options) {
119
+ yield el;
120
+ }
121
+ },
122
+ focus() {
123
+ this.focusCurrentOrFirst();
124
+ },
125
+ /**
126
+ * @param {number} index
127
+ * @return {ListOption|null}
128
+ */
129
+ item(index) { return this.options[index]; },
130
+ /**
131
+ * @param {string} name ID of ListOption
132
+ * @return {ListOption|null}
133
+ */
134
+ namedItem(name) {
135
+ for (const option of this.options) {
136
+ if (option.id === name) {
137
+ return option;
138
+ }
139
+ }
140
+ return null;
141
+ },
142
+ /** @param {Event} event */
143
+ onListboxClick(event) {
144
+ const target = event.target;
145
+ if (!(target instanceof ListOption)) return;
146
+ event.stopPropagation();
147
+ if (target.disabledState) return;
148
+
149
+ let sendUpdateNotifications = false;
150
+ this._handlingSelectedness = true;
151
+
152
+ // Perform unselect
153
+ if (target.selected) {
154
+ // Unselect condition
155
+ if (!this.required || (this.multiple && this.selectedOptions.length > 1)) {
156
+ sendUpdateNotifications = true;
157
+ target.selected = false;
158
+ }
159
+ } else {
160
+ if (!this.multiple) {
161
+ // Unselect all other values
162
+ for (const option of this.selectedOptions) {
163
+ option.selected = false;
164
+ }
165
+ }
166
+
167
+ target.selected = true;
168
+ sendUpdateNotifications = true;
169
+ }
170
+
171
+ this._value = this.value;
172
+ this._handlingSelectedness = false;
173
+
174
+ if (sendUpdateNotifications) {
175
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
176
+ this.dispatchEvent(new Event('change', { bubbles: true }));
177
+ }
178
+ },
179
+ })
180
+ .css`
181
+ :host(:disabled) {
182
+ cursor: not-allowed;
183
+ pointer-events: none;
184
+ }
185
+
186
+ :host([internals-disabled]) {
187
+ cursor: not-allowed;
188
+ pointer-events: none;
189
+ }
190
+ `
191
+ .events({
192
+ 'mdw-list-option:changed'(event) {
193
+ event.stopPropagation();
194
+ if (this.multiple) return;
195
+ if (this._handlingSelectedness) return;
196
+
197
+ const target = /** @type {ListOption} */ (/** @type {unknown} */ (event.target));
198
+ if (target.selected) return;
199
+ this._handlingSelectedness = true;
200
+
201
+ // Programmatic selection of option means deselection of others
202
+ for (const option of this.selectedOptions) {
203
+ if (option !== target) {
204
+ option.selected = false;
205
+ }
206
+ }
207
+
208
+ this._value = this.value;
209
+ this._handlingSelectedness = false;
210
+ },
211
+ focus() {
212
+ // Manual delegates focus because disabled items need to be focusable
213
+ this.focusCurrentOrFirst();
214
+ },
215
+ keydown(event) {
216
+ if (event.key === 'Spacebar' || event.key === ' ') {
217
+ const target = event.target;
218
+ if (!(target instanceof ListOption)) return;
219
+ event.stopPropagation();
220
+ event.preventDefault();
221
+ this.onListboxClick.call(this, event);
222
+ }
223
+ },
224
+ click: 'onListboxClick',
225
+ })
226
+ .childEvents({
227
+ slot: {
228
+ slotchange() {
229
+ this.refreshTabIndexes();
230
+ let index = 0;
231
+ for (const el of this.options) {
232
+ el._index = index++;
233
+ }
234
+ // Refresh internal value
235
+ this._value = this.value;
236
+ },
237
+ },
238
+ })
239
+ .autoRegister('mdw-listbox');