@vaadin/component-base 23.0.6 → 23.1.0-alpha3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/component-base",
3
- "version": "23.0.6",
3
+ "version": "23.1.0-alpha3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@esm-bundle/chai": "^4.3.4",
42
42
  "@vaadin/testing-helpers": "^0.3.2",
43
- "sinon": "^9.2.4"
43
+ "sinon": "^13.0.2"
44
44
  },
45
- "gitHead": "82ca8522e24a63343fb28bcb4c686e55d25c8858"
45
+ "gitHead": "8c9e64e8dfa158dd52a9bf6da351ff038c88ca85"
46
46
  }
@@ -39,7 +39,7 @@ const registered = new Set();
39
39
  export const ElementMixin = (superClass) =>
40
40
  class VaadinElementMixin extends DirMixin(superClass) {
41
41
  static get version() {
42
- return '23.0.6';
42
+ return '23.1.0-alpha3';
43
43
  }
44
44
 
45
45
  /** @protected */
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { Constructor } from '@open-wc/dedupe-mixin';
7
+ import { LitElement } from 'lit';
8
+
9
+ export declare function PolylitMixin<T extends Constructor<LitElement>>(base: T): T & Constructor<PolylitMixinClass>;
10
+
11
+ export declare class PolylitMixinClass {
12
+ ready(): void;
13
+
14
+ /**
15
+ * Reads a value from a path.
16
+ */
17
+ protected _get(root: Object, path: String): any;
18
+
19
+ /**
20
+ * Sets a value to a path.
21
+ */
22
+ protected _set(root: Object, path: String, value: any): void;
23
+ }
@@ -0,0 +1,266 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
+
8
+ const caseMap = {};
9
+
10
+ const CAMEL_TO_DASH = /([A-Z])/g;
11
+
12
+ function camelToDash(camel) {
13
+ return caseMap[camel] || (caseMap[camel] = camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase());
14
+ }
15
+
16
+ function upper(name) {
17
+ return name[0].toUpperCase() + name.substring(1);
18
+ }
19
+
20
+ function parseObserver(observerString) {
21
+ const [method, rest] = observerString.split('(');
22
+ const observerProps = rest
23
+ .replace(')', '')
24
+ .split(',')
25
+ .map((prop) => prop.trim());
26
+
27
+ return {
28
+ method,
29
+ observerProps
30
+ };
31
+ }
32
+
33
+ function getOrCreateMap(obj, name) {
34
+ if (!Object.prototype.hasOwnProperty.call(obj, name)) {
35
+ // clone any existing entries (superclasses)
36
+ obj[name] = new Map(obj[name]);
37
+ }
38
+ return obj[name];
39
+ }
40
+
41
+ const PolylitMixinImplementation = (superclass) => {
42
+ class PolylitMixinClass extends superclass {
43
+ static createProperty(name, options) {
44
+ if ([String, Boolean, Number, Array].includes(options)) {
45
+ options = {
46
+ type: options
47
+ };
48
+ }
49
+
50
+ if (options.reflectToAttribute) {
51
+ options.reflect = true;
52
+ }
53
+
54
+ super.createProperty(name, options);
55
+ }
56
+
57
+ static getOrCreateMap(name) {
58
+ return getOrCreateMap(this, name);
59
+ }
60
+
61
+ /**
62
+ * @protected
63
+ * @override
64
+ */
65
+ static finalize() {
66
+ super.finalize();
67
+
68
+ if (Array.isArray(this.observers)) {
69
+ const complexObservers = this.getOrCreateMap('__complexObservers');
70
+
71
+ this.observers.forEach((observer) => {
72
+ const { method, observerProps } = parseObserver(observer);
73
+ complexObservers.set(method, observerProps);
74
+ });
75
+ }
76
+ }
77
+
78
+ static addCheckedInitializer(initializer) {
79
+ super.addInitializer((instance) => {
80
+ // Prevent initializer from affecting superclass
81
+ if (instance instanceof this) {
82
+ initializer(instance);
83
+ }
84
+ });
85
+ }
86
+
87
+ static getPropertyDescriptor(name, key, options) {
88
+ const defaultDescriptor = super.getPropertyDescriptor(name, key, options);
89
+
90
+ let result = defaultDescriptor;
91
+
92
+ if ('value' in options) {
93
+ // Set the default value
94
+ this.addCheckedInitializer((instance) => {
95
+ if (typeof options.value === 'function') {
96
+ instance[name] = options.value.call(instance);
97
+ } else {
98
+ instance[name] = options.value;
99
+ }
100
+ });
101
+ }
102
+
103
+ if (options.readOnly) {
104
+ const setter = defaultDescriptor.set;
105
+
106
+ this.addCheckedInitializer((instance) => {
107
+ // This is run during construction of the element
108
+ instance['_set' + upper(name)] = function (value) {
109
+ setter.call(instance, value);
110
+ };
111
+ });
112
+
113
+ result = {
114
+ get: defaultDescriptor.get,
115
+ set() {
116
+ // Do nothing, property is read-only.
117
+ },
118
+ configurable: true,
119
+ enumerable: true
120
+ };
121
+ }
122
+
123
+ if (options.observer) {
124
+ const method = options.observer;
125
+
126
+ // set this method
127
+ this.getOrCreateMap('__observers').set(name, method);
128
+
129
+ this.addCheckedInitializer((instance) => {
130
+ if (!instance[method]) {
131
+ console.warn(`observer method ${method} not defined`);
132
+ }
133
+ });
134
+ }
135
+
136
+ if (options.notify) {
137
+ if (!this.__notifyProps) {
138
+ this.__notifyProps = new Set();
139
+ // eslint-disable-next-line no-prototype-builtins
140
+ } else if (!this.hasOwnProperty('__notifyProps')) {
141
+ // clone any existing observers (superclasses)
142
+ const notifyProps = this.__notifyProps;
143
+ this.__notifyProps = new Set(notifyProps);
144
+ }
145
+
146
+ // set this method
147
+ this.__notifyProps.add(name);
148
+ }
149
+
150
+ if (options.computed) {
151
+ const assignComputedMethod = `__assignComputed${name}`;
152
+ const observer = parseObserver(options.computed);
153
+ this.prototype[assignComputedMethod] = function (...props) {
154
+ this[name] = this[observer.method](...props);
155
+ };
156
+
157
+ this.getOrCreateMap('__complexObservers').set(assignComputedMethod, observer.observerProps);
158
+ }
159
+
160
+ if (!options.attribute) {
161
+ options.attribute = camelToDash(name);
162
+ }
163
+
164
+ return result;
165
+ }
166
+
167
+ /** @protected */
168
+ ready() {
169
+ if (super.ready) {
170
+ super.ready();
171
+ }
172
+ this.$ = this.$ || {};
173
+ this.shadowRoot.querySelectorAll('[id]').forEach((node) => {
174
+ this.$[node.id] = node;
175
+ });
176
+ }
177
+
178
+ /** @protected */
179
+ firstUpdated() {
180
+ super.firstUpdated();
181
+
182
+ this.ready();
183
+ }
184
+
185
+ /** @protected */
186
+ updated(props) {
187
+ if (this.constructor.__observers) {
188
+ this.__runObservers(props, this.constructor.__observers);
189
+ }
190
+
191
+ if (this.constructor.__complexObservers) {
192
+ this.__runComplexObservers(props, this.constructor.__complexObservers);
193
+ }
194
+
195
+ if (this.__dynamicObservers) {
196
+ this.__runComplexObservers(props, this.__dynamicObservers);
197
+ }
198
+
199
+ if (this.constructor.__notifyProps) {
200
+ this.__runNotifyProps(props, this.constructor.__notifyProps);
201
+ }
202
+ }
203
+
204
+ /** @protected */
205
+ _createMethodObserver(observer) {
206
+ const dynamicObservers = getOrCreateMap(this, '__dynamicObservers');
207
+ const { method, observerProps } = parseObserver(observer);
208
+ dynamicObservers.set(method, observerProps);
209
+ }
210
+
211
+ /** @private */
212
+ __runComplexObservers(props, observers) {
213
+ observers.forEach((observerProps, method) => {
214
+ if (observerProps.some((prop) => props.has(prop))) {
215
+ if (!this[method]) {
216
+ console.warn(`observer method ${method} not defined`);
217
+ } else {
218
+ this[method](...observerProps.map((prop) => this[prop]));
219
+ }
220
+ }
221
+ });
222
+ }
223
+
224
+ /** @private */
225
+ __runObservers(props, observers) {
226
+ props.forEach((v, k) => {
227
+ const observer = observers.get(k);
228
+ if (observer !== undefined && this[observer]) {
229
+ this[observer](this[k], v);
230
+ }
231
+ });
232
+ }
233
+
234
+ /** @private */
235
+ __runNotifyProps(props, notifyProps) {
236
+ props.forEach((_, k) => {
237
+ if (notifyProps.has(k)) {
238
+ this.dispatchEvent(
239
+ new CustomEvent(`${camelToDash(k)}-changed`, {
240
+ detail: {
241
+ value: this[k]
242
+ }
243
+ })
244
+ );
245
+ }
246
+ });
247
+ }
248
+
249
+ /** @protected */
250
+ _get(path, object) {
251
+ return path.split('.').reduce((obj, property) => (obj ? obj[property] : undefined), object);
252
+ }
253
+
254
+ /** @protected */
255
+ _set(path, value, object) {
256
+ const pathParts = path.split('.');
257
+ const lastPart = pathParts.pop();
258
+ const target = pathParts.reduce((target, part) => target[part], object);
259
+ target[lastPart] = value;
260
+ }
261
+ }
262
+
263
+ return PolylitMixinClass;
264
+ };
265
+
266
+ export const PolylitMixin = dedupeMixin(PolylitMixinImplementation);