@itwin/imodel-components-react 5.28.0 → 5.29.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Change Log - @itwin/imodel-components-react
2
2
 
3
+ ## 5.29.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 8202fee: New editor system now enforces numeric and string constraints. Numeric and quantity editors clamp rawValues to `minimumValue`/`maximumValue`. Text editors truncate to `maximumLength` and reject values shorter than `minimumLength`.
8
+ - Updated dependencies [8202fee]
9
+ - Updated dependencies [8202fee]
10
+ - Updated dependencies [cdd7f5b]
11
+ - @itwin/components-react@5.29.0
12
+ - @itwin/core-react@5.29.0
13
+
14
+ ## 5.28.1
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [5976547]
19
+ - Updated dependencies [2a864ed]
20
+ - @itwin/components-react@5.28.1
21
+ - @itwin/core-react@5.28.1
22
+
3
23
  ## 5.28.0
4
24
 
5
25
  ### Patch Changes
@@ -1,10 +1,17 @@
1
1
  /** @packageDocumentation
2
2
  * @module PropertyEditors
3
3
  */
4
+ import * as React from "react";
4
5
  import { type QuantityTypeArg } from "@itwin/core-frontend";
5
- import { type EditorSpec, type ValueMetadata } from "@itwin/components-react";
6
+ import { type EditorProps, type EditorSpec, type NumericValue, type NumericValueMetadata } from "@itwin/components-react";
6
7
  /**
7
8
  * Editor specification for quantity values based on `IModelApp.quantityFormatter`.
9
+ *
10
+ * **Note:** value provided to `onChange` might have mismatching `displayValue` and `rawValue`.
11
+ * This can happen when input is invalid, some examples:
12
+ * - input is not numeric. input `abc` -> { `displayValue`: "abc", `rawValue`: undefined }
13
+ * - input is smaller than property constraints. input: `2 in`, minimumValue is `1 m` -> { `displayValue`: `2 in`, `rawValue`: 1 }
14
+ * - input is larger than property constraints. input: `6 m`, maximumValue is `5 m` -> { `displayValue`: `6 m`, `rawValue`: 5 }
8
15
  * @beta
9
16
  */
10
17
  export declare const QuantityEditorSpec: EditorSpec;
@@ -12,8 +19,9 @@ export declare const QuantityEditorSpec: EditorSpec;
12
19
  * Metadata for quantity values.
13
20
  * @beta
14
21
  */
15
- export interface QuantityValueMetadata extends ValueMetadata {
16
- type: "number";
22
+ export interface QuantityValueMetadata extends NumericValueMetadata {
17
23
  quantityType: QuantityTypeArg;
18
24
  }
25
+ /** @internal */
26
+ export declare function QuantityEditor({ metadata, value, onChange, size, }: EditorProps<QuantityValueMetadata, NumericValue>): React.JSX.Element;
19
27
  //# sourceMappingURL=QuantityEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QuantityEditor.d.ts","sourceRoot":"","sources":["../../../../src/imodel-components-react/inputs/new-editors/QuantityEditor.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAGL,KAAK,UAAU,EAEf,KAAK,aAAa,EAEnB,MAAM,yBAAyB,CAAC;AAKjC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAO/B,CAAC;AAEH;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,eAAe,CAAC;CAC/B"}
1
+ {"version":3,"file":"QuantityEditor.d.ts","sourceRoot":"","sources":["../../../../src/imodel-components-react/inputs/new-editors/QuantityEditor.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AAMjC;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAO/B,CAAC;AAEH;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB;IACjE,YAAY,EAAE,eAAe,CAAC;CAC/B;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,GACL,EAAE,WAAW,CAAC,qBAAqB,EAAE,YAAY,CAAC,qBAwClD"}
@@ -8,10 +8,17 @@
8
8
  import * as React from "react";
9
9
  import { useQuantityInfo } from "./UseQuantityInfo.js";
10
10
  import { createEditorSpec, ValueUtilities, } from "@itwin/components-react";
11
+ import { applyNumericConstraints } from "@itwin/components-react/internal";
11
12
  import { QuantityInput } from "./QuantityInput.js";
12
13
  /* v8 ignore start */
13
14
  /**
14
15
  * Editor specification for quantity values based on `IModelApp.quantityFormatter`.
16
+ *
17
+ * **Note:** value provided to `onChange` might have mismatching `displayValue` and `rawValue`.
18
+ * This can happen when input is invalid, some examples:
19
+ * - input is not numeric. input `abc` -> { `displayValue`: "abc", `rawValue`: undefined }
20
+ * - input is smaller than property constraints. input: `2 in`, minimumValue is `1 m` -> { `displayValue`: `2 in`, `rawValue`: 1 }
21
+ * - input is larger than property constraints. input: `6 m`, maximumValue is `5 m` -> { `displayValue`: `6 m`, `rawValue`: 5 }
15
22
  * @beta
16
23
  */
17
24
  export const QuantityEditorSpec = createEditorSpec({
@@ -21,7 +28,8 @@ export const QuantityEditorSpec = createEditorSpec({
21
28
  isValueSupported: ValueUtilities.isNumeric,
22
29
  Editor: QuantityEditor,
23
30
  });
24
- function QuantityEditor({ metadata, value, onChange, size, }) {
31
+ /** @internal */
32
+ export function QuantityEditor({ metadata, value, onChange, size, }) {
25
33
  const { defaultFormatter, highPrecisionFormatter, parser } = useQuantityInfo({
26
34
  type: metadata.quantityType,
27
35
  });
@@ -29,7 +37,26 @@ function QuantityEditor({ metadata, value, onChange, size, }) {
29
37
  const currentValue = value
30
38
  ? value
31
39
  : { rawValue: undefined, displayValue: "" };
32
- return (React.createElement(QuantityInput, { value: currentValue, onChange: onChange, size: size, formatter: isEditing ? highPrecisionFormatter : defaultFormatter, parser: parser, onBlur: () => setEditing(false), onFocus: () => setEditing(true) }));
40
+ const { minimumValue, maximumValue } = metadata.constraints ?? {
41
+ minimumValue: undefined,
42
+ maximumValue: undefined,
43
+ };
44
+ const handleChange = (newValue) => {
45
+ if (!newValue?.rawValue) {
46
+ onChange(newValue);
47
+ return;
48
+ }
49
+ onChange({
50
+ ...newValue,
51
+ rawValue: applyNumericConstraints({
52
+ value: newValue.rawValue,
53
+ min: minimumValue,
54
+ max: maximumValue,
55
+ }),
56
+ });
57
+ return;
58
+ };
59
+ return (React.createElement(QuantityInput, { value: currentValue, onChange: handleChange, size: size, formatter: isEditing ? highPrecisionFormatter : defaultFormatter, parser: parser, onBlur: () => setEditing(false), onFocus: () => setEditing(true) }));
33
60
  }
34
61
  /* v8 ignore stop */
35
62
  //# sourceMappingURL=QuantityEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QuantityEditor.js","sourceRoot":"","sources":["../../../../src/imodel-components-react/inputs/new-editors/QuantityEditor.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,gBAAgB,EAKhB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,qBAAqB;AAErB;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe,gBAAgB,CAAC;IAC7D,mBAAmB,EAAE,CAAC,QAAQ,EAAqC,EAAE,CACnE,QAAQ,CAAC,IAAI,KAAK,QAAQ;QAC1B,cAAc,IAAI,QAAQ;QAC1B,QAAQ,CAAC,YAAY,KAAK,SAAS;IACrC,gBAAgB,EAAE,cAAc,CAAC,SAAS;IAC1C,MAAM,EAAE,cAAc;CACvB,CAAC,CAAC;AAWH,SAAS,cAAc,CAAC,EACtB,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,GAC6C;IACjD,MAAM,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QAC3E,IAAI,EAAE,QAAQ,CAAC,YAAY;KAC5B,CAAC,CAAC;IACH,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,KAAK;QACxB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAE9C,OAAO,CACL,oBAAC,aAAa,IACZ,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,gBAAgB,EAChE,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAC/B,CACH,CAAC;AACJ,CAAC;AAED,oBAAoB","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module PropertyEditors\n */\n\nimport * as React from \"react\";\nimport { type QuantityTypeArg } from \"@itwin/core-frontend\";\nimport { useQuantityInfo } from \"./UseQuantityInfo.js\";\nimport {\n createEditorSpec,\n type EditorProps,\n type EditorSpec,\n type NumericValue,\n type ValueMetadata,\n ValueUtilities,\n} from \"@itwin/components-react\";\nimport { QuantityInput } from \"./QuantityInput.js\";\n\n/* v8 ignore start */\n\n/**\n * Editor specification for quantity values based on `IModelApp.quantityFormatter`.\n * @beta\n */\nexport const QuantityEditorSpec: EditorSpec = createEditorSpec({\n isMetadataSupported: (metadata): metadata is QuantityValueMetadata =>\n metadata.type === \"number\" &&\n \"quantityType\" in metadata &&\n metadata.quantityType !== undefined,\n isValueSupported: ValueUtilities.isNumeric,\n Editor: QuantityEditor,\n});\n\n/**\n * Metadata for quantity values.\n * @beta\n */\nexport interface QuantityValueMetadata extends ValueMetadata {\n type: \"number\";\n quantityType: QuantityTypeArg;\n}\n\nfunction QuantityEditor({\n metadata,\n value,\n onChange,\n size,\n}: EditorProps<QuantityValueMetadata, NumericValue>) {\n const { defaultFormatter, highPrecisionFormatter, parser } = useQuantityInfo({\n type: metadata.quantityType,\n });\n const [isEditing, setEditing] = React.useState(false);\n const currentValue = value\n ? value\n : { rawValue: undefined, displayValue: \"\" };\n\n return (\n <QuantityInput\n value={currentValue}\n onChange={onChange}\n size={size}\n formatter={isEditing ? highPrecisionFormatter : defaultFormatter}\n parser={parser}\n onBlur={() => setEditing(false)}\n onFocus={() => setEditing(true)}\n />\n );\n}\n\n/* v8 ignore stop */\n"]}
1
+ {"version":3,"file":"QuantityEditor.js","sourceRoot":"","sources":["../../../../src/imodel-components-react/inputs/new-editors/QuantityEditor.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,gBAAgB,EAKhB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,qBAAqB;AAErB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe,gBAAgB,CAAC;IAC7D,mBAAmB,EAAE,CAAC,QAAQ,EAAqC,EAAE,CACnE,QAAQ,CAAC,IAAI,KAAK,QAAQ;QAC1B,cAAc,IAAI,QAAQ;QAC1B,QAAQ,CAAC,YAAY,KAAK,SAAS;IACrC,gBAAgB,EAAE,cAAc,CAAC,SAAS;IAC1C,MAAM,EAAE,cAAc;CACvB,CAAC,CAAC;AAUH,gBAAgB;AAChB,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,GAC6C;IACjD,MAAM,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QAC3E,IAAI,EAAE,QAAQ,CAAC,YAAY;KAC5B,CAAC,CAAC;IACH,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,KAAK;QACxB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAE9C,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC,WAAW,IAAI;QAC7D,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,SAAS;KACxB,CAAC;IACF,MAAM,YAAY,GAAG,CAAC,QAAsB,EAAE,EAAE;QAC9C,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;YACxB,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,QAAQ,CAAC;YACP,GAAG,QAAQ;YACX,QAAQ,EAAE,uBAAuB,CAAC;gBAChC,KAAK,EAAE,QAAQ,CAAC,QAAQ;gBACxB,GAAG,EAAE,YAAY;gBACjB,GAAG,EAAE,YAAY;aAClB,CAAC;SACH,CAAC,CAAC;QACH,OAAO;IACT,CAAC,CAAC;IAEF,OAAO,CACL,oBAAC,aAAa,IACZ,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,gBAAgB,EAChE,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAC/B,CACH,CAAC;AACJ,CAAC;AAED,oBAAoB","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module PropertyEditors\n */\n\nimport * as React from \"react\";\nimport { type QuantityTypeArg } from \"@itwin/core-frontend\";\nimport { useQuantityInfo } from \"./UseQuantityInfo.js\";\nimport {\n createEditorSpec,\n type EditorProps,\n type EditorSpec,\n type NumericValue,\n type NumericValueMetadata,\n ValueUtilities,\n} from \"@itwin/components-react\";\nimport { applyNumericConstraints } from \"@itwin/components-react/internal\";\nimport { QuantityInput } from \"./QuantityInput.js\";\n\n/* v8 ignore start */\n\n/**\n * Editor specification for quantity values based on `IModelApp.quantityFormatter`.\n *\n * **Note:** value provided to `onChange` might have mismatching `displayValue` and `rawValue`.\n * This can happen when input is invalid, some examples:\n * - input is not numeric. input `abc` -> { `displayValue`: \"abc\", `rawValue`: undefined }\n * - input is smaller than property constraints. input: `2 in`, minimumValue is `1 m` -> { `displayValue`: `2 in`, `rawValue`: 1 }\n * - input is larger than property constraints. input: `6 m`, maximumValue is `5 m` -> { `displayValue`: `6 m`, `rawValue`: 5 }\n * @beta\n */\nexport const QuantityEditorSpec: EditorSpec = createEditorSpec({\n isMetadataSupported: (metadata): metadata is QuantityValueMetadata =>\n metadata.type === \"number\" &&\n \"quantityType\" in metadata &&\n metadata.quantityType !== undefined,\n isValueSupported: ValueUtilities.isNumeric,\n Editor: QuantityEditor,\n});\n\n/**\n * Metadata for quantity values.\n * @beta\n */\nexport interface QuantityValueMetadata extends NumericValueMetadata {\n quantityType: QuantityTypeArg;\n}\n\n/** @internal */\nexport function QuantityEditor({\n metadata,\n value,\n onChange,\n size,\n}: EditorProps<QuantityValueMetadata, NumericValue>) {\n const { defaultFormatter, highPrecisionFormatter, parser } = useQuantityInfo({\n type: metadata.quantityType,\n });\n const [isEditing, setEditing] = React.useState(false);\n const currentValue = value\n ? value\n : { rawValue: undefined, displayValue: \"\" };\n\n const { minimumValue, maximumValue } = metadata.constraints ?? {\n minimumValue: undefined,\n maximumValue: undefined,\n };\n const handleChange = (newValue: NumericValue) => {\n if (!newValue?.rawValue) {\n onChange(newValue);\n return;\n }\n onChange({\n ...newValue,\n rawValue: applyNumericConstraints({\n value: newValue.rawValue,\n min: minimumValue,\n max: maximumValue,\n }),\n });\n return;\n };\n\n return (\n <QuantityInput\n value={currentValue}\n onChange={handleChange}\n size={size}\n formatter={isEditing ? highPrecisionFormatter : defaultFormatter}\n parser={parser}\n onBlur={() => setEditing(false)}\n onFocus={() => setEditing(true)}\n />\n );\n}\n\n/* v8 ignore stop */\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/imodel-components-react",
3
- "version": "5.28.0",
3
+ "version": "5.29.0",
4
4
  "description": "A react component library of iTwin.js UI iModel components",
5
5
  "type": "module",
6
6
  "types": "./lib/imodel-components-react.d.ts",
@@ -44,8 +44,8 @@
44
44
  "@itwin/itwinui-react": "^3.15.0",
45
45
  "react": "^18.0.0 || ^19.0.0",
46
46
  "react-dom": "^18.0.0 || ^19.0.0",
47
- "@itwin/components-react": "5.28.0",
48
- "@itwin/core-react": "5.28.0"
47
+ "@itwin/components-react": "5.29.0",
48
+ "@itwin/core-react": "5.29.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@itwin/appui-abstract": "^5.8.1",
@@ -83,8 +83,8 @@
83
83
  "typescript": "~5.6.3",
84
84
  "upath": "^2.0.1",
85
85
  "vitest": "^3.2.4",
86
- "@itwin/components-react": "5.28.0",
87
- "@itwin/core-react": "5.28.0"
86
+ "@itwin/core-react": "5.29.0",
87
+ "@itwin/components-react": "5.29.0"
88
88
  },
89
89
  "dependencies": {
90
90
  "@itwin/itwinui-icons-react": "^2.11.0",