@rettangoli/fe 0.0.14 → 1.0.0-rc1
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 +24 -8
- package/package.json +9 -3
- package/src/cli/blank/blank.handlers.js +5 -2
- package/src/cli/blank/blank.schema.yaml +11 -0
- package/src/cli/blank/blank.view.yaml +0 -11
- package/src/cli/build.js +55 -23
- package/src/cli/check.js +53 -0
- package/src/cli/contracts.js +143 -0
- package/src/cli/index.js +5 -11
- package/src/cli/scaffold.js +6 -0
- package/src/cli/watch.js +3 -2
- package/src/core/contracts/componentFiles.js +119 -0
- package/src/core/runtime/componentOrchestrator.js +156 -0
- package/src/core/runtime/componentRuntime.js +54 -0
- package/src/core/runtime/constants.js +27 -0
- package/src/core/runtime/events.js +191 -0
- package/src/core/runtime/globalListeners.js +87 -0
- package/src/core/runtime/lifecycle.js +124 -0
- package/src/core/runtime/methods.js +40 -0
- package/src/core/runtime/payload.js +3 -0
- package/src/core/runtime/props.js +79 -0
- package/src/core/runtime/refs.js +70 -0
- package/src/core/runtime/store.js +42 -0
- package/src/core/schema/validateSchemaContract.js +26 -0
- package/src/core/style/yamlToCss.js +44 -0
- package/src/core/view/bindings.js +189 -0
- package/src/core/view/refs.js +234 -0
- package/src/createComponent.js +37 -518
- package/src/parser.js +83 -249
- package/src/web/componentDom.js +49 -0
- package/src/web/componentUpdateHook.js +43 -0
- package/src/web/createWebComponentClass.js +150 -0
- package/src/web/scheduler.js +6 -0
package/src/createComponent.js
CHANGED
|
@@ -1,485 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
'button':
|
|
12
|
-
background-color: var(--background)
|
|
13
|
-
font-size: var(--sm-font-size)
|
|
14
|
-
font-weight: var(--sm-font-weight)
|
|
15
|
-
line-height: var(--sm-line-height)
|
|
16
|
-
letter-spacing: var(--sm-letter-spacing)
|
|
17
|
-
border: 1px solid var(--ring)
|
|
18
|
-
border-radius: var(--border-radius-lg)
|
|
19
|
-
padding-left: var(--spacing-md)
|
|
20
|
-
padding-right: var(--spacing-md)
|
|
21
|
-
height: 32px
|
|
22
|
-
color: var(--foreground)
|
|
23
|
-
outline: none
|
|
24
|
-
cursor: pointer
|
|
25
|
-
'button:focus':
|
|
26
|
-
border-color: var(--foreground)
|
|
27
|
-
'@media (min-width: 768px)':
|
|
28
|
-
'button':
|
|
29
|
-
height: 40px
|
|
30
|
-
* @param {*} styleObject
|
|
31
|
-
* @returns
|
|
32
|
-
*/
|
|
33
|
-
const yamlToCss = (elementName, styleObject) => {
|
|
34
|
-
if (!styleObject || typeof styleObject !== "object") {
|
|
35
|
-
return "";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let css = ``;
|
|
39
|
-
const convertPropertiesToCss = (properties) => {
|
|
40
|
-
return Object.entries(properties)
|
|
41
|
-
.map(([property, value]) => ` ${property}: ${value};`)
|
|
42
|
-
.join("\n");
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const processSelector = (selector, rules) => {
|
|
46
|
-
if (typeof rules !== "object" || rules === null) {
|
|
47
|
-
return "";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Check if this is an @ rule (like @media, @keyframes, etc.)
|
|
51
|
-
if (selector.startsWith("@")) {
|
|
52
|
-
const nestedCss = Object.entries(rules)
|
|
53
|
-
.map(([nestedSelector, nestedRules]) => {
|
|
54
|
-
const nestedProperties = convertPropertiesToCss(nestedRules);
|
|
55
|
-
return ` ${nestedSelector} {\n${nestedProperties
|
|
56
|
-
.split("\n")
|
|
57
|
-
.map((line) => (line ? ` ${line}` : ""))
|
|
58
|
-
.join("\n")}\n }`;
|
|
59
|
-
})
|
|
60
|
-
.join("\n");
|
|
61
|
-
|
|
62
|
-
return `${selector} {\n${nestedCss}\n}`;
|
|
63
|
-
} else {
|
|
64
|
-
// Regular selector
|
|
65
|
-
const properties = convertPropertiesToCss(rules);
|
|
66
|
-
return `${selector} {\n${properties}\n}`;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Process all top-level selectors
|
|
71
|
-
Object.entries(styleObject).forEach(([selector, rules]) => {
|
|
72
|
-
const selectorCss = processSelector(selector, rules);
|
|
73
|
-
if (selectorCss) {
|
|
74
|
-
css += (css ? "\n\n" : "") + selectorCss;
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return css;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Subscribes to all observables and returns a function that will unsubscribe
|
|
83
|
-
* from all observables when called
|
|
84
|
-
* @param {*} observables
|
|
85
|
-
* @returns
|
|
86
|
-
*/
|
|
87
|
-
const subscribeAll = (observables) => {
|
|
88
|
-
// Subscribe to all observables and store the subscription objects
|
|
89
|
-
const subscriptions = observables.map((observable) => observable.subscribe());
|
|
90
|
-
|
|
91
|
-
// Return a function that will unsubscribe from all observables when called
|
|
92
|
-
return () => {
|
|
93
|
-
for (const subscription of subscriptions) {
|
|
94
|
-
if (subscription && typeof subscription.unsubscribe === "function") {
|
|
95
|
-
subscription.unsubscribe();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
function createAttrsProxy(source) {
|
|
103
|
-
return new Proxy(
|
|
104
|
-
{},
|
|
105
|
-
{
|
|
106
|
-
get(_, prop) {
|
|
107
|
-
if (typeof prop === "string") {
|
|
108
|
-
const value = source.getAttribute(prop);
|
|
109
|
-
// Return true for boolean attributes (empty string values)
|
|
110
|
-
return value === "" ? true : value;
|
|
111
|
-
}
|
|
112
|
-
return undefined;
|
|
113
|
-
},
|
|
114
|
-
set() {
|
|
115
|
-
throw new Error("Cannot assign to read-only proxy");
|
|
116
|
-
},
|
|
117
|
-
defineProperty() {
|
|
118
|
-
throw new Error("Cannot define properties on read-only proxy");
|
|
119
|
-
},
|
|
120
|
-
deleteProperty() {
|
|
121
|
-
throw new Error("Cannot delete properties from read-only proxy");
|
|
122
|
-
},
|
|
123
|
-
has(_, prop) {
|
|
124
|
-
return typeof prop === "string" && source.hasAttribute(prop);
|
|
125
|
-
},
|
|
126
|
-
ownKeys() {
|
|
127
|
-
return source.getAttributeNames();
|
|
128
|
-
},
|
|
129
|
-
getOwnPropertyDescriptor(_, prop) {
|
|
130
|
-
if (typeof prop === "string" && source.hasAttribute(prop)) {
|
|
131
|
-
return {
|
|
132
|
-
configurable: true,
|
|
133
|
-
enumerable: true,
|
|
134
|
-
get: () => source.getAttribute(prop),
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
return undefined;
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Creates a read-only proxy object that only allows access to specified properties from the source object
|
|
145
|
-
* Props are directly attached to the web-component element for example this.title
|
|
146
|
-
* We don't want to expose the whole web compoenent but only want to expose the props
|
|
147
|
-
* createPropsProxy(this, ['title']) will expose only the title
|
|
148
|
-
* @param {Object} source - The source object to create a proxy from
|
|
149
|
-
* @param {string[]} allowedKeys - Array of property names that are allowed to be accessed
|
|
150
|
-
* @returns {Proxy} A read-only proxy object that only allows access to the specified properties
|
|
151
|
-
* @throws {Error} When attempting to modify the proxy object
|
|
152
|
-
*/
|
|
153
|
-
function createPropsProxy(source, allowedKeys) {
|
|
154
|
-
// return source;
|
|
155
|
-
const allowed = new Set(allowedKeys);
|
|
156
|
-
return new Proxy(
|
|
157
|
-
{},
|
|
158
|
-
{
|
|
159
|
-
get(_, prop) {
|
|
160
|
-
if (typeof prop === "string" && allowed.has(prop)) {
|
|
161
|
-
return source[prop];
|
|
162
|
-
}
|
|
163
|
-
return undefined;
|
|
164
|
-
},
|
|
165
|
-
set() {
|
|
166
|
-
throw new Error("Cannot assign to read-only proxy");
|
|
167
|
-
},
|
|
168
|
-
defineProperty() {
|
|
169
|
-
throw new Error("Cannot define properties on read-only proxy");
|
|
170
|
-
},
|
|
171
|
-
deleteProperty() {
|
|
172
|
-
throw new Error("Cannot delete properties from read-only proxy");
|
|
173
|
-
},
|
|
174
|
-
has(_, prop) {
|
|
175
|
-
return typeof prop === "string" && allowed.has(prop);
|
|
176
|
-
},
|
|
177
|
-
ownKeys() {
|
|
178
|
-
return [...allowed];
|
|
179
|
-
},
|
|
180
|
-
getOwnPropertyDescriptor(_, prop) {
|
|
181
|
-
if (typeof prop === "string" && allowed.has(prop)) {
|
|
182
|
-
return {
|
|
183
|
-
configurable: true,
|
|
184
|
-
enumerable: true,
|
|
185
|
-
get: () => source[prop],
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
return undefined;
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Base class for web components
|
|
196
|
-
* Connects web compnent with the rettangoli framework
|
|
197
|
-
*/
|
|
198
|
-
class BaseComponent extends HTMLElement {
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* @type {string}
|
|
202
|
-
*/
|
|
203
|
-
elementName;
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* @type {Object}
|
|
207
|
-
*/
|
|
208
|
-
styles;
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* @type {Function}
|
|
212
|
-
*/
|
|
213
|
-
h;
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @type {Object}
|
|
217
|
-
*/
|
|
218
|
-
store;
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* @type {Object}
|
|
222
|
-
*/
|
|
223
|
-
props;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* @type {Object}
|
|
227
|
-
*/
|
|
228
|
-
propsSchema;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* @type {Object}
|
|
232
|
-
*/
|
|
233
|
-
template;
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* @type {Object}
|
|
237
|
-
*/
|
|
238
|
-
handlers;
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* @type {Object}
|
|
242
|
-
*/
|
|
243
|
-
transformedHandlers = {};
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* @type {Object}
|
|
247
|
-
*/
|
|
248
|
-
refs;
|
|
249
|
-
refIds = {};
|
|
250
|
-
patch;
|
|
251
|
-
_unmountCallback;
|
|
252
|
-
_oldVNode;
|
|
253
|
-
deps;
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* @type {string}
|
|
257
|
-
*/
|
|
258
|
-
cssText;
|
|
259
|
-
|
|
260
|
-
static get observedAttributes() {
|
|
261
|
-
return ["key"];
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
get viewData() {
|
|
265
|
-
let data = {};
|
|
266
|
-
if (this.store.selectViewData) {
|
|
267
|
-
data = this.store.selectViewData();
|
|
268
|
-
}
|
|
269
|
-
return data;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
connectedCallback() {
|
|
273
|
-
this.shadow = this.attachShadow({ mode: "open" });
|
|
274
|
-
|
|
275
|
-
const commonStyleSheet = new CSSStyleSheet();
|
|
276
|
-
commonStyleSheet.replaceSync(`
|
|
277
|
-
a, a:link, a:visited, a:hover, a:active {
|
|
278
|
-
display: contents;
|
|
279
|
-
color: inherit;
|
|
280
|
-
text-decoration: none;
|
|
281
|
-
background: none;
|
|
282
|
-
border: none;
|
|
283
|
-
padding: 0;
|
|
284
|
-
margin: 0;
|
|
285
|
-
font: inherit;
|
|
286
|
-
cursor: pointer;
|
|
287
|
-
}
|
|
288
|
-
`);
|
|
289
|
-
|
|
290
|
-
const adoptedStyleSheets = [commonStyleSheet];
|
|
291
|
-
|
|
292
|
-
if (this.cssText) {
|
|
293
|
-
const styleSheet = new CSSStyleSheet();
|
|
294
|
-
styleSheet.replaceSync(this.cssText);
|
|
295
|
-
adoptedStyleSheets.push(styleSheet);
|
|
296
|
-
}
|
|
297
|
-
this.shadow.adoptedStyleSheets = adoptedStyleSheets;
|
|
298
|
-
this.renderTarget = document.createElement("div");
|
|
299
|
-
this.renderTarget.style.cssText = "display: contents;";
|
|
300
|
-
this.shadow.appendChild(this.renderTarget);
|
|
301
|
-
if (!this.renderTarget.parentNode) {
|
|
302
|
-
this.appendChild(this.renderTarget);
|
|
303
|
-
}
|
|
304
|
-
this.style.display = "contents";
|
|
305
|
-
const deps = {
|
|
306
|
-
...this.deps,
|
|
307
|
-
refIds: this.refIds,
|
|
308
|
-
getRefIds: () => this.refIds,
|
|
309
|
-
dispatchEvent: this.dispatchEvent.bind(this),
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
this.transformedHandlers = {
|
|
313
|
-
handleCallStoreAction: (payload) => {
|
|
314
|
-
const { render, store } = deps;
|
|
315
|
-
const { _event, _action } = payload;
|
|
316
|
-
const context = parseAndRender(payload, {
|
|
317
|
-
event: _event
|
|
318
|
-
})
|
|
319
|
-
console.log('context', context)
|
|
320
|
-
if (!store[_action]) {
|
|
321
|
-
throw new Error(`store action store.${store._action} is not defined`)
|
|
322
|
-
}
|
|
323
|
-
store[_action](context);
|
|
324
|
-
render();
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
// TODO don't include onmount, subscriptions, etc in transformedHandlers
|
|
328
|
-
Object.keys(this.handlers || {}).forEach((key) => {
|
|
329
|
-
this.transformedHandlers[key] = (event, payload) => {
|
|
330
|
-
const result = this.handlers[key](deps, event, payload);
|
|
331
|
-
return result;
|
|
332
|
-
};
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
if (this.handlers?.handleBeforeMount) {
|
|
336
|
-
this._unmountCallback = this.handlers?.handleBeforeMount(deps);
|
|
337
|
-
|
|
338
|
-
// Validate that handleBeforeMount doesn't return a Promise
|
|
339
|
-
if (this._unmountCallback && typeof this._unmountCallback.then === 'function') {
|
|
340
|
-
throw new Error('handleBeforeMount must be synchronous and cannot return a Promise.');
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
this.render();
|
|
345
|
-
|
|
346
|
-
if (this.handlers?.handleAfterMount) {
|
|
347
|
-
this.handlers?.handleAfterMount(deps);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (this.handlers?.subscriptions) {
|
|
351
|
-
this.unsubscribeAll = subscribeAll(this.handlers.subscriptions(deps));
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
disconnectedCallback() {
|
|
356
|
-
if (this._unmountCallback) {
|
|
357
|
-
this._unmountCallback();
|
|
358
|
-
}
|
|
359
|
-
if (this.unsubscribeAll) {
|
|
360
|
-
this.unsubscribeAll();
|
|
361
|
-
}
|
|
1
|
+
import { toCamelCase } from "./core/runtime/props.js";
|
|
2
|
+
import { validateSchemaContract } from "./core/schema/validateSchemaContract.js";
|
|
3
|
+
import { createWebComponentClass } from "./web/createWebComponentClass.js";
|
|
4
|
+
|
|
5
|
+
const createComponent = (
|
|
6
|
+
{ handlers, methods, constants, schema, view, store, patch, h },
|
|
7
|
+
deps,
|
|
8
|
+
) => {
|
|
9
|
+
if (!view) {
|
|
10
|
+
throw new Error("view is not defined");
|
|
362
11
|
}
|
|
363
12
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
// Call handleOnUpdate if it exists
|
|
367
|
-
if (this.handlers?.handleOnUpdate) {
|
|
368
|
-
const deps = {
|
|
369
|
-
...this.deps,
|
|
370
|
-
refIds: this.refIds,
|
|
371
|
-
getRefIds: () => this.refIds,
|
|
372
|
-
dispatchEvent: this.dispatchEvent.bind(this),
|
|
373
|
-
store: this.store,
|
|
374
|
-
render: this.render.bind(this),
|
|
375
|
-
};
|
|
376
|
-
const changes = {
|
|
377
|
-
oldAttrs: { [name]: oldValue },
|
|
378
|
-
newAttrs: { [name]: newValue },
|
|
379
|
-
oldProps: deps.props,
|
|
380
|
-
newProps: deps.props,
|
|
381
|
-
};
|
|
382
|
-
this.handlers.handleOnUpdate(deps, changes);
|
|
383
|
-
} else {
|
|
384
|
-
requestAnimationFrame(() => {
|
|
385
|
-
this.render();
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
}
|
|
13
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
|
|
14
|
+
throw new Error("schema is required. Define component metadata in .schema.yaml.");
|
|
389
15
|
}
|
|
390
16
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
console.error("Patch function is not defined!");
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
17
|
+
const resolvedSchema = schema;
|
|
18
|
+
const { template, refs, styles } = view;
|
|
396
19
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
try {
|
|
403
|
-
const deps = {
|
|
404
|
-
...this.deps,
|
|
405
|
-
refIds: this.refIds,
|
|
406
|
-
getRefIds: () => this.refIds,
|
|
407
|
-
dispatchEvent: this.dispatchEvent.bind(this),
|
|
408
|
-
store: this.store,
|
|
409
|
-
render: this.render.bind(this),
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
const vDom = parseView({
|
|
413
|
-
h: this.h,
|
|
414
|
-
template: this.template,
|
|
415
|
-
viewData: this.viewData,
|
|
416
|
-
refs: this.refs,
|
|
417
|
-
handlers: this.transformedHandlers,
|
|
418
|
-
});
|
|
419
|
-
// parse through vDom and recursively find all elements with id
|
|
420
|
-
const ids = {};
|
|
421
|
-
const findIds = (vDom) => {
|
|
422
|
-
if (vDom.data?.attrs && vDom.data.attrs.id) {
|
|
423
|
-
ids[vDom.data.attrs.id] = vDom;
|
|
424
|
-
}
|
|
425
|
-
if (vDom.children) {
|
|
426
|
-
vDom.children.forEach(findIds);
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
findIds(vDom);
|
|
430
|
-
this.refIds = ids;
|
|
431
|
-
|
|
432
|
-
if (!this._oldVNode) {
|
|
433
|
-
this._oldVNode = this.patch(this.renderTarget, vDom);
|
|
434
|
-
} else {
|
|
435
|
-
this._oldVNode = this.patch(this._oldVNode, vDom);
|
|
436
|
-
}
|
|
437
|
-
} catch (error) {
|
|
438
|
-
console.error("Error during patching:", error);
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Binds store functions with actual framework data flow
|
|
445
|
-
* Makes state changes immutable with immer
|
|
446
|
-
* Passes props to selectors
|
|
447
|
-
* @param {*} store
|
|
448
|
-
* @param {*} props
|
|
449
|
-
* @returns
|
|
450
|
-
*/
|
|
451
|
-
const bindStore = (store, props, attrs) => {
|
|
452
|
-
const { createInitialState, ...selectorsAndActions } = store;
|
|
453
|
-
const selectors = {};
|
|
454
|
-
const actions = {};
|
|
455
|
-
let currentState = {};
|
|
456
|
-
if (createInitialState) {
|
|
457
|
-
currentState = createInitialState();
|
|
458
|
-
}
|
|
459
|
-
Object.entries(selectorsAndActions).forEach(([key, fn]) => {
|
|
460
|
-
if (key.startsWith("select")) {
|
|
461
|
-
selectors[key] = (...args) => {
|
|
462
|
-
return fn({ state: currentState, props, attrs }, ...args);
|
|
463
|
-
};
|
|
464
|
-
} else {
|
|
465
|
-
actions[key] = (payload) => {
|
|
466
|
-
currentState = produce(currentState, (draft) => {
|
|
467
|
-
return fn(draft, payload);
|
|
468
|
-
});
|
|
469
|
-
return currentState;
|
|
470
|
-
};
|
|
471
|
-
}
|
|
20
|
+
validateSchemaContract({
|
|
21
|
+
schema: resolvedSchema,
|
|
22
|
+
methodExports: Object.keys(methods || {}),
|
|
472
23
|
});
|
|
473
24
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
...
|
|
478
|
-
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
const createComponent = ({ handlers, view, store, patch, h }, deps) => {
|
|
482
|
-
const { elementName, propsSchema, attrsSchema, template, refs, styles } = view;
|
|
25
|
+
const elementName = resolvedSchema.componentName;
|
|
26
|
+
const propsSchema = resolvedSchema.propsSchema;
|
|
27
|
+
const propsSchemaKeys = propsSchema?.properties
|
|
28
|
+
? [...new Set(Object.keys(propsSchema.properties).map((propKey) => toCamelCase(propKey)))]
|
|
29
|
+
: [];
|
|
483
30
|
|
|
484
31
|
if (!patch) {
|
|
485
32
|
throw new Error("Patch is not defined");
|
|
@@ -489,49 +36,21 @@ const createComponent = ({ handlers, view, store, patch, h }, deps) => {
|
|
|
489
36
|
throw new Error("h is not defined");
|
|
490
37
|
}
|
|
491
38
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this.propsSchema = propsSchema;
|
|
508
|
-
this.props = propsSchema
|
|
509
|
-
? createPropsProxy(this, Object.keys(propsSchema.properties))
|
|
510
|
-
: {};
|
|
511
|
-
/**
|
|
512
|
-
* TODO currently if user forgot to define propsSchema for a prop
|
|
513
|
-
* there will be no warning. would be better to shos some warnng
|
|
514
|
-
*/
|
|
515
|
-
this.elementName = elementName;
|
|
516
|
-
this.styles = styles;
|
|
517
|
-
this.store = bindStore(store, this.props, attrsProxy);
|
|
518
|
-
this.template = template;
|
|
519
|
-
this.handlers = handlers;
|
|
520
|
-
this.refs = refs;
|
|
521
|
-
this.patch = patch;
|
|
522
|
-
this.deps = {
|
|
523
|
-
...deps,
|
|
524
|
-
store: this.store,
|
|
525
|
-
render: this.render,
|
|
526
|
-
handlers,
|
|
527
|
-
attrs: attrsProxy,
|
|
528
|
-
props: this.props,
|
|
529
|
-
};
|
|
530
|
-
this.h = h;
|
|
531
|
-
this.cssText = yamlToCss(elementName, styles);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
return MyComponent;
|
|
39
|
+
return createWebComponentClass({
|
|
40
|
+
elementName,
|
|
41
|
+
propsSchema,
|
|
42
|
+
propsSchemaKeys,
|
|
43
|
+
template,
|
|
44
|
+
refs,
|
|
45
|
+
styles,
|
|
46
|
+
handlers,
|
|
47
|
+
methods,
|
|
48
|
+
constants,
|
|
49
|
+
store,
|
|
50
|
+
patch,
|
|
51
|
+
h,
|
|
52
|
+
deps,
|
|
53
|
+
});
|
|
535
54
|
};
|
|
536
55
|
|
|
537
56
|
export default createComponent;
|