@rettangoli/fe 1.1.2 → 1.2.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 +8 -0
- package/package.json +1 -1
- package/src/cli/build.js +10 -0
- package/src/cli/check.js +6 -1
- package/src/cli/contracts.js +32 -6
- package/src/cli/frontendEntrySource.js +54 -2
- package/src/cli/i18nBuild.js +367 -0
- package/src/cli/vitePlugin.js +68 -0
- package/src/cli/watch.js +2 -0
- package/src/core/contracts/componentFiles.js +10 -1
- package/src/core/i18n/viewReferences.js +287 -0
- package/src/core/runtime/componentOrchestrator.js +1 -0
- package/src/core/runtime/events.js +7 -0
- package/src/core/runtime/globalListeners.js +2 -0
- package/src/core/runtime/i18n.js +155 -0
- package/src/core/runtime/lifecycle.js +14 -1
- package/src/core/runtime/props.js +49 -0
- package/src/core/runtime/store.js +11 -3
- package/src/index.js +2 -0
- package/src/parser.js +1 -0
- package/src/web/componentDom.js +6 -1
- package/src/web/createWebComponentClass.js +28 -2
|
@@ -29,6 +29,51 @@ export const readPropFallbackFromAttributes = (source, propName) => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const REACTIVE_PROP_VALUES = Symbol("rtglReactivePropValues");
|
|
32
|
+
const NATIVE_HOST_STYLE = Symbol("rtglNativeHostStyle");
|
|
33
|
+
|
|
34
|
+
const findPrototypePropertyDescriptor = (source, propName) => {
|
|
35
|
+
let current = Object.getPrototypeOf(source);
|
|
36
|
+
|
|
37
|
+
while (current) {
|
|
38
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, propName);
|
|
39
|
+
if (descriptor) {
|
|
40
|
+
return descriptor;
|
|
41
|
+
}
|
|
42
|
+
current = Object.getPrototypeOf(current);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return undefined;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const getNativeHostStyle = (source) => {
|
|
49
|
+
if (!source || typeof source !== "object") {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (Object.prototype.hasOwnProperty.call(source, NATIVE_HOST_STYLE)) {
|
|
54
|
+
return source[NATIVE_HOST_STYLE];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const styleDescriptor = findPrototypePropertyDescriptor(source, "style");
|
|
58
|
+
let nativeStyle;
|
|
59
|
+
|
|
60
|
+
if (typeof styleDescriptor?.get === "function") {
|
|
61
|
+
nativeStyle = styleDescriptor.get.call(source);
|
|
62
|
+
} else if (source.style && typeof source.style === "object") {
|
|
63
|
+
nativeStyle = source.style;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (nativeStyle && typeof nativeStyle === "object") {
|
|
67
|
+
Object.defineProperty(source, NATIVE_HOST_STYLE, {
|
|
68
|
+
value: nativeStyle,
|
|
69
|
+
enumerable: false,
|
|
70
|
+
configurable: false,
|
|
71
|
+
writable: false,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return nativeStyle;
|
|
76
|
+
};
|
|
32
77
|
|
|
33
78
|
const ensureReactivePropValues = (source) => {
|
|
34
79
|
if (!Object.prototype.hasOwnProperty.call(source, REACTIVE_PROP_VALUES)) {
|
|
@@ -50,6 +95,10 @@ export const installReactiveProps = ({
|
|
|
50
95
|
}) => {
|
|
51
96
|
const reactiveValues = ensureReactivePropValues(source);
|
|
52
97
|
|
|
98
|
+
if (allowedKeys.includes("style")) {
|
|
99
|
+
getNativeHostStyle(source);
|
|
100
|
+
}
|
|
101
|
+
|
|
53
102
|
allowedKeys.forEach((propName) => {
|
|
54
103
|
if (typeof propName !== "string" || propName.length === 0) {
|
|
55
104
|
return;
|
|
@@ -2,12 +2,20 @@ import { produce } from "immer";
|
|
|
2
2
|
|
|
3
3
|
import { isObjectPayload } from "./payload.js";
|
|
4
4
|
|
|
5
|
-
export const bindStore = (store, props, constants) => {
|
|
5
|
+
export const bindStore = (store, props, constants, runtimeContext = {}) => {
|
|
6
6
|
const { createInitialState, ...selectorsAndActions } = store;
|
|
7
7
|
const selectors = {};
|
|
8
8
|
const actions = {};
|
|
9
9
|
let currentState = {};
|
|
10
10
|
|
|
11
|
+
const createStoreContext = (state) => ({
|
|
12
|
+
state,
|
|
13
|
+
props,
|
|
14
|
+
constants,
|
|
15
|
+
i18n: runtimeContext.getI18n?.() || {},
|
|
16
|
+
locale: runtimeContext.locale,
|
|
17
|
+
});
|
|
18
|
+
|
|
11
19
|
if (createInitialState) {
|
|
12
20
|
currentState = createInitialState({ props, constants });
|
|
13
21
|
}
|
|
@@ -15,7 +23,7 @@ export const bindStore = (store, props, constants) => {
|
|
|
15
23
|
Object.entries(selectorsAndActions).forEach(([key, fn]) => {
|
|
16
24
|
if (key.startsWith("select")) {
|
|
17
25
|
selectors[key] = (...args) => {
|
|
18
|
-
return fn(
|
|
26
|
+
return fn(createStoreContext(currentState), ...args);
|
|
19
27
|
};
|
|
20
28
|
return;
|
|
21
29
|
}
|
|
@@ -28,7 +36,7 @@ export const bindStore = (store, props, constants) => {
|
|
|
28
36
|
);
|
|
29
37
|
}
|
|
30
38
|
currentState = produce(currentState, (draft) => {
|
|
31
|
-
return fn(
|
|
39
|
+
return fn(createStoreContext(draft), normalizedPayload);
|
|
32
40
|
});
|
|
33
41
|
return currentState;
|
|
34
42
|
};
|
package/src/index.js
CHANGED
package/src/parser.js
CHANGED
|
@@ -227,6 +227,7 @@ export const createVirtualDom = ({
|
|
|
227
227
|
eventRateLimitState,
|
|
228
228
|
stateKey,
|
|
229
229
|
parseAndRenderFn: jemplParseAndRender,
|
|
230
|
+
getPayloadContext: () => viewData,
|
|
230
231
|
onMissingHandler: (missingHandlerName) => {
|
|
231
232
|
console.warn(
|
|
232
233
|
`[Parser] Handler '${missingHandlerName}' for refKey '${bestMatchRefKey}' (matching '${matchIdentity}') is referenced but not found in available handlers.`,
|
package/src/web/componentDom.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getNativeHostStyle } from "../core/runtime/props.js";
|
|
2
|
+
|
|
1
3
|
const COMMON_LINK_STYLE_TEXT = `
|
|
2
4
|
a, a:link, a:visited, a:hover, a:active {
|
|
3
5
|
display: contents;
|
|
@@ -98,7 +100,10 @@ export const initializeComponentDom = ({
|
|
|
98
100
|
if (renderTarget.parentNode !== shadow) {
|
|
99
101
|
shadow.appendChild(renderTarget);
|
|
100
102
|
}
|
|
101
|
-
|
|
103
|
+
const hostStyle = getNativeHostStyle(host);
|
|
104
|
+
if (hostStyle && typeof hostStyle === "object") {
|
|
105
|
+
hostStyle.display = "contents";
|
|
106
|
+
}
|
|
102
107
|
|
|
103
108
|
return {
|
|
104
109
|
shadow,
|
|
@@ -52,6 +52,8 @@ export const createWebComponentClass = ({
|
|
|
52
52
|
_globalListenersCleanup;
|
|
53
53
|
_oldVNode;
|
|
54
54
|
deps;
|
|
55
|
+
i18nRuntime;
|
|
56
|
+
_i18nUnsubscribe;
|
|
55
57
|
_propsSchemaKeys = [];
|
|
56
58
|
cssText;
|
|
57
59
|
|
|
@@ -64,7 +66,10 @@ export const createWebComponentClass = ({
|
|
|
64
66
|
if (this.store.selectViewData) {
|
|
65
67
|
data = this.store.selectViewData();
|
|
66
68
|
}
|
|
67
|
-
return
|
|
69
|
+
return {
|
|
70
|
+
...data,
|
|
71
|
+
i18n: this.i18nRuntime?.getMessages?.() || {},
|
|
72
|
+
};
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
connectedCallback() {
|
|
@@ -74,6 +79,11 @@ export const createWebComponentClass = ({
|
|
|
74
79
|
});
|
|
75
80
|
this.shadow = dom.shadow;
|
|
76
81
|
this.renderTarget = dom.renderTarget;
|
|
82
|
+
if (this.i18nRuntime?.subscribe && !this._i18nUnsubscribe) {
|
|
83
|
+
this._i18nUnsubscribe = this.i18nRuntime.subscribe(() => {
|
|
84
|
+
this.render();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
77
87
|
runConnectedComponentLifecycle({
|
|
78
88
|
instance: this,
|
|
79
89
|
parseAndRenderFn: parseAndRender,
|
|
@@ -82,6 +92,10 @@ export const createWebComponentClass = ({
|
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
disconnectedCallback() {
|
|
95
|
+
if (this._i18nUnsubscribe) {
|
|
96
|
+
this._i18nUnsubscribe();
|
|
97
|
+
this._i18nUnsubscribe = undefined;
|
|
98
|
+
}
|
|
85
99
|
runDisconnectedComponentLifecycle({
|
|
86
100
|
instance: this,
|
|
87
101
|
clearTimerFn: clearTimeout,
|
|
@@ -140,7 +154,11 @@ export const createWebComponentClass = ({
|
|
|
140
154
|
this._propsSchemaKeys = propsSchemaKeys;
|
|
141
155
|
this.elementName = elementName;
|
|
142
156
|
this.styles = styles;
|
|
143
|
-
this.
|
|
157
|
+
this.i18nRuntime = deps?.__rtglI18nRuntime;
|
|
158
|
+
this.store = bindStore(store, this.props, this.constants, {
|
|
159
|
+
getI18n: () => this.i18nRuntime?.getMessages?.() || {},
|
|
160
|
+
locale: this.i18nRuntime?.locale,
|
|
161
|
+
});
|
|
144
162
|
this.template = template;
|
|
145
163
|
this.handlers = handlers;
|
|
146
164
|
this.methods = methods;
|
|
@@ -148,12 +166,20 @@ export const createWebComponentClass = ({
|
|
|
148
166
|
this.patch = patch;
|
|
149
167
|
this.deps = {
|
|
150
168
|
...deps,
|
|
169
|
+
locale: this.i18nRuntime?.locale || deps?.locale,
|
|
151
170
|
store: this.store,
|
|
152
171
|
render: this.render,
|
|
153
172
|
handlers,
|
|
154
173
|
props: this.props,
|
|
155
174
|
constants: this.constants,
|
|
156
175
|
};
|
|
176
|
+
if (this.i18nRuntime) {
|
|
177
|
+
Object.defineProperty(this.deps, "i18n", {
|
|
178
|
+
enumerable: true,
|
|
179
|
+
configurable: true,
|
|
180
|
+
get: () => this.i18nRuntime.getMessages(),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
157
183
|
bindMethods(this, this.methods);
|
|
158
184
|
// Keep the Snabbdom helper off public prop names (e.g. schema prop "h").
|
|
159
185
|
this._snabbdomH = h;
|