@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.
- package/README.md +57 -68
- package/components/Badge.js +2 -2
- package/components/BottomAppBar.js +3 -5
- package/components/Box.js +33 -3
- package/components/Button.js +48 -21
- package/components/Button.md +9 -9
- package/components/Card.js +9 -16
- package/components/Checkbox.js +45 -36
- package/components/CheckboxIcon.js +2 -2
- package/components/Chip.js +1 -1
- package/components/Dialog.js +228 -359
- package/components/DialogActions.js +2 -2
- package/components/Divider.js +3 -3
- package/components/ExtendedFab.js +4 -8
- package/components/Fab.js +1 -2
- package/components/FilterChip.js +4 -4
- package/components/Headline.js +1 -1
- package/components/Icon.js +8 -8
- package/components/IconButton.js +9 -14
- package/components/Input.js +273 -1
- package/components/Layout.js +485 -16
- package/components/List.js +6 -4
- package/components/ListItem.js +12 -12
- package/components/ListOption.js +21 -5
- package/components/Listbox.js +239 -0
- package/components/Menu.js +77 -526
- package/components/MenuItem.js +12 -14
- package/components/Nav.js +0 -2
- package/components/NavBar.js +8 -79
- package/components/NavDrawer.js +12 -11
- package/components/NavDrawerItem.js +2 -1
- package/components/NavItem.js +18 -8
- package/components/NavRail.js +15 -7
- package/components/NavRailItem.js +3 -1
- package/components/Popup.js +20 -0
- package/components/Progress.js +24 -23
- package/components/Radio.js +42 -35
- package/components/RadioIcon.js +3 -3
- package/components/Ripple.js +2 -3
- package/components/Search.js +85 -0
- package/components/SegmentedButton.js +1 -10
- package/components/SegmentedButtonGroup.js +16 -10
- package/components/Select.js +4 -4
- package/components/Shape.js +1 -1
- package/components/Slider.js +43 -50
- package/components/Snackbar.js +4 -5
- package/components/Surface.js +3 -3
- package/components/Switch.js +55 -21
- package/components/SwitchIcon.js +10 -8
- package/components/Tab.js +11 -9
- package/components/TabContent.js +4 -3
- package/components/TabList.js +2 -2
- package/components/TabPanel.js +11 -8
- package/components/TextArea.js +38 -35
- package/components/Tooltip.js +2 -2
- package/components/TopAppBar.js +65 -147
- package/core/Composition.js +985 -628
- package/core/CompositionAdapter.js +315 -0
- package/core/CustomElement.js +153 -90
- package/core/DomAdapter.js +586 -0
- package/core/ICustomElement.d.ts +2 -2
- package/core/css.js +8 -7
- package/core/customTypes.js +53 -31
- package/{utils → core}/jsonMergePatch.js +36 -14
- package/core/observe.js +111 -57
- package/core/optimizations.js +23 -0
- package/core/template.js +17 -11
- package/core/test.js +126 -0
- package/core/typings.d.ts +11 -5
- package/core/uid.js +13 -0
- package/dist/index.min.js +83 -152
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +1 -1
- package/mixins/AriaReflectorMixin.js +1 -2
- package/mixins/AriaToolbarMixin.js +2 -3
- package/mixins/ControlMixin.js +25 -17
- package/mixins/DensityMixin.js +0 -1
- package/mixins/FlexableMixin.js +1 -2
- package/mixins/FormAssociatedMixin.js +13 -10
- package/mixins/InputMixin.js +2 -9
- package/mixins/KeyboardNavMixin.js +14 -1
- package/mixins/PopupMixin.js +757 -0
- package/mixins/RTLObserverMixin.js +0 -1
- package/mixins/ResizeObserverMixin.js +0 -1
- package/mixins/RippleMixin.js +3 -4
- package/mixins/ScrollListenerMixin.js +41 -32
- package/mixins/SemiStickyMixin.js +151 -0
- package/mixins/ShapeMixin.js +29 -24
- package/mixins/StateMixin.js +11 -6
- package/mixins/SurfaceMixin.js +3 -57
- package/mixins/TextFieldMixin.js +57 -65
- package/mixins/ThemableMixin.js +78 -156
- package/mixins/TooltipTriggerMixin.js +7 -13
- package/mixins/TouchTargetMixin.js +4 -3
- package/package.json +9 -5
- package/theming/index.js +1 -1
- package/theming/themableMixinLoader.js +12 -0
- package/utils/{hct → material-color}/blend.js +8 -10
- package/utils/{hct → material-color/hct}/Cam16.js +196 -69
- package/utils/{hct → material-color/hct}/Hct.js +61 -19
- package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
- package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
- package/utils/{hct → material-color}/helper.js +11 -18
- package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
- package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
- package/utils/material-color/scheme/Scheme.js +376 -0
- package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
- package/utils/popup.js +46 -25
- package/components/ListSelect.js +0 -220
- package/components/Option.js +0 -91
- package/components/Pane.js +0 -281
- package/core/identify.js +0 -40
- package/utils/hct/Scheme.js +0 -587
- /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { createEmptyComment } from './optimizations.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Object} DomAdapterCreateOptions
|
|
5
|
+
* @prop {Comment} anchorNode
|
|
6
|
+
* @prop {(...args:any[]) => HTMLElement} [create]
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} ItemMetadata
|
|
11
|
+
* @prop {Element} element
|
|
12
|
+
* @prop {any} key
|
|
13
|
+
* @prop {Element|Comment} domNode
|
|
14
|
+
* @prop {Function} render
|
|
15
|
+
* @prop {boolean} [hidden]
|
|
16
|
+
* @prop {Comment} [comment]
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export default class CompositionAdapter {
|
|
20
|
+
/** @param {DomAdapterCreateOptions} options */
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.anchorNode = options.anchorNode;
|
|
23
|
+
|
|
24
|
+
/** @type {ItemMetadata[]} */
|
|
25
|
+
this.metadata = [];
|
|
26
|
+
/**
|
|
27
|
+
* Ordered-list of metadata keys
|
|
28
|
+
* Chrome and FireFox optimize arrays for indexOf/includes
|
|
29
|
+
* Safari is faster with WeakMap.get(), but can't use Primitive keys
|
|
30
|
+
* TODO: Add Safari path
|
|
31
|
+
* @type {any[]}
|
|
32
|
+
*/
|
|
33
|
+
this.keys = [];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Chrome needs a hint to know we will need a fast path for array by keys.
|
|
37
|
+
*/
|
|
38
|
+
this.needsArrayKeyFastPath = false;
|
|
39
|
+
|
|
40
|
+
this.composition = options.composition;
|
|
41
|
+
this.renderOptions = options.renderOptions;
|
|
42
|
+
|
|
43
|
+
this.pendingRemoves = [];
|
|
44
|
+
// Batch objects
|
|
45
|
+
|
|
46
|
+
/** @type {Map<any, ItemMetadata>} */
|
|
47
|
+
this.metadataCache = null;
|
|
48
|
+
|
|
49
|
+
/** @type {Element[]} */
|
|
50
|
+
this.queuedElements = [];
|
|
51
|
+
// this.batching = false;
|
|
52
|
+
/** @type {number|null} */
|
|
53
|
+
this.batchStartIndex = null;
|
|
54
|
+
/** @type {number|null} */
|
|
55
|
+
this.batchEndIndex = null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render(changes, data) {
|
|
59
|
+
return this.composition.render(changes, data, this.renderOptions);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
startBatch() {
|
|
63
|
+
this.needsArrayKeyFastPath = true;
|
|
64
|
+
// this.batching = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
writeBatch() {
|
|
68
|
+
if (!this.queuedElements.length) return;
|
|
69
|
+
/** @type {Comment|Element} */
|
|
70
|
+
const previousSibling = this.metadata[this.batchStartIndex - 1]?.domNode ?? this.anchorNode;
|
|
71
|
+
previousSibling.after(...this.queuedElements);
|
|
72
|
+
this.queuedElements.length = 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
stopBatch() {
|
|
76
|
+
this.writeBatch();
|
|
77
|
+
|
|
78
|
+
this.needsArrayKeyFastPath = false;
|
|
79
|
+
this.batchStartIndex = null;
|
|
80
|
+
this.batchEndIndex = null;
|
|
81
|
+
if (this.metadataCache !== null) {
|
|
82
|
+
for (const { domNode } of this.metadataCache.values()) {
|
|
83
|
+
domNode.remove();
|
|
84
|
+
}
|
|
85
|
+
this.metadataCache.clear();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** @param {number} index */
|
|
90
|
+
removeByIndex(index) {
|
|
91
|
+
const [metadata] = this.metadata.splice(index, 1);
|
|
92
|
+
const { domNode, key } = metadata;
|
|
93
|
+
this.keys.splice(index, 1);
|
|
94
|
+
domNode.remove();
|
|
95
|
+
|
|
96
|
+
// Don't release in case we may need it later
|
|
97
|
+
if (this.metadataCache === null) {
|
|
98
|
+
this.metadataCache = new Map([[key, metadata]]);
|
|
99
|
+
} else {
|
|
100
|
+
this.metadataCache.set(key, metadata);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Worst case scenario
|
|
106
|
+
* @param {number} newIndex expectedIndex
|
|
107
|
+
* @param {*} changes
|
|
108
|
+
* @param {*} data
|
|
109
|
+
* @param {*} key
|
|
110
|
+
* @param {*} change
|
|
111
|
+
* @param {boolean} [skipOnMatch]
|
|
112
|
+
* JSON Merge has no way to express sort change and data change. Best
|
|
113
|
+
* performance is done via invoking render on sort change and another on
|
|
114
|
+
* inner change. Can't skip if mixing change types.
|
|
115
|
+
*/
|
|
116
|
+
renderData(newIndex, changes, data, key, change, skipOnMatch) {
|
|
117
|
+
if (newIndex < this.metadata.length) {
|
|
118
|
+
const metadataAtIndex = this.metadata[newIndex];
|
|
119
|
+
|
|
120
|
+
// There is an element in this slot
|
|
121
|
+
|
|
122
|
+
// Compare if different
|
|
123
|
+
const currentKey = metadataAtIndex.key;
|
|
124
|
+
const sameKey = (currentKey === key);
|
|
125
|
+
const isPartial = (change !== key);
|
|
126
|
+
|
|
127
|
+
if (sameKey) {
|
|
128
|
+
// Both reference the same key (correct spot)
|
|
129
|
+
if (isPartial) {
|
|
130
|
+
metadataAtIndex.render(changes, data);
|
|
131
|
+
} else if (skipOnMatch) {
|
|
132
|
+
// Skip overwrite. Presume no change
|
|
133
|
+
// console.warn('same key, no reason to repaint', newIndex);
|
|
134
|
+
} else {
|
|
135
|
+
// console.warn('no skip on match', newIndex);
|
|
136
|
+
metadataAtIndex.render(changes, data);
|
|
137
|
+
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (this.metadataCache === null) {
|
|
142
|
+
this.metadataCache = new Map();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// If not same key. Scan key list.
|
|
146
|
+
// Can avoid checking before current index. Will always be after current
|
|
147
|
+
let failedFastPath = false;
|
|
148
|
+
if (this.needsArrayKeyFastPath) {
|
|
149
|
+
// Invoking includes will ensure Chrome generates an internal hash map
|
|
150
|
+
failedFastPath = !this.keys.includes(key);
|
|
151
|
+
this.needsArrayFastPath = false;
|
|
152
|
+
}
|
|
153
|
+
const oldIndex = failedFastPath ? -1 : this.keys.indexOf(key, newIndex + 1);
|
|
154
|
+
if (oldIndex === -1) {
|
|
155
|
+
// New key
|
|
156
|
+
// console.log('new key?', 'should be at', newIndex);
|
|
157
|
+
// Was key removed in this batch?
|
|
158
|
+
if (this.metadataCache.has(key)) {
|
|
159
|
+
// console.log('inserting removed element', 'at', newIndex);
|
|
160
|
+
// (Optimistic insert)
|
|
161
|
+
// Key was removed and should be here instead
|
|
162
|
+
// If should have been replace, will correct next step
|
|
163
|
+
const previousMetadata = this.metadataCache.get(key);
|
|
164
|
+
this.metadata.splice(newIndex, 0, previousMetadata);
|
|
165
|
+
this.keys.splice(newIndex, 0, key);
|
|
166
|
+
|
|
167
|
+
const previousSibling = this.metadata[newIndex - 1]?.domNode ?? this.anchorNode;
|
|
168
|
+
previousSibling.after(previousMetadata.domNode);
|
|
169
|
+
this.metadataCache.delete(key);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// (Optimistic replace)
|
|
174
|
+
// Brand new key. Cache whatever is in current and replace
|
|
175
|
+
// If should have been insert, will correct itself next step.
|
|
176
|
+
// Allows multiple inserts to batch instead of one-by-one
|
|
177
|
+
|
|
178
|
+
// console.log('completely new key', 'removing old. will replace', newIndex);
|
|
179
|
+
this.metadataCache.set(metadataAtIndex.key, metadataAtIndex);
|
|
180
|
+
|
|
181
|
+
// Continue to PUT below
|
|
182
|
+
} else {
|
|
183
|
+
// Key is in the wrong spot (guaranteed to be oldIndex > newIndex)
|
|
184
|
+
// console.warn('Found key for', newIndex, '@', oldIndex);
|
|
185
|
+
// console.warn('swapping', newIndex, '<=>', oldIndex);
|
|
186
|
+
if ((newIndex - oldIndex) === -1) {
|
|
187
|
+
// (Optimistic removal)
|
|
188
|
+
// If element should be one step sooner, remove instead to shift up.
|
|
189
|
+
// If should have been swap, will correct itself next step.
|
|
190
|
+
// console.warn('Removing', newIndex, 'instead');
|
|
191
|
+
this.removeByIndex(newIndex);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Swap with other element
|
|
195
|
+
// Arrays should be iterated sequentially.
|
|
196
|
+
// Array can never swap before current index
|
|
197
|
+
|
|
198
|
+
// Store what's later in the tree to move here
|
|
199
|
+
|
|
200
|
+
const correctMetadata = this.metadata[oldIndex];
|
|
201
|
+
|
|
202
|
+
// Move back <=
|
|
203
|
+
this.metadata[newIndex] = correctMetadata;
|
|
204
|
+
this.metadata.splice(oldIndex, 1);
|
|
205
|
+
|
|
206
|
+
const { domNode: domNodeToRemove } = metadataAtIndex;
|
|
207
|
+
domNodeToRemove.replaceWith(correctMetadata.domNode);
|
|
208
|
+
|
|
209
|
+
if (!skipOnMatch) {
|
|
210
|
+
console.warn('no skip on match on swap', newIndex);
|
|
211
|
+
correctMetadata.render(changes, data);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Remove posterior
|
|
215
|
+
|
|
216
|
+
this.keys[newIndex] = key;
|
|
217
|
+
this.keys.splice(oldIndex, 1);
|
|
218
|
+
|
|
219
|
+
domNodeToRemove.remove();
|
|
220
|
+
|
|
221
|
+
// Don't release in case we may need it later
|
|
222
|
+
// console.debug('Caching key', key);
|
|
223
|
+
this.metadataCache.set(metadataAtIndex.key, metadataAtIndex);
|
|
224
|
+
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const render = this.render(changes, data);
|
|
230
|
+
const element = render.target;
|
|
231
|
+
|
|
232
|
+
this.metadata[newIndex] = {
|
|
233
|
+
render,
|
|
234
|
+
element,
|
|
235
|
+
key,
|
|
236
|
+
domNode: element,
|
|
237
|
+
};
|
|
238
|
+
this.keys[newIndex] = key;
|
|
239
|
+
|
|
240
|
+
if (this.batchEndIndex === null || this.batchEndIndex !== (newIndex - 1)) {
|
|
241
|
+
this.writeBatch();
|
|
242
|
+
// Start new batch
|
|
243
|
+
this.batchStartIndex = newIndex;
|
|
244
|
+
}
|
|
245
|
+
this.batchEndIndex = newIndex;
|
|
246
|
+
this.queuedElements.push(element);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
removeEntries(startIndex = 0) {
|
|
250
|
+
const { length } = this.metadata;
|
|
251
|
+
for (let index = length - 1; index >= startIndex; index--) {
|
|
252
|
+
this.metadata[index].domNode.remove();
|
|
253
|
+
}
|
|
254
|
+
this.metadata.length = startIndex;
|
|
255
|
+
this.keys.length = startIndex;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @param {number} [index]
|
|
260
|
+
* @param {ItemMetadata} [metadata]
|
|
261
|
+
* @param {any} [key]
|
|
262
|
+
* @return {boolean} changed
|
|
263
|
+
*/
|
|
264
|
+
hide(index, metadata, key) {
|
|
265
|
+
if (!metadata) {
|
|
266
|
+
if (index == null) {
|
|
267
|
+
index = this.keys.indexOf(key);
|
|
268
|
+
}
|
|
269
|
+
metadata = this.metadata[index];
|
|
270
|
+
if (!metadata) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (metadata.hidden) return false;
|
|
276
|
+
|
|
277
|
+
let { comment, element } = metadata;
|
|
278
|
+
if (!comment) {
|
|
279
|
+
comment = createEmptyComment();
|
|
280
|
+
metadata.comment = comment;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
element.replaceWith(comment);
|
|
284
|
+
metadata.domNode = comment;
|
|
285
|
+
metadata.hidden = true;
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* @param {number} [index]
|
|
291
|
+
* @param {ItemMetadata} [metadata]
|
|
292
|
+
* @param {any} [key]
|
|
293
|
+
* @return {boolean} changed
|
|
294
|
+
*/
|
|
295
|
+
show(index, metadata, key) {
|
|
296
|
+
if (!metadata) {
|
|
297
|
+
if (index == null) {
|
|
298
|
+
index = this.keys.indexOf(key);
|
|
299
|
+
}
|
|
300
|
+
metadata = this.metadata[index];
|
|
301
|
+
if (!metadata) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!metadata.hidden) return false;
|
|
307
|
+
|
|
308
|
+
const { comment, element } = metadata;
|
|
309
|
+
|
|
310
|
+
comment.replaceWith(element);
|
|
311
|
+
metadata.domNode = element;
|
|
312
|
+
metadata.hidden = false;
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
}
|