@vanilla-bean/components 1.1.0 → 2.0.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/Component/Component.js +226 -40
- package/Component/Component.scenarios.js +2 -2
- package/Component/Component.test.js +427 -40
- package/Component/README.md +480 -0
- package/Component/observeElementConnection.js +1 -1
- package/Elem/README.md +373 -0
- package/README.md +2 -2
- package/components/BottomSheet/BottomSheet.js +8 -16
- package/components/BottomSheet/README.md +1 -1
- package/components/Button/Button.js +12 -18
- package/components/Button/Button.lld.md +1 -1
- package/components/Calendar/Calendar.js +139 -59
- package/components/Calendar/CalendarEvent.js +9 -4
- package/components/Calendar/Toolbar.js +28 -20
- package/components/Calendar/index.js +1 -0
- package/components/Code/Code.js +26 -30
- package/components/Code/Code.lld.md +1 -1
- package/components/ColorPicker/ColorPicker.js +58 -58
- package/components/Dialog/Dialog.js +79 -73
- package/components/Dialog/Dialog.lld.md +1 -1
- package/components/Dialog/README.md +10 -10
- package/components/Form/Form.js +21 -17
- package/components/Form/Form.lld.md +2 -2
- package/components/Form/README.md +3 -3
- package/components/Icon/Icon.js +19 -11
- package/components/Input/Input.js +85 -67
- package/components/Input/README.md +7 -9
- package/components/Keyboard/Key.js +7 -10
- package/components/Keyboard/Keyboard.js +38 -46
- package/components/Keyboard/Keyboard.lld.md +1 -1
- package/components/Label/Label.js +52 -50
- package/components/Link/Link.js +14 -20
- package/components/List/List.js +28 -30
- package/components/Menu/Menu.js +19 -10
- package/components/Menu/Menu.lld.md +2 -2
- package/components/Notify/Notify.js +29 -19
- package/components/Notify/Notify.lld.md +2 -2
- package/components/Page/Page.lld.md +1 -1
- package/components/Popover/Popover.js +49 -44
- package/components/RadioButton/RadioButton.js +33 -29
- package/components/RadioButton/RadioButton.lld.md +1 -1
- package/components/Router/README.md +12 -12
- package/components/Router/Router.js +19 -21
- package/components/Select/README.md +5 -5
- package/components/Select/Select.js +25 -31
- package/components/Table/README.md +4 -4
- package/components/Table/Table.js +55 -36
- package/components/Table/Table.lld.md +1 -1
- package/components/TagList/Tag.js +16 -14
- package/components/TagList/TagList.js +15 -8
- package/components/TagList/TagList.lld.md +1 -1
- package/components/Tooltip/Tooltip.js +12 -25
- package/components/TooltipWrapper/TooltipWrapper.js +55 -49
- package/components/TooltipWrapper/TooltipWrapper.lld.md +2 -2
- package/components/Whiteboard/Whiteboard.js +45 -43
- package/components/Whiteboard/Whiteboard.lld.md +1 -1
- package/devTools/build.js +43 -0
- package/devTools/buildTypes.js +322 -0
- package/devTools/createComponent.js +155 -0
- package/devTools/extractJSDoc.js +395 -0
- package/devTools/processTemplate.js +500 -0
- package/devTools/updateComponentIndex.js +16 -0
- package/devTools/updateDemoViewIndex.js +90 -0
- package/eslint.config.cjs +5 -2
- package/index.d.ts +120 -62
- package/package.json +23 -22
- package/spellcheck.config.cjs +3 -0
- package/styled/README.md +329 -0
- package/theme/.test.js +2 -2
- package/theme/README.md +8 -8
- package/theme/colors.js +16 -13
- package/theme/colors.test.js +28 -0
- package/utils/browser.js +1 -1
- package/utils/element.js +2 -2
- package/FontWithASyntaxHighlighter-Regular.woff2 +0 -0
package/Component/Component.js
CHANGED
|
@@ -14,7 +14,6 @@ const _internalProperties = new Set([
|
|
|
14
14
|
'elem',
|
|
15
15
|
'tag',
|
|
16
16
|
'defaultOptions',
|
|
17
|
-
'handlers',
|
|
18
17
|
'__registeredEvents',
|
|
19
18
|
'__knownAttributes',
|
|
20
19
|
'__priorityOptions',
|
|
@@ -47,30 +46,169 @@ const commonEvents = new Set([
|
|
|
47
46
|
const defaultOptions = {
|
|
48
47
|
tag: 'div',
|
|
49
48
|
autoRender: true,
|
|
50
|
-
registeredEvents: new Set([]),
|
|
51
|
-
knownAttributes: new Set(['role', 'name', 'colspan', 'anchor', 'popover', 'popovertarget', 'popovertargetaction']),
|
|
52
|
-
get priorityOptions() {
|
|
53
|
-
return new Set(['onConnected', 'textContent', 'content', 'appendTo', 'prependTo', 'value']);
|
|
54
|
-
},
|
|
55
49
|
};
|
|
56
50
|
|
|
51
|
+
const baseKnownAttributes = new Set([
|
|
52
|
+
'role',
|
|
53
|
+
'name',
|
|
54
|
+
'colspan',
|
|
55
|
+
'anchor',
|
|
56
|
+
'popover',
|
|
57
|
+
'popovertarget',
|
|
58
|
+
'popovertargetaction',
|
|
59
|
+
]);
|
|
60
|
+
const basePriorityOptions = new Set(['onConnected', 'textContent', 'content', 'appendTo', 'prependTo', 'value']);
|
|
61
|
+
|
|
62
|
+
const _staticsCache = new WeakMap();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Collects a static field's own values up the constructor chain, leaf class first,
|
|
66
|
+
* stopping before Component. The single walk behind every schema mechanism.
|
|
67
|
+
* Results are cached per leaf class - static declarations are treated as immutable
|
|
68
|
+
* after a class's first construction.
|
|
69
|
+
* @param {Function} klass - Leaf constructor (new.target or this.constructor) to walk from
|
|
70
|
+
* @param {string} name - Static field name ('schema', 'events', 'prepareOptions')
|
|
71
|
+
* @returns {Array<*>} Own static values from leaf to root
|
|
72
|
+
*/
|
|
73
|
+
const collectStatics = (klass, name) => {
|
|
74
|
+
let cache = _staticsCache.get(klass);
|
|
75
|
+
if (cache?.[name]) return cache[name];
|
|
76
|
+
|
|
77
|
+
const values = [];
|
|
78
|
+
let current = klass;
|
|
79
|
+
|
|
80
|
+
while (current && current !== Component) {
|
|
81
|
+
if (Object.prototype.hasOwnProperty.call(current, name) && current[name]) values.push(current[name]);
|
|
82
|
+
current = Object.getPrototypeOf(current);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!cache) _staticsCache.set(klass, (cache = {}));
|
|
86
|
+
cache[name] = values;
|
|
87
|
+
|
|
88
|
+
return values;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Collects `default` values from static schemas up the constructor chain.
|
|
93
|
+
* Parent schemas apply first so child classes override per-key. Descriptor `default`
|
|
94
|
+
* is read at construction time, so getter defaults (e.g. `get default() { return document.body; }`)
|
|
95
|
+
* evaluate fresh per instance.
|
|
96
|
+
* @param {Function} klass - Leaf constructor (new.target) to walk from
|
|
97
|
+
* @returns {object} Merged default values keyed by option name
|
|
98
|
+
*/
|
|
99
|
+
const collectSchemaDefaults = klass => {
|
|
100
|
+
const defaults = {};
|
|
101
|
+
|
|
102
|
+
// Copied before reversing - the collected array is cached and must stay leaf-first
|
|
103
|
+
for (const schema of [...collectStatics(klass, 'schema')].reverse()) {
|
|
104
|
+
for (const [key, descriptor] of Object.entries(schema)) {
|
|
105
|
+
if (descriptor && 'default' in descriptor) defaults[key] = descriptor.default;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return defaults;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Collects schema keys carrying a given flag (e.g. `attribute`, `priority`) up the constructor chain.
|
|
114
|
+
* The nearest class whose descriptor declares the flag decides, so a subclass can opt out
|
|
115
|
+
* of a parent's flag with e.g. `attribute: false`.
|
|
116
|
+
* @param {Function} klass - Leaf constructor to walk from
|
|
117
|
+
* @param {string} flag - Descriptor flag name to collect
|
|
118
|
+
* @returns {Set<string>} Option keys with the flag enabled
|
|
119
|
+
*/
|
|
120
|
+
const collectSchemaFlags = (klass, flag) => {
|
|
121
|
+
const keys = new Set();
|
|
122
|
+
const decided = new Set();
|
|
123
|
+
|
|
124
|
+
for (const schema of collectStatics(klass, 'schema')) {
|
|
125
|
+
for (const [key, descriptor] of Object.entries(schema)) {
|
|
126
|
+
if (descriptor && flag in descriptor && !decided.has(key)) {
|
|
127
|
+
decided.add(key);
|
|
128
|
+
if (descriptor[flag]) keys.add(key);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return keys;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Collects `static events` declarations up the constructor chain into one union.
|
|
138
|
+
* @param {Function} klass - Leaf constructor to walk from
|
|
139
|
+
* @returns {Set<string>} Union of every class's declared event names
|
|
140
|
+
*/
|
|
141
|
+
const collectStaticEvents = klass => new Set(collectStatics(klass, 'events').flat());
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Runs `static prepareOptions(options, children)` hooks leaf-first up the constructor chain.
|
|
145
|
+
* Hooks receive the merged (schema defaults + user) options and return a transformed copy,
|
|
146
|
+
* which handles computed defaults that previously required a constructor.
|
|
147
|
+
* @param {Function} klass - Leaf constructor to walk from
|
|
148
|
+
* @param {object} options - Merged options to transform
|
|
149
|
+
* @param {Array} children - Constructor children, for hooks that derive options from them
|
|
150
|
+
* @returns {object} Transformed options
|
|
151
|
+
*/
|
|
152
|
+
const runPrepareOptions = (klass, options, children) => {
|
|
153
|
+
for (const prepare of collectStatics(klass, 'prepareOptions')) {
|
|
154
|
+
options = prepare(options, children) ?? options;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return options;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const union = (base, additions) => (additions.size > 0 ? new Set([...(base || []), ...additions]) : base);
|
|
161
|
+
|
|
57
162
|
/**
|
|
58
163
|
* General purpose reactive component with automatic cleanup and lifecycle management.
|
|
59
164
|
* Extends Elem with Oxject-driven options, event handling, and style processing.
|
|
165
|
+
*
|
|
166
|
+
* Subclasses declare their option schema once via `static schema` - each key maps to a
|
|
167
|
+
* descriptor defining what the option is:
|
|
168
|
+
* - `default` - initial value, merged automatically (child classes override parents per-key)
|
|
169
|
+
* - `set(value, next)` - change handler, chained deepest-class-first;
|
|
170
|
+
* omit `next()` to own the key, call it to continue down the chain
|
|
171
|
+
* - `attribute: true` - routed to elem.setAttribute
|
|
172
|
+
* - `priority: true` - processed before other keys during render
|
|
173
|
+
* - `data: true` - force store-only routing; needed only when a data key's name collides
|
|
174
|
+
* with a real DOM property that standard routing would otherwise hit
|
|
175
|
+
* - `enum: [...]` - valid values; assigning anything else (other than null/undefined) throws.
|
|
176
|
+
* Readable via optionEnum(key)
|
|
177
|
+
*
|
|
178
|
+
* Declared keys route through standard option processing (elem properties, events, methods)
|
|
179
|
+
* when a real match exists, so DOM-bound defaults still reach the element - but they never
|
|
180
|
+
* fall through to guessing: with no match they live in this.options, silently. Undeclared
|
|
181
|
+
* keys keep the full fallback behavior including the dev warning.
|
|
182
|
+
*
|
|
183
|
+
* Two more statics:
|
|
184
|
+
* - `static events = ['select']` - custom event names usable with on()/emit(); collected as a
|
|
185
|
+
* union up the class chain, so subclasses add to their parents' events instead of replacing them
|
|
186
|
+
* - `static prepareOptions(options, children)` - pure transform of the merged
|
|
187
|
+
* (schema defaults + user) options, run leaf-first, for computed defaults that
|
|
188
|
+
* would otherwise require a constructor
|
|
189
|
+
* @example
|
|
190
|
+
* static schema = {
|
|
191
|
+
* tag: { default: 'canvas' },
|
|
192
|
+
* background: { default: '#FFF', set(value) { this.elem.style.background = value; } },
|
|
193
|
+
* color: { default: '#000' },
|
|
194
|
+
* };
|
|
195
|
+
* static events = ['line', 'draw'];
|
|
196
|
+
* static prepareOptions(options) {
|
|
197
|
+
* return { ...options, style: { cursor: 'crosshair', ...options.style } };
|
|
198
|
+
* }
|
|
60
199
|
* @augments Elem
|
|
61
200
|
* @augments EventTarget
|
|
62
201
|
*/
|
|
63
202
|
class Component extends Elem {
|
|
64
|
-
defaultOptions
|
|
203
|
+
get defaultOptions() {
|
|
204
|
+
return { ...defaultOptions, ...collectSchemaDefaults(this.constructor) };
|
|
205
|
+
}
|
|
65
206
|
|
|
66
207
|
/**
|
|
67
208
|
* Creates reactive component with Oxject-driven options, automatic cleanup, and lifecycle management.
|
|
68
209
|
* @param {object} [options] - Component configuration object with reactive properties
|
|
69
210
|
* @param {string} [options.tag] - HTML tag name for the root element
|
|
70
211
|
* @param {boolean|'onload'|'animationFrame'} [options.autoRender] - Render timing: true (immediate), 'onload' (window load), 'animationFrame' (next frame), false (manual)
|
|
71
|
-
* @param {Set<string>} [options.registeredEvents] - Additional event types to handle via on() method
|
|
72
|
-
* @param {Set<string>} [options.knownAttributes] - Attribute names routed to elem.setAttribute() instead of property assignment
|
|
73
|
-
* @param {Set<string>} [options.priorityOptions] - Option keys processed first during render
|
|
74
212
|
* @param {object} [options.style] - Inline CSS properties applied as HTMLElement.style
|
|
75
213
|
* @param {object} [options.attributes] - HTML attributes applied via setAttribute()
|
|
76
214
|
* @param {string|object|Function} [options.styles] - CSS definition: string/function processed through theme system, object applied inline
|
|
@@ -84,16 +222,21 @@ class Component extends Elem {
|
|
|
84
222
|
* @returns {Component} Component instance with reactive options accessible via this.options
|
|
85
223
|
*/
|
|
86
224
|
constructor(options = {}, ...children) {
|
|
87
|
-
const { tag, autoRender,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
225
|
+
const { tag, autoRender, ...optionsWithoutConfig } = runPrepareOptions(
|
|
226
|
+
new.target,
|
|
227
|
+
{
|
|
228
|
+
...defaultOptions,
|
|
229
|
+
...collectSchemaDefaults(new.target),
|
|
230
|
+
...options,
|
|
231
|
+
},
|
|
232
|
+
children,
|
|
233
|
+
);
|
|
91
234
|
|
|
92
235
|
super({ tag });
|
|
93
236
|
|
|
94
|
-
this.__registeredEvents =
|
|
95
|
-
this.__knownAttributes =
|
|
96
|
-
this.__priorityOptions =
|
|
237
|
+
this.__registeredEvents = collectStaticEvents(new.target);
|
|
238
|
+
this.__knownAttributes = union(baseKnownAttributes, collectSchemaFlags(new.target, 'attribute'));
|
|
239
|
+
this.__priorityOptions = union(basePriorityOptions, collectSchemaFlags(new.target, 'priority'));
|
|
97
240
|
|
|
98
241
|
this.elem._component = this;
|
|
99
242
|
|
|
@@ -139,7 +282,7 @@ class Component extends Elem {
|
|
|
139
282
|
if (this.constructor !== Component && this.constructor.prototype.hasOwnProperty('render')) {
|
|
140
283
|
// eslint-disable-next-line no-console
|
|
141
284
|
console.warn(
|
|
142
|
-
`[Component] ${this.constructor.name} overrides render(). Structure belongs in build()
|
|
285
|
+
`[Component] ${this.constructor.name} overrides render(). Structure belongs in build() - render() is the lifecycle orchestrator.`,
|
|
143
286
|
);
|
|
144
287
|
}
|
|
145
288
|
}
|
|
@@ -154,7 +297,7 @@ class Component extends Elem {
|
|
|
154
297
|
}
|
|
155
298
|
|
|
156
299
|
/**
|
|
157
|
-
* Subclass structural hook
|
|
300
|
+
* Subclass structural hook - override to create child elements and component structure.
|
|
158
301
|
* Called by render() before options are processed, so all structure exists
|
|
159
302
|
* before _setOption receives values.
|
|
160
303
|
*/
|
|
@@ -201,48 +344,73 @@ class Component extends Elem {
|
|
|
201
344
|
}
|
|
202
345
|
|
|
203
346
|
/**
|
|
204
|
-
* Routes option changes through the
|
|
347
|
+
* Routes option changes through the schema set chain, then standard routing.
|
|
205
348
|
*
|
|
206
|
-
* Walks the constructor chain collecting
|
|
207
|
-
* first), then executes them in order. Each
|
|
208
|
-
* to continue to the next
|
|
209
|
-
* is exhausted.
|
|
349
|
+
* Walks the constructor chain collecting every `static schema` set function for the
|
|
350
|
+
* given key (deepest class first), then executes them in order. Each receives
|
|
351
|
+
* `next(value?)` - call it to continue to the next in the chain, or to standard
|
|
352
|
+
* routing when the chain is exhausted. Not calling `next` fully owns the key.
|
|
353
|
+
* Keys flagged `data: true` never reach standard routing at all.
|
|
210
354
|
* @param {string} key - Option property name being changed
|
|
211
355
|
* @param {*} value - New value being assigned to the option
|
|
212
356
|
* @private
|
|
213
357
|
*/
|
|
214
358
|
_setOption(key, value) {
|
|
215
359
|
const chain = [];
|
|
216
|
-
let
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
360
|
+
let dataOption;
|
|
361
|
+
let enumValues;
|
|
362
|
+
let enumDecided = false;
|
|
363
|
+
|
|
364
|
+
// set functions chain across the class hierarchy; scalar fields (data, enum) are
|
|
365
|
+
// decided by the nearest class whose descriptor declares them, so subclasses can
|
|
366
|
+
// opt out with data: false or enum: null
|
|
367
|
+
let declared = false;
|
|
368
|
+
for (const schema of collectStatics(this.constructor, 'schema')) {
|
|
369
|
+
const descriptor = schema[key];
|
|
370
|
+
if (!descriptor) continue;
|
|
371
|
+
declared = true;
|
|
372
|
+
if (descriptor.set) chain.push(descriptor.set);
|
|
373
|
+
if (dataOption === undefined && 'data' in descriptor) dataOption = !!descriptor.data;
|
|
374
|
+
if (!enumDecided && 'enum' in descriptor) {
|
|
375
|
+
enumDecided = true;
|
|
376
|
+
enumValues = descriptor.enum;
|
|
220
377
|
}
|
|
221
|
-
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (enumValues && value !== undefined && value !== null && !enumValues.includes(value)) {
|
|
381
|
+
throw new Error(
|
|
382
|
+
`"${value}" is not a valid ${key}. The ${key} must be one of the following values: ${enumValues.join(', ')}`,
|
|
383
|
+
);
|
|
222
384
|
}
|
|
223
385
|
|
|
224
386
|
if (chain.length > 0) {
|
|
225
387
|
let i = 0;
|
|
226
388
|
const next = (v = value) => {
|
|
227
389
|
if (i < chain.length) chain[i++].call(this, v, next);
|
|
228
|
-
else this._standardSetOption(key, v);
|
|
390
|
+
else if (!dataOption) this._standardSetOption(key, v, declared);
|
|
229
391
|
};
|
|
230
392
|
chain[i++].call(this, value, next);
|
|
231
393
|
return;
|
|
232
394
|
}
|
|
233
395
|
|
|
234
|
-
|
|
396
|
+
if (dataOption) return;
|
|
397
|
+
this._standardSetOption(key, value, declared);
|
|
235
398
|
}
|
|
236
399
|
|
|
237
400
|
/**
|
|
238
|
-
* Standard option routing pipeline
|
|
239
|
-
* Called by _setOption when no
|
|
401
|
+
* Standard option routing pipeline - event handlers, special keys, attributes, methods, properties.
|
|
402
|
+
* Called by _setOption when no set claims the key, or when a set calls next() past
|
|
240
403
|
* the end of its chain.
|
|
404
|
+
*
|
|
405
|
+
* Declared keys never fall through to guessing: they route to a real match (elem property,
|
|
406
|
+
* registered event, attribute) or stay store-only, silently. The unknown-key warning and
|
|
407
|
+
* elem expando assignment apply only to undeclared keys.
|
|
241
408
|
* @param {string} key - Option property name
|
|
242
409
|
* @param {*} value - Value to apply
|
|
410
|
+
* @param {boolean} [declared] - Whether any class's schema declares this key
|
|
243
411
|
* @private
|
|
244
412
|
*/
|
|
245
|
-
_standardSetOption(key, value) {
|
|
413
|
+
_standardSetOption(key, value, declared = false) {
|
|
246
414
|
if (key === 'onRendered') {
|
|
247
415
|
this.onRendered = value;
|
|
248
416
|
return;
|
|
@@ -252,15 +420,17 @@ class Component extends Elem {
|
|
|
252
420
|
const targetEvent = key.replace(/^on/, '').toLowerCase();
|
|
253
421
|
if (this.on({ targetEvent, id: key, callback: value })) return;
|
|
254
422
|
if (typeof this[key] !== 'function') {
|
|
255
|
-
|
|
423
|
+
// Declared callback options (e.g. onSort, onButtonPress) live in this.options,
|
|
424
|
+
// invoked by the component itself rather than the event system
|
|
425
|
+
if (!declared && isDev) {
|
|
256
426
|
// eslint-disable-next-line no-console
|
|
257
427
|
console.warn(
|
|
258
|
-
`Component._setOption(): "${key}" starts with "on" but "${targetEvent}" is not a recognized event and there is no "${key}" method. Add "${targetEvent}" to
|
|
428
|
+
`Component._setOption(): "${key}" starts with "on" but "${targetEvent}" is not a recognized event and there is no "${key}" method. Add "${targetEvent}" to static events to register it as a custom event.`,
|
|
259
429
|
);
|
|
260
430
|
}
|
|
261
431
|
return;
|
|
262
432
|
}
|
|
263
|
-
// method route
|
|
433
|
+
// method route - e.g. onPointerPress, onHover
|
|
264
434
|
}
|
|
265
435
|
|
|
266
436
|
if (key === 'uniqueId') this.elem.id = typeof value === 'string' ? value : this.uniqueId;
|
|
@@ -277,18 +447,34 @@ class Component extends Elem {
|
|
|
277
447
|
if (value?.elem) value = value.elem;
|
|
278
448
|
|
|
279
449
|
this.elem[key].call(this.elem, value);
|
|
280
|
-
} else if (typeof value === 'function')
|
|
281
|
-
|
|
450
|
+
} else if (typeof value === 'function') {
|
|
451
|
+
if (declared) return;
|
|
452
|
+
this[key] = value;
|
|
453
|
+
} else {
|
|
454
|
+
if (!(key in this.elem) && declared) return;
|
|
282
455
|
if (isDev && !(key in this.elem)) {
|
|
283
456
|
// eslint-disable-next-line no-console
|
|
284
457
|
console.warn(
|
|
285
|
-
`Component._setOption(): unknown key "${key}" assigned directly to elem. If intentional,
|
|
458
|
+
`Component._setOption(): unknown key "${key}" assigned directly to elem. If intentional, declare it in the static schema.`,
|
|
286
459
|
);
|
|
287
460
|
}
|
|
288
461
|
this.elem[key] = value;
|
|
289
462
|
}
|
|
290
463
|
}
|
|
291
464
|
|
|
465
|
+
/**
|
|
466
|
+
* Looks up the declared enum for an option key from the schema chain (nearest class wins).
|
|
467
|
+
* @param {string} key - Option property name
|
|
468
|
+
* @returns {Array<*>|undefined} Valid values declared for the key, or undefined if unconstrained
|
|
469
|
+
*/
|
|
470
|
+
optionEnum(key) {
|
|
471
|
+
for (const schema of collectStatics(this.constructor, 'schema')) {
|
|
472
|
+
if (schema[key]?.enum) return schema[key].enum;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return undefined;
|
|
476
|
+
}
|
|
477
|
+
|
|
292
478
|
/**
|
|
293
479
|
* Get parent Component instance.
|
|
294
480
|
* @returns {Component|undefined} Parent component or undefined if none
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Component from './Component.js';
|
|
2
2
|
|
|
3
3
|
export const __lld_api = `
|
|
4
|
-
destructiveRender() -> boolean | renders a component twice; returns true if child count matches (1)
|
|
4
|
+
destructiveRender() -> boolean | renders a component twice; returns true if child count matches (1) - second render cleared the first
|
|
5
5
|
optionReactionFires() -> number | assigns to option after render; returns how many times _setOption was called (1 = reactive)
|
|
6
6
|
buildBeforeOptions() -> boolean | verifies build() DOM structure exists when _setOption runs (true = ordering is correct)
|
|
7
7
|
priorityRunsFirst() -> boolean | textContent (priority option) runs before style (non-priority); returns true if correct order
|
|
@@ -84,5 +84,5 @@ export const replaceCleanupRunsOnce = () => {
|
|
|
84
84
|
}); // runs previous = 2, stores latest
|
|
85
85
|
const countBeforeCleanup = count;
|
|
86
86
|
comp.processCleanup(); // runs only the latest = 3
|
|
87
|
-
return count - countBeforeCleanup; // 1
|
|
87
|
+
return count - countBeforeCleanup; // 1 - only latest ran at cleanup time
|
|
88
88
|
};
|