@babylonjs/shared-ui-components 8.23.1 → 8.23.2
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/fluent/hoc/propertyLines/inputPropertyLine.d.ts +7 -3
- package/fluent/hoc/propertyLines/inputPropertyLine.js +6 -2
- package/fluent/hoc/propertyLines/inputPropertyLine.js.map +1 -1
- package/fluent/hoc/propertyLines/vectorPropertyLine.d.ts +4 -0
- package/fluent/hoc/propertyLines/vectorPropertyLine.js +3 -3
- package/fluent/hoc/propertyLines/vectorPropertyLine.js.map +1 -1
- package/fluent/primitives/colorPicker.d.ts +2 -6
- package/fluent/primitives/colorPicker.js +41 -48
- package/fluent/primitives/colorPicker.js.map +1 -1
- package/fluent/primitives/infoLabel.d.ts +13 -0
- package/fluent/primitives/infoLabel.js +11 -0
- package/fluent/primitives/infoLabel.js.map +1 -0
- package/fluent/primitives/primitive.d.ts +5 -0
- package/fluent/primitives/primitive.js.map +1 -1
- package/fluent/primitives/spinButton.d.ts +9 -3
- package/fluent/primitives/spinButton.js +100 -16
- package/fluent/primitives/spinButton.js.map +1 -1
- package/fluent/primitives/syncedSlider.d.ts +2 -0
- package/fluent/primitives/syncedSlider.js +6 -10
- package/fluent/primitives/syncedSlider.js.map +1 -1
- package/fluent/primitives/textInput.d.ts +6 -0
- package/fluent/primitives/textInput.js +48 -0
- package/fluent/primitives/textInput.js.map +1 -0
- package/lines/textInputLineComponent.js +3 -4
- package/lines/textInputLineComponent.js.map +1 -1
- package/package.json +1 -1
- package/fluent/primitives/input.d.ts +0 -10
- package/fluent/primitives/input.js +0 -41
- package/fluent/primitives/input.js.map +0 -1
@@ -1,15 +1,19 @@
|
|
1
1
|
import type { PropertyLineProps } from "./propertyLine.js";
|
2
2
|
import type { FunctionComponent } from "react";
|
3
|
-
import type {
|
3
|
+
import type { TextInputProps } from "../../primitives/textInput.js";
|
4
|
+
import type { SpinButtonProps } from "../../primitives/spinButton.js";
|
4
5
|
/**
|
5
6
|
* Wraps a text input in a property line
|
6
7
|
* @param props - PropertyLineProps and InputProps
|
7
8
|
* @returns property-line wrapped input component
|
8
9
|
*/
|
9
|
-
export declare const TextInputPropertyLine: FunctionComponent<
|
10
|
+
export declare const TextInputPropertyLine: FunctionComponent<TextInputProps & PropertyLineProps<string>>;
|
10
11
|
/**
|
11
12
|
* Wraps a number input in a property line
|
13
|
+
* To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
|
12
14
|
* @param props - PropertyLineProps and InputProps
|
13
15
|
* @returns property-line wrapped input component
|
14
16
|
*/
|
15
|
-
export declare const NumberInputPropertyLine: FunctionComponent<
|
17
|
+
export declare const NumberInputPropertyLine: FunctionComponent<SpinButtonProps & PropertyLineProps<number> & {
|
18
|
+
forceInt?: boolean;
|
19
|
+
}>;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import { PropertyLine } from "./propertyLine.js";
|
3
|
-
import {
|
3
|
+
import { TextInput } from "../../primitives/textInput.js";
|
4
|
+
import { SpinButton } from "../../primitives/spinButton.js";
|
4
5
|
/**
|
5
6
|
* Wraps a text input in a property line
|
6
7
|
* @param props - PropertyLineProps and InputProps
|
@@ -9,8 +10,11 @@ import { NumberInput, TextInput } from "../../primitives/input.js";
|
|
9
10
|
export const TextInputPropertyLine = (props) => (_jsx(PropertyLine, { ...props, children: _jsx(TextInput, { ...props }) }));
|
10
11
|
/**
|
11
12
|
* Wraps a number input in a property line
|
13
|
+
* To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
|
12
14
|
* @param props - PropertyLineProps and InputProps
|
13
15
|
* @returns property-line wrapped input component
|
14
16
|
*/
|
15
|
-
export const NumberInputPropertyLine = (props) =>
|
17
|
+
export const NumberInputPropertyLine = (props) => {
|
18
|
+
return (_jsx(PropertyLine, { ...props, children: _jsx(SpinButton, { ...props }) }));
|
19
|
+
};
|
16
20
|
//# sourceMappingURL=inputPropertyLine.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"inputPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/inputPropertyLine.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
1
|
+
{"version":3,"file":"inputPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/inputPropertyLine.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAkE,CAAC,KAAK,EAAE,EAAE,CAAC,CAC3G,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,SAAS,OAAK,KAAK,GAAI,GACb,CAClB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA4F,CAAC,KAAK,EAAE,EAAE;IACtI,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,UAAU,OAAK,KAAK,GAAI,GACd,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { PropertyLine } from \"./propertyLine\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { TextInputProps } from \"../../primitives/textInput\";\r\nimport { TextInput } from \"../../primitives/textInput\";\r\nimport type { SpinButtonProps } from \"../../primitives/spinButton\";\r\nimport { SpinButton } from \"../../primitives/spinButton\";\r\n/**\r\n * Wraps a text input in a property line\r\n * @param props - PropertyLineProps and InputProps\r\n * @returns property-line wrapped input component\r\n */\r\nexport const TextInputPropertyLine: FunctionComponent<TextInputProps & PropertyLineProps<string>> = (props) => (\r\n <PropertyLine {...props}>\r\n <TextInput {...props} />\r\n </PropertyLine>\r\n);\r\n\r\n/**\r\n * Wraps a number input in a property line\r\n * To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)\r\n * @param props - PropertyLineProps and InputProps\r\n * @returns property-line wrapped input component\r\n */\r\nexport const NumberInputPropertyLine: FunctionComponent<SpinButtonProps & PropertyLineProps<number> & { forceInt?: boolean }> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <SpinButton {...props} />\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
@@ -12,6 +12,10 @@ export type TensorPropertyLineProps<V extends Vector2 | Vector3 | Vector4 | Quat
|
|
12
12
|
* If passed, all sliders will use this for the max value
|
13
13
|
*/
|
14
14
|
max?: number;
|
15
|
+
/**
|
16
|
+
* Will be displayed in the input UI to indicate the unit of measurement
|
17
|
+
*/
|
18
|
+
unit?: string;
|
15
19
|
/**
|
16
20
|
* If passed, the UX will use the conversion functions to display/update values
|
17
21
|
*/
|
@@ -25,13 +25,13 @@ const TensorPropertyLine = (props) => {
|
|
25
25
|
setVector(newVector);
|
26
26
|
props.onChange(newVector);
|
27
27
|
};
|
28
|
-
return (_jsx(PropertyLine, { ...props, expandedContent: _jsxs(_Fragment, { children: [_jsx(SyncedSliderPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x") }), _jsx(SyncedSliderPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y") }), HasZ(vector) && _jsx(SyncedSliderPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z") }), HasW(vector) && _jsx(SyncedSliderPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w") })] }), children: _jsx(Body1, { children: `X: ${formatted(props.value.x)} | Y: ${formatted(props.value.y)}${HasZ(props.value) ? ` | Z: ${formatted(props.value.z)}` : ""}${HasW(props.value) ? ` | W: ${formatted(props.value.w)}` : ""}` }) }));
|
28
|
+
return (_jsx(PropertyLine, { ...props, expandedContent: _jsxs(_Fragment, { children: [_jsx(SyncedSliderPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x"), unit: props.unit }), _jsx(SyncedSliderPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y"), unit: props.unit }), HasZ(vector) && (_jsx(SyncedSliderPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z"), unit: props.unit })), HasW(vector) && (_jsx(SyncedSliderPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w"), unit: props.unit }))] }), children: _jsx(Body1, { children: `X: ${formatted(props.value.x)} | Y: ${formatted(props.value.y)}${HasZ(props.value) ? ` | Z: ${formatted(props.value.z)}` : ""}${HasW(props.value) ? ` | W: ${formatted(props.value.w)}` : ""}` }) }));
|
29
29
|
};
|
30
30
|
const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
|
31
31
|
export const RotationVectorPropertyLine = (props) => {
|
32
32
|
const min = props.useDegrees ? 0 : undefined;
|
33
33
|
const max = props.useDegrees ? 360 : undefined;
|
34
|
-
return _jsx(Vector3PropertyLine, { ...props, valueConverter: props.useDegrees ? ToDegreesConverter : undefined, min: min, max: max });
|
34
|
+
return _jsx(Vector3PropertyLine, { ...props, unit: props.useDegrees ? "deg" : "rad", valueConverter: props.useDegrees ? ToDegreesConverter : undefined, min: min, max: max });
|
35
35
|
};
|
36
36
|
const QuaternionPropertyLineInternal = TensorPropertyLine;
|
37
37
|
export const QuaternionPropertyLine = (props) => {
|
@@ -49,7 +49,7 @@ export const QuaternionPropertyLine = (props) => {
|
|
49
49
|
setQuat(quat);
|
50
50
|
props.onChange(quat);
|
51
51
|
};
|
52
|
-
return
|
52
|
+
return useDegrees ? (_jsx(Vector3PropertyLine, { ...restProps, nullable: false, ignoreNullable: false, value: quat.toEulerAngles(), valueConverter: ToDegreesConverter, min: min, max: max, onChange: onEulerChange, unit: "deg" })) : (_jsx(QuaternionPropertyLineInternal, { ...props, unit: "rad", nullable: false, value: quat, min: min, max: max, onChange: onQuatChange }));
|
53
53
|
};
|
54
54
|
export const Vector2PropertyLine = TensorPropertyLine;
|
55
55
|
export const Vector3PropertyLine = TensorPropertyLine;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\nimport { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\n\r\nimport { SyncedSliderPropertyLine } from \"./syncedSliderPropertyLine\";\r\nimport type { Vector3 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, Vector2, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\nexport type TensorPropertyLineProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = PropertyLineProps<V> &\r\n PrimitiveProps<V> & {\r\n /**\r\n * If passed, all sliders will use this for the min value\r\n */\r\n min?: number;\r\n /**\r\n * If passed, all sliders will use this for the max value\r\n */\r\n max?: number;\r\n /**\r\n * If passed, the UX will use the conversion functions to display/update values\r\n */\r\n valueConverter?: {\r\n /**\r\n * Will call from(val) before displaying in the UX\r\n */\r\n from: (val: number) => number;\r\n /**\r\n * Will call to(val) before calling onChange\r\n */\r\n to: (val: number) => number;\r\n };\r\n };\r\n\r\nconst HasZ = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector3 => !(vector instanceof Vector2);\r\nconst HasW = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector4 => vector instanceof Vector4 || vector instanceof Quaternion;\r\n\r\n/**\r\n * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values\r\n * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)\r\n * @param props\r\n * @returns\r\n */\r\nconst TensorPropertyLine: FunctionComponent<TensorPropertyLineProps<Vector2 | Vector3 | Vector4 | Quaternion>> = (props) => {\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(2);\r\n\r\n const [vector, setVector] = useState(props.value);\r\n const { min, max } = props;\r\n\r\n const onChange = (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => {\r\n const value = props.valueConverter ? props.valueConverter.to(val) : val;\r\n const newVector = vector.clone();\r\n (newVector as Vector4)[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe\r\n\r\n setVector(newVector);\r\n props.onChange(newVector);\r\n };\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n expandedContent={\r\n <>\r\n <SyncedSliderPropertyLine label=\"X\" value={converted(vector.x)} min={min} max={max} onChange={(val) => onChange(val, \"x\")} />\r\n <SyncedSliderPropertyLine label=\"Y\" value={converted(vector.y)} min={min} max={max} onChange={(val) => onChange(val, \"y\")} />\r\n {HasZ(vector) && <SyncedSliderPropertyLine label=\"Z\" value={converted(vector.z)} min={min} max={max} onChange={(val) => onChange(val, \"z\")} />}\r\n {HasW(vector) && <SyncedSliderPropertyLine label=\"W\" value={converted(vector.w)} min={min} max={max} onChange={(val) => onChange(val, \"w\")} />}\r\n </>\r\n }\r\n >\r\n <Body1>{`X: ${formatted(props.value.x)} | Y: ${formatted(props.value.y)}${HasZ(props.value) ? ` | Z: ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? ` | W: ${formatted(props.value.w)}` : \"\"}`}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n\r\ntype RotationVectorPropertyLineProps = TensorPropertyLineProps<Vector3> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\n\r\nconst ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };\r\nexport const RotationVectorPropertyLine: FunctionComponent<RotationVectorPropertyLineProps> = (props) => {\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return <Vector3PropertyLine {...props} valueConverter={props.useDegrees ? ToDegreesConverter : undefined} min={min} max={max} />;\r\n};\r\n\r\ntype QuaternionPropertyLineProps = TensorPropertyLineProps<Quaternion> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\nconst QuaternionPropertyLineInternal = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Quaternion>>;\r\nexport const QuaternionPropertyLine: FunctionComponent<QuaternionPropertyLineProps> = (props) => {\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n const [quat, setQuat] = useState(props.value);\r\n\r\n // Extract only the properties that exist on QuaternionPropertyLineProps\r\n const { useDegrees, ...restProps } = props;\r\n\r\n const onQuatChange = (val: Quaternion) => {\r\n setQuat(val);\r\n props.onChange(val);\r\n };\r\n\r\n const onEulerChange = (val: Vector3) => {\r\n const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);\r\n setQuat(quat);\r\n props.onChange(quat);\r\n };\r\n\r\n return props.useDegrees ? (\r\n <Vector3PropertyLine\r\n {...restProps}\r\n nullable={false}\r\n ignoreNullable={false}\r\n value={quat.toEulerAngles()}\r\n valueConverter={ToDegreesConverter}\r\n min={min}\r\n max={max}\r\n onChange={onEulerChange}\r\n />\r\n ) : (\r\n <QuaternionPropertyLineInternal {...props} nullable={false} value={quat} min={min} max={max} onChange={onQuatChange} />\r\n );\r\n};\r\nexport const Vector2PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector2>>;\r\nexport const Vector3PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector3>>;\r\nexport const Vector4PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector4>>;\r\n"]}
|
1
|
+
{"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\n\r\nimport { Body1 } from \"@fluentui/react-components\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\n\r\nimport { SyncedSliderPropertyLine } from \"./syncedSliderPropertyLine\";\r\nimport type { Vector3 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, Vector2, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\nexport type TensorPropertyLineProps<V extends Vector2 | Vector3 | Vector4 | Quaternion> = PropertyLineProps<V> &\r\n PrimitiveProps<V> & {\r\n /**\r\n * If passed, all sliders will use this for the min value\r\n */\r\n min?: number;\r\n /**\r\n * If passed, all sliders will use this for the max value\r\n */\r\n max?: number;\r\n /**\r\n * Will be displayed in the input UI to indicate the unit of measurement\r\n */\r\n unit?: string;\r\n /**\r\n * If passed, the UX will use the conversion functions to display/update values\r\n */\r\n valueConverter?: {\r\n /**\r\n * Will call from(val) before displaying in the UX\r\n */\r\n from: (val: number) => number;\r\n /**\r\n * Will call to(val) before calling onChange\r\n */\r\n to: (val: number) => number;\r\n };\r\n };\r\n\r\nconst HasZ = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector3 => !(vector instanceof Vector2);\r\nconst HasW = (vector: Vector2 | Vector3 | Vector4 | Quaternion): vector is Vector4 => vector instanceof Vector4 || vector instanceof Quaternion;\r\n\r\n/**\r\n * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values\r\n * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)\r\n * @param props\r\n * @returns\r\n */\r\nconst TensorPropertyLine: FunctionComponent<TensorPropertyLineProps<Vector2 | Vector3 | Vector4 | Quaternion>> = (props) => {\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(2);\r\n\r\n const [vector, setVector] = useState(props.value);\r\n const { min, max } = props;\r\n\r\n const onChange = (val: number, key: \"x\" | \"y\" | \"z\" | \"w\") => {\r\n const value = props.valueConverter ? props.valueConverter.to(val) : val;\r\n const newVector = vector.clone();\r\n (newVector as Vector4)[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe\r\n\r\n setVector(newVector);\r\n props.onChange(newVector);\r\n };\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n expandedContent={\r\n <>\r\n <SyncedSliderPropertyLine label=\"X\" value={converted(vector.x)} min={min} max={max} onChange={(val) => onChange(val, \"x\")} unit={props.unit} />\r\n <SyncedSliderPropertyLine label=\"Y\" value={converted(vector.y)} min={min} max={max} onChange={(val) => onChange(val, \"y\")} unit={props.unit} />\r\n {HasZ(vector) && (\r\n <SyncedSliderPropertyLine label=\"Z\" value={converted(vector.z)} min={min} max={max} onChange={(val) => onChange(val, \"z\")} unit={props.unit} />\r\n )}\r\n {HasW(vector) && (\r\n <SyncedSliderPropertyLine label=\"W\" value={converted(vector.w)} min={min} max={max} onChange={(val) => onChange(val, \"w\")} unit={props.unit} />\r\n )}\r\n </>\r\n }\r\n >\r\n <Body1>{`X: ${formatted(props.value.x)} | Y: ${formatted(props.value.y)}${HasZ(props.value) ? ` | Z: ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? ` | W: ${formatted(props.value.w)}` : \"\"}`}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n\r\ntype RotationVectorPropertyLineProps = TensorPropertyLineProps<Vector3> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\n\r\nconst ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };\r\nexport const RotationVectorPropertyLine: FunctionComponent<RotationVectorPropertyLineProps> = (props) => {\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return <Vector3PropertyLine {...props} unit={props.useDegrees ? \"deg\" : \"rad\"} valueConverter={props.useDegrees ? ToDegreesConverter : undefined} min={min} max={max} />;\r\n};\r\n\r\ntype QuaternionPropertyLineProps = TensorPropertyLineProps<Quaternion> & {\r\n /**\r\n * Display angles as degrees instead of radians\r\n */\r\n useDegrees?: boolean;\r\n};\r\nconst QuaternionPropertyLineInternal = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Quaternion>>;\r\nexport const QuaternionPropertyLine: FunctionComponent<QuaternionPropertyLineProps> = (props) => {\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n const [quat, setQuat] = useState(props.value);\r\n\r\n // Extract only the properties that exist on QuaternionPropertyLineProps\r\n const { useDegrees, ...restProps } = props;\r\n\r\n const onQuatChange = (val: Quaternion) => {\r\n setQuat(val);\r\n props.onChange(val);\r\n };\r\n\r\n const onEulerChange = (val: Vector3) => {\r\n const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);\r\n setQuat(quat);\r\n props.onChange(quat);\r\n };\r\n\r\n return useDegrees ? (\r\n <Vector3PropertyLine\r\n {...restProps}\r\n nullable={false}\r\n ignoreNullable={false}\r\n value={quat.toEulerAngles()}\r\n valueConverter={ToDegreesConverter}\r\n min={min}\r\n max={max}\r\n onChange={onEulerChange}\r\n unit=\"deg\"\r\n />\r\n ) : (\r\n <QuaternionPropertyLineInternal {...props} unit={\"rad\"} nullable={false} value={quat} min={min} max={max} onChange={onQuatChange} />\r\n );\r\n};\r\nexport const Vector2PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector2>>;\r\nexport const Vector3PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector3>>;\r\nexport const Vector4PropertyLine = TensorPropertyLine as FunctionComponent<TensorPropertyLineProps<Vector4>>;\r\n"]}
|
@@ -5,9 +5,7 @@ export type ColorPickerProps<C extends Color3 | Color4> = {
|
|
5
5
|
isLinearMode?: boolean;
|
6
6
|
} & PrimitiveProps<C>;
|
7
7
|
export declare const ColorPickerPopup: FunctionComponent<ColorPickerProps<Color3 | Color4>>;
|
8
|
-
type HsvKey = "h" | "s" | "v";
|
9
8
|
export type InputHexProps = PrimitiveProps<Color3 | Color4> & {
|
10
|
-
label?: string;
|
11
9
|
linearHex?: boolean;
|
12
10
|
isLinearMode?: boolean;
|
13
11
|
};
|
@@ -20,11 +18,9 @@ export type InputHexProps = PrimitiveProps<Color3 | Color4> & {
|
|
20
18
|
* @returns
|
21
19
|
*/
|
22
20
|
export declare const InputHexField: FunctionComponent<InputHexProps>;
|
23
|
-
type
|
24
|
-
|
25
|
-
label: string;
|
21
|
+
type HsvKey = "h" | "s" | "v";
|
22
|
+
type InputHsvFieldProps = PrimitiveProps<Color3 | Color4> & {
|
26
23
|
hsvKey: HsvKey;
|
27
|
-
onChange: (color: Color3 | Color4) => void;
|
28
24
|
max: number;
|
29
25
|
scale?: number;
|
30
26
|
};
|
@@ -2,8 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
2
2
|
/* eslint-disable jsdoc/require-returns */
|
3
3
|
/* eslint-disable @typescript-eslint/naming-convention */
|
4
4
|
import { useState, useEffect, useCallback } from "react";
|
5
|
-
import {
|
5
|
+
import { ColorPicker as FluentColorPicker, ColorSlider, ColorArea, AlphaSlider, Link, makeStyles, Popover, PopoverSurface, PopoverTrigger, tokens, Body1Strong, ColorSwatch, } from "@fluentui/react-components";
|
6
6
|
import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js";
|
7
|
+
import { SpinButton } from "./spinButton.js";
|
8
|
+
import { TextInput } from "./textInput.js";
|
7
9
|
const useColorPickerStyles = makeStyles({
|
8
10
|
colorPickerContainer: {
|
9
11
|
width: "325px",
|
@@ -36,7 +38,7 @@ const useColorPickerStyles = makeStyles({
|
|
36
38
|
width: "80px",
|
37
39
|
},
|
38
40
|
spinButton: {
|
39
|
-
|
41
|
+
width: "50px",
|
40
42
|
},
|
41
43
|
container: {
|
42
44
|
display: "flex",
|
@@ -66,8 +68,9 @@ export const ColorPickerPopup = (props) => {
|
|
66
68
|
align: "start",
|
67
69
|
overflowBoundary: document.body,
|
68
70
|
autoSize: true,
|
69
|
-
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: _jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: "small", color: color.toHexString(), value: color.toHexString().slice(1) }) }), _jsx(PopoverSurface, { children: _jsxs("div", { className: classes.colorPickerContainer, children: [_jsxs(
|
71
|
+
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: _jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: "small", color: color.toHexString(), value: color.toHexString().slice(1) }) }), _jsx(PopoverSurface, { children: _jsxs("div", { className: classes.colorPickerContainer, children: [_jsxs(FluentColorPicker, { color: rgbaToHsv(color), onColorChange: handleColorPickerChange, children: [_jsx(ColorArea, { inputX: { "aria-label": "Saturation" }, inputY: { "aria-label": "Brightness" } }), _jsx(ColorSlider, { "aria-label": "Hue" }), color instanceof Color4 && _jsx(AlphaSlider, { "aria-label": "Alpha" })] }), _jsxs("div", { className: classes.container, children: [_jsxs("div", { className: classes.row, children: [_jsx("div", { className: classes.previewColor, style: { backgroundColor: color.toHexString() } }), _jsx(InputHexField, { title: "Gamma Hex", value: color, isLinearMode: props.isLinearMode, onChange: handleChange }), _jsx(InputHexField, { title: "Linear Hex", linearHex: true, isLinearMode: props.isLinearMode, value: color, onChange: handleChange })] }), _jsxs("div", { className: classes.row, children: [_jsx(InputRgbField, { title: "Red", value: color, rgbKey: "r", onChange: handleChange }), _jsx(InputRgbField, { title: "Green", value: color, rgbKey: "g", onChange: handleChange }), _jsx(InputRgbField, { title: "Blue", value: color, rgbKey: "b", onChange: handleChange }), _jsx(InputAlphaField, { color: color, onChange: handleChange })] }), _jsxs("div", { className: classes.row, children: [_jsx(InputHsvField, { title: "Hue", value: color, hsvKey: "h", max: 360, onChange: handleChange }), _jsx(InputHsvField, { title: "Saturation", value: color, hsvKey: "s", max: 100, scale: 100, onChange: handleChange }), _jsx(InputHsvField, { title: "Value", value: color, hsvKey: "v", max: 100, scale: 100, onChange: handleChange })] })] })] }) })] }));
|
70
72
|
};
|
73
|
+
const HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
|
71
74
|
/**
|
72
75
|
* Component which displays the passed in color's HEX value, either in linearSpace (if linearHex is true) or in gamma space
|
73
76
|
* When the hex color is changed by user, component calculates the new Color3/4 value and calls onChange
|
@@ -77,34 +80,34 @@ export const ColorPickerPopup = (props) => {
|
|
77
80
|
* @returns
|
78
81
|
*/
|
79
82
|
export const InputHexField = (props) => {
|
80
|
-
const id = useId("hex-input");
|
81
83
|
const styles = useColorPickerStyles();
|
82
|
-
const {
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
84
|
+
const { title, value, onChange, linearHex, isLinearMode } = props;
|
85
|
+
return (_jsx("div", { className: styles.colorFieldWrapper, children: _jsx(TextInput, { disabled: linearHex ? !isLinearMode : false, className: styles.input, value: linearHex ? value.toLinearSpace().toHexString() : value.toHexString(), validator: (val) => val != "" && HEX_REGEX.test(val), onChange: (val) => (linearHex ? onChange(Color3.FromHexString(val).toGammaSpace()) : onChange(Color3.FromHexString(val))), infoLabel: title
|
86
|
+
? {
|
87
|
+
label: title,
|
88
|
+
// If not representing a linearHex, no info is needed.
|
89
|
+
info: !props.linearHex ? undefined : !isLinearMode ? ( // If representing a linear hex but we are in gammaMode, simple message explaining why linearHex is disabled
|
90
|
+
_jsx(_Fragment, { children: " This color picker is attached to an entity whose color is stored in gamma space, so we are showing linear hex in disabled view " })) : (
|
91
|
+
// If representing a linear hex and we are in linearMode, give information about how to use these hex values
|
92
|
+
_jsxs(_Fragment, { children: ["This color picker is attached to an entity whose color is stored in linear space (ex: PBR Material), and Babylon converts the color to gamma space before rendering on screen because the human eye is best at processing colors in gamma space. We thus also want to display the color picker in gamma space so that the color chosen here will match the color seen in your entity.", _jsx("br", {}), "If you want to copy/paste the HEX into your code, you can either use", _jsx(Body1Strong, { children: "Color3.FromHexString(LINEAR_HEX)" }), _jsx("br", {}), "or", _jsx("br", {}), _jsx(Body1Strong, { children: "Color3.FromHexString(GAMMA_HEX).toLinearSpace()" }), _jsx("br", {}), _jsx("br", {}), _jsx(Link, { href: "https://doc.babylonjs.com/preparingArtForBabylon/controllingColorSpace/", children: " Read more in our docs! " })] })),
|
93
|
+
}
|
94
|
+
: undefined }) }));
|
92
95
|
};
|
93
96
|
const InputRgbField = (props) => {
|
94
|
-
const {
|
95
|
-
const id = useId(`${label.toLowerCase()}-input`);
|
97
|
+
const { value, onChange, title, rgbKey } = props;
|
96
98
|
const classes = useColorPickerStyles();
|
97
|
-
const handleChange = useCallback((
|
98
|
-
const
|
99
|
-
if (val === null || Number.isNaN(val) || !NUMBER_REGEX.test(val.toString())) {
|
100
|
-
return;
|
101
|
-
}
|
102
|
-
const newColor = color.clone();
|
99
|
+
const handleChange = useCallback((val) => {
|
100
|
+
const newColor = value.clone();
|
103
101
|
newColor[rgbKey] = val / 255.0; // Convert to 0-1 range
|
104
102
|
onChange(newColor);
|
105
|
-
}, [
|
106
|
-
return (
|
103
|
+
}, [value, onChange, rgbKey]);
|
104
|
+
return (_jsx("div", { className: classes.colorFieldWrapper, children: _jsx(SpinButton, { title: title, infoLabel: title ? { label: title } : undefined, className: classes.spinButton, min: 0, max: 255, value: Math.round(value[rgbKey] * 255), forceInt: true, onChange: handleChange }) }));
|
107
105
|
};
|
106
|
+
function rgbaToHsv(color) {
|
107
|
+
const c = new Color3(color.r, color.g, color.b);
|
108
|
+
const hsv = c.toHSV();
|
109
|
+
return { h: hsv.r, s: hsv.g, v: hsv.b, a: color.a };
|
110
|
+
}
|
108
111
|
/**
|
109
112
|
* In the HSV (Hue, Saturation, Value) color model, Hue (H) ranges from 0 to 360 degrees, representing the color's position on the color wheel.
|
110
113
|
* Saturation (S) ranges from 0 to 100%, indicating the intensity or purity of the color, with 0 being shades of gray and 100 being a fully saturated color.
|
@@ -112,24 +115,19 @@ const InputRgbField = (props) => {
|
|
112
115
|
* @param props - The properties for the InputHsvField component.
|
113
116
|
*/
|
114
117
|
export const InputHsvField = (props) => {
|
115
|
-
const {
|
116
|
-
const id = useId(`${label.toLowerCase()}-input`);
|
118
|
+
const { value, title, hsvKey, max, onChange, scale = 1 } = props;
|
117
119
|
const classes = useColorPickerStyles();
|
118
|
-
const handleChange = useCallback((
|
119
|
-
const val = data.value ?? parseFloat(data.displayValue ?? "");
|
120
|
-
if (val === null || Number.isNaN(val) || !NUMBER_REGEX.test(val.toString())) {
|
121
|
-
return;
|
122
|
-
}
|
120
|
+
const handleChange = useCallback((val) => {
|
123
121
|
// Convert current color to HSV, update the new hsv value, then call onChange prop
|
124
|
-
const hsv = rgbaToHsv(
|
122
|
+
const hsv = rgbaToHsv(value);
|
125
123
|
hsv[hsvKey] = val / scale;
|
126
124
|
let newColor = Color3.FromHSV(hsv.h, hsv.s, hsv.v);
|
127
|
-
if (
|
128
|
-
newColor = Color4.FromColor3(newColor,
|
125
|
+
if (value instanceof Color4) {
|
126
|
+
newColor = Color4.FromColor3(newColor, value.a ?? 1);
|
129
127
|
}
|
130
128
|
props.onChange(newColor);
|
131
|
-
}, [
|
132
|
-
return (
|
129
|
+
}, [value, onChange, hsvKey, scale]);
|
130
|
+
return (_jsx("div", { className: classes.colorFieldWrapper, children: _jsx(SpinButton, { infoLabel: title ? { label: title } : undefined, title: title, className: classes.spinButton, min: 0, max: max, value: Math.round(rgbaToHsv(value)[hsvKey] * scale), forceInt: true, onChange: handleChange }) }));
|
133
131
|
};
|
134
132
|
/**
|
135
133
|
* Displays the alpha value of a color, either in the disabled state (if color is Color3) or as a spin button (if color is Color4).
|
@@ -138,10 +136,8 @@ export const InputHsvField = (props) => {
|
|
138
136
|
*/
|
139
137
|
const InputAlphaField = (props) => {
|
140
138
|
const classes = useColorPickerStyles();
|
141
|
-
const
|
142
|
-
const
|
143
|
-
const onChange = (_, data) => {
|
144
|
-
const value = data.value ?? parseFloat(data.displayValue ?? "");
|
139
|
+
const { color, onChange } = props;
|
140
|
+
const handleChange = useCallback((value) => {
|
145
141
|
if (Number.isNaN(value) || value < 0 || value > 1) {
|
146
142
|
return;
|
147
143
|
}
|
@@ -153,13 +149,10 @@ const InputAlphaField = (props) => {
|
|
153
149
|
else {
|
154
150
|
return Color4.FromColor3(color, value);
|
155
151
|
}
|
156
|
-
};
|
157
|
-
return (
|
152
|
+
}, [onChange]);
|
153
|
+
return (_jsx("div", { className: classes.colorFieldWrapper, children: _jsx(SpinButton, { disabled: color instanceof Color3, min: 0, max: 1, className: classes.spinButton, value: color instanceof Color3 ? 1 : color.a, step: 0.01, onChange: handleChange, infoLabel: {
|
154
|
+
label: "Alpha",
|
155
|
+
info: color instanceof Color3 ? (_jsx(_Fragment, { children: "Because this color picker is representing a Color3, we do not permit modifying alpha from the color picker. You can however modify the entity's alpha property directly, either in code via entity.alpha OR via inspector's transparency section." })) : undefined,
|
156
|
+
} }) }));
|
158
157
|
};
|
159
|
-
const NUMBER_REGEX = /^\d+$/;
|
160
|
-
function rgbaToHsv(color) {
|
161
|
-
const c = new Color3(color.r, color.g, color.b);
|
162
|
-
const hsv = c.toHSV();
|
163
|
-
return { h: hsv.r, s: hsv.g, v: hsv.b, a: color.a };
|
164
|
-
}
|
165
158
|
//# sourceMappingURL=colorPicker.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"colorPicker.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/colorPicker.tsx"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable jsdoc/require-returns */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { useState, useEffect, useCallback } from \"react\";\r\nimport type { FunctionComponent, ChangeEvent } from \"react\";\r\nimport {\r\n Input,\r\n Label,\r\n SpinButton,\r\n useId,\r\n ColorPicker,\r\n ColorSlider,\r\n ColorArea,\r\n AlphaSlider,\r\n InfoLabel,\r\n Link,\r\n makeStyles,\r\n Popover,\r\n PopoverSurface,\r\n PopoverTrigger,\r\n tokens,\r\n Body1Strong,\r\n ColorSwatch,\r\n} from \"@fluentui/react-components\";\r\nimport type { SpinButtonChangeEvent, SpinButtonOnChangeData, ColorPickerProps as FluentColorPickerProps, InputOnChangeData } from \"@fluentui/react-components\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useColorPickerStyles = makeStyles({\r\n colorPickerContainer: {\r\n width: \"325px\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalMNudge, // 10px\r\n overflow: \"visible\",\r\n },\r\n previewColor: {\r\n width: \"50px\",\r\n height: \"50px\",\r\n borderRadius: tokens.borderRadiusMedium,\r\n border: `${tokens.spacingVerticalXXS} solid ${tokens.colorNeutralShadowKeyLighter}`,\r\n \"@media (forced-colors: active)\": {\r\n forcedColorAdjust: \"none\", // ensures elmement maintains color in high constrast mode\r\n },\r\n },\r\n row: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n gap: tokens.spacingVerticalM, // 12px\r\n alignItems: \"center\",\r\n },\r\n colorFieldWrapper: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalSNudge, // 6px\r\n },\r\n input: {\r\n width: \"80px\",\r\n },\r\n spinButton: {\r\n minWidth: \"60px\",\r\n },\r\n container: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalL, // 16px\r\n },\r\n});\r\n\r\nexport type ColorPickerProps<C extends Color3 | Color4> = {\r\n isLinearMode?: boolean;\r\n} & PrimitiveProps<C>;\r\n\r\nexport const ColorPickerPopup: FunctionComponent<ColorPickerProps<Color3 | Color4>> = (props) => {\r\n const classes = useColorPickerStyles();\r\n const [color, setColor] = useState(props.value);\r\n\r\n const [popoverOpen, setPopoverOpen] = useState(false);\r\n\r\n useEffect(() => {\r\n setColor(props.value); // Ensures the trigger color updates when props.value changes\r\n }, [props.value]);\r\n\r\n const handleColorPickerChange: FluentColorPickerProps[\"onColorChange\"] = (_, data) => {\r\n let color: Color3 | Color4 = Color3.FromHSV(data.color.h, data.color.s, data.color.v);\r\n if (props.value instanceof Color4) {\r\n color = Color4.FromColor3(color, data.color.a ?? 1);\r\n }\r\n handleChange(color);\r\n };\r\n\r\n const handleChange = (newColor: Color3 | Color4) => {\r\n setColor(newColor);\r\n props.onChange(newColor); // Ensures the parent is notified when color changes from within colorPicker\r\n };\r\n\r\n return (\r\n <Popover\r\n positioning={{\r\n align: \"start\",\r\n overflowBoundary: document.body,\r\n autoSize: true,\r\n }}\r\n open={popoverOpen}\r\n trapFocus\r\n onOpenChange={(_, data) => setPopoverOpen(data.open)}\r\n >\r\n <PopoverTrigger disableButtonEnhancement>\r\n <ColorSwatch borderColor={tokens.colorNeutralShadowKeyDarker} size=\"small\" color={color.toHexString()} value={color.toHexString().slice(1)} />\r\n </PopoverTrigger>\r\n\r\n <PopoverSurface>\r\n <div className={classes.colorPickerContainer}>\r\n <ColorPicker color={rgbaToHsv(color)} onColorChange={handleColorPickerChange}>\r\n <ColorArea inputX={{ \"aria-label\": \"Saturation\" }} inputY={{ \"aria-label\": \"Brightness\" }} />\r\n <ColorSlider aria-label=\"Hue\" />\r\n {color instanceof Color4 && <AlphaSlider aria-label=\"Alpha\" />}\r\n </ColorPicker>\r\n <div className={classes.container}>\r\n {/* Top Row: Preview, Gamma Hex, Linear Hex */}\r\n <div className={classes.row}>\r\n <div className={classes.previewColor} style={{ backgroundColor: color.toHexString() }} />\r\n <InputHexField label=\"Gamma Hex\" value={color} isLinearMode={props.isLinearMode} onChange={handleChange} />\r\n <InputHexField label=\"Linear Hex\" linearHex={true} isLinearMode={props.isLinearMode} value={color} onChange={handleChange} />\r\n </div>\r\n\r\n {/* Middle Row: Red, Green, Blue, Alpha */}\r\n <div className={classes.row}>\r\n <InputRgbField label=\"Red\" color={color} rgbKey=\"r\" onChange={handleChange} />\r\n <InputRgbField label=\"Green\" color={color} rgbKey=\"g\" onChange={handleChange} />\r\n <InputRgbField label=\"Blue\" color={color} rgbKey=\"b\" onChange={handleChange} />\r\n <InputAlphaField color={color} onChange={handleChange} />\r\n </div>\r\n\r\n {/* Bottom Row: Hue, Saturation, Value */}\r\n <div className={classes.row}>\r\n <InputHsvField label=\"Hue\" color={color} hsvKey=\"h\" max={360} onChange={handleChange} />\r\n <InputHsvField label=\"Saturation\" color={color} hsvKey=\"s\" max={100} scale={100} onChange={handleChange} />\r\n <InputHsvField label=\"Value\" color={color} hsvKey=\"v\" max={100} scale={100} onChange={handleChange} />\r\n </div>\r\n </div>\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\r\n\r\ntype HsvKey = \"h\" | \"s\" | \"v\";\r\nexport type InputHexProps = PrimitiveProps<Color3 | Color4> & {\r\n label?: string;\r\n linearHex?: boolean;\r\n isLinearMode?: boolean;\r\n};\r\n/**\r\n * Component which displays the passed in color's HEX value, either in linearSpace (if linearHex is true) or in gamma space\r\n * When the hex color is changed by user, component calculates the new Color3/4 value and calls onChange\r\n *\r\n * Component uses the isLinearMode boolean to display an informative label regarding linear / gamma space\r\n * @param props - The properties for the InputHexField component.\r\n * @returns\r\n */\r\nexport const InputHexField: FunctionComponent<InputHexProps> = (props) => {\r\n const id = useId(\"hex-input\");\r\n const styles = useColorPickerStyles();\r\n const { label, value, onChange, linearHex, isLinearMode } = props;\r\n\r\n const handleChange = (e: ChangeEvent<HTMLInputElement>, _: InputOnChangeData) => {\r\n // If linearHint (aka PBR material, ensure the other values are displayed in gamma even if linear hex changes)\r\n const value = e.target.value;\r\n if (value != \"\" && /^[0-9A-Fa-f]+$/g.test(value) == false) {\r\n return;\r\n }\r\n onChange(Color3.FromHexString(value).toGammaSpace());\r\n };\r\n return (\r\n <div className={styles.colorFieldWrapper}>\r\n {props.linearHex ? (\r\n <InfoLabel\r\n htmlFor={id}\r\n info={\r\n !isLinearMode ? (\r\n <> This color picker is attached to an entity whose color is stored in gamma space, so we are showing linear hex in disabled view </>\r\n ) : (\r\n <>\r\n This color picker is attached to an entity whose color is stored in linear space (ex: PBR Material), and Babylon converts the color to gamma space\r\n before rendering on screen because the human eye is best at processing colors in gamma space. We thus also want to display the color picker in gamma\r\n space so that the color chosen here will match the color seen in your entity.\r\n <br />\r\n If you want to copy/paste the HEX into your code, you can either use\r\n <Body1Strong>Color3.FromHexString(LINEAR_HEX)</Body1Strong>\r\n <br />\r\n or\r\n <br />\r\n <Body1Strong>Color3.FromHexString(GAMMA_HEX).toLinearSpace()</Body1Strong>\r\n <br />\r\n <br />\r\n <Link href=\"https://doc.babylonjs.com/preparingArtForBabylon/controllingColorSpace/\"> Read more in our docs! </Link>\r\n </>\r\n )\r\n }\r\n >\r\n {label}\r\n </InfoLabel>\r\n ) : (\r\n <Label htmlFor={id}>{label}</Label>\r\n )}\r\n <Input\r\n disabled={linearHex ? !isLinearMode : false}\r\n className={styles.input}\r\n value={linearHex ? value.toLinearSpace().toHexString() : value.toHexString()}\r\n id={id}\r\n onChange={handleChange}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ntype RgbKey = \"r\" | \"g\" | \"b\";\r\ntype InputRgbFieldProps = {\r\n color: Color3 | Color4;\r\n label: string;\r\n rgbKey: RgbKey;\r\n onChange: (color: Color3 | Color4) => void;\r\n};\r\n\r\nconst InputRgbField: FunctionComponent<InputRgbFieldProps> = (props) => {\r\n const { color, onChange, label, rgbKey } = props;\r\n const id = useId(`${label.toLowerCase()}-input`);\r\n const classes = useColorPickerStyles();\r\n\r\n const handleChange = useCallback(\r\n (_: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n const val = data.value ?? parseFloat(data.displayValue ?? \"\");\r\n\r\n if (val === null || Number.isNaN(val) || !NUMBER_REGEX.test(val.toString())) {\r\n return;\r\n }\r\n\r\n const newColor = color.clone();\r\n newColor[rgbKey] = val / 255.0; // Convert to 0-1 range\r\n onChange(newColor);\r\n },\r\n [color]\r\n );\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <Label htmlFor={id}>{label}</Label>\r\n <SpinButton className={classes.spinButton} min={0} max={255} value={color[rgbKey] * 255.0} step={1} id={id} onChange={handleChange} name={rgbKey} />\r\n </div>\r\n );\r\n};\r\n\r\ntype InputHsvFieldProps = {\r\n color: Color3 | Color4;\r\n label: string;\r\n hsvKey: HsvKey;\r\n onChange: (color: Color3 | Color4) => void;\r\n max: number;\r\n scale?: number;\r\n};\r\n\r\n/**\r\n * In the HSV (Hue, Saturation, Value) color model, Hue (H) ranges from 0 to 360 degrees, representing the color's position on the color wheel.\r\n * Saturation (S) ranges from 0 to 100%, indicating the intensity or purity of the color, with 0 being shades of gray and 100 being a fully saturated color.\r\n * Value (V) ranges from 0 to 100%, representing the brightness of the color, with 0 being black and 100 being the brightest.\r\n * @param props - The properties for the InputHsvField component.\r\n */\r\nexport const InputHsvField: FunctionComponent<InputHsvFieldProps> = (props) => {\r\n const { color, label, hsvKey, max, scale = 1 } = props;\r\n\r\n const id = useId(`${label.toLowerCase()}-input`);\r\n const classes = useColorPickerStyles();\r\n\r\n const handleChange = useCallback(\r\n (_: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n const val = data.value ?? parseFloat(data.displayValue ?? \"\");\r\n\r\n if (val === null || Number.isNaN(val) || !NUMBER_REGEX.test(val.toString())) {\r\n return;\r\n }\r\n\r\n // Convert current color to HSV, update the new hsv value, then call onChange prop\r\n const hsv = rgbaToHsv(color);\r\n hsv[hsvKey] = val / scale;\r\n let newColor: Color3 | Color4 = Color3.FromHSV(hsv.h, hsv.s, hsv.v);\r\n if (color instanceof Color4) {\r\n newColor = Color4.FromColor3(newColor, color.a ?? 1);\r\n }\r\n props.onChange(newColor);\r\n },\r\n [color]\r\n );\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <Label htmlFor={id}>{label}</Label>\r\n <SpinButton className={classes.spinButton} min={0} max={max} value={rgbaToHsv(color)[hsvKey] * scale} step={1} id={id} onChange={handleChange} name={hsvKey} />\r\n </div>\r\n );\r\n};\r\n\r\ntype InputAlphaProps = {\r\n color: Color3 | Color4;\r\n onChange: (color: Color4) => void;\r\n};\r\n\r\n/**\r\n * Displays the alpha value of a color, either in the disabled state (if color is Color3) or as a spin button (if color is Color4).\r\n * @param props\r\n * @returns\r\n */\r\nconst InputAlphaField: FunctionComponent<InputAlphaProps> = (props) => {\r\n const classes = useColorPickerStyles();\r\n const id = useId(\"alpha-input\");\r\n const { color } = props;\r\n\r\n const onChange = (_: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n const value = data.value ?? parseFloat(data.displayValue ?? \"\");\r\n\r\n if (Number.isNaN(value) || value < 0 || value > 1) {\r\n return;\r\n }\r\n\r\n if (color instanceof Color4) {\r\n const newColor = color.clone();\r\n newColor.a = value;\r\n return newColor;\r\n } else {\r\n return Color4.FromColor3(color, value);\r\n }\r\n };\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <div className={classes.row}>\r\n <Label htmlFor={id}>Alpha</Label>\r\n {color instanceof Color3 && (\r\n <InfoLabel\r\n htmlFor={id}\r\n info={\r\n <>\r\n Because this color picker is representing a Color3, we do not permit modifying alpha from the color picker. You can however modify the material's\r\n alpha property directly, either in code via material.alpha OR via inspector's transparency section.\r\n </>\r\n }\r\n ></InfoLabel>\r\n )}\r\n </div>\r\n <SpinButton\r\n disabled={color instanceof Color3}\r\n min={0}\r\n max={1}\r\n className={classes.spinButton}\r\n value={color instanceof Color3 ? 1 : color.a}\r\n step={0.01}\r\n onChange={onChange}\r\n id={id}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nconst NUMBER_REGEX = /^\\d+$/;\r\n\r\nfunction rgbaToHsv(color: { r: number; g: number; b: number; a?: number }): { h: number; s: number; v: number; a?: number } {\r\n const c = new Color3(color.r, color.g, color.b);\r\n const hsv = c.toHSV();\r\n return { h: hsv.r, s: hsv.g, v: hsv.b, a: color.a };\r\n}\r\n"]}
|
1
|
+
{"version":3,"file":"colorPicker.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/colorPicker.tsx"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable jsdoc/require-returns */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { useState, useEffect, useCallback } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport {\r\n ColorPicker as FluentColorPicker,\r\n ColorSlider,\r\n ColorArea,\r\n AlphaSlider,\r\n Link,\r\n makeStyles,\r\n Popover,\r\n PopoverSurface,\r\n PopoverTrigger,\r\n tokens,\r\n Body1Strong,\r\n ColorSwatch,\r\n} from \"@fluentui/react-components\";\r\nimport type { ColorPickerProps as FluentColorPickerProps } from \"@fluentui/react-components\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { SpinButton } from \"./spinButton\";\r\nimport { TextInput } from \"./textInput\";\r\n\r\nconst useColorPickerStyles = makeStyles({\r\n colorPickerContainer: {\r\n width: \"325px\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalMNudge, // 10px\r\n overflow: \"visible\",\r\n },\r\n previewColor: {\r\n width: \"50px\",\r\n height: \"50px\",\r\n borderRadius: tokens.borderRadiusMedium,\r\n border: `${tokens.spacingVerticalXXS} solid ${tokens.colorNeutralShadowKeyLighter}`,\r\n \"@media (forced-colors: active)\": {\r\n forcedColorAdjust: \"none\", // ensures elmement maintains color in high constrast mode\r\n },\r\n },\r\n row: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n gap: tokens.spacingVerticalM, // 12px\r\n alignItems: \"center\",\r\n },\r\n colorFieldWrapper: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalSNudge, // 6px\r\n },\r\n input: {\r\n width: \"80px\",\r\n },\r\n spinButton: {\r\n width: \"50px\",\r\n },\r\n container: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: tokens.spacingVerticalL, // 16px\r\n },\r\n});\r\n\r\nexport type ColorPickerProps<C extends Color3 | Color4> = {\r\n isLinearMode?: boolean;\r\n} & PrimitiveProps<C>;\r\n\r\nexport const ColorPickerPopup: FunctionComponent<ColorPickerProps<Color3 | Color4>> = (props) => {\r\n const classes = useColorPickerStyles();\r\n const [color, setColor] = useState(props.value);\r\n\r\n const [popoverOpen, setPopoverOpen] = useState(false);\r\n\r\n useEffect(() => {\r\n setColor(props.value); // Ensures the trigger color updates when props.value changes\r\n }, [props.value]);\r\n\r\n const handleColorPickerChange: FluentColorPickerProps[\"onColorChange\"] = (_, data) => {\r\n let color: Color3 | Color4 = Color3.FromHSV(data.color.h, data.color.s, data.color.v);\r\n if (props.value instanceof Color4) {\r\n color = Color4.FromColor3(color, data.color.a ?? 1);\r\n }\r\n handleChange(color);\r\n };\r\n\r\n const handleChange = (newColor: Color3 | Color4) => {\r\n setColor(newColor);\r\n props.onChange(newColor); // Ensures the parent is notified when color changes from within colorPicker\r\n };\r\n\r\n return (\r\n <Popover\r\n positioning={{\r\n align: \"start\",\r\n overflowBoundary: document.body,\r\n autoSize: true,\r\n }}\r\n open={popoverOpen}\r\n trapFocus\r\n onOpenChange={(_, data) => setPopoverOpen(data.open)}\r\n >\r\n <PopoverTrigger disableButtonEnhancement>\r\n <ColorSwatch borderColor={tokens.colorNeutralShadowKeyDarker} size=\"small\" color={color.toHexString()} value={color.toHexString().slice(1)} />\r\n </PopoverTrigger>\r\n\r\n <PopoverSurface>\r\n <div className={classes.colorPickerContainer}>\r\n <FluentColorPicker color={rgbaToHsv(color)} onColorChange={handleColorPickerChange}>\r\n <ColorArea inputX={{ \"aria-label\": \"Saturation\" }} inputY={{ \"aria-label\": \"Brightness\" }} />\r\n <ColorSlider aria-label=\"Hue\" />\r\n {color instanceof Color4 && <AlphaSlider aria-label=\"Alpha\" />}\r\n </FluentColorPicker>\r\n <div className={classes.container}>\r\n {/* Top Row: Preview, Gamma Hex, Linear Hex */}\r\n <div className={classes.row}>\r\n <div className={classes.previewColor} style={{ backgroundColor: color.toHexString() }} />\r\n <InputHexField title=\"Gamma Hex\" value={color} isLinearMode={props.isLinearMode} onChange={handleChange} />\r\n <InputHexField title=\"Linear Hex\" linearHex={true} isLinearMode={props.isLinearMode} value={color} onChange={handleChange} />\r\n </div>\r\n\r\n {/* Middle Row: Red, Green, Blue, Alpha */}\r\n <div className={classes.row}>\r\n <InputRgbField title=\"Red\" value={color} rgbKey=\"r\" onChange={handleChange} />\r\n <InputRgbField title=\"Green\" value={color} rgbKey=\"g\" onChange={handleChange} />\r\n <InputRgbField title=\"Blue\" value={color} rgbKey=\"b\" onChange={handleChange} />\r\n <InputAlphaField color={color} onChange={handleChange} />\r\n </div>\r\n\r\n {/* Bottom Row: Hue, Saturation, Value */}\r\n <div className={classes.row}>\r\n <InputHsvField title=\"Hue\" value={color} hsvKey=\"h\" max={360} onChange={handleChange} />\r\n <InputHsvField title=\"Saturation\" value={color} hsvKey=\"s\" max={100} scale={100} onChange={handleChange} />\r\n <InputHsvField title=\"Value\" value={color} hsvKey=\"v\" max={100} scale={100} onChange={handleChange} />\r\n </div>\r\n </div>\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\r\n\r\nconst HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);\r\n\r\nexport type InputHexProps = PrimitiveProps<Color3 | Color4> & {\r\n linearHex?: boolean;\r\n isLinearMode?: boolean;\r\n};\r\n/**\r\n * Component which displays the passed in color's HEX value, either in linearSpace (if linearHex is true) or in gamma space\r\n * When the hex color is changed by user, component calculates the new Color3/4 value and calls onChange\r\n *\r\n * Component uses the isLinearMode boolean to display an informative label regarding linear / gamma space\r\n * @param props - The properties for the InputHexField component.\r\n * @returns\r\n */\r\nexport const InputHexField: FunctionComponent<InputHexProps> = (props) => {\r\n const styles = useColorPickerStyles();\r\n const { title, value, onChange, linearHex, isLinearMode } = props;\r\n\r\n return (\r\n <div className={styles.colorFieldWrapper}>\r\n <TextInput\r\n disabled={linearHex ? !isLinearMode : false}\r\n className={styles.input}\r\n value={linearHex ? value.toLinearSpace().toHexString() : value.toHexString()}\r\n validator={(val) => val != \"\" && HEX_REGEX.test(val)}\r\n onChange={(val) => (linearHex ? onChange(Color3.FromHexString(val).toGammaSpace()) : onChange(Color3.FromHexString(val)))}\r\n infoLabel={\r\n title\r\n ? {\r\n label: title,\r\n // If not representing a linearHex, no info is needed.\r\n info: !props.linearHex ? undefined : !isLinearMode ? ( // If representing a linear hex but we are in gammaMode, simple message explaining why linearHex is disabled\r\n <> This color picker is attached to an entity whose color is stored in gamma space, so we are showing linear hex in disabled view </>\r\n ) : (\r\n // If representing a linear hex and we are in linearMode, give information about how to use these hex values\r\n <>\r\n This color picker is attached to an entity whose color is stored in linear space (ex: PBR Material), and Babylon converts the color to gamma\r\n space before rendering on screen because the human eye is best at processing colors in gamma space. We thus also want to display the color\r\n picker in gamma space so that the color chosen here will match the color seen in your entity.\r\n <br />\r\n If you want to copy/paste the HEX into your code, you can either use\r\n <Body1Strong>Color3.FromHexString(LINEAR_HEX)</Body1Strong>\r\n <br />\r\n or\r\n <br />\r\n <Body1Strong>Color3.FromHexString(GAMMA_HEX).toLinearSpace()</Body1Strong>\r\n <br />\r\n <br />\r\n <Link href=\"https://doc.babylonjs.com/preparingArtForBabylon/controllingColorSpace/\"> Read more in our docs! </Link>\r\n </>\r\n ),\r\n }\r\n : undefined\r\n }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ntype RgbKey = \"r\" | \"g\" | \"b\";\r\ntype InputRgbFieldProps = PrimitiveProps<Color3 | Color4> & {\r\n rgbKey: RgbKey;\r\n};\r\n\r\nconst InputRgbField: FunctionComponent<InputRgbFieldProps> = (props) => {\r\n const { value, onChange, title, rgbKey } = props;\r\n const classes = useColorPickerStyles();\r\n\r\n const handleChange = useCallback(\r\n (val: number) => {\r\n const newColor = value.clone();\r\n newColor[rgbKey] = val / 255.0; // Convert to 0-1 range\r\n onChange(newColor);\r\n },\r\n [value, onChange, rgbKey]\r\n );\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <SpinButton\r\n title={title}\r\n infoLabel={title ? { label: title } : undefined}\r\n className={classes.spinButton}\r\n min={0}\r\n max={255}\r\n value={Math.round(value[rgbKey] * 255)}\r\n forceInt\r\n onChange={handleChange}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nfunction rgbaToHsv(color: { r: number; g: number; b: number; a?: number }): { h: number; s: number; v: number; a?: number } {\r\n const c = new Color3(color.r, color.g, color.b);\r\n const hsv = c.toHSV();\r\n return { h: hsv.r, s: hsv.g, v: hsv.b, a: color.a };\r\n}\r\n\r\ntype HsvKey = \"h\" | \"s\" | \"v\";\r\ntype InputHsvFieldProps = PrimitiveProps<Color3 | Color4> & {\r\n hsvKey: HsvKey;\r\n max: number;\r\n scale?: number;\r\n};\r\n\r\n/**\r\n * In the HSV (Hue, Saturation, Value) color model, Hue (H) ranges from 0 to 360 degrees, representing the color's position on the color wheel.\r\n * Saturation (S) ranges from 0 to 100%, indicating the intensity or purity of the color, with 0 being shades of gray and 100 being a fully saturated color.\r\n * Value (V) ranges from 0 to 100%, representing the brightness of the color, with 0 being black and 100 being the brightest.\r\n * @param props - The properties for the InputHsvField component.\r\n */\r\nexport const InputHsvField: FunctionComponent<InputHsvFieldProps> = (props) => {\r\n const { value, title, hsvKey, max, onChange, scale = 1 } = props;\r\n\r\n const classes = useColorPickerStyles();\r\n\r\n const handleChange = useCallback(\r\n (val: number) => {\r\n // Convert current color to HSV, update the new hsv value, then call onChange prop\r\n const hsv = rgbaToHsv(value);\r\n hsv[hsvKey] = val / scale;\r\n let newColor: Color3 | Color4 = Color3.FromHSV(hsv.h, hsv.s, hsv.v);\r\n if (value instanceof Color4) {\r\n newColor = Color4.FromColor3(newColor, value.a ?? 1);\r\n }\r\n props.onChange(newColor);\r\n },\r\n [value, onChange, hsvKey, scale]\r\n );\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <SpinButton\r\n infoLabel={title ? { label: title } : undefined}\r\n title={title}\r\n className={classes.spinButton}\r\n min={0}\r\n max={max}\r\n value={Math.round(rgbaToHsv(value)[hsvKey] * scale)}\r\n forceInt\r\n onChange={handleChange}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ntype InputAlphaProps = {\r\n color: Color3 | Color4;\r\n onChange: (color: Color4) => void;\r\n};\r\n\r\n/**\r\n * Displays the alpha value of a color, either in the disabled state (if color is Color3) or as a spin button (if color is Color4).\r\n * @param props\r\n * @returns\r\n */\r\nconst InputAlphaField: FunctionComponent<InputAlphaProps> = (props) => {\r\n const classes = useColorPickerStyles();\r\n const { color, onChange } = props;\r\n\r\n const handleChange = useCallback(\r\n (value: number) => {\r\n if (Number.isNaN(value) || value < 0 || value > 1) {\r\n return;\r\n }\r\n\r\n if (color instanceof Color4) {\r\n const newColor = color.clone();\r\n newColor.a = value;\r\n return newColor;\r\n } else {\r\n return Color4.FromColor3(color, value);\r\n }\r\n },\r\n [onChange]\r\n );\r\n\r\n return (\r\n <div className={classes.colorFieldWrapper}>\r\n <SpinButton\r\n disabled={color instanceof Color3}\r\n min={0}\r\n max={1}\r\n className={classes.spinButton}\r\n value={color instanceof Color3 ? 1 : color.a}\r\n step={0.01}\r\n onChange={handleChange}\r\n infoLabel={{\r\n label: \"Alpha\",\r\n info:\r\n color instanceof Color3 ? (\r\n <>\r\n Because this color picker is representing a Color3, we do not permit modifying alpha from the color picker. You can however modify the entity's\r\n alpha property directly, either in code via entity.alpha OR via inspector's transparency section.\r\n </>\r\n ) : undefined,\r\n }}\r\n />\r\n </div>\r\n );\r\n};\r\n"]}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import type { FunctionComponent } from "react";
|
2
|
+
export type InfoLabelProps = {
|
3
|
+
htmlFor: string;
|
4
|
+
info?: JSX.Element;
|
5
|
+
label: string;
|
6
|
+
};
|
7
|
+
export type InfoLabelParentProps = Omit<InfoLabelProps, "htmlFor">;
|
8
|
+
/**
|
9
|
+
* Renders a label with an optional popup containing more info
|
10
|
+
* @param props
|
11
|
+
* @returns
|
12
|
+
*/
|
13
|
+
export declare const InfoLabel: FunctionComponent<InfoLabelProps>;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { InfoLabel as FluentInfoLabel } from "@fluentui/react-components";
|
3
|
+
/**
|
4
|
+
* Renders a label with an optional popup containing more info
|
5
|
+
* @param props
|
6
|
+
* @returns
|
7
|
+
*/
|
8
|
+
export const InfoLabel = (props) => {
|
9
|
+
return (_jsx(FluentInfoLabel, { htmlFor: props.htmlFor, info: props.info, children: props.label }));
|
10
|
+
};
|
11
|
+
//# sourceMappingURL=infoLabel.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"infoLabel.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/infoLabel.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAS1E;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAsC,CAAC,KAAK,EAAE,EAAE;IAClE,OAAO,CACH,KAAC,eAAe,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,YACpD,KAAK,CAAC,KAAK,GACE,CACrB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport { InfoLabel as FluentInfoLabel } from \"@fluentui/react-components\";\r\n\r\nexport type InfoLabelProps = {\r\n htmlFor: string; // required ID of the element whose label we are applying\r\n info?: JSX.Element;\r\n label: string;\r\n};\r\nexport type InfoLabelParentProps = Omit<InfoLabelProps, \"htmlFor\">;\r\n\r\n/**\r\n * Renders a label with an optional popup containing more info\r\n * @param props\r\n * @returns\r\n */\r\nexport const InfoLabel: FunctionComponent<InfoLabelProps> = (props) => {\r\n return (\r\n <FluentInfoLabel htmlFor={props.htmlFor} info={props.info}>\r\n {props.label}\r\n </FluentInfoLabel>\r\n );\r\n};\r\n"]}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { InfoLabelParentProps } from "./infoLabel.js";
|
1
2
|
export type ImmutablePrimitiveProps<ValueT> = {
|
2
3
|
/**
|
3
4
|
* The value of the property to be displayed and modified.
|
@@ -15,6 +16,10 @@ export type ImmutablePrimitiveProps<ValueT> = {
|
|
15
16
|
* Optional title for the component, used for tooltips or accessibility.
|
16
17
|
*/
|
17
18
|
title?: string;
|
19
|
+
/**
|
20
|
+
* Optional information to display as an infoLabel popup aside the component.
|
21
|
+
*/
|
22
|
+
infoLabel?: InfoLabelParentProps;
|
18
23
|
};
|
19
24
|
export type PrimitiveProps<T> = ImmutablePrimitiveProps<T> & {
|
20
25
|
/**
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"primitive.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/primitive.ts"],"names":[],"mappings":"","sourcesContent":["
|
1
|
+
{"version":3,"file":"primitive.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/primitive.ts"],"names":[],"mappings":"","sourcesContent":["import type { InfoLabelParentProps } from \"./infoLabel\";\r\n\r\nexport type ImmutablePrimitiveProps<ValueT> = {\r\n /**\r\n * The value of the property to be displayed and modified.\r\n */\r\n value: ValueT;\r\n\r\n /**\r\n * Optional flag to disable the component, preventing any interaction.\r\n */\r\n disabled?: boolean;\r\n /**\r\n * Optional class name to apply custom styles to the component.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Optional title for the component, used for tooltips or accessibility.\r\n */\r\n title?: string;\r\n\r\n /**\r\n * Optional information to display as an infoLabel popup aside the component.\r\n */\r\n infoLabel?: InfoLabelParentProps;\r\n};\r\n\r\nexport type PrimitiveProps<T> = ImmutablePrimitiveProps<T> & {\r\n /**\r\n * Called when the primitive value changes\r\n */\r\n onChange: (value: T) => void;\r\n};\r\n"]}
|
@@ -1,9 +1,15 @@
|
|
1
|
-
import type { FunctionComponent } from "react";
|
1
|
+
import type { FunctionComponent, KeyboardEvent, FocusEvent } from "react";
|
2
2
|
import type { PrimitiveProps } from "./primitive.js";
|
3
3
|
export type SpinButtonProps = PrimitiveProps<number> & {
|
4
|
-
precision?: number;
|
5
|
-
step?: number;
|
6
4
|
min?: number;
|
7
5
|
max?: number;
|
6
|
+
/** Determines how much the spinbutton increments with the arrow keys. Note this also determines the precision value (# of decimals in display value)
|
7
|
+
* i.e. if step = 1, precision = 0. step = 0.0089, precision = 4. step = 300, precision = 2. step = 23.00, precision = 2. */
|
8
|
+
step?: number;
|
9
|
+
unit?: string;
|
10
|
+
forceInt?: boolean;
|
11
|
+
validator?: (value: number) => boolean;
|
8
12
|
};
|
9
13
|
export declare const SpinButton: FunctionComponent<SpinButtonProps>;
|
14
|
+
export declare function HandleOnBlur(event: FocusEvent<HTMLInputElement>): void;
|
15
|
+
export declare function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>): void;
|
@@ -1,28 +1,112 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { makeStyles, SpinButton as FluentSpinButton } from "@fluentui/react-components";
|
3
|
-
import {
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { makeStyles, SpinButton as FluentSpinButton, useId, tokens } from "@fluentui/react-components";
|
3
|
+
import { useEffect, useState, useRef } from "react";
|
4
|
+
import { InfoLabel } from "./infoLabel.js";
|
4
5
|
const useSpinStyles = makeStyles({
|
5
6
|
base: {
|
6
7
|
display: "flex",
|
7
8
|
flexDirection: "column",
|
9
|
+
minWidth: "55px",
|
8
10
|
},
|
11
|
+
invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
|
9
12
|
});
|
10
13
|
export const SpinButton = (props) => {
|
11
14
|
const classes = useSpinStyles();
|
12
|
-
const
|
13
|
-
const
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
const { min, max } = props;
|
16
|
+
const [value, setValue] = useState(props.value);
|
17
|
+
const lastCommittedValue = useRef(props.value);
|
18
|
+
// step and forceInt are not mutually exclusive since there could be cases where you want to forceInt but have spinButton jump >1 int per spin
|
19
|
+
const step = props.step != undefined ? props.step : props.forceInt ? 1 : undefined;
|
20
|
+
useEffect(() => {
|
21
|
+
if (props.value !== lastCommittedValue.current) {
|
22
|
+
lastCommittedValue.current = props.value;
|
23
|
+
setValue(props.value); // Update local state when props.value changes
|
18
24
|
}
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
}, [props.value]);
|
26
|
+
const validateValue = (numericValue) => {
|
27
|
+
const outOfBounds = (min !== undefined && numericValue < min) || (max !== undefined && numericValue > max);
|
28
|
+
const failsValidator = props.validator && !props.validator(numericValue);
|
29
|
+
const failsIntCheck = props.forceInt ? !Number.isInteger(numericValue) : false;
|
30
|
+
const invalid = !!outOfBounds || !!failsValidator || isNaN(numericValue) || !!failsIntCheck;
|
31
|
+
return !invalid;
|
32
|
+
};
|
33
|
+
const tryCommitValue = (currVal) => {
|
34
|
+
// Only commit if valid and different from last committed value
|
35
|
+
if (validateValue(currVal) && currVal !== lastCommittedValue.current) {
|
36
|
+
lastCommittedValue.current = currVal;
|
37
|
+
props.onChange(currVal);
|
24
38
|
}
|
25
|
-
}
|
26
|
-
|
39
|
+
};
|
40
|
+
const handleChange = (event, data) => {
|
41
|
+
event.stopPropagation(); // Prevent event propagation
|
42
|
+
if (data.value != null && !Number.isNaN(data.value)) {
|
43
|
+
setValue(data.value);
|
44
|
+
tryCommitValue(data.value);
|
45
|
+
}
|
46
|
+
};
|
47
|
+
const handleKeyUp = (event) => {
|
48
|
+
event.stopPropagation(); // Prevent event propagation
|
49
|
+
if (event.key !== "Enter") {
|
50
|
+
const currVal = parseFloat(event.target.value); // Cannot use currentTarget.value as it won't have the most recently typed value
|
51
|
+
setValue(currVal);
|
52
|
+
tryCommitValue(currVal);
|
53
|
+
}
|
54
|
+
};
|
55
|
+
const id = useId("spin-button");
|
56
|
+
return (_jsxs("div", { className: classes.base, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentSpinButton, { ...props, step: step, id: id, size: "small", precision: CalculatePrecision(step ?? 1.01), displayValue: props.unit ? `${PrecisionRound(value, CalculatePrecision(step ?? 1.01))} ${props.unit}` : undefined, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: `${!validateValue(value) ? classes.invalid : ""}` })] }));
|
27
57
|
};
|
58
|
+
/**
|
59
|
+
* Fluent's CalculatePrecision function
|
60
|
+
* https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L91C1
|
61
|
+
*
|
62
|
+
* Calculates a number's precision based on the number of trailing
|
63
|
+
* zeros if the number does not have a decimal indicated by a negative
|
64
|
+
* precision. Otherwise, it calculates the number of digits after
|
65
|
+
* the decimal point indicated by a positive precision.
|
66
|
+
*
|
67
|
+
* @param value - the value to determine the precision of
|
68
|
+
* @returns the calculated precision
|
69
|
+
*/
|
70
|
+
function CalculatePrecision(value) {
|
71
|
+
/**
|
72
|
+
* Group 1:
|
73
|
+
* [1-9]([0]+$) matches trailing zeros
|
74
|
+
* Group 2:
|
75
|
+
* \.([0-9]*) matches all digits after a decimal point.
|
76
|
+
*/ const groups = /[1-9]([0]+$)|\.([0-9]*)/.exec(String(value));
|
77
|
+
if (!groups) {
|
78
|
+
return 0;
|
79
|
+
}
|
80
|
+
if (groups[1]) {
|
81
|
+
return -groups[1].length;
|
82
|
+
}
|
83
|
+
if (groups[2]) {
|
84
|
+
return groups[2].length;
|
85
|
+
}
|
86
|
+
return 0;
|
87
|
+
}
|
88
|
+
/**
|
89
|
+
* Fluent's PrecisionRound function
|
90
|
+
* https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L116
|
91
|
+
*
|
92
|
+
* Rounds a number to a certain level of precision. Accepts negative precision.
|
93
|
+
* @param value - The value that is being rounded.
|
94
|
+
* @param precision - The number of decimal places to round the number to
|
95
|
+
* @returns The rounded number.
|
96
|
+
*/
|
97
|
+
function PrecisionRound(value, precision) {
|
98
|
+
const exp = Math.pow(10, precision);
|
99
|
+
return Math.round(value * exp) / exp;
|
100
|
+
}
|
101
|
+
export function HandleOnBlur(event) {
|
102
|
+
event.stopPropagation();
|
103
|
+
event.preventDefault();
|
104
|
+
}
|
105
|
+
export function HandleKeyDown(event) {
|
106
|
+
event.stopPropagation(); // Prevent event propagation
|
107
|
+
// Prevent Enter key from causing form submission or value reversion
|
108
|
+
if (event.key === "Enter") {
|
109
|
+
event.preventDefault();
|
110
|
+
}
|
111
|
+
}
|
28
112
|
//# sourceMappingURL=spinButton.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"spinButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/spinButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGxF,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG9C,MAAM,aAAa,GAAG,UAAU,CAAC;IAC7B,IAAI,EAAE;QACF,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;KAC1B;CACJ,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,UAAU,GAAuC,CAAC,KAAK,EAAE,EAAE;IACpE,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEpE,MAAM,kBAAkB,GAAG,WAAW,CAClC,CAAC,GAA0B,EAAE,IAA4B,EAAE,EAAE;QACzD,+DAA+D;QAC/D,GAAG,CAAC,eAAe,EAAE,CAAC;QAEtB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YACrB,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACjC,CAAC;QACL,CAAC;IACL,CAAC,EACD,CAAC,kBAAkB,CAAC,CACvB,CAAC;IAEF,OAAO,CACH,cAAK,SAAS,EAAE,OAAO,CAAC,IAAI,YACxB,KAAC,gBAAgB,OAAK,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,kBAAkB,GAAI,GACnF,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { makeStyles, SpinButton as FluentSpinButton } from \"@fluentui/react-components\";\r\nimport type { SpinButtonOnChangeData, SpinButtonChangeEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport { useCallback, useState } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useSpinStyles = makeStyles({\r\n base: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n },\r\n});\r\n\r\nexport type SpinButtonProps = PrimitiveProps<number> & {\r\n precision?: number; // Optional precision for the spin button\r\n step?: number; // Optional step value for the spin button\r\n min?: number;\r\n max?: number;\r\n};\r\n\r\nexport const SpinButton: FunctionComponent<SpinButtonProps> = (props) => {\r\n const classes = useSpinStyles();\r\n\r\n const [spinButtonValue, setSpinButtonValue] = useState(props.value);\r\n\r\n const onSpinButtonChange = useCallback(\r\n (_ev: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n // Stop propagation of the event to prevent it from bubbling up\r\n _ev.stopPropagation();\r\n\r\n if (data.value != null) {\r\n setSpinButtonValue(data.value);\r\n } else if (data.displayValue !== undefined) {\r\n const newValue = parseFloat(data.displayValue);\r\n if (!Number.isNaN(newValue)) {\r\n setSpinButtonValue(newValue);\r\n }\r\n }\r\n },\r\n [setSpinButtonValue]\r\n );\r\n\r\n return (\r\n <div className={classes.base}>\r\n <FluentSpinButton {...props} value={spinButtonValue} onChange={onSpinButtonChange} />\r\n </div>\r\n );\r\n};\r\n"]}
|
1
|
+
{"version":3,"file":"spinButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/spinButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { makeStyles, SpinButton as FluentSpinButton, useId, tokens } from \"@fluentui/react-components\";\r\nimport type { SpinButtonOnChangeData, SpinButtonChangeEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, KeyboardEvent, FocusEvent } from \"react\";\r\nimport { useEffect, useState, useRef } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\n\r\nconst useSpinStyles = makeStyles({\r\n base: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n minWidth: \"55px\",\r\n },\r\n invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },\r\n});\r\n\r\nexport type SpinButtonProps = PrimitiveProps<number> & {\r\n min?: number;\r\n max?: number;\r\n /** Determines how much the spinbutton increments with the arrow keys. Note this also determines the precision value (# of decimals in display value)\r\n * i.e. if step = 1, precision = 0. step = 0.0089, precision = 4. step = 300, precision = 2. step = 23.00, precision = 2. */\r\n step?: number;\r\n unit?: string;\r\n forceInt?: boolean;\r\n validator?: (value: number) => boolean;\r\n};\r\n\r\nexport const SpinButton: FunctionComponent<SpinButtonProps> = (props) => {\r\n const classes = useSpinStyles();\r\n const { min, max } = props;\r\n\r\n const [value, setValue] = useState(props.value);\r\n const lastCommittedValue = useRef(props.value);\r\n // step and forceInt are not mutually exclusive since there could be cases where you want to forceInt but have spinButton jump >1 int per spin\r\n const step = props.step != undefined ? props.step : props.forceInt ? 1 : undefined;\r\n\r\n useEffect(() => {\r\n if (props.value !== lastCommittedValue.current) {\r\n lastCommittedValue.current = props.value;\r\n setValue(props.value); // Update local state when props.value changes\r\n }\r\n }, [props.value]);\r\n\r\n const validateValue = (numericValue: number): boolean => {\r\n const outOfBounds = (min !== undefined && numericValue < min) || (max !== undefined && numericValue > max);\r\n const failsValidator = props.validator && !props.validator(numericValue);\r\n const failsIntCheck = props.forceInt ? !Number.isInteger(numericValue) : false;\r\n const invalid = !!outOfBounds || !!failsValidator || isNaN(numericValue) || !!failsIntCheck;\r\n return !invalid;\r\n };\r\n\r\n const tryCommitValue = (currVal: number) => {\r\n // Only commit if valid and different from last committed value\r\n if (validateValue(currVal) && currVal !== lastCommittedValue.current) {\r\n lastCommittedValue.current = currVal;\r\n props.onChange(currVal);\r\n }\r\n };\r\n\r\n const handleChange = (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n if (data.value != null && !Number.isNaN(data.value)) {\r\n setValue(data.value);\r\n tryCommitValue(data.value);\r\n }\r\n };\r\n\r\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n if (event.key !== \"Enter\") {\r\n const currVal = parseFloat((event.target as any).value); // Cannot use currentTarget.value as it won't have the most recently typed value\r\n setValue(currVal);\r\n tryCommitValue(currVal);\r\n }\r\n };\r\n\r\n const id = useId(\"spin-button\");\r\n return (\r\n <div className={classes.base}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentSpinButton\r\n {...props}\r\n step={step}\r\n id={id}\r\n size=\"small\"\r\n precision={CalculatePrecision(step ?? 1.01)}\r\n displayValue={props.unit ? `${PrecisionRound(value, CalculatePrecision(step ?? 1.01))} ${props.unit}` : undefined}\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={`${!validateValue(value) ? classes.invalid : \"\"}`}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Fluent's CalculatePrecision function\r\n * https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L91C1\r\n *\r\n * Calculates a number's precision based on the number of trailing\r\n * zeros if the number does not have a decimal indicated by a negative\r\n * precision. Otherwise, it calculates the number of digits after\r\n * the decimal point indicated by a positive precision.\r\n *\r\n * @param value - the value to determine the precision of\r\n * @returns the calculated precision\r\n */\r\nfunction CalculatePrecision(value: number) {\r\n /**\r\n * Group 1:\r\n * [1-9]([0]+$) matches trailing zeros\r\n * Group 2:\r\n * \\.([0-9]*) matches all digits after a decimal point.\r\n */ const groups = /[1-9]([0]+$)|\\.([0-9]*)/.exec(String(value));\r\n if (!groups) {\r\n return 0;\r\n }\r\n if (groups[1]) {\r\n return -groups[1].length;\r\n }\r\n if (groups[2]) {\r\n return groups[2].length;\r\n }\r\n return 0;\r\n}\r\n/**\r\n * Fluent's PrecisionRound function\r\n * https://github.com/microsoft/fluentui/blob/dcbf775d37938eacffa37922fc0b43a3cdd5753f/packages/utilities/src/math.ts#L116\r\n *\r\n * Rounds a number to a certain level of precision. Accepts negative precision.\r\n * @param value - The value that is being rounded.\r\n * @param precision - The number of decimal places to round the number to\r\n * @returns The rounded number.\r\n */\r\nfunction PrecisionRound(value: number, precision: number) {\r\n const exp = Math.pow(10, precision);\r\n return Math.round(value * exp) / exp;\r\n}\r\n\r\nexport function HandleOnBlur(event: FocusEvent<HTMLInputElement>) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n}\r\n\r\nexport function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\r\n event.stopPropagation(); // Prevent event propagation\r\n\r\n // Prevent Enter key from causing form submission or value reversion\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n }\r\n}\r\n"]}
|
@@ -7,6 +7,8 @@ export type SyncedSliderProps = PrimitiveProps<number> & {
|
|
7
7
|
max?: number;
|
8
8
|
/** Step size for the slider */
|
9
9
|
step?: number;
|
10
|
+
/** Displayed in the ux to indicate unit of measurement */
|
11
|
+
unit?: string;
|
10
12
|
/** When true, onChange is only called when the user releases the slider, not during drag */
|
11
13
|
notifyOnlyOnRelease?: boolean;
|
12
14
|
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import { makeStyles, Slider, tokens } from "@fluentui/react-components";
|
3
|
-
import {
|
3
|
+
import { SpinButton } from "./spinButton.js";
|
4
4
|
import { useEffect, useState, useRef } from "react";
|
5
5
|
const useSyncedSliderStyles = makeStyles({
|
6
6
|
syncedSlider: {
|
@@ -13,9 +13,8 @@ const useSyncedSliderStyles = makeStyles({
|
|
13
13
|
flexGrow: 1, // Let slider grow
|
14
14
|
minWidth: "40px", // Minimum width for slider to remain usable
|
15
15
|
},
|
16
|
-
|
17
|
-
width: "
|
18
|
-
flexShrink: 0,
|
16
|
+
spinButton: {
|
17
|
+
width: "60px",
|
19
18
|
},
|
20
19
|
});
|
21
20
|
/**
|
@@ -60,12 +59,9 @@ export const SyncedSliderInput = (props) => {
|
|
60
59
|
isDraggingRef.current = false;
|
61
60
|
};
|
62
61
|
const handleInputChange = (value) => {
|
63
|
-
|
64
|
-
|
65
|
-
setValue(newValue);
|
66
|
-
props.onChange(newValue); // Input always updates immediately
|
67
|
-
}
|
62
|
+
setValue(value);
|
63
|
+
props.onChange(value); // Input always updates immediately
|
68
64
|
};
|
69
|
-
return (_jsxs("div", { className: classes.syncedSlider, children: [props.min !== undefined && props.max !== undefined && (_jsx(Slider, { ...props, size: "small", className: classes.slider, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(
|
65
|
+
return (_jsxs("div", { className: classes.syncedSlider, children: [props.min !== undefined && props.max !== undefined && (_jsx(Slider, { ...props, size: "small", className: classes.slider, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(SpinButton, { ...props, className: classes.spinButton, value: Math.round(value / step) * step, onChange: handleInputChange, step: props.step })] }));
|
70
66
|
};
|
71
67
|
//# sourceMappingURL=syncedSlider.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"syncedSlider.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/syncedSlider.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,
|
1
|
+
{"version":3,"file":"syncedSlider.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/syncedSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SliderOnChangeData } from \"@fluentui/react-components\";\r\nimport { makeStyles, Slider, tokens } from \"@fluentui/react-components\";\r\nimport { SpinButton } from \"./spinButton\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\nimport { useEffect, useState, useRef } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useSyncedSliderStyles = makeStyles({\r\n syncedSlider: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalXXS, // 2px\r\n width: \"100%\", // Only fill available space\r\n },\r\n slider: {\r\n flexGrow: 1, // Let slider grow\r\n minWidth: \"40px\", // Minimum width for slider to remain usable\r\n },\r\n spinButton: {\r\n width: \"60px\",\r\n },\r\n});\r\n\r\nexport type SyncedSliderProps = PrimitiveProps<number> & {\r\n /** Minimum value for the slider */\r\n min?: number;\r\n /** Maximum value for the slider */\r\n max?: number;\r\n /** Step size for the slider */\r\n step?: number;\r\n /** Displayed in the ux to indicate unit of measurement */\r\n unit?: string;\r\n /** When true, onChange is only called when the user releases the slider, not during drag */\r\n notifyOnlyOnRelease?: boolean;\r\n};\r\n\r\n/**\r\n * Component which synchronizes a slider and an input field, allowing the user to change the value using either control\r\n * @param props\r\n * @returns SyncedSlider component\r\n */\r\nexport const SyncedSliderInput: FunctionComponent<SyncedSliderProps> = (props) => {\r\n const classes = useSyncedSliderStyles();\r\n const [value, setValue] = useState<number>(props.value);\r\n const pendingValueRef = useRef<number>(undefined);\r\n const isDraggingRef = useRef(false);\r\n\r\n // NOTE: The Fluent slider will add tick marks if the step prop is anything other than undefined.\r\n // To avoid this, we scale the min/max based on the step so we can always make step undefined.\r\n // The actual step size in the Fluent slider is 1 when it is ste to undefined.\r\n const min = props.min ?? 0;\r\n const max = props.max ?? 100;\r\n const step = props.step ?? 1;\r\n\r\n useEffect(() => {\r\n !isDraggingRef.current && setValue(props.value ?? \"\"); // Update local state when props.value changes as long as user is not actively dragging\r\n }, [props.value]);\r\n\r\n const handleSliderChange = (_: ChangeEvent<HTMLInputElement>, data: SliderOnChangeData) => {\r\n const newValue = data.value * step;\r\n setValue(newValue);\r\n\r\n if (props.notifyOnlyOnRelease) {\r\n // Store the value but don't notify parent yet\r\n pendingValueRef.current = newValue;\r\n } else {\r\n // Notify parent as slider changes\r\n props.onChange(newValue);\r\n }\r\n };\r\n\r\n const handleSliderPointerDown = () => {\r\n isDraggingRef.current = true;\r\n };\r\n\r\n const handleSliderPointerUp = () => {\r\n if (props.notifyOnlyOnRelease && isDraggingRef.current && pendingValueRef.current !== undefined) {\r\n props.onChange(pendingValueRef.current);\r\n pendingValueRef.current = undefined;\r\n }\r\n isDraggingRef.current = false;\r\n };\r\n\r\n const handleInputChange = (value: number) => {\r\n setValue(value);\r\n props.onChange(value); // Input always updates immediately\r\n };\r\n\r\n return (\r\n <div className={classes.syncedSlider}>\r\n {props.min !== undefined && props.max !== undefined && (\r\n <Slider\r\n {...props}\r\n size=\"small\"\r\n className={classes.slider}\r\n min={min / step}\r\n max={max / step}\r\n step={undefined}\r\n value={value / step}\r\n onChange={handleSliderChange}\r\n onPointerDown={handleSliderPointerDown}\r\n onPointerUp={handleSliderPointerUp}\r\n />\r\n )}\r\n <SpinButton {...props} className={classes.spinButton} value={Math.round(value / step) * step} onChange={handleInputChange} step={props.step} />\r\n </div>\r\n );\r\n};\r\n"]}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import type { FunctionComponent } from "react";
|
2
|
+
import type { PrimitiveProps } from "./primitive.js";
|
3
|
+
export type TextInputProps = PrimitiveProps<string> & {
|
4
|
+
validator?: (value: string) => boolean;
|
5
|
+
};
|
6
|
+
export declare const TextInput: FunctionComponent<TextInputProps>;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
3
|
+
import { Input as FluentInput, makeStyles, tokens, useId } from "@fluentui/react-components";
|
4
|
+
import { InfoLabel } from "./infoLabel.js";
|
5
|
+
import { HandleOnBlur, HandleKeyDown } from "./spinButton.js";
|
6
|
+
const useInputStyles = makeStyles({
|
7
|
+
base: {
|
8
|
+
display: "flex",
|
9
|
+
flexDirection: "column",
|
10
|
+
width: "100px",
|
11
|
+
},
|
12
|
+
invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
|
13
|
+
});
|
14
|
+
export const TextInput = (props) => {
|
15
|
+
const classes = useInputStyles();
|
16
|
+
const [value, setValue] = useState(props.value);
|
17
|
+
const lastCommittedValue = useRef(props.value);
|
18
|
+
useEffect(() => {
|
19
|
+
if (props.value !== lastCommittedValue.current) {
|
20
|
+
setValue(props.value); // Update local state when props.value changes
|
21
|
+
lastCommittedValue.current = props.value;
|
22
|
+
}
|
23
|
+
}, [props.value]);
|
24
|
+
const validateValue = (val) => {
|
25
|
+
const failsValidator = props.validator && !props.validator(val);
|
26
|
+
return !failsValidator;
|
27
|
+
};
|
28
|
+
const tryCommitValue = (currVal) => {
|
29
|
+
// Only commit if valid and different from last committed value
|
30
|
+
if (validateValue(currVal) && currVal !== lastCommittedValue.current) {
|
31
|
+
lastCommittedValue.current = currVal;
|
32
|
+
props.onChange(currVal);
|
33
|
+
}
|
34
|
+
};
|
35
|
+
const handleChange = (event, data) => {
|
36
|
+
event.stopPropagation();
|
37
|
+
setValue(data.value);
|
38
|
+
tryCommitValue(data.value);
|
39
|
+
};
|
40
|
+
const handleKeyUp = (event) => {
|
41
|
+
event.stopPropagation();
|
42
|
+
setValue(event.currentTarget.value);
|
43
|
+
tryCommitValue(event.currentTarget.value);
|
44
|
+
};
|
45
|
+
const id = useId("input-button");
|
46
|
+
return (_jsxs("div", { className: classes.base, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentInput, { ...props, id: id, size: "small", value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: `${!validateValue(value) ? classes.invalid : ""}` })] }));
|
47
|
+
};
|
48
|
+
//# sourceMappingURL=textInput.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"textInput.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textInput.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAE7F,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,cAAc,GAAG,UAAU,CAAC;IAC9B,IAAI,EAAE;QACF,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,KAAK,EAAE,OAAO;KACjB;IACD,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,0BAA0B,EAAE;CAClE,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,SAAS,GAAsC,CAAC,KAAK,EAAE,EAAE;IAClE,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IAEjC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,KAAK,CAAC,KAAK,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC7C,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,8CAA8C;YACrE,kBAAkB,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC;QAC7C,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,MAAM,aAAa,GAAG,CAAC,GAAW,EAAW,EAAE;QAC3C,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,cAAc,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE;QACvC,+DAA+D;QAC/D,IAAI,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YACnE,kBAAkB,CAAC,OAAO,GAAG,OAAO,CAAC;YACrC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,KAAoC,EAAE,IAAuB,EAAE,EAAE;QACnF,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,KAAsC,EAAE,EAAE;QAC3D,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpC,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,MAAM,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACjC,OAAO,CACH,eAAK,SAAS,EAAE,OAAO,CAAC,IAAI,aACvB,KAAK,CAAC,SAAS,IAAI,KAAC,SAAS,OAAK,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,GAAI,EACnE,KAAC,WAAW,OACJ,KAAK,EACT,EAAE,EAAE,EAAE,EACN,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,GAC9D,IACA,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { FunctionComponent, KeyboardEvent, ChangeEvent } from \"react\";\r\nimport { useEffect, useRef, useState } from \"react\";\r\nimport type { InputOnChangeData } from \"@fluentui/react-components\";\r\nimport { Input as FluentInput, makeStyles, tokens, useId } from \"@fluentui/react-components\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { HandleOnBlur, HandleKeyDown } from \"./spinButton\";\r\n\r\nconst useInputStyles = makeStyles({\r\n base: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n width: \"100px\",\r\n },\r\n invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },\r\n});\r\n\r\nexport type TextInputProps = PrimitiveProps<string> & {\r\n validator?: (value: string) => boolean;\r\n};\r\n\r\nexport const TextInput: FunctionComponent<TextInputProps> = (props) => {\r\n const classes = useInputStyles();\r\n\r\n const [value, setValue] = useState(props.value);\r\n const lastCommittedValue = useRef(props.value);\r\n\r\n useEffect(() => {\r\n if (props.value !== lastCommittedValue.current) {\r\n setValue(props.value); // Update local state when props.value changes\r\n lastCommittedValue.current = props.value;\r\n }\r\n }, [props.value]);\r\n\r\n const validateValue = (val: string): boolean => {\r\n const failsValidator = props.validator && !props.validator(val);\r\n return !failsValidator;\r\n };\r\n\r\n const tryCommitValue = (currVal: string) => {\r\n // Only commit if valid and different from last committed value\r\n if (validateValue(currVal) && currVal !== lastCommittedValue.current) {\r\n lastCommittedValue.current = currVal;\r\n props.onChange(currVal);\r\n }\r\n };\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {\r\n event.stopPropagation();\r\n setValue(data.value);\r\n tryCommitValue(data.value);\r\n };\r\n\r\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\r\n event.stopPropagation();\r\n setValue(event.currentTarget.value);\r\n tryCommitValue(event.currentTarget.value);\r\n };\r\n\r\n const id = useId(\"input-button\");\r\n return (\r\n <div className={classes.base}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentInput\r\n {...props}\r\n id={id}\r\n size=\"small\"\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={`${!validateValue(value) ? classes.invalid : \"\"}`}\r\n />\r\n </div>\r\n );\r\n};\r\n"]}
|
@@ -2,9 +2,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
2
2
|
import { Component } from "react";
|
3
3
|
import { conflictingValuesPlaceholder } from "./targetsProxy.js";
|
4
4
|
import { InputArrowsComponent } from "./inputArrowsComponent.js";
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import { TextInput, NumberInput } from "../fluent/primitives/input.js";
|
5
|
+
import { TextInputPropertyLine, NumberInputPropertyLine } from "../fluent/hoc/propertyLines/inputPropertyLine.js";
|
6
|
+
import { TextAreaPropertyLine } from "../fluent/hoc/propertyLines/textAreaPropertyLine.js";
|
8
7
|
import { ToolContext } from "../fluent/hoc/fluentToolWrapper.js";
|
9
8
|
let ThrottleTimerId = -1;
|
10
9
|
export class TextInputLineComponent extends Component {
|
@@ -141,7 +140,7 @@ export class TextInputLineComponent extends Component {
|
|
141
140
|
}
|
142
141
|
}
|
143
142
|
renderFluent(value, placeholder, step) {
|
144
|
-
return (_jsx(
|
143
|
+
return this.props.multilines ? (_jsx(TextAreaPropertyLine, { label: this.props.label || "", value: this.state.value, onChange: (val) => this.updateValue(val), disabled: this.props.disabled })) : this.props.numeric ? (_jsx(NumberInputPropertyLine, { label: this.props.label || "", value: this.getCurrentNumericValue(value), onChange: (val) => this.updateValue(val.toString()), step: step, disabled: this.props.disabled })) : (_jsx(TextInputPropertyLine, { label: this.props.label || "", value: value, onChange: (val) => this.updateValue(val.toString()), disabled: this.props.disabled }));
|
145
144
|
}
|
146
145
|
renderOriginal(value, placeholder, step) {
|
147
146
|
const className = this.props.multilines ? "textInputArea" : this.props.unit !== undefined ? "textInputLine withUnits" : "textInputLine";
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"textInputLineComponent.js","sourceRoot":"","sources":["../../../../dev/sharedUiComponents/src/lines/textInputLineComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode, KeyboardEvent } from \"react\";\r\nimport { Component } from \"react\";\r\nimport type { Observable } from \"core/Misc/observable\";\r\nimport type { PropertyChangedEvent } from \"../propertyChangedEvent\";\r\nimport type { LockObject } from \"../tabs/propertyGrids/lockObject\";\r\nimport { conflictingValuesPlaceholder } from \"./targetsProxy\";\r\nimport { InputArrowsComponent } from \"./inputArrowsComponent\";\r\nimport { PropertyLine } from \"../fluent/hoc/propertyLines/propertyLine\";\r\nimport { Textarea } from \"../fluent/primitives/textarea\";\r\nimport { TextInput, NumberInput } from \"../fluent/primitives/input\";\r\nimport { ToolContext } from \"../fluent/hoc/fluentToolWrapper\";\r\n\r\nexport interface ITextInputLineComponentProps {\r\n label?: string;\r\n lockObject?: LockObject;\r\n target?: any;\r\n propertyName?: string;\r\n value?: string;\r\n onChange?: (value: string) => void;\r\n onPropertyChangedObservable?: Observable<PropertyChangedEvent>;\r\n icon?: string;\r\n iconLabel?: string;\r\n noUnderline?: boolean;\r\n numbersOnly?: boolean;\r\n delayInput?: boolean;\r\n arrows?: boolean;\r\n arrowsIncrement?: (amount: number) => void;\r\n step?: number;\r\n numeric?: boolean;\r\n roundValues?: boolean;\r\n min?: number;\r\n max?: number;\r\n placeholder?: string;\r\n unit?: ReactNode;\r\n validator?: (value: string) => boolean;\r\n multilines?: boolean;\r\n throttlePropertyChangedNotification?: boolean;\r\n throttlePropertyChangedNotificationDelay?: number;\r\n disabled?: boolean;\r\n}\r\n\r\nlet ThrottleTimerId = -1;\r\n\r\nexport class TextInputLineComponent extends Component<ITextInputLineComponentProps, { value: string; dragging: boolean }> {\r\n private _localChange = false;\r\n\r\n constructor(props: ITextInputLineComponentProps) {\r\n super(props);\r\n\r\n const emptyValue = this.props.numeric ? \"0\" : \"\";\r\n\r\n this.state = {\r\n value: (this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!]) || emptyValue,\r\n dragging: false,\r\n };\r\n }\r\n\r\n override componentWillUnmount() {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n }\r\n\r\n override shouldComponentUpdate(nextProps: ITextInputLineComponentProps, nextState: { value: string; dragging: boolean }) {\r\n if (this._localChange) {\r\n this._localChange = false;\r\n return true;\r\n }\r\n\r\n const newValue = nextProps.value !== undefined ? nextProps.value : nextProps.target[nextProps.propertyName!];\r\n if (newValue !== nextState.value) {\r\n nextState.value = newValue || \"\";\r\n return true;\r\n }\r\n\r\n if (nextState.dragging != this.state.dragging || nextProps.unit !== this.props.unit) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n raiseOnPropertyChanged(newValue: string, previousValue: string) {\r\n if (this.props.onChange) {\r\n this.props.onChange(newValue);\r\n return;\r\n }\r\n\r\n if (!this.props.onPropertyChangedObservable) {\r\n return;\r\n }\r\n\r\n this.props.onPropertyChangedObservable.notifyObservers({\r\n object: this.props.target,\r\n property: this.props.propertyName!,\r\n value: newValue,\r\n initialValue: previousValue,\r\n });\r\n }\r\n\r\n getCurrentNumericValue(value: string) {\r\n const numeric = parseFloat(value);\r\n if (!isNaN(numeric)) {\r\n return numeric;\r\n }\r\n if (this.props.placeholder !== undefined) {\r\n const placeholderNumeric = parseFloat(this.props.placeholder);\r\n if (!isNaN(placeholderNumeric)) {\r\n return placeholderNumeric;\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n updateValue(value: string, valueToValidate?: string) {\r\n if (this.props.disabled) {\r\n return;\r\n }\r\n if (this.props.numbersOnly) {\r\n if (/[^0-9.px%-]/g.test(value)) {\r\n return;\r\n }\r\n if (!value) {\r\n value = \"0\";\r\n }\r\n\r\n //Removing starting zero if there is a number of a minus after it.\r\n if (value.search(/0+[0-9-]/g) === 0) {\r\n value = value.substring(1);\r\n }\r\n }\r\n\r\n if (this.props.numeric) {\r\n let numericValue = this.getCurrentNumericValue(value);\r\n if (this.props.roundValues) {\r\n numericValue = Math.round(numericValue);\r\n }\r\n if (this.props.min !== undefined) {\r\n numericValue = Math.max(this.props.min, numericValue);\r\n }\r\n if (this.props.max !== undefined) {\r\n numericValue = Math.min(this.props.max, numericValue);\r\n }\r\n value = numericValue.toString();\r\n }\r\n\r\n this._localChange = true;\r\n const store = this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!];\r\n\r\n if (this.props.validator && valueToValidate) {\r\n if (this.props.validator(valueToValidate) == false) {\r\n value = store;\r\n }\r\n }\r\n\r\n this.setState({ value: value });\r\n\r\n if (this.props.propertyName && !this.props.delayInput) {\r\n this.props.target[this.props.propertyName] = value;\r\n }\r\n\r\n if (this.props.throttlePropertyChangedNotification) {\r\n if (ThrottleTimerId >= 0) {\r\n window.clearTimeout(ThrottleTimerId);\r\n }\r\n ThrottleTimerId = window.setTimeout(() => {\r\n this.raiseOnPropertyChanged(value, store);\r\n }, this.props.throttlePropertyChangedNotificationDelay ?? 200);\r\n } else {\r\n this.raiseOnPropertyChanged(value, store);\r\n }\r\n }\r\n\r\n incrementValue(amount: number) {\r\n if (this.props.step) {\r\n amount *= this.props.step;\r\n }\r\n if (this.props.arrowsIncrement) {\r\n this.props.arrowsIncrement(amount);\r\n return;\r\n }\r\n const currentValue = this.getCurrentNumericValue(this.state.value);\r\n this.updateValue((currentValue + amount).toFixed(2));\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent) {\r\n if (!this.props.disabled && this.props.arrows) {\r\n if (event.key === \"ArrowUp\") {\r\n this.incrementValue(1);\r\n event.preventDefault();\r\n }\r\n if (event.key === \"ArrowDown\") {\r\n this.incrementValue(-1);\r\n event.preventDefault();\r\n }\r\n }\r\n }\r\n\r\n renderFluent(value: string, placeholder: string, step: number) {\r\n return (\r\n <PropertyLine label={this.props.label || \"\"}>\r\n {this.props.multilines ? (\r\n <Textarea value={this.state.value} onChange={(val) => this.updateValue(val)} disabled={this.props.disabled} />\r\n ) : this.props.numeric ? (\r\n <NumberInput value={this.getCurrentNumericValue(value)} onChange={(val) => this.updateValue(val.toString())} step={step} disabled={this.props.disabled} />\r\n ) : (\r\n <TextInput value={value} onChange={(val) => this.updateValue(val.toString())} step={step} disabled={this.props.disabled} />\r\n )}\r\n </PropertyLine>\r\n );\r\n }\r\n\r\n renderOriginal(value: string, placeholder: string, step: number) {\r\n const className = this.props.multilines ? \"textInputArea\" : this.props.unit !== undefined ? \"textInputLine withUnits\" : \"textInputLine\";\r\n return (\r\n <div className={className}>\r\n {this.props.icon && <img src={this.props.icon} title={this.props.iconLabel} alt={this.props.iconLabel} color=\"black\" className=\"icon\" />}\r\n {this.props.label !== undefined && (\r\n <div className=\"label\" title={this.props.label}>\r\n {this.props.label}\r\n </div>\r\n )}\r\n {this.props.multilines && (\r\n <>\r\n <textarea\r\n className={this.props.disabled ? \"disabled\" : \"\"}\r\n value={this.state.value}\r\n onFocus={() => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = true;\r\n }\r\n }}\r\n onChange={(evt) => this.updateValue(evt.target.value)}\r\n onKeyDown={(evt) => {\r\n if (evt.keyCode !== 13) {\r\n return;\r\n }\r\n this.updateValue(this.state.value);\r\n }}\r\n onBlur={(evt) => {\r\n this.updateValue(evt.target.value, evt.target.value);\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n }}\r\n disabled={this.props.disabled}\r\n />\r\n </>\r\n )}\r\n {!this.props.multilines && (\r\n <div\r\n className={`value${this.props.noUnderline === true ? \" noUnderline\" : \"\"}${this.props.arrows ? \" hasArrows\" : \"\"}${this.state.dragging ? \" dragging\" : \"\"}`}\r\n >\r\n <input\r\n className={this.props.disabled ? \"disabled\" : \"\"}\r\n value={value}\r\n onBlur={(evt) => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n this.updateValue((this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!]) || \"\", evt.target.value);\r\n }}\r\n onFocus={() => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = true;\r\n }\r\n }}\r\n onChange={(evt) => this.updateValue(evt.target.value)}\r\n onKeyDown={(evt) => this.onKeyDown(evt)}\r\n placeholder={placeholder}\r\n type={this.props.numeric ? \"number\" : \"text\"}\r\n step={step}\r\n disabled={this.props.disabled}\r\n />\r\n {this.props.arrows && (\r\n <InputArrowsComponent incrementValue={(amount) => this.incrementValue(amount)} setDragging={(dragging) => this.setState({ dragging })} />\r\n )}\r\n </div>\r\n )}\r\n {this.props.unit}\r\n </div>\r\n );\r\n }\r\n override render() {\r\n const value = this.state.value === conflictingValuesPlaceholder ? \"\" : this.state.value;\r\n const placeholder = this.state.value === conflictingValuesPlaceholder ? conflictingValuesPlaceholder : this.props.placeholder || \"\";\r\n const step = this.props.step || (this.props.roundValues ? 1 : 0.01);\r\n return (\r\n <ToolContext.Consumer>\r\n {({ useFluent }) => (useFluent ? this.renderFluent(value, placeholder, step) : this.renderOriginal(value, placeholder, step))}\r\n </ToolContext.Consumer>\r\n );\r\n }\r\n}\r\n"]}
|
1
|
+
{"version":3,"file":"textInputLineComponent.js","sourceRoot":"","sources":["../../../../dev/sharedUiComponents/src/lines/textInputLineComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode, KeyboardEvent } from \"react\";\r\nimport { Component } from \"react\";\r\nimport type { Observable } from \"core/Misc/observable\";\r\nimport type { PropertyChangedEvent } from \"../propertyChangedEvent\";\r\nimport type { LockObject } from \"../tabs/propertyGrids/lockObject\";\r\nimport { conflictingValuesPlaceholder } from \"./targetsProxy\";\r\nimport { InputArrowsComponent } from \"./inputArrowsComponent\";\r\nimport { TextInputPropertyLine, NumberInputPropertyLine } from \"../fluent/hoc/propertyLines/inputPropertyLine\";\r\nimport { TextAreaPropertyLine } from \"../fluent/hoc/propertyLines/textAreaPropertyLine\";\r\nimport { ToolContext } from \"../fluent/hoc/fluentToolWrapper\";\r\n\r\nexport interface ITextInputLineComponentProps {\r\n label?: string;\r\n lockObject?: LockObject;\r\n target?: any;\r\n propertyName?: string;\r\n value?: string;\r\n onChange?: (value: string) => void;\r\n onPropertyChangedObservable?: Observable<PropertyChangedEvent>;\r\n icon?: string;\r\n iconLabel?: string;\r\n noUnderline?: boolean;\r\n numbersOnly?: boolean;\r\n delayInput?: boolean;\r\n arrows?: boolean;\r\n arrowsIncrement?: (amount: number) => void;\r\n step?: number;\r\n numeric?: boolean;\r\n roundValues?: boolean;\r\n min?: number;\r\n max?: number;\r\n placeholder?: string;\r\n unit?: ReactNode;\r\n validator?: (value: string) => boolean;\r\n multilines?: boolean;\r\n throttlePropertyChangedNotification?: boolean;\r\n throttlePropertyChangedNotificationDelay?: number;\r\n disabled?: boolean;\r\n}\r\n\r\nlet ThrottleTimerId = -1;\r\n\r\nexport class TextInputLineComponent extends Component<ITextInputLineComponentProps, { value: string; dragging: boolean }> {\r\n private _localChange = false;\r\n\r\n constructor(props: ITextInputLineComponentProps) {\r\n super(props);\r\n\r\n const emptyValue = this.props.numeric ? \"0\" : \"\";\r\n\r\n this.state = {\r\n value: (this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!]) || emptyValue,\r\n dragging: false,\r\n };\r\n }\r\n\r\n override componentWillUnmount() {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n }\r\n\r\n override shouldComponentUpdate(nextProps: ITextInputLineComponentProps, nextState: { value: string; dragging: boolean }) {\r\n if (this._localChange) {\r\n this._localChange = false;\r\n return true;\r\n }\r\n\r\n const newValue = nextProps.value !== undefined ? nextProps.value : nextProps.target[nextProps.propertyName!];\r\n if (newValue !== nextState.value) {\r\n nextState.value = newValue || \"\";\r\n return true;\r\n }\r\n\r\n if (nextState.dragging != this.state.dragging || nextProps.unit !== this.props.unit) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n raiseOnPropertyChanged(newValue: string, previousValue: string) {\r\n if (this.props.onChange) {\r\n this.props.onChange(newValue);\r\n return;\r\n }\r\n\r\n if (!this.props.onPropertyChangedObservable) {\r\n return;\r\n }\r\n\r\n this.props.onPropertyChangedObservable.notifyObservers({\r\n object: this.props.target,\r\n property: this.props.propertyName!,\r\n value: newValue,\r\n initialValue: previousValue,\r\n });\r\n }\r\n\r\n getCurrentNumericValue(value: string) {\r\n const numeric = parseFloat(value);\r\n if (!isNaN(numeric)) {\r\n return numeric;\r\n }\r\n if (this.props.placeholder !== undefined) {\r\n const placeholderNumeric = parseFloat(this.props.placeholder);\r\n if (!isNaN(placeholderNumeric)) {\r\n return placeholderNumeric;\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n updateValue(value: string, valueToValidate?: string) {\r\n if (this.props.disabled) {\r\n return;\r\n }\r\n if (this.props.numbersOnly) {\r\n if (/[^0-9.px%-]/g.test(value)) {\r\n return;\r\n }\r\n if (!value) {\r\n value = \"0\";\r\n }\r\n\r\n //Removing starting zero if there is a number of a minus after it.\r\n if (value.search(/0+[0-9-]/g) === 0) {\r\n value = value.substring(1);\r\n }\r\n }\r\n\r\n if (this.props.numeric) {\r\n let numericValue = this.getCurrentNumericValue(value);\r\n if (this.props.roundValues) {\r\n numericValue = Math.round(numericValue);\r\n }\r\n if (this.props.min !== undefined) {\r\n numericValue = Math.max(this.props.min, numericValue);\r\n }\r\n if (this.props.max !== undefined) {\r\n numericValue = Math.min(this.props.max, numericValue);\r\n }\r\n value = numericValue.toString();\r\n }\r\n\r\n this._localChange = true;\r\n const store = this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!];\r\n\r\n if (this.props.validator && valueToValidate) {\r\n if (this.props.validator(valueToValidate) == false) {\r\n value = store;\r\n }\r\n }\r\n\r\n this.setState({ value: value });\r\n\r\n if (this.props.propertyName && !this.props.delayInput) {\r\n this.props.target[this.props.propertyName] = value;\r\n }\r\n\r\n if (this.props.throttlePropertyChangedNotification) {\r\n if (ThrottleTimerId >= 0) {\r\n window.clearTimeout(ThrottleTimerId);\r\n }\r\n ThrottleTimerId = window.setTimeout(() => {\r\n this.raiseOnPropertyChanged(value, store);\r\n }, this.props.throttlePropertyChangedNotificationDelay ?? 200);\r\n } else {\r\n this.raiseOnPropertyChanged(value, store);\r\n }\r\n }\r\n\r\n incrementValue(amount: number) {\r\n if (this.props.step) {\r\n amount *= this.props.step;\r\n }\r\n if (this.props.arrowsIncrement) {\r\n this.props.arrowsIncrement(amount);\r\n return;\r\n }\r\n const currentValue = this.getCurrentNumericValue(this.state.value);\r\n this.updateValue((currentValue + amount).toFixed(2));\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent) {\r\n if (!this.props.disabled && this.props.arrows) {\r\n if (event.key === \"ArrowUp\") {\r\n this.incrementValue(1);\r\n event.preventDefault();\r\n }\r\n if (event.key === \"ArrowDown\") {\r\n this.incrementValue(-1);\r\n event.preventDefault();\r\n }\r\n }\r\n }\r\n\r\n renderFluent(value: string, placeholder: string, step: number) {\r\n return this.props.multilines ? (\r\n <TextAreaPropertyLine label={this.props.label || \"\"} value={this.state.value} onChange={(val) => this.updateValue(val)} disabled={this.props.disabled} />\r\n ) : this.props.numeric ? (\r\n <NumberInputPropertyLine\r\n label={this.props.label || \"\"}\r\n value={this.getCurrentNumericValue(value)}\r\n onChange={(val) => this.updateValue(val.toString())}\r\n step={step}\r\n disabled={this.props.disabled}\r\n />\r\n ) : (\r\n <TextInputPropertyLine label={this.props.label || \"\"} value={value} onChange={(val) => this.updateValue(val.toString())} disabled={this.props.disabled} />\r\n );\r\n }\r\n\r\n renderOriginal(value: string, placeholder: string, step: number) {\r\n const className = this.props.multilines ? \"textInputArea\" : this.props.unit !== undefined ? \"textInputLine withUnits\" : \"textInputLine\";\r\n return (\r\n <div className={className}>\r\n {this.props.icon && <img src={this.props.icon} title={this.props.iconLabel} alt={this.props.iconLabel} color=\"black\" className=\"icon\" />}\r\n {this.props.label !== undefined && (\r\n <div className=\"label\" title={this.props.label}>\r\n {this.props.label}\r\n </div>\r\n )}\r\n {this.props.multilines && (\r\n <>\r\n <textarea\r\n className={this.props.disabled ? \"disabled\" : \"\"}\r\n value={this.state.value}\r\n onFocus={() => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = true;\r\n }\r\n }}\r\n onChange={(evt) => this.updateValue(evt.target.value)}\r\n onKeyDown={(evt) => {\r\n if (evt.keyCode !== 13) {\r\n return;\r\n }\r\n this.updateValue(this.state.value);\r\n }}\r\n onBlur={(evt) => {\r\n this.updateValue(evt.target.value, evt.target.value);\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n }}\r\n disabled={this.props.disabled}\r\n />\r\n </>\r\n )}\r\n {!this.props.multilines && (\r\n <div\r\n className={`value${this.props.noUnderline === true ? \" noUnderline\" : \"\"}${this.props.arrows ? \" hasArrows\" : \"\"}${this.state.dragging ? \" dragging\" : \"\"}`}\r\n >\r\n <input\r\n className={this.props.disabled ? \"disabled\" : \"\"}\r\n value={value}\r\n onBlur={(evt) => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = false;\r\n }\r\n this.updateValue((this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!]) || \"\", evt.target.value);\r\n }}\r\n onFocus={() => {\r\n if (this.props.lockObject) {\r\n this.props.lockObject.lock = true;\r\n }\r\n }}\r\n onChange={(evt) => this.updateValue(evt.target.value)}\r\n onKeyDown={(evt) => this.onKeyDown(evt)}\r\n placeholder={placeholder}\r\n type={this.props.numeric ? \"number\" : \"text\"}\r\n step={step}\r\n disabled={this.props.disabled}\r\n />\r\n {this.props.arrows && (\r\n <InputArrowsComponent incrementValue={(amount) => this.incrementValue(amount)} setDragging={(dragging) => this.setState({ dragging })} />\r\n )}\r\n </div>\r\n )}\r\n {this.props.unit}\r\n </div>\r\n );\r\n }\r\n override render() {\r\n const value = this.state.value === conflictingValuesPlaceholder ? \"\" : this.state.value;\r\n const placeholder = this.state.value === conflictingValuesPlaceholder ? conflictingValuesPlaceholder : this.props.placeholder || \"\";\r\n const step = this.props.step || (this.props.roundValues ? 1 : 0.01);\r\n return (\r\n <ToolContext.Consumer>\r\n {({ useFluent }) => (useFluent ? this.renderFluent(value, placeholder, step) : this.renderOriginal(value, placeholder, step))}\r\n </ToolContext.Consumer>\r\n );\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
@@ -1,10 +0,0 @@
|
|
1
|
-
import type { FunctionComponent } from "react";
|
2
|
-
import type { PrimitiveProps } from "./primitive.js";
|
3
|
-
export type InputProps<T extends string | number> = PrimitiveProps<T> & {
|
4
|
-
step?: number;
|
5
|
-
placeholder?: string;
|
6
|
-
min?: number;
|
7
|
-
max?: number;
|
8
|
-
};
|
9
|
-
export declare const NumberInput: FunctionComponent<InputProps<number>>;
|
10
|
-
export declare const TextInput: FunctionComponent<InputProps<string>>;
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useEffect, useState } from "react";
|
3
|
-
import { Input as FluentInput, makeStyles } from "@fluentui/react-components";
|
4
|
-
const useInputStyles = makeStyles({
|
5
|
-
text: {
|
6
|
-
height: "auto",
|
7
|
-
textAlign: "right",
|
8
|
-
minWidth: "100px", // Min width for text input
|
9
|
-
},
|
10
|
-
number: {
|
11
|
-
height: "auto",
|
12
|
-
minWidth: "40px", // Min width for number input
|
13
|
-
},
|
14
|
-
});
|
15
|
-
/**
|
16
|
-
* This is an input text box that stops propagation of change events and sets its width based on the type of input (text or number)
|
17
|
-
* @param props
|
18
|
-
* @returns
|
19
|
-
*/
|
20
|
-
const Input = (props) => {
|
21
|
-
const classes = useInputStyles();
|
22
|
-
const [value, setValue] = useState(props.value ?? "");
|
23
|
-
useEffect(() => {
|
24
|
-
setValue(props.value ?? ""); // Update local state when props.value changes
|
25
|
-
}, [props.value]);
|
26
|
-
const handleChange = (event, _) => {
|
27
|
-
event.stopPropagation(); // Prevent event propagation
|
28
|
-
const value = props.type === "number" ? Number(event.target.value) : String(event.target.value);
|
29
|
-
props.onChange(value); // Call the original onChange handler passed as prop
|
30
|
-
setValue(value); // Update local state with the new value
|
31
|
-
};
|
32
|
-
const handleKeyDown = (event) => {
|
33
|
-
event.stopPropagation(); // Prevent event propagation
|
34
|
-
};
|
35
|
-
return (_jsx(FluentInput, { ...props, size: "small", value: value.toString(), className: props.type === "number" ? classes.number : classes.text, onChange: handleChange, onKeyDown: handleKeyDown }));
|
36
|
-
};
|
37
|
-
const NumberInputCast = Input;
|
38
|
-
const TextInputCast = Input;
|
39
|
-
export const NumberInput = (props) => _jsx(NumberInputCast, { ...props, type: "number" });
|
40
|
-
export const TextInput = (props) => _jsx(TextInputCast, { ...props, type: "text" });
|
41
|
-
//# sourceMappingURL=input.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/input.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG9E,MAAM,cAAc,GAAG,UAAU,CAAC;IAC9B,IAAI,EAAE;QACF,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,OAAO;QAClB,QAAQ,EAAE,OAAO,EAAE,2BAA2B;KACjD;IACD,MAAM,EAAE;QACJ,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,MAAM,EAAE,6BAA6B;KAClD;CACJ,CAAC,CAAC;AAQH;;;;GAIG;AACH,MAAM,KAAK,GAAiF,CAAC,KAAK,EAAE,EAAE;IAClG,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACX,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,8CAA8C;IAC/E,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,MAAM,YAAY,GAAG,CAAC,KAAoC,EAAE,CAAU,EAAE,EAAE;QACtE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,oDAAoD;QAC3E,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,wCAAwC;IAC7D,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,KAAsC,EAAE,EAAE;QAC7D,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;IACzD,CAAC,CAAC;IAEF,OAAO,CACH,KAAC,WAAW,OACJ,KAAK,EACT,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,EACvB,SAAS,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAClE,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,aAAa,GAC1B,CACL,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAmE,CAAC;AAC5F,MAAM,aAAa,GAAG,KAAiE,CAAC;AAExF,MAAM,CAAC,MAAM,WAAW,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAC,eAAe,OAAK,KAAK,EAAE,IAAI,EAAC,QAAQ,GAAG,CAAC;AAC1H,MAAM,CAAC,MAAM,SAAS,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAC,aAAa,OAAK,KAAK,EAAE,IAAI,EAAC,MAAM,GAAG,CAAC","sourcesContent":["import type { FunctionComponent, KeyboardEvent, ChangeEvent } from \"react\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nimport { Input as FluentInput, makeStyles } from \"@fluentui/react-components\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useInputStyles = makeStyles({\r\n text: {\r\n height: \"auto\",\r\n textAlign: \"right\",\r\n minWidth: \"100px\", // Min width for text input\r\n },\r\n number: {\r\n height: \"auto\",\r\n minWidth: \"40px\", // Min width for number input\r\n },\r\n});\r\n\r\nexport type InputProps<T extends string | number> = PrimitiveProps<T> & {\r\n step?: number;\r\n placeholder?: string;\r\n min?: number;\r\n max?: number;\r\n};\r\n/**\r\n * This is an input text box that stops propagation of change events and sets its width based on the type of input (text or number)\r\n * @param props\r\n * @returns\r\n */\r\nconst Input: FunctionComponent<InputProps<string | number> & { type: \"text\" | \"number\" }> = (props) => {\r\n const classes = useInputStyles();\r\n const [value, setValue] = useState(props.value ?? \"\");\r\n\r\n useEffect(() => {\r\n setValue(props.value ?? \"\"); // Update local state when props.value changes\r\n }, [props.value]);\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>, _: unknown) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n const value = props.type === \"number\" ? Number(event.target.value) : String(event.target.value);\r\n props.onChange(value); // Call the original onChange handler passed as prop\r\n setValue(value); // Update local state with the new value\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n };\r\n\r\n return (\r\n <FluentInput\r\n {...props}\r\n size=\"small\"\r\n value={value.toString()}\r\n className={props.type === \"number\" ? classes.number : classes.text}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n />\r\n );\r\n};\r\n\r\nconst NumberInputCast = Input as FunctionComponent<InputProps<number> & { type: \"number\" }>;\r\nconst TextInputCast = Input as FunctionComponent<InputProps<string> & { type: \"text\" }>;\r\n\r\nexport const NumberInput: FunctionComponent<InputProps<number>> = (props) => <NumberInputCast {...props} type=\"number\" />;\r\nexport const TextInput: FunctionComponent<InputProps<string>> = (props) => <TextInputCast {...props} type=\"text\" />;\r\n"]}
|