cx 26.1.4 → 26.1.5

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/dist/ui.js CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  NestedDataView,
21
21
  Grouper,
22
22
  getComparer,
23
+ StringTemplate,
23
24
  } from "cx/data";
24
25
  export { computable, createAccessorModelProxy } from "cx/data";
25
26
  import {
@@ -27,8 +28,8 @@ import {
27
28
  isArray,
28
29
  isFunction,
29
30
  parseStyle,
30
- Console,
31
31
  isString,
32
+ Console,
32
33
  isDefined,
33
34
  innerTextTrim,
34
35
  GlobalCacheIdentifier,
@@ -69,7 +70,7 @@ import {
69
70
  isNumber,
70
71
  isDataRecord,
71
72
  } from "cx/util";
72
- import { VDOM as VDOM$2 } from "cx-react";
73
+ import { VDOM as VDOM$1 } from "cx-react";
73
74
  import { NumberCulture, DateTimeCulture } from "intl-io";
74
75
  import { jsx, jsxs } from "react/jsx-runtime";
75
76
 
@@ -261,9 +262,6 @@ class CSS {
261
262
  CSS.classPrefix = "cx";
262
263
  CSSHelper.alias("cx", CSS);
263
264
 
264
- // @ts-expect-error
265
- const VDOM$1 = VDOM$2;
266
-
267
265
  const VDOM = VDOM$1;
268
266
  let widgetId = 100;
269
267
  class Widget extends Component {
@@ -292,13 +290,6 @@ class Widget extends Component {
292
290
  init() {
293
291
  if (this.styles) this.style = this.styles;
294
292
  if (this.styled) this.style = parseStyle(this.style);
295
- else if (this.style) {
296
- Console.warn(
297
- "Components that allow use of the style attribute should set styled = true on their prototype. This will be an error in future versions.",
298
- );
299
- this.style = parseStyle(this.style);
300
- this.styled = true;
301
- }
302
293
  if (typeof this.if !== "undefined") this.visible = this.if;
303
294
  this.declareData();
304
295
  if (this.outerLayout) {
@@ -3576,11 +3567,8 @@ function startAppLoop(parentDOMElement, storeOrInstance, widget, options = {}) {
3576
3567
  options: options,
3577
3568
  subscribe: true,
3578
3569
  });
3579
- let root = null;
3580
- if (VDOM.DOM.createRoot) {
3581
- root = VDOM.DOM.createRoot(parentDOMElement);
3582
- root.render(content);
3583
- } else VDOM.DOM.render(content, parentDOMElement);
3570
+ let root = VDOM.DOM.createRoot(parentDOMElement);
3571
+ root.render(content);
3584
3572
  let stopped = false;
3585
3573
  return function () {
3586
3574
  if (stopped) return;
@@ -3595,7 +3583,6 @@ function startAppLoop(parentDOMElement, storeOrInstance, widget, options = {}) {
3595
3583
  }
3596
3584
  function destroy(parentDOMElement, options, root) {
3597
3585
  if (root) root.unmount();
3598
- else VDOM.DOM.unmountComponentAtNode(parentDOMElement);
3599
3586
  if (options.removeParentDOMElement && parentDOMElement.parentNode)
3600
3587
  parentDOMElement.parentNode.removeChild(parentDOMElement);
3601
3588
  }
@@ -4062,10 +4049,15 @@ function bind(path, defaultValue) {
4062
4049
  };
4063
4050
  }
4064
4051
 
4065
- function tpl(text) {
4066
- return {
4067
- tpl: text,
4068
- };
4052
+ function tpl(...args) {
4053
+ if (args.length === 1)
4054
+ return {
4055
+ tpl: args[0],
4056
+ };
4057
+ let template = args[args.length - 1];
4058
+ let formatter = StringTemplate.get(template);
4059
+ let selectors = args.slice(0, -1);
4060
+ return computable(...selectors, (...values) => formatter(values));
4069
4061
  }
4070
4062
 
4071
4063
  function expr(...args) {
@@ -4143,6 +4135,21 @@ function strictEqual(arg, value) {
4143
4135
  function strictNotEqual(arg, value) {
4144
4136
  return expr(arg, (x) => x !== value);
4145
4137
  }
4138
+ /** Returns a selector that formats the value using the specified format string.
4139
+ * Format strings use semicolon-separated syntax: "formatType;param1;param2"
4140
+ * @param arg - The accessor chain to the value
4141
+ * @param fmt - The format string
4142
+ * @param nullText - Optional text to display for null/undefined values
4143
+ * @example
4144
+ * format(m.price, "n;2") // formats as number with 2 decimal places
4145
+ * format(m.date, "d") // formats as date
4146
+ * format(m.value, "p;0;2") // formats as percentage with 0-2 decimal places
4147
+ * format(m.value, "n;2", "N/A") // shows "N/A" for null values
4148
+ */
4149
+ function format(arg, fmt, nullText) {
4150
+ let f = nullText != null ? `${fmt}|${nullText}` : fmt;
4151
+ return computable(arg, (x) => Format$1.value(x, f));
4152
+ }
4146
4153
 
4147
4154
  export {
4148
4155
  ArrayAdapter,
@@ -4211,6 +4218,7 @@ export {
4211
4218
  expr,
4212
4219
  falsy,
4213
4220
  flattenProps,
4221
+ format,
4214
4222
  getContent,
4215
4223
  getContentArray,
4216
4224
  getCurrentCulture,
package/dist/util.js CHANGED
@@ -1389,6 +1389,10 @@ class Component {
1389
1389
  if (isArray(config)) return config.map((cfg) => this.create(cmpType, cfg, more));
1390
1390
  let cfg = config;
1391
1391
  if (more) cfg = Object.assign({}, config, more);
1392
+ // Check if merged cfg has type/$type that should override cmpType
1393
+ // Only redirect if cfgType is a class (not a string alias or factory) to prevent infinite recursion
1394
+ let cfgType = cfg && (cfg.type || cfg.$type);
1395
+ if (cfgType && cfgType.isComponentType && cfgType !== cmpType) return this.create(cfg);
1392
1396
  let cmp = new cmpType(cfg);
1393
1397
  if (cmpType.autoInit && cmp.init) cmp.init();
1394
1398
  return cmp;