cx 26.1.13 → 26.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.
Files changed (127) hide show
  1. package/build/charts/Marker.d.ts +1 -1
  2. package/build/charts/Marker.d.ts.map +1 -1
  3. package/build/charts/Marker.js +16 -6
  4. package/build/charts/MouseTracker.d.ts +2 -0
  5. package/build/charts/MouseTracker.d.ts.map +1 -1
  6. package/build/charts/helpers/PointReducer.d.ts +2 -2
  7. package/build/charts/helpers/PointReducer.d.ts.map +1 -1
  8. package/build/data/View.d.ts +5 -3
  9. package/build/data/View.d.ts.map +1 -1
  10. package/build/data/View.js +3 -1
  11. package/build/data/ops/findTreeNode.d.ts +20 -1
  12. package/build/data/ops/findTreeNode.d.ts.map +1 -1
  13. package/build/data/ops/findTreeNode.js +19 -0
  14. package/build/data/ops/findTreePath.d.ts +1 -1
  15. package/build/data/ops/findTreePath.d.ts.map +1 -1
  16. package/build/data/ops/findTreePath.js +1 -1
  17. package/build/data/ops/removeTreeNodes.d.ts +14 -1
  18. package/build/data/ops/removeTreeNodes.d.ts.map +1 -1
  19. package/build/data/ops/removeTreeNodes.js +13 -0
  20. package/build/data/ops/updateArray.d.ts +1 -1
  21. package/build/data/ops/updateArray.d.ts.map +1 -1
  22. package/build/data/ops/updateArray.js +1 -1
  23. package/build/data/ops/updateTree.d.ts +20 -1
  24. package/build/data/ops/updateTree.d.ts.map +1 -1
  25. package/build/data/ops/updateTree.js +19 -0
  26. package/build/jsx-runtime.d.ts +1 -0
  27. package/build/jsx-runtime.d.ts.map +1 -1
  28. package/build/jsx-runtime.js +3 -1
  29. package/build/svg/Rectangle.d.ts +6 -4
  30. package/build/svg/Rectangle.d.ts.map +1 -1
  31. package/build/svg/Rectangle.js +9 -7
  32. package/build/ui/Instance.d.ts +1 -1
  33. package/build/ui/Instance.d.ts.map +1 -1
  34. package/build/ui/Instance.js +18 -8
  35. package/build/ui/IsolatedScope.d.ts +2 -1
  36. package/build/ui/IsolatedScope.d.ts.map +1 -1
  37. package/build/ui/Prop.d.ts +1 -1
  38. package/build/ui/Prop.d.ts.map +1 -1
  39. package/build/ui/Widget.d.ts +2 -0
  40. package/build/ui/Widget.d.ts.map +1 -1
  41. package/build/ui/Widget.js +4 -0
  42. package/build/ui/adapter/GroupAdapter.d.ts +4 -4
  43. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  44. package/build/ui/adapter/GroupAdapter.js +4 -4
  45. package/build/ui/adapter/TreeAdapter.d.ts +5 -3
  46. package/build/ui/adapter/TreeAdapter.d.ts.map +1 -1
  47. package/build/ui/adapter/TreeAdapter.js +12 -5
  48. package/build/ui/app/startAppLoop.d.ts +2 -2
  49. package/build/ui/app/startAppLoop.d.ts.map +1 -1
  50. package/build/ui/app/startHotAppLoop.d.ts +4 -4
  51. package/build/ui/app/startHotAppLoop.d.ts.map +1 -1
  52. package/build/ui/app/startHotAppLoop.js +1 -1
  53. package/build/ui/batchUpdates.d.ts.map +1 -1
  54. package/build/ui/batchUpdates.js +3 -4
  55. package/build/widgets/Button.d.ts +0 -7
  56. package/build/widgets/Button.d.ts.map +1 -1
  57. package/build/widgets/HtmlElement.d.ts +2 -2
  58. package/build/widgets/HtmlElement.d.ts.map +1 -1
  59. package/build/widgets/form/Checkbox.d.ts +3 -3
  60. package/build/widgets/form/Checkbox.d.ts.map +1 -1
  61. package/build/widgets/form/Checkbox.js +11 -6
  62. package/build/widgets/form/DateTimeField.d.ts +4 -0
  63. package/build/widgets/form/DateTimeField.d.ts.map +1 -1
  64. package/build/widgets/form/TextField.d.ts +2 -2
  65. package/build/widgets/form/TextField.d.ts.map +1 -1
  66. package/build/widgets/grid/Grid.d.ts +20 -16
  67. package/build/widgets/grid/Grid.d.ts.map +1 -1
  68. package/build/widgets/grid/Grid.js +200 -86
  69. package/build/widgets/nav/Menu.d.ts +2 -0
  70. package/build/widgets/nav/Menu.d.ts.map +1 -1
  71. package/build/widgets/nav/Route.js +1 -1
  72. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts +6 -4
  73. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts.map +1 -1
  74. package/build/widgets/overlay/FlyweightTooltipTracker.js +3 -0
  75. package/build/widgets/overlay/Overlay.d.ts +2 -2
  76. package/build/widgets/overlay/Overlay.d.ts.map +1 -1
  77. package/dist/data.js +52 -1
  78. package/dist/jsx-runtime.js +4 -2
  79. package/dist/manifest.js +910 -904
  80. package/dist/svg.js +3 -0
  81. package/dist/ui.js +1548 -1544
  82. package/dist/widgets.css +1 -1
  83. package/dist/widgets.js +395 -4
  84. package/package.json +2 -2
  85. package/src/charts/Marker.tsx +448 -394
  86. package/src/charts/MouseTracker.tsx +3 -0
  87. package/src/charts/helpers/PointReducer.ts +2 -2
  88. package/src/data/View.ts +76 -19
  89. package/src/data/ops/findTreeNode.ts +20 -1
  90. package/src/data/ops/findTreePath.ts +7 -2
  91. package/src/data/ops/removeTreeNodes.ts +14 -1
  92. package/src/data/ops/updateArray.ts +4 -4
  93. package/src/data/ops/updateTree.ts +32 -6
  94. package/src/index.scss +6 -6
  95. package/src/jsx-runtime.spec.tsx +40 -0
  96. package/src/jsx-runtime.ts +87 -84
  97. package/src/svg/Rectangle.tsx +80 -73
  98. package/src/ui/DataProxy.ts +55 -55
  99. package/src/ui/Instance.ts +142 -45
  100. package/src/ui/IsolatedScope.ts +4 -2
  101. package/src/ui/Prop.ts +141 -141
  102. package/src/ui/Rescope.ts +50 -50
  103. package/src/ui/Widget.tsx +292 -234
  104. package/src/ui/adapter/ArrayAdapter.ts +229 -229
  105. package/src/ui/adapter/GroupAdapter.ts +8 -10
  106. package/src/ui/adapter/TreeAdapter.ts +75 -15
  107. package/src/ui/app/Url.spec.ts +1 -1
  108. package/src/ui/app/startAppLoop.tsx +56 -45
  109. package/src/ui/app/startHotAppLoop.ts +4 -4
  110. package/src/ui/batchUpdates.ts +16 -21
  111. package/src/ui/exprHelpers.ts +96 -96
  112. package/src/widgets/Button.tsx +0 -8
  113. package/src/widgets/HtmlElement.spec.tsx +100 -72
  114. package/src/widgets/HtmlElement.tsx +11 -10
  115. package/src/widgets/Sandbox.ts +104 -104
  116. package/src/widgets/Section.scss +55 -55
  117. package/src/widgets/drag-drop/DropZone.scss +74 -74
  118. package/src/widgets/form/Checkbox.tsx +296 -243
  119. package/src/widgets/form/DateTimeField.tsx +6 -0
  120. package/src/widgets/form/TextField.tsx +2 -2
  121. package/src/widgets/grid/Grid.scss +43 -10
  122. package/src/widgets/grid/Grid.tsx +4401 -3848
  123. package/src/widgets/nav/Menu.tsx +3 -0
  124. package/src/widgets/nav/Route.ts +1 -1
  125. package/src/widgets/overlay/FlyweightTooltipTracker.ts +15 -4
  126. package/src/widgets/overlay/Overlay.tsx +2 -1
  127. package/src/widgets/overlay/index.d.ts +11 -11
package/dist/widgets.css CHANGED
@@ -5067,7 +5067,7 @@ th.cxe-calendar-display {
5067
5067
  left: 0;
5068
5068
  width: 0;
5069
5069
  border-right: 3px solid #bfbfbf;
5070
- background: rgba(191, 191, 191, 0.15);
5070
+ background: color-mix(in srgb, #bfbfbf 15%, transparent);
5071
5071
  box-sizing: border-box;
5072
5072
  }
5073
5073
 
package/dist/widgets.js CHANGED
@@ -144,7 +144,6 @@ import {
144
144
  enableFatArrowExpansion,
145
145
  } from "cx/data";
146
146
  import { jsx as jsx$1, jsxs as jsxs$1 } from "cx/jsx-runtime";
147
- import RouteMatcher from "route-parser";
148
147
 
149
148
  function autoFocus(el, component) {
150
149
  let data = component.props.data || component.props.instance.data;
@@ -4537,6 +4536,9 @@ const openContextMenu = (e, content, storeOrInstance, options) => {
4537
4536
 
4538
4537
  class FlyweightTooltipTrackerInstance extends Instance {}
4539
4538
  class FlyweightTooltipTracker extends Widget {
4539
+ constructor(config) {
4540
+ super(config);
4541
+ }
4540
4542
  initInstance(context, instance) {
4541
4543
  let handler = (e) => this.handleMouseMove(e, instance);
4542
4544
  if (typeof document !== "undefined") {
@@ -4619,13 +4621,391 @@ function createHotPromiseWindowFactory(module, factory) {
4619
4621
  return (options) => result(null, options);
4620
4622
  }
4621
4623
 
4624
+ /**
4625
+ * Route Parser - A TypeScript URL routing library
4626
+ * Supports named parameters (:param), splats (*param), and optional segments (())
4627
+ */
4628
+ /**
4629
+ * Parse a route specification into tokens
4630
+ */
4631
+ function tokenize(spec) {
4632
+ const tokens = [];
4633
+ let i = 0;
4634
+ while (i < spec.length) {
4635
+ const char = spec[i];
4636
+ if (char === ":") {
4637
+ // Named parameter
4638
+ i++;
4639
+ let name = "";
4640
+ while (i < spec.length && /[\w]/.test(spec[i])) {
4641
+ name += spec[i];
4642
+ i++;
4643
+ }
4644
+ if (name) {
4645
+ tokens.push({
4646
+ type: "param",
4647
+ value: name,
4648
+ });
4649
+ }
4650
+ } else if (char === "*") {
4651
+ // Splat parameter
4652
+ i++;
4653
+ let name = "";
4654
+ while (i < spec.length && /[\w]/.test(spec[i])) {
4655
+ name += spec[i];
4656
+ i++;
4657
+ }
4658
+ if (name) {
4659
+ tokens.push({
4660
+ type: "splat",
4661
+ value: name,
4662
+ });
4663
+ }
4664
+ } else if (char === "(") {
4665
+ // Optional segment - find matching closing paren
4666
+ i++;
4667
+ let depth = 1;
4668
+ let optionalContent = "";
4669
+ while (i < spec.length && depth > 0) {
4670
+ if (spec[i] === "(") depth++;
4671
+ else if (spec[i] === ")") depth--;
4672
+ if (depth > 0) {
4673
+ optionalContent += spec[i];
4674
+ }
4675
+ i++;
4676
+ }
4677
+ // Recursively parse the optional content
4678
+ const children = tokenize(optionalContent);
4679
+ tokens.push({
4680
+ type: "optional",
4681
+ value: optionalContent,
4682
+ children,
4683
+ });
4684
+ } else if (char === "?" || char === "&") {
4685
+ // Query separator - mark it specially
4686
+ tokens.push({
4687
+ type: "querySeparator",
4688
+ value: char,
4689
+ });
4690
+ i++;
4691
+ } else {
4692
+ // Static text - consume until we hit a special character
4693
+ let text = "";
4694
+ while (i < spec.length && !":*()&?".includes(spec[i])) {
4695
+ text += spec[i];
4696
+ i++;
4697
+ }
4698
+ if (text) {
4699
+ tokens.push({
4700
+ type: "static",
4701
+ value: text,
4702
+ });
4703
+ }
4704
+ }
4705
+ }
4706
+ return tokens;
4707
+ }
4708
+ /**
4709
+ * Check if tokens contain any query-related content (? or &)
4710
+ */
4711
+ function hasQueryTokens(tokens) {
4712
+ for (const token of tokens) {
4713
+ if (token.type === "querySeparator") return true;
4714
+ if (token.type === "optional" && token.children && hasQueryTokens(token.children)) return true;
4715
+ }
4716
+ return false;
4717
+ }
4718
+ /**
4719
+ * Extract query parameter definitions from tokens
4720
+ */
4721
+ function extractQueryParams(tokens, optional = false) {
4722
+ const params = [];
4723
+ for (let i = 0; i < tokens.length; i++) {
4724
+ const token = tokens[i];
4725
+ if (token.type === "param") {
4726
+ // Look back for the key name (e.g., 'page=' before ':page')
4727
+ let key = token.value; // Default to param name
4728
+ if (i > 0) {
4729
+ const prevToken = tokens[i - 1];
4730
+ if (prevToken.type === "static" && prevToken.value.endsWith("=")) {
4731
+ // Extract key from "key="
4732
+ const match = prevToken.value.match(/([^=&?]+)=$/);
4733
+ if (match) {
4734
+ key = match[1];
4735
+ }
4736
+ }
4737
+ }
4738
+ params.push({
4739
+ name: token.value,
4740
+ key,
4741
+ optional,
4742
+ });
4743
+ } else if (token.type === "optional" && token.children) {
4744
+ // Recursively extract from optional segments
4745
+ params.push(...extractQueryParams(token.children, true));
4746
+ }
4747
+ }
4748
+ return params;
4749
+ }
4750
+ /**
4751
+ * Split tokens into path tokens and query tokens
4752
+ */
4753
+ function splitPathAndQuery(tokens) {
4754
+ const pathTokens = [];
4755
+ const queryTokens = [];
4756
+ let inQuery = false;
4757
+ for (const token of tokens) {
4758
+ if (token.type === "querySeparator" && token.value === "?") {
4759
+ inQuery = true;
4760
+ queryTokens.push(token);
4761
+ } else if (inQuery) {
4762
+ queryTokens.push(token);
4763
+ } else if (token.type === "optional" && token.children) {
4764
+ // Check if this optional contains query content
4765
+ if (hasQueryTokens(token.children)) {
4766
+ // This optional is part of query
4767
+ queryTokens.push(token);
4768
+ inQuery = true; // After query optional, we're in query mode
4769
+ } else {
4770
+ pathTokens.push(token);
4771
+ }
4772
+ } else {
4773
+ pathTokens.push(token);
4774
+ }
4775
+ }
4776
+ return {
4777
+ pathTokens,
4778
+ queryTokens,
4779
+ };
4780
+ }
4781
+ /**
4782
+ * Escape special regex characters in a string
4783
+ */
4784
+ function escapeRegex(str) {
4785
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4786
+ }
4787
+ /**
4788
+ * Build a regex pattern from path tokens only (no query handling)
4789
+ */
4790
+ function buildPathRegex(tokens) {
4791
+ let pattern = "";
4792
+ const paramNames = [];
4793
+ for (const token of tokens) {
4794
+ switch (token.type) {
4795
+ case "static":
4796
+ pattern += escapeRegex(token.value);
4797
+ break;
4798
+ case "param":
4799
+ // Named parameter matches one path segment (no slashes)
4800
+ pattern += "([^/]+)";
4801
+ paramNames.push(token.value);
4802
+ break;
4803
+ case "splat":
4804
+ // Splat matches any characters including slashes (non-greedy within constraints)
4805
+ pattern += "(.+?)";
4806
+ paramNames.push(token.value);
4807
+ break;
4808
+ case "optional":
4809
+ // Optional segment - recursively build and wrap in optional group
4810
+ if (token.children) {
4811
+ const { pattern: childPattern, paramNames: childNames } = buildPathRegex(token.children);
4812
+ pattern += `(?:${childPattern})?`;
4813
+ paramNames.push(...childNames);
4814
+ }
4815
+ break;
4816
+ }
4817
+ }
4818
+ return {
4819
+ pattern,
4820
+ paramNames,
4821
+ };
4822
+ }
4823
+ /**
4824
+ * Parse a query string into key-value pairs
4825
+ */
4826
+ function parseQueryString(queryString) {
4827
+ const params = new Map();
4828
+ if (!queryString) return params;
4829
+ // Remove leading ? if present
4830
+ const qs = queryString.startsWith("?") ? queryString.slice(1) : queryString;
4831
+ if (!qs) return params;
4832
+ for (const pair of qs.split("&")) {
4833
+ const [key, value] = pair.split("=");
4834
+ if (key) {
4835
+ params.set(key, value || "");
4836
+ }
4837
+ }
4838
+ return params;
4839
+ }
4840
+ /**
4841
+ * Attempt to reverse a route with given parameters
4842
+ */
4843
+ function reverseTokens(tokens, params, isFirstQueryParam) {
4844
+ let result = "";
4845
+ for (const token of tokens) {
4846
+ switch (token.type) {
4847
+ case "static":
4848
+ result += token.value;
4849
+ break;
4850
+ case "param":
4851
+ case "splat": {
4852
+ const value = params[token.value];
4853
+ if (value === undefined || value === null || value === "") {
4854
+ return false;
4855
+ }
4856
+ result += String(value);
4857
+ break;
4858
+ }
4859
+ case "querySeparator":
4860
+ // For reverse, we handle ? and & smartly
4861
+ if (token.value === "?") {
4862
+ if (isFirstQueryParam.value) {
4863
+ result += "?";
4864
+ isFirstQueryParam.value = false;
4865
+ } else {
4866
+ result += "&";
4867
+ }
4868
+ } else if (token.value === "&") {
4869
+ if (isFirstQueryParam.value) {
4870
+ result += "?";
4871
+ isFirstQueryParam.value = false;
4872
+ } else {
4873
+ result += "&";
4874
+ }
4875
+ }
4876
+ break;
4877
+ case "optional":
4878
+ if (token.children) {
4879
+ // Try to fill the optional segment
4880
+ const optionalResult = reverseTokens(token.children, params, isFirstQueryParam);
4881
+ if (optionalResult !== false) {
4882
+ result += optionalResult;
4883
+ }
4884
+ // If it fails, just skip the optional part (don't return false)
4885
+ }
4886
+ break;
4887
+ }
4888
+ }
4889
+ return result;
4890
+ }
4891
+ /**
4892
+ * RouteParser class
4893
+ */
4894
+ class RouteParser {
4895
+ spec;
4896
+ tokens;
4897
+ pathRegex;
4898
+ pathParamNames;
4899
+ queryParamDefs;
4900
+ hasQueryInSpec;
4901
+ constructor(spec) {
4902
+ if (!spec) {
4903
+ throw new Error("spec is required");
4904
+ }
4905
+ this.spec = spec;
4906
+ this.tokens = tokenize(spec);
4907
+ // Split into path and query parts
4908
+ const { pathTokens, queryTokens } = splitPathAndQuery(this.tokens);
4909
+ // Build regex for path part only
4910
+ const { pattern, paramNames } = buildPathRegex(pathTokens);
4911
+ this.pathRegex = new RegExp(`^${pattern}(?:\\?.*)?$`);
4912
+ this.pathParamNames = paramNames;
4913
+ // Extract query parameter definitions
4914
+ this.queryParamDefs = extractQueryParams(queryTokens);
4915
+ this.hasQueryInSpec = queryTokens.length > 0;
4916
+ }
4917
+ /**
4918
+ * Match a path against this route
4919
+ * Returns params object on match, false otherwise
4920
+ */
4921
+ match(path) {
4922
+ // Split path into pathname and query string
4923
+ const queryIndex = path.indexOf("?");
4924
+ const pathname = queryIndex >= 0 ? path.slice(0, queryIndex) : path;
4925
+ const queryString = queryIndex >= 0 ? path.slice(queryIndex + 1) : "";
4926
+ // Match only the pathname part (not query string) to avoid capturing ? in params
4927
+ const match = this.pathRegex.exec(pathname);
4928
+ if (!match) {
4929
+ return false;
4930
+ }
4931
+ const params = {};
4932
+ // Extract path parameters
4933
+ for (let i = 0; i < this.pathParamNames.length; i++) {
4934
+ params[this.pathParamNames[i]] = match[i + 1];
4935
+ }
4936
+ // If route has query params in spec, match them from URL's query string
4937
+ if (this.hasQueryInSpec) {
4938
+ const urlQueryParams = parseQueryString(queryString);
4939
+ for (const paramDef of this.queryParamDefs) {
4940
+ const value = urlQueryParams.get(paramDef.key);
4941
+ if (value !== undefined) {
4942
+ params[paramDef.name] = value;
4943
+ } else if (paramDef.optional) {
4944
+ params[paramDef.name] = undefined;
4945
+ } else {
4946
+ // Required query param not found
4947
+ return false;
4948
+ }
4949
+ }
4950
+ }
4951
+ return params;
4952
+ }
4953
+ /**
4954
+ * Reverse the route with given parameters
4955
+ * Returns the path string on success, false otherwise
4956
+ */
4957
+ reverse(params = {}) {
4958
+ // Check if required (non-optional) params can be fulfilled
4959
+ if (!this.canFulfillRequired(this.tokens, params)) {
4960
+ return false;
4961
+ }
4962
+ const isFirstQueryParam = {
4963
+ value: true,
4964
+ };
4965
+ return reverseTokens(this.tokens, params, isFirstQueryParam);
4966
+ }
4967
+ /**
4968
+ * Check if required params (non-optional) can be fulfilled
4969
+ */
4970
+ canFulfillRequired(tokens, params) {
4971
+ for (const token of tokens) {
4972
+ if (token.type === "param" || token.type === "splat") {
4973
+ const value = params[token.value];
4974
+ if (value === undefined || value === null || value === "") {
4975
+ return false;
4976
+ }
4977
+ }
4978
+ // Optional segments don't need to be checked at top level
4979
+ }
4980
+ return true;
4981
+ }
4982
+ }
4983
+ // Export a wrapper that supports both calling conventions
4984
+ const Route$1 = function (spec) {
4985
+ if (!(this instanceof Route$1)) {
4986
+ return new Route$1(spec);
4987
+ }
4988
+ if (!spec) {
4989
+ throw new Error("spec is required");
4990
+ }
4991
+ const parser = new RouteParser(spec);
4992
+ // Copy properties to this instance
4993
+ this.spec = parser.spec;
4994
+ this.match = parser.match.bind(parser);
4995
+ this.reverse = parser.reverse.bind(parser);
4996
+ return this;
4997
+ };
4998
+ // Ensure prototype chain works for instanceof
4999
+ Route$1.prototype = Object.create(Object.prototype);
5000
+ Route$1.prototype.constructor = Route$1;
5001
+
4622
5002
  // Base class for extending with custom Config types
4623
5003
  class RouteBase extends PureContainerBase {
4624
5004
  init() {
4625
5005
  if (this.path) this.route = this.path;
4626
5006
  super.init();
4627
5007
  if (this.route && this.route[0] !== "+")
4628
- this.matcher = new RouteMatcher(this.route + (this.prefix ? "(*remainder)" : ""));
5008
+ this.matcher = new Route$1(this.route + (this.prefix ? "(*remainder)" : ""));
4629
5009
  }
4630
5010
  initInstance(context, instance) {
4631
5011
  instance.store = new ReadOnlyDataView({
@@ -4650,7 +5030,7 @@ class RouteBase extends PureContainerBase {
4650
5030
  if (this.route[0] === "+") {
4651
5031
  route = routeAppend(context.lastRoute.route, this.route.substring(1));
4652
5032
  if (!instance.cached.matcher || instance.cached.route !== route)
4653
- instance.cached.matcher = new RouteMatcher(route + (this.prefix ? "(*remainder)" : ""));
5033
+ instance.cached.matcher = new Route$1(route + (this.prefix ? "(*remainder)" : ""));
4654
5034
  matcher = instance.cached.matcher;
4655
5035
  }
4656
5036
  instance.cached.result = matcher.match(data.url);
@@ -14071,6 +14451,13 @@ class GridRowComponent extends VDOM.Component {
14071
14451
  }
14072
14452
  }
14073
14453
 
14454
+ class GridInstance extends Instance {
14455
+ resetColumnWidths() {
14456
+ this.setState({
14457
+ colWidth: {},
14458
+ });
14459
+ }
14460
+ }
14074
14461
  class Grid extends ContainerBase {
14075
14462
  constructor(config) {
14076
14463
  super(config);
@@ -14128,6 +14515,9 @@ class Grid extends ContainerBase {
14128
14515
  if (this.focusable == null) this.focusable = !this.selection.isDummy || this.cellEditable;
14129
14516
  super.init();
14130
14517
  }
14518
+ createInstance(key, parent, parentStore) {
14519
+ return new GridInstance(this, key, parent, parentStore);
14520
+ }
14131
14521
  initState(context, instance) {
14132
14522
  instance.state = {
14133
14523
  colWidth: {},
@@ -16353,7 +16743,7 @@ class GridComponent extends VDOM.Component {
16353
16743
  if (dstTableBody) {
16354
16744
  let srcTableBody = this.dom.table.lastElementChild;
16355
16745
  copyCellSize(srcTableBody, dstTableBody, fixedFooterOverlap);
16356
- let scrollColumnEl = dstTableBody.firstElementChild?.firstElementChild;
16746
+ let scrollColumnEl = dstTableBody.firstElementChild?.lastElementChild;
16357
16747
  if (scrollColumnEl) scrollColumnEl.style.minWidth = scrollColumnEl.style.maxWidth = this.scrollWidth + "px";
16358
16748
  this.dom.fixedFooter.style.display = "block";
16359
16749
  footerHeight = this.dom.fixedFooter.offsetHeight;
@@ -17793,6 +18183,7 @@ export {
17793
18183
  FlyweightTooltipTracker,
17794
18184
  FlyweightTooltipTrackerInstance,
17795
18185
  Grid,
18186
+ GridInstance,
17796
18187
  GridRow,
17797
18188
  GridRowComponent,
17798
18189
  GridRowLine,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cx",
3
- "version": "26.1.13",
3
+ "version": "26.2.0",
4
4
  "description": "Advanced JavaScript UI framework for admin and dashboard applications with ready to use grid, form and chart components.",
5
5
  "exports": {
6
6
  "./data": {
@@ -70,7 +70,7 @@
70
70
  "dependencies": {
71
71
  "@types/route-parser": "^0.1.7",
72
72
  "intl-io": "^0.4.4",
73
- "route-parser": "^0.0.5"
73
+ "route-parser-ts": "^1.1.0"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@types/react": ">=18",