@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.
@@ -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({ state: currentState, props, constants }, ...args);
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({ state: draft, props, constants }, normalizedPayload);
39
+ return fn(createStoreContext(draft), normalizedPayload);
32
40
  });
33
41
  return currentState;
34
42
  };
package/src/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import createComponent from './createComponent.js';
2
+ import { createI18nRuntime } from "./core/runtime/i18n.js";
2
3
 
3
4
  export {
4
5
  createComponent,
6
+ createI18nRuntime,
5
7
  }
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.`,
@@ -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
- host.style.display = "contents";
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 data;
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.store = bindStore(store, this.props, this.constants);
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;