@babylonjs/shared-ui-components 8.31.4 → 8.32.1
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/fluentToolWrapper.d.ts +6 -0
- package/fluent/hoc/fluentToolWrapper.js +2 -1
- package/fluent/hoc/fluentToolWrapper.js.map +1 -1
- package/fluent/hoc/propertyLines/propertyLine.js +23 -17
- package/fluent/hoc/propertyLines/propertyLine.js.map +1 -1
- package/fluent/hoc/propertyLines/stringifiedPropertyLine.d.ts +1 -1
- package/fluent/hoc/propertyLines/stringifiedPropertyLine.js.map +1 -1
- package/fluent/hoc/propertyLines/vectorPropertyLine.js +1 -1
- package/fluent/hoc/propertyLines/vectorPropertyLine.js.map +1 -1
- package/fluent/primitives/accordion.js +11 -4
- package/fluent/primitives/accordion.js.map +1 -1
- package/fluent/primitives/button.js +4 -1
- package/fluent/primitives/button.js.map +1 -1
- package/fluent/primitives/checkbox.js +8 -2
- package/fluent/primitives/checkbox.js.map +1 -1
- package/fluent/primitives/colorPicker.js +6 -4
- package/fluent/primitives/colorPicker.js.map +1 -1
- package/fluent/primitives/dropdown.js +4 -3
- package/fluent/primitives/dropdown.js.map +1 -1
- package/fluent/primitives/spinButton.js +4 -2
- package/fluent/primitives/spinButton.js.map +1 -1
- package/fluent/primitives/switch.js +9 -3
- package/fluent/primitives/switch.js.map +1 -1
- package/fluent/primitives/syncedSlider.js +4 -2
- package/fluent/primitives/syncedSlider.js.map +1 -1
- package/fluent/primitives/textInput.js +4 -2
- package/fluent/primitives/textInput.js.map +1 -1
- package/fluent/primitives/toggleButton.js +4 -2
- package/fluent/primitives/toggleButton.js.map +1 -1
- package/fluent/primitives/utils.d.ts +5 -2
- package/fluent/primitives/utils.js +6 -4
- package/fluent/primitives/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { PropsWithChildren, FunctionComponent } from "react";
|
|
2
2
|
import type { Theme } from "@fluentui/react-components";
|
|
3
|
+
export type UiSize = "small" | "medium";
|
|
3
4
|
export type ToolHostProps = {
|
|
5
|
+
/**
|
|
6
|
+
* Will ensure all of the controls within the tool are of the same scale
|
|
7
|
+
*/
|
|
8
|
+
size?: UiSize;
|
|
4
9
|
/**
|
|
5
10
|
* Allows host to pass in a theme
|
|
6
11
|
*/
|
|
@@ -18,6 +23,7 @@ export declare const ToolContext: import("react").Context<{
|
|
|
18
23
|
readonly useFluent: boolean;
|
|
19
24
|
readonly disableCopy: boolean;
|
|
20
25
|
readonly toolName: string;
|
|
26
|
+
readonly size: UiSize | undefined;
|
|
21
27
|
}>;
|
|
22
28
|
/**
|
|
23
29
|
* For tools which are ready to move over the fluent, wrap the root of the tool (or the panel which you want fluentized) with this component
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext } from "react";
|
|
3
3
|
import { FluentProvider, webDarkTheme } from "@fluentui/react-components";
|
|
4
|
-
export const ToolContext = createContext({ useFluent: false, disableCopy: false, toolName: "" });
|
|
4
|
+
export const ToolContext = createContext({ useFluent: false, disableCopy: false, toolName: "", size: undefined });
|
|
5
5
|
/**
|
|
6
6
|
* For tools which are ready to move over the fluent, wrap the root of the tool (or the panel which you want fluentized) with this component
|
|
7
7
|
* Today we will only enable fluent if the URL has the `newUX` query parameter is truthy
|
|
@@ -15,6 +15,7 @@ export const FluentToolWrapper = (props) => {
|
|
|
15
15
|
useFluent,
|
|
16
16
|
disableCopy: !!props.disableCopy,
|
|
17
17
|
toolName: props.toolName,
|
|
18
|
+
size: props.size,
|
|
18
19
|
};
|
|
19
20
|
return useFluent ? (_jsx(FluentProvider, { theme: props.customTheme || webDarkTheme, children: _jsx(ToolContext.Provider, { value: contextValue, children: props.children }) })) : (_jsx(ToolContext.Provider, { value: contextValue, children: props.children }));
|
|
20
21
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluentToolWrapper.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/fluentToolWrapper.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"fluentToolWrapper.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/fluentToolWrapper.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyB1E,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC,EAAE,SAAS,EAAE,KAAgB,EAAE,WAAW,EAAE,KAAgB,EAAE,QAAQ,EAAE,EAAY,EAAE,IAAI,EAAE,SAA+B,EAAW,CAAC,CAAC;AAEjL;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAwD,CAAC,KAAK,EAAE,EAAE;IAC5F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG;QACjB,SAAS;QACT,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;KACnB,CAAC;IACF,OAAO,SAAS,CAAC,CAAC,CAAC,CACf,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,CAAC,WAAW,IAAI,YAAY,YACpD,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,KAAK,CAAC,QAAQ,GAAwB,GACrE,CACpB,CAAC,CAAC,CAAC,CACA,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,KAAK,CAAC,QAAQ,GAAwB,CACrF,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { PropsWithChildren, FunctionComponent } from \"react\";\r\nimport { createContext } from \"react\";\r\nimport type { Theme } from \"@fluentui/react-components\";\r\nimport { FluentProvider, webDarkTheme } from \"@fluentui/react-components\";\r\n\r\nexport type UiSize = \"small\" | \"medium\";\r\nexport type ToolHostProps = {\r\n /**\r\n * Will ensure all of the controls within the tool are of the same scale\r\n */\r\n size?: UiSize;\r\n\r\n /**\r\n * Allows host to pass in a theme\r\n */\r\n customTheme?: Theme;\r\n\r\n /**\r\n * Can be set to true to disable the copy button in the tool's property lines. Default is false (copy enabled)\r\n */\r\n disableCopy?: boolean;\r\n\r\n /**\r\n * Name of the tool displayed in the UX\r\n */\r\n toolName: string;\r\n};\r\n\r\nexport const ToolContext = createContext({ useFluent: false as boolean, disableCopy: false as boolean, toolName: \"\" as string, size: undefined as UiSize | undefined } as const);\r\n\r\n/**\r\n * For tools which are ready to move over the fluent, wrap the root of the tool (or the panel which you want fluentized) with this component\r\n * Today we will only enable fluent if the URL has the `newUX` query parameter is truthy\r\n * @param props\r\n * @returns\r\n */\r\nexport const FluentToolWrapper: FunctionComponent<PropsWithChildren<ToolHostProps>> = (props) => {\r\n const url = new URL(window.location.href);\r\n const useFluent = url.searchParams.has(\"newUX\") || url.hash.includes(\"newUX\");\r\n const contextValue = {\r\n useFluent,\r\n disableCopy: !!props.disableCopy,\r\n toolName: props.toolName,\r\n size: props.size,\r\n };\r\n return useFluent ? (\r\n <FluentProvider theme={props.customTheme || webDarkTheme}>\r\n <ToolContext.Provider value={contextValue}>{props.children}</ToolContext.Provider>\r\n </FluentProvider>\r\n ) : (\r\n <ToolContext.Provider value={contextValue}>{props.children}</ToolContext.Provider>\r\n );\r\n};\r\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Body1, InfoLabel, Link, Checkbox, makeStyles, Body1Strong, tokens } from "@fluentui/react-components";
|
|
3
|
-
import { ChevronCircleDown20Regular, ChevronCircleRight20Regular,
|
|
2
|
+
import { Body1, InfoLabel, Link, Checkbox, makeStyles, Body1Strong, tokens, mergeClasses } from "@fluentui/react-components";
|
|
3
|
+
import { ChevronCircleDown20Regular, ChevronCircleDown16Regular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, Copy16Regular, Copy20Regular, } from "@fluentui/react-icons";
|
|
4
4
|
import { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from "react";
|
|
5
5
|
import { Collapse } from "../../primitives/collapse.js";
|
|
6
6
|
import { copyCommandToClipboard } from "../../../copyCommandToClipboard.js";
|
|
@@ -9,16 +9,6 @@ import { ToggleButton } from "../../primitives/toggleButton.js";
|
|
|
9
9
|
import { Button } from "../../primitives/button.js";
|
|
10
10
|
import { CustomTokens } from "../../primitives/utils.js";
|
|
11
11
|
const usePropertyLineStyles = makeStyles({
|
|
12
|
-
container: {
|
|
13
|
-
width: "100%",
|
|
14
|
-
display: "flex",
|
|
15
|
-
flexDirection: "column", // Stack line + expanded content
|
|
16
|
-
minHeight: CustomTokens.lineHeight,
|
|
17
|
-
boxSizing: "border-box",
|
|
18
|
-
justifyContent: "center",
|
|
19
|
-
paddingTop: tokens.spacingVerticalXXS,
|
|
20
|
-
paddingBottom: tokens.spacingVerticalXXS,
|
|
21
|
-
},
|
|
22
12
|
baseLine: {
|
|
23
13
|
display: "flex",
|
|
24
14
|
alignItems: "center",
|
|
@@ -66,11 +56,11 @@ const usePropertyLineStyles = makeStyles({
|
|
|
66
56
|
*/
|
|
67
57
|
export const PropertyLine = forwardRef((props, ref) => {
|
|
68
58
|
PropertyLine.displayName = "PropertyLine";
|
|
59
|
+
const { disableCopy, size } = useContext(ToolContext);
|
|
69
60
|
const classes = usePropertyLineStyles();
|
|
70
61
|
const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;
|
|
71
62
|
const [expanded, setExpanded] = useState("expandByDefault" in props ? props.expandByDefault : false);
|
|
72
63
|
const cachedVal = useRef(nullable ? props.value : null);
|
|
73
|
-
const { disableCopy } = useContext(ToolContext);
|
|
74
64
|
const description = props.docLink ? _jsx(Link, { href: props.docLink, children: props.description ?? "Docs" }) : props.description;
|
|
75
65
|
// Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value
|
|
76
66
|
const processedChildren = (nullable || ignoreNullable) && isValidElement(children)
|
|
@@ -81,7 +71,7 @@ export const PropertyLine = forwardRef((props, ref) => {
|
|
|
81
71
|
defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state
|
|
82
72
|
})
|
|
83
73
|
: children;
|
|
84
|
-
return (_jsxs(LineContainer, { ref: ref, children: [_jsxs("div", { className: classes.baseLine, children: [_jsx(InfoLabel, { className: classes.infoLabel, label: { className: classes.labelSlot }, info: description ? _jsx("div", { className: classes.infoPopup, children: description }) : undefined, title: label, children: _jsx(Body1Strong, { className: classes.labelText, children: label }) }), _jsxs("div", { className: classes.rightContent, children: [expandedContent && (_jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: ChevronCircleDown20Regular, uncheckedIcon: ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (
|
|
74
|
+
return (_jsxs(LineContainer, { ref: ref, children: [_jsxs("div", { className: classes.baseLine, children: [_jsx(InfoLabel, { size: size, className: classes.infoLabel, label: { className: classes.labelSlot }, info: description ? _jsx("div", { className: classes.infoPopup, children: description }) : undefined, title: label, children: _jsx(Body1Strong, { className: classes.labelText, children: label }) }), _jsxs("div", { className: classes.rightContent, children: [expandedContent && (_jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: size === "small" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular, uncheckedIcon: size === "small" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (
|
|
85
75
|
// If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')
|
|
86
76
|
_jsx(Checkbox, { checked: !(props.value == null), onChange: (_, data) => {
|
|
87
77
|
if (data.checked) {
|
|
@@ -93,11 +83,27 @@ export const PropertyLine = forwardRef((props, ref) => {
|
|
|
93
83
|
cachedVal.current = props.value;
|
|
94
84
|
props.onChange(null);
|
|
95
85
|
}
|
|
96
|
-
}, title: "Toggle null state" })), processedChildren, onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon:
|
|
86
|
+
}, title: "Toggle null state" })), processedChildren, onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon: size === "small" ? Copy16Regular : Copy20Regular, onClick: () => copyCommandToClipboard(onCopy()) }))] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
|
|
87
|
+
});
|
|
88
|
+
const useLineStyles = makeStyles({
|
|
89
|
+
container: {
|
|
90
|
+
width: "100%",
|
|
91
|
+
display: "flex",
|
|
92
|
+
flexDirection: "column", // Stack line + expanded content
|
|
93
|
+
minHeight: CustomTokens.lineHeight,
|
|
94
|
+
boxSizing: "border-box",
|
|
95
|
+
justifyContent: "center",
|
|
96
|
+
paddingTop: tokens.spacingVerticalXXS,
|
|
97
|
+
paddingBottom: tokens.spacingVerticalXXS,
|
|
98
|
+
},
|
|
99
|
+
containerSmall: {
|
|
100
|
+
minHeight: CustomTokens.lineHeightSmall,
|
|
101
|
+
},
|
|
97
102
|
});
|
|
98
103
|
export const LineContainer = forwardRef((props, ref) => {
|
|
99
|
-
const
|
|
100
|
-
|
|
104
|
+
const { size } = useContext(ToolContext);
|
|
105
|
+
const classes = useLineStyles();
|
|
106
|
+
return (_jsx("div", { ref: ref, className: mergeClasses(classes.container, size == "small" ? classes.containerSmall : undefined), ...props, children: props.children }));
|
|
101
107
|
});
|
|
102
108
|
export const PlaceholderPropertyLine = (props) => {
|
|
103
109
|
return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { children: props.value }) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, InfoLabel, Link, Checkbox, makeStyles, Body1Strong, tokens } from \"@fluentui/react-components\";\r\nimport { ChevronCircleDown20Regular, ChevronCircleRight20Regular, CopyRegular } from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens } from \"../../primitives/utils\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n },\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n labelSlot: {\r\n display: \"flex\",\r\n minWidth: 0,\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const { disableCopy } = useContext(ToolContext);\r\n\r\n const description = props.docLink ? <Link href={props.docLink}>{props.description ?? \"Docs\"}</Link> : props.description;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel\r\n className={classes.infoLabel}\r\n label={{ className: classes.labelSlot }}\r\n info={description ? <div className={classes.infoPopup}>{description}</div> : undefined}\r\n title={label}\r\n >\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={ChevronCircleDown20Regular}\r\n uncheckedIcon={ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Checkbox\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n title=\"Toggle null state\"\r\n />\r\n )}\r\n {processedChildren}\r\n {onCopy && !disableCopy && (\r\n <Button className={classes.copy} title=\"Copy to clipboard\" appearance=\"transparent\" icon={CopyRegular} onClick={() => copyCommandToClipboard(onCopy())} />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const classes = usePropertyLineStyles();\r\n return (\r\n <div ref={ref} className={classes.container} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, InfoLabel, Link, Checkbox, makeStyles, Body1Strong, tokens, mergeClasses } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n Copy16Regular,\r\n Copy20Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens } from \"../../primitives/utils\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n labelSlot: {\r\n display: \"flex\",\r\n minWidth: 0,\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const description = props.docLink ? <Link href={props.docLink}>{props.description ?? \"Docs\"}</Link> : props.description;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel\r\n size={size}\r\n className={classes.infoLabel}\r\n label={{ className: classes.labelSlot }}\r\n info={description ? <div className={classes.infoPopup}>{description}</div> : undefined}\r\n title={label}\r\n >\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={size === \"small\" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular}\r\n uncheckedIcon={size === \"small\" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Checkbox\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n title=\"Toggle null state\"\r\n />\r\n )}\r\n {processedChildren}\r\n {onCopy && !disableCopy && (\r\n <Button\r\n className={classes.copy}\r\n title=\"Copy to clipboard\"\r\n appearance=\"transparent\"\r\n icon={size === \"small\" ? Copy16Regular : Copy20Regular}\r\n onClick={() => copyCommandToClipboard(onCopy())}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nconst useLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n },\r\n containerSmall: {\r\n minHeight: CustomTokens.lineHeightSmall,\r\n },\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ImmutablePrimitiveProps } from "../../primitives/primitive.js";
|
|
2
|
-
import {
|
|
2
|
+
import type { PropertyLineProps } from "./propertyLine.js";
|
|
3
3
|
import type { FunctionComponent } from "react";
|
|
4
4
|
type StringifiedPropertyLineProps = PropertyLineProps<number> & ImmutablePrimitiveProps<number> & {
|
|
5
5
|
precision?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringifiedPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/stringifiedPropertyLine.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"stringifiedPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/stringifiedPropertyLine.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAQnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAoD,CAAC,KAAK,EAAE,EAAE;IAC9F,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC;IAChE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;IAClH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,SAAS,GAAS,GACnC,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { ImmutablePrimitiveProps } from \"../../primitives/primitive\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport { Body1 } from \"@fluentui/react-components\";\r\n\r\ntype StringifiedPropertyLineProps = PropertyLineProps<number> &\r\n ImmutablePrimitiveProps<number> & {\r\n precision?: number;\r\n units?: string;\r\n };\r\n\r\n/**\r\n * Expects a numerical value and converts it toFixed(if precision is supplied) or toLocaleString\r\n * Can pass optional units to be appending to the end of the string\r\n * @param props\r\n * @returns\r\n */\r\nexport const StringifiedPropertyLine: FunctionComponent<StringifiedPropertyLineProps> = (props) => {\r\n StringifiedPropertyLine.displayName = \"StringifiedPropertyLine\";\r\n const value = props.precision !== undefined ? props.value.toFixed(props.precision) : props.value.toLocaleString();\r\n const withUnits = props.units ? `${value} ${props.units}` : value;\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1 title={props.title}>{withUnits}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
|
@@ -30,7 +30,7 @@ const TensorPropertyLine = (props) => {
|
|
|
30
30
|
useEffect(() => {
|
|
31
31
|
setVector(props.value);
|
|
32
32
|
}, [props.value, props.expandedContent]);
|
|
33
|
-
return (_jsx(PropertyLine, { ...props, onCopy: () => `new ${props.value.
|
|
33
|
+
return (_jsx(PropertyLine, { ...props, onCopy: () => `new ${props.value.getClassName()}(${vector.x},${vector.y}${HasZ(vector) ? `,${vector.z}` : ""}${HasW(vector) ? `,${vector.w}` : ""})`, expandedContent: _jsxs(_Fragment, { children: [_jsx(SyncedSliderPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x"), unit: props.unit, step: props.step }), _jsx(SyncedSliderPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y"), unit: props.unit, step: props.step }), HasZ(vector) && (_jsx(SyncedSliderPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z"), unit: props.unit, step: props.step })), HasW(vector) && (_jsx(SyncedSliderPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w"), unit: props.unit, step: props.step }))] }), children: _jsx(Body1, { children: `[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : ""}${HasW(props.value) ? `, ${formatted(props.value.w)}` : ""}]` }) }));
|
|
34
34
|
};
|
|
35
35
|
const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
|
|
36
36
|
export const RotationVectorPropertyLine = (props) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,6CAA+B;AACtE,OAAO,EAAE,KAAK,EAAE,sCAAwB;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAoC5D,MAAM,IAAI,GAAG,CAAC,MAAgD,EAAqB,EAAE,CAAC,CAAC,CAAC,MAAM,YAAY,OAAO,CAAC,CAAC;AACnH,MAAM,IAAI,GAAG,CAAC,MAAgD,EAAqB,EAAE,CAAC,MAAM,YAAY,OAAO,IAAI,MAAM,YAAY,UAAU,CAAC;AAEhJ;;;;;GAKG;AACH,MAAM,kBAAkB,GAAyF,CAAC,KAAK,EAAE,EAAE;IACvH,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;IACtD,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjG,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAE3B,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,GAA0B,EAAE,EAAE;QACzD,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACxE,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,SAAqB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,sFAAsF;QAE3H,SAAS,CAAC,SAAS,CAAC,CAAC;QACrB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAEzC,OAAO,CACH,KAAC,YAAY,OACL,KAAK,EACT,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EACvJ,eAAe,EACX,8BACI,KAAC,wBAAwB,IACrB,KAAK,EAAC,GAAG,EACT,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,IAAI,EAAE,KAAK,CAAC,IAAI,GAClB,EACF,KAAC,wBAAwB,IACrB,KAAK,EAAC,GAAG,EACT,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,IAAI,EAAE,KAAK,CAAC,IAAI,GAClB,EACD,IAAI,CAAC,MAAM,CAAC,IAAI,CACb,KAAC,wBAAwB,IACrB,KAAK,EAAC,GAAG,EACT,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,IAAI,EAAE,KAAK,CAAC,IAAI,GAClB,CACL,EACA,IAAI,CAAC,MAAM,CAAC,IAAI,CACb,KAAC,wBAAwB,IACrB,KAAK,EAAC,GAAG,EACT,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,IAAI,EAAE,KAAK,CAAC,IAAI,GAClB,CACL,IACF,YAGP,KAAC,KAAK,cAAE,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAS,GACxL,CAClB,CAAC;AACN,CAAC,CAAC;AASF,MAAM,kBAAkB,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;AAC1E,MAAM,CAAC,MAAM,0BAA0B,GAAuD,CAAC,KAAK,EAAE,EAAE;IACpG,0BAA0B,CAAC,WAAW,GAAG,4BAA4B,CAAC;IACtE,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,OAAO,CACH,KAAC,mBAAmB,OACZ,KAAK,EACT,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EACtC,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,EACjE,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,KAAK,GACb,CACL,CAAC;AACN,CAAC,CAAC;AAQF,MAAM,8BAA8B,GAAG,kBAA4E,CAAC;AACpH,MAAM,CAAC,MAAM,sBAAsB,GAAmD,CAAC,KAAK,EAAE,EAAE;IAC5F,sBAAsB,CAAC,WAAW,GAAG,wBAAwB,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE9C,wEAAwE;IACxE,MAAM,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAE3C,MAAM,YAAY,GAAG,CAAC,GAAe,EAAE,EAAE;QACrC,OAAO,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,GAAY,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,OAAO,UAAU,CAAC,CAAC,CAAC,CAChB,KAAC,mBAAmB,OACZ,SAAS,EACb,QAAQ,EAAE,KAAK,EACf,cAAc,EAAE,KAAK,EACrB,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,EAC3B,cAAc,EAAE,kBAAkB,EAClC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAC,KAAK,GACZ,CACL,CAAC,CAAC,CAAC,CACA,KAAC,8BAA8B,OAAK,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,GAAI,CACvI,CAAC;AACN,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAyE,CAAC;AAC7G,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAyE,CAAC;AAC7G,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAyE,CAAC","sourcesContent":["import { useEffect, 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\nimport { CalculatePrecision } from \"../../primitives/utils\";\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 /**\r\n * Internal spinbutton's step\r\n */\r\n step?: 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 TensorPropertyLine.displayName = \"TensorPropertyLine\";\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 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 useEffect(() => {\r\n setVector(props.value);\r\n }, [props.value, props.expandedContent]);\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n onCopy={() => `new ${props.value.constructor.name}(${vector.x},${vector.y} ${HasZ(vector) ? `,${vector.z}` : \"\"}${HasW(vector) ? `,${vector.w}` : \"\"})`}\r\n expandedContent={\r\n <>\r\n <SyncedSliderPropertyLine\r\n label=\"X\"\r\n value={converted(vector.x)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"x\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n <SyncedSliderPropertyLine\r\n label=\"Y\"\r\n value={converted(vector.y)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"y\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n {HasZ(vector) && (\r\n <SyncedSliderPropertyLine\r\n label=\"Z\"\r\n value={converted(vector.z)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"z\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n )}\r\n {HasW(vector) && (\r\n <SyncedSliderPropertyLine\r\n label=\"W\"\r\n value={converted(vector.w)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"w\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n )}\r\n </>\r\n }\r\n >\r\n <Body1>{`[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? `, ${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 RotationVectorPropertyLine.displayName = \"RotationVectorPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return (\r\n <Vector3PropertyLine\r\n {...props}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n valueConverter={props.useDegrees ? ToDegreesConverter : undefined}\r\n min={min}\r\n max={max}\r\n step={0.001}\r\n />\r\n );\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 QuaternionPropertyLine.displayName = \"QuaternionPropertyLine\";\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"]}
|
|
1
|
+
{"version":3,"file":"vectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/vectorPropertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, 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\nimport { CalculatePrecision } from \"../../primitives/utils\";\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 /**\r\n * Internal spinbutton's step\r\n */\r\n step?: 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 TensorPropertyLine.displayName = \"TensorPropertyLine\";\r\n const converted = (val: number) => (props.valueConverter ? props.valueConverter.from(val) : val);\r\n const formatted = (val: number) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 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 useEffect(() => {\r\n setVector(props.value);\r\n }, [props.value, props.expandedContent]);\r\n\r\n return (\r\n <PropertyLine\r\n {...props}\r\n onCopy={() => `new ${props.value.getClassName()}(${vector.x},${vector.y}${HasZ(vector) ? `,${vector.z}` : \"\"}${HasW(vector) ? `,${vector.w}` : \"\"})`}\r\n expandedContent={\r\n <>\r\n <SyncedSliderPropertyLine\r\n label=\"X\"\r\n value={converted(vector.x)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"x\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n <SyncedSliderPropertyLine\r\n label=\"Y\"\r\n value={converted(vector.y)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"y\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n {HasZ(vector) && (\r\n <SyncedSliderPropertyLine\r\n label=\"Z\"\r\n value={converted(vector.z)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"z\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n )}\r\n {HasW(vector) && (\r\n <SyncedSliderPropertyLine\r\n label=\"W\"\r\n value={converted(vector.w)}\r\n min={min}\r\n max={max}\r\n onChange={(val) => onChange(val, \"w\")}\r\n unit={props.unit}\r\n step={props.step}\r\n />\r\n )}\r\n </>\r\n }\r\n >\r\n <Body1>{`[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : \"\"}${HasW(props.value) ? `, ${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 RotationVectorPropertyLine.displayName = \"RotationVectorPropertyLine\";\r\n const min = props.useDegrees ? 0 : undefined;\r\n const max = props.useDegrees ? 360 : undefined;\r\n return (\r\n <Vector3PropertyLine\r\n {...props}\r\n unit={props.useDegrees ? \"deg\" : \"rad\"}\r\n valueConverter={props.useDegrees ? ToDegreesConverter : undefined}\r\n min={min}\r\n max={max}\r\n step={0.001}\r\n />\r\n );\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 QuaternionPropertyLine.displayName = \"QuaternionPropertyLine\";\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"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Children, isValidElement, useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { Children, isValidElement, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { AccordionHeader, AccordionItem, AccordionPanel, Divider, Accordion as FluentAccordion, Subtitle2Stronger, makeStyles, tokens } from "@fluentui/react-components";
|
|
4
|
+
import { CustomTokens } from "./utils.js";
|
|
5
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
4
6
|
const useStyles = makeStyles({
|
|
5
7
|
accordion: {
|
|
6
8
|
overflowX: "hidden",
|
|
@@ -11,8 +13,12 @@ const useStyles = makeStyles({
|
|
|
11
13
|
height: "100%",
|
|
12
14
|
},
|
|
13
15
|
divider: {
|
|
14
|
-
paddingTop:
|
|
15
|
-
paddingBottom:
|
|
16
|
+
paddingTop: CustomTokens.dividerGap,
|
|
17
|
+
paddingBottom: CustomTokens.dividerGap,
|
|
18
|
+
},
|
|
19
|
+
dividerSmall: {
|
|
20
|
+
paddingTop: CustomTokens.dividerGapSmall,
|
|
21
|
+
paddingBottom: CustomTokens.dividerGapSmall,
|
|
16
22
|
},
|
|
17
23
|
panelDiv: {
|
|
18
24
|
display: "flex",
|
|
@@ -28,6 +34,7 @@ export const AccordionSection = (props) => {
|
|
|
28
34
|
export const Accordion = (props) => {
|
|
29
35
|
Accordion.displayName = "Accordion";
|
|
30
36
|
const classes = useStyles();
|
|
37
|
+
const { size } = useContext(ToolContext);
|
|
31
38
|
const { children, ...rest } = props;
|
|
32
39
|
const validChildren = useMemo(() => {
|
|
33
40
|
return (Children.map(children, (child) => {
|
|
@@ -69,7 +76,7 @@ export const Accordion = (props) => {
|
|
|
69
76
|
}
|
|
70
77
|
}, []);
|
|
71
78
|
return (_jsx(FluentAccordion, { className: classes.accordion, collapsible: true, multiple: true, onToggle: onToggle, openItems: openItems, ...rest, children: validChildren.map((child, index) => {
|
|
72
|
-
return (_jsxs(AccordionItem, { value: child.title, children: [_jsx(AccordionHeader, { children: _jsx(Subtitle2Stronger, { children: child.title }) }), _jsx(AccordionPanel, { children: _jsx("div", { className: classes.panelDiv, children: child.content }) }), index < validChildren.length - 1 && _jsx(Divider, { inset: true, className: classes.divider })] }, child.content.key));
|
|
79
|
+
return (_jsxs(AccordionItem, { value: child.title, children: [_jsx(AccordionHeader, { size: size, children: _jsx(Subtitle2Stronger, { children: child.title }) }), _jsx(AccordionPanel, { children: _jsx("div", { className: classes.panelDiv, children: child.content }) }), index < validChildren.length - 1 && _jsx(Divider, { inset: true, className: size === "small" ? classes.dividerSmall : classes.divider })] }, child.content.key));
|
|
73
80
|
}) }));
|
|
74
81
|
};
|
|
75
82
|
//# sourceMappingURL=accordion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { AccordionToggleData, AccordionToggleEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, PropsWithChildren } from \"react\";\r\n\r\nimport { Children, isValidElement, useCallback, useContext, useEffect, useMemo, useState } from \"react\";\r\n\r\nimport { AccordionHeader, AccordionItem, AccordionPanel, Divider, Accordion as FluentAccordion, Subtitle2Stronger, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { CustomTokens } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nconst useStyles = makeStyles({\r\n accordion: {\r\n overflowX: \"hidden\",\r\n overflowY: \"auto\",\r\n paddingBottom: tokens.spacingVerticalM, // bottom padding since there is no divider at the bottom\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n },\r\n divider: {\r\n paddingTop: CustomTokens.dividerGap,\r\n paddingBottom: CustomTokens.dividerGap,\r\n },\r\n dividerSmall: {\r\n paddingTop: CustomTokens.dividerGapSmall,\r\n paddingBottom: CustomTokens.dividerGapSmall,\r\n },\r\n panelDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n },\r\n});\r\n\r\nexport type AccordionSectionProps = {\r\n title: string;\r\n collapseByDefault?: boolean;\r\n};\r\n\r\nexport const AccordionSection: FunctionComponent<PropsWithChildren<AccordionSectionProps>> = (props) => {\r\n AccordionSection.displayName = \"AccordionSection\";\r\n const classes = useStyles();\r\n\r\n return <div className={classes.panelDiv}>{props.children}</div>;\r\n};\r\n\r\nexport const Accordion: FunctionComponent<PropsWithChildren> = (props) => {\r\n Accordion.displayName = \"Accordion\";\r\n const classes = useStyles();\r\n const { size } = useContext(ToolContext);\r\n const { children, ...rest } = props;\r\n const validChildren = useMemo(() => {\r\n return (\r\n Children.map(children, (child) => {\r\n if (isValidElement(child)) {\r\n const childProps = child.props as Partial<AccordionSectionProps>;\r\n if (childProps.title) {\r\n return {\r\n title: childProps.title,\r\n collapseByDefault: childProps.collapseByDefault,\r\n content: child,\r\n };\r\n }\r\n }\r\n return null;\r\n })?.filter(Boolean) ?? []\r\n );\r\n }, [children]);\r\n\r\n // Tracks open items, and used to tell the Accordion which sections should be expanded.\r\n const [openItems, setOpenItems] = useState(validChildren.filter((child) => !child.collapseByDefault).map((child) => child.title));\r\n\r\n // Tracks closed items, which is needed so that when the children change, we only update the open/closed state\r\n // (depending on the collapseByDefault prop) for items that have not been explicitly opened or closed.\r\n const [closedItems, setClosedItems] = useState(validChildren.filter((child) => child.collapseByDefault).map((child) => child.title));\r\n\r\n useEffect(() => {\r\n for (const defaultOpenItem of validChildren.filter((child) => !child.collapseByDefault).map((child) => child.title)) {\r\n // If a child is not marked as collapseByDefault, then it should be opened by default, and\r\n // it is only \"default\" if it hasn't already been explicitly added to the opened or closed list.\r\n if (!closedItems.includes(defaultOpenItem) && !openItems.includes(defaultOpenItem)) {\r\n setOpenItems((prev) => [...prev, defaultOpenItem]);\r\n }\r\n }\r\n }, [validChildren]);\r\n\r\n const onToggle = useCallback((event: AccordionToggleEvent, data: AccordionToggleData<string>) => {\r\n if (data.openItems.includes(data.value)) {\r\n setOpenItems((prev) => [...prev, data.value]);\r\n setClosedItems((prev) => prev.filter((item) => item !== data.value));\r\n } else {\r\n setClosedItems((prev) => [...prev, data.value]);\r\n setOpenItems((prev) => prev.filter((item) => item !== data.value));\r\n }\r\n }, []);\r\n\r\n return (\r\n <FluentAccordion className={classes.accordion} collapsible multiple onToggle={onToggle} openItems={openItems} {...rest}>\r\n {validChildren.map((child, index) => {\r\n return (\r\n <AccordionItem key={child.content.key} value={child.title}>\r\n <AccordionHeader size={size}>\r\n <Subtitle2Stronger>{child.title}</Subtitle2Stronger>\r\n </AccordionHeader>\r\n <AccordionPanel>\r\n <div className={classes.panelDiv}>{child.content}</div>\r\n </AccordionPanel>\r\n {index < validChildren.length - 1 && <Divider inset={true} className={size === \"small\" ? classes.dividerSmall : classes.divider} />}\r\n </AccordionItem>\r\n );\r\n })}\r\n </FluentAccordion>\r\n );\r\n};\r\n"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Button as FluentButton } from "@fluentui/react-components";
|
|
3
|
+
import { useContext } from "react";
|
|
4
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
3
5
|
export const Button = (props) => {
|
|
4
6
|
Button.displayName = "Button";
|
|
7
|
+
const { size } = useContext(ToolContext);
|
|
5
8
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
6
9
|
const { icon: Icon, label, ...buttonProps } = props;
|
|
7
|
-
return (_jsx(FluentButton, { iconPosition: "after", ...buttonProps, icon: Icon && _jsx(Icon, {}), children: label && props.label }));
|
|
10
|
+
return (_jsx(FluentButton, { iconPosition: "after", ...buttonProps, size: size, icon: Icon && _jsx(Icon, {}), children: label && props.label }));
|
|
8
11
|
};
|
|
9
12
|
//# sourceMappingURL=button.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGnC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AASvD,MAAM,CAAC,MAAM,MAAM,GAAmC,CAAC,KAAK,EAAE,EAAE;IAC5D,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC;IACpD,OAAO,CACH,KAAC,YAAY,IAAC,YAAY,EAAC,OAAO,KAAK,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,KAAC,IAAI,KAAG,YACjF,KAAK,IAAI,KAAK,CAAC,KAAK,GACV,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { Button as FluentButton } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport { useContext } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport type { BasePrimitiveProps } from \"./primitive\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nexport type ButtonProps = BasePrimitiveProps & {\r\n onClick: () => void;\r\n icon?: FluentIcon;\r\n appearance?: \"subtle\" | \"transparent\";\r\n label?: string;\r\n};\r\n\r\nexport const Button: FunctionComponent<ButtonProps> = (props) => {\r\n Button.displayName = \"Button\";\r\n const { size } = useContext(ToolContext);\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { icon: Icon, label, ...buttonProps } = props;\r\n return (\r\n <FluentButton iconPosition=\"after\" {...buttonProps} size={size} icon={Icon && <Icon />}>\r\n {label && props.label}\r\n </FluentButton>\r\n );\r\n};\r\n"]}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Checkbox as FluentCheckbox } from "@fluentui/react-components";
|
|
2
|
+
import { Checkbox as FluentCheckbox, makeStyles } from "@fluentui/react-components";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
|
+
const useCheckboxStyles = makeStyles({
|
|
5
|
+
indicator: {
|
|
6
|
+
margin: 0,
|
|
7
|
+
},
|
|
8
|
+
});
|
|
4
9
|
/**
|
|
5
10
|
* This is a primitive fluent checkbox that can both read and write checked state
|
|
6
11
|
* @param props
|
|
@@ -9,6 +14,7 @@ import { useEffect, useState } from "react";
|
|
|
9
14
|
export const Checkbox = (props) => {
|
|
10
15
|
Checkbox.displayName = "Checkbox";
|
|
11
16
|
const [checked, setChecked] = useState(() => props.value ?? false);
|
|
17
|
+
const classes = useCheckboxStyles();
|
|
12
18
|
useEffect(() => {
|
|
13
19
|
if (props.value != undefined) {
|
|
14
20
|
setChecked(props.value); // Update local state when props.checked changes
|
|
@@ -18,6 +24,6 @@ export const Checkbox = (props) => {
|
|
|
18
24
|
props.onChange(ev.target.checked);
|
|
19
25
|
setChecked(ev.target.checked);
|
|
20
26
|
};
|
|
21
|
-
return _jsx(FluentCheckbox, { checked: checked, onChange: onChange,
|
|
27
|
+
return _jsx(FluentCheckbox, { checked: checked, onChange: onChange, indicator: { className: classes.indicator } });
|
|
22
28
|
};
|
|
23
29
|
//# sourceMappingURL=checkbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/checkbox.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"checkbox.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/checkbox.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,iBAAiB,GAAG,UAAU,CAAC;IACjC,SAAS,EAAE;QACP,MAAM,EAAE,CAAC;KACZ;CACJ,CAAC,CAAC;AACH;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAA+C,CAAC,KAAK,EAAE,EAAE;IAC1E,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;YAC3B,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,gDAAgD;QAC7E,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,MAAM,QAAQ,GAAG,CAAC,EAAiC,EAAE,CAAuB,EAAE,EAAE;QAC5E,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF,OAAO,KAAC,cAAc,IAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,GAAI,CAAC;AACjH,CAAC,CAAC","sourcesContent":["import type { CheckboxOnChangeData } from \"@fluentui/react-components\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\n\r\nimport { Checkbox as FluentCheckbox, makeStyles } from \"@fluentui/react-components\";\r\nimport { useEffect, useState } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useCheckboxStyles = makeStyles({\r\n indicator: {\r\n margin: 0,\r\n },\r\n});\r\n/**\r\n * This is a primitive fluent checkbox that can both read and write checked state\r\n * @param props\r\n * @returns Checkbox component\r\n */\r\nexport const Checkbox: FunctionComponent<PrimitiveProps<boolean>> = (props) => {\r\n Checkbox.displayName = \"Checkbox\";\r\n const [checked, setChecked] = useState(() => props.value ?? false);\r\n const classes = useCheckboxStyles();\r\n useEffect(() => {\r\n if (props.value != undefined) {\r\n setChecked(props.value); // Update local state when props.checked changes\r\n }\r\n }, [props.value]);\r\n\r\n const onChange = (ev: ChangeEvent<HTMLInputElement>, _: CheckboxOnChangeData) => {\r\n props.onChange(ev.target.checked);\r\n setChecked(ev.target.checked);\r\n };\r\n\r\n return <FluentCheckbox checked={checked} onChange={onChange} indicator={{ className: classes.indicator }} />;\r\n};\r\n"]}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable jsdoc/require-returns */
|
|
3
3
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
4
|
-
import { useState, useEffect, useCallback } from "react";
|
|
4
|
+
import { useState, useEffect, useCallback, useContext } from "react";
|
|
5
5
|
import { ColorPicker as FluentColorPicker, ColorSlider, ColorArea, AlphaSlider, Link, makeStyles, Popover, PopoverSurface, PopoverTrigger, tokens, Body1Strong, ColorSwatch, Body1, } from "@fluentui/react-components";
|
|
6
6
|
import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js";
|
|
7
7
|
import { SpinButton } from "./spinButton.js";
|
|
8
8
|
import { TextInput } from "./textInput.js";
|
|
9
9
|
import { NumberDropdown } from "./dropdown.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ValidateColorHex } from "./utils.js";
|
|
11
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
11
12
|
const useColorPickerStyles = makeStyles({
|
|
12
13
|
container: {
|
|
13
14
|
width: "350px",
|
|
@@ -62,6 +63,7 @@ export const ColorPickerPopup = (props) => {
|
|
|
62
63
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
63
64
|
const [isLinear, setIsLinear] = useState(props.isLinearMode ?? false);
|
|
64
65
|
const [isFloat, setFloat] = useState(false);
|
|
66
|
+
const { size } = useContext(ToolContext);
|
|
65
67
|
useEffect(() => {
|
|
66
68
|
setColor(props.value); // Ensures the trigger color updates when props.value changes
|
|
67
69
|
}, [props.value]);
|
|
@@ -80,7 +82,7 @@ export const ColorPickerPopup = (props) => {
|
|
|
80
82
|
align: "start",
|
|
81
83
|
overflowBoundary: document.body,
|
|
82
84
|
autoSize: true,
|
|
83
|
-
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: _jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: "small", shape: "rounded", color: color.toHexString(), value: color.toHexString().slice(1) }) }), _jsx(PopoverSurface, { children: _jsxs("div", { className: classes.container, children: [_jsxs(FluentColorPicker, { className: classes.colorPicker, 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.row, children: [_jsx("div", { className: classes.previewColor, style: { backgroundColor: color.toHexString() } }), _jsx(NumberDropdown, { className: classes.inputField, infoLabel: {
|
|
85
|
+
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: _jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: size === "small" ? "extra-small" : "small", shape: "rounded", color: color.toHexString(), value: color.toHexString().slice(1) }) }), _jsx(PopoverSurface, { children: _jsxs("div", { className: classes.container, children: [_jsxs(FluentColorPicker, { className: classes.colorPicker, 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.row, children: [_jsx("div", { className: classes.previewColor, style: { backgroundColor: color.toHexString() } }), _jsx(NumberDropdown, { className: classes.inputField, infoLabel: {
|
|
84
86
|
label: "Color Space",
|
|
85
87
|
info: _jsx(Body1, { children: "Today this is not mutable as the color space is determined by the entity. Soon we will allow swapping" }),
|
|
86
88
|
}, options: [
|
|
@@ -105,7 +107,7 @@ export const ColorPickerPopup = (props) => {
|
|
|
105
107
|
export const InputHexField = (props) => {
|
|
106
108
|
const classes = useColorPickerStyles();
|
|
107
109
|
const { title, value, onChange, linearHex, isLinearMode } = props;
|
|
108
|
-
return (_jsx(TextInput, { disabled: linearHex ? !isLinearMode : false, className: classes.inputField, value: linearHex ? value.toLinearSpace().toHexString() : value.toHexString(), validator:
|
|
110
|
+
return (_jsx(TextInput, { disabled: linearHex ? !isLinearMode : false, className: classes.inputField, value: linearHex ? value.toLinearSpace().toHexString() : value.toHexString(), validator: ValidateColorHex, onChange: (val) => (linearHex ? onChange(Color3.FromHexString(val).toGammaSpace()) : onChange(Color3.FromHexString(val))), infoLabel: title
|
|
109
111
|
? {
|
|
110
112
|
label: title,
|
|
111
113
|
// If not representing a linearHex, no info is needed.
|
|
@@ -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 } 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 Body1,\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\nimport { NumberDropdown } from \"./dropdown\";\r\nimport { ColorHexValidatorFn } from \"./utils\";\r\n\r\nconst useColorPickerStyles = makeStyles({\r\n container: {\r\n width: \"350px\",\r\n display: \"flex\", // becomes a flexbox\r\n flexDirection: \"column\", // with children in a column\r\n alignItems: \"center\", // centers children horizontally\r\n justifyContent: \"center\", // centers children vertically (if height is set)\r\n gap: tokens.spacingVerticalM,\r\n overflow: \"visible\",\r\n },\r\n row: {\r\n flex: 1, // is a row in the container's flex column\r\n display: \"flex\", // becomes its own flexbox\r\n flexDirection: \"row\", // with children in a row\r\n gap: tokens.spacingHorizontalXL,\r\n alignItems: \"center\", // align items vertically\r\n width: \"100%\",\r\n },\r\n colorPicker: {\r\n flex: 1,\r\n width: \"350px\",\r\n height: \"350px\",\r\n },\r\n previewColor: {\r\n width: \"60px\",\r\n height: \"60px\",\r\n borderRadius: tokens.borderRadiusMedium, // 4px?\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 inputRow: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n flex: 1, // grow and fill available space\r\n justifyContent: \"center\",\r\n gap: \"10px\",\r\n width: \"100%\",\r\n },\r\n inputField: {\r\n flex: 1, // grow and fill available space\r\n width: \"auto\",\r\n minWidth: 0,\r\n gap: tokens.spacingVerticalSNudge, // 6px\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 ColorPickerPopup.displayName = \"ColorPickerPopup\";\r\n const classes = useColorPickerStyles();\r\n const [color, setColor] = useState(props.value);\r\n const [popoverOpen, setPopoverOpen] = useState(false);\r\n const [isLinear, setIsLinear] = useState(props.isLinearMode ?? false);\r\n const [isFloat, setFloat] = 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\" shape=\"rounded\" color={color.toHexString()} value={color.toHexString().slice(1)} />\r\n </PopoverTrigger>\r\n\r\n <PopoverSurface>\r\n <div className={classes.container}>\r\n <FluentColorPicker className={classes.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 </FluentColorPicker>\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 <NumberDropdown\r\n className={classes.inputField}\r\n infoLabel={{\r\n label: \"Color Space\",\r\n info: <Body1>Today this is not mutable as the color space is determined by the entity. Soon we will allow swapping</Body1>,\r\n }}\r\n options={[\r\n { label: \"Gamma\", value: 0 },\r\n { label: \"Linear\", value: 1 },\r\n ]}\r\n disabled={true}\r\n value={isLinear ? 1 : 0}\r\n onChange={(val: number) => setIsLinear(val === 1)}\r\n />\r\n <NumberDropdown\r\n className={classes.inputField}\r\n infoLabel={{\r\n label: \"Data Type\",\r\n info: <Body1>We will introduce this functionality soon!</Body1>,\r\n }}\r\n options={[\r\n { label: \"Int\", value: 0 },\r\n { label: \"Float\", value: 1 },\r\n ]}\r\n disabled={true}\r\n value={isFloat ? 1 : 0}\r\n onChange={(val: number) => setFloat(val === 1)}\r\n />\r\n </div>\r\n\r\n {/* Middle Row: Red, Green, Blue, Alpha */}\r\n <div className={classes.inputRow}>\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.inputRow}>\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\r\n <div className={classes.inputRow}>\r\n <InputHexField title=\"Hexadecimal\" linearHex={isLinear} isLinearMode={isLinear} value={color} onChange={handleChange} />\r\n </div>\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\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 classes = useColorPickerStyles();\r\n const { title, value, onChange, linearHex, isLinearMode } = props;\r\n\r\n return (\r\n <TextInput\r\n disabled={linearHex ? !isLinearMode : false}\r\n className={classes.inputField}\r\n value={linearHex ? value.toLinearSpace().toHexString() : value.toHexString()}\r\n validator={ColorHexValidatorFn}\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 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\r\n 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 );\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 <SpinButton\r\n title={title}\r\n infoLabel={title ? { label: title } : undefined}\r\n className={classes.inputField}\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 );\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 <SpinButton\r\n infoLabel={title ? { label: title } : undefined}\r\n title={title}\r\n className={classes.inputField}\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 );\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 <SpinButton\r\n disabled={color instanceof Color3}\r\n min={0}\r\n max={1}\r\n className={classes.inputField}\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 alpha\r\n 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 );\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, useContext } 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 Body1,\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\nimport { NumberDropdown } from \"./dropdown\";\r\nimport { ValidateColorHex } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useColorPickerStyles = makeStyles({\r\n container: {\r\n width: \"350px\",\r\n display: \"flex\", // becomes a flexbox\r\n flexDirection: \"column\", // with children in a column\r\n alignItems: \"center\", // centers children horizontally\r\n justifyContent: \"center\", // centers children vertically (if height is set)\r\n gap: tokens.spacingVerticalM,\r\n overflow: \"visible\",\r\n },\r\n row: {\r\n flex: 1, // is a row in the container's flex column\r\n display: \"flex\", // becomes its own flexbox\r\n flexDirection: \"row\", // with children in a row\r\n gap: tokens.spacingHorizontalXL,\r\n alignItems: \"center\", // align items vertically\r\n width: \"100%\",\r\n },\r\n colorPicker: {\r\n flex: 1,\r\n width: \"350px\",\r\n height: \"350px\",\r\n },\r\n previewColor: {\r\n width: \"60px\",\r\n height: \"60px\",\r\n borderRadius: tokens.borderRadiusMedium, // 4px?\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 inputRow: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n flex: 1, // grow and fill available space\r\n justifyContent: \"center\",\r\n gap: \"10px\",\r\n width: \"100%\",\r\n },\r\n inputField: {\r\n flex: 1, // grow and fill available space\r\n width: \"auto\",\r\n minWidth: 0,\r\n gap: tokens.spacingVerticalSNudge, // 6px\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 ColorPickerPopup.displayName = \"ColorPickerPopup\";\r\n const classes = useColorPickerStyles();\r\n const [color, setColor] = useState(props.value);\r\n const [popoverOpen, setPopoverOpen] = useState(false);\r\n const [isLinear, setIsLinear] = useState(props.isLinearMode ?? false);\r\n const [isFloat, setFloat] = useState(false);\r\n const { size } = useContext(ToolContext);\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\r\n borderColor={tokens.colorNeutralShadowKeyDarker}\r\n size={size === \"small\" ? \"extra-small\" : \"small\"}\r\n shape=\"rounded\"\r\n color={color.toHexString()}\r\n value={color.toHexString().slice(1)}\r\n />\r\n </PopoverTrigger>\r\n\r\n <PopoverSurface>\r\n <div className={classes.container}>\r\n <FluentColorPicker className={classes.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 </FluentColorPicker>\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 <NumberDropdown\r\n className={classes.inputField}\r\n infoLabel={{\r\n label: \"Color Space\",\r\n info: <Body1>Today this is not mutable as the color space is determined by the entity. Soon we will allow swapping</Body1>,\r\n }}\r\n options={[\r\n { label: \"Gamma\", value: 0 },\r\n { label: \"Linear\", value: 1 },\r\n ]}\r\n disabled={true}\r\n value={isLinear ? 1 : 0}\r\n onChange={(val: number) => setIsLinear(val === 1)}\r\n />\r\n <NumberDropdown\r\n className={classes.inputField}\r\n infoLabel={{\r\n label: \"Data Type\",\r\n info: <Body1>We will introduce this functionality soon!</Body1>,\r\n }}\r\n options={[\r\n { label: \"Int\", value: 0 },\r\n { label: \"Float\", value: 1 },\r\n ]}\r\n disabled={true}\r\n value={isFloat ? 1 : 0}\r\n onChange={(val: number) => setFloat(val === 1)}\r\n />\r\n </div>\r\n\r\n {/* Middle Row: Red, Green, Blue, Alpha */}\r\n <div className={classes.inputRow}>\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.inputRow}>\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\r\n <div className={classes.inputRow}>\r\n <InputHexField title=\"Hexadecimal\" linearHex={isLinear} isLinearMode={isLinear} value={color} onChange={handleChange} />\r\n </div>\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\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 classes = useColorPickerStyles();\r\n const { title, value, onChange, linearHex, isLinearMode } = props;\r\n\r\n return (\r\n <TextInput\r\n disabled={linearHex ? !isLinearMode : false}\r\n className={classes.inputField}\r\n value={linearHex ? value.toLinearSpace().toHexString() : value.toHexString()}\r\n validator={ValidateColorHex}\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 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\r\n 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 );\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 <SpinButton\r\n title={title}\r\n infoLabel={title ? { label: title } : undefined}\r\n className={classes.inputField}\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 );\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 <SpinButton\r\n infoLabel={title ? { label: title } : undefined}\r\n title={title}\r\n className={classes.inputField}\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 );\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 <SpinButton\r\n disabled={color instanceof Color3}\r\n min={0}\r\n max={1}\r\n className={classes.inputField}\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 alpha\r\n 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 );\r\n};\r\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Dropdown as FluentDropdown, makeStyles, mergeClasses, Option, useId } from "@fluentui/react-components";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
3
|
+
import { useContext, useEffect, useState } from "react";
|
|
4
4
|
import { InfoLabel } from "./infoLabel.js";
|
|
5
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
5
6
|
const useDropdownStyles = makeStyles({
|
|
6
7
|
dropdown: {
|
|
7
8
|
minWidth: 0,
|
|
@@ -11,7 +12,6 @@ const useDropdownStyles = makeStyles({
|
|
|
11
12
|
display: "flex",
|
|
12
13
|
flexDirection: "column",
|
|
13
14
|
justifyContent: "center", // align items vertically
|
|
14
|
-
gap: "4px",
|
|
15
15
|
},
|
|
16
16
|
dropdownText: { textAlign: "end", textOverflow: "ellipsis", whiteSpace: "nowrap", overflowX: "hidden" },
|
|
17
17
|
});
|
|
@@ -26,13 +26,14 @@ export const Dropdown = (props) => {
|
|
|
26
26
|
const classes = useDropdownStyles();
|
|
27
27
|
const { options, value } = props;
|
|
28
28
|
const [defaultVal, setDefaultVal] = useState(props.value);
|
|
29
|
+
const { size } = useContext(ToolContext);
|
|
29
30
|
useEffect(() => {
|
|
30
31
|
setDefaultVal(value);
|
|
31
32
|
}, [props.value]);
|
|
32
33
|
const id = useId("dropdown");
|
|
33
34
|
const mergedClassName = mergeClasses(classes.container, props.className);
|
|
34
35
|
const optionLabel = options.find((o) => o.value === defaultVal)?.label;
|
|
35
|
-
return (_jsxs("div", { className: mergedClassName, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentDropdown, { id: id, disabled: props.disabled, size:
|
|
36
|
+
return (_jsxs("div", { className: mergedClassName, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentDropdown, { id: id, disabled: props.disabled, size: size, className: classes.dropdown, button: _jsx("span", { className: classes.dropdownText, children: optionLabel }), onOptionSelect: (evt, data) => {
|
|
36
37
|
const value = typeof props.value === "number" ? Number(data.optionValue) : data.optionValue;
|
|
37
38
|
if (value !== undefined) {
|
|
38
39
|
setDefaultVal(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/dropdown.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACjH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Dropdown as FluentDropdown, makeStyles, mergeClasses, Option, useId } from \"@fluentui/react-components\";\r\nimport { useContext, useEffect, useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useDropdownStyles = makeStyles({\r\n dropdown: {\r\n minWidth: 0,\r\n width: \"100%\",\r\n },\r\n container: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"center\", // align items vertically\r\n },\r\n dropdownText: { textAlign: \"end\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", overflowX: \"hidden\" },\r\n});\r\n\r\nexport type AcceptedDropdownValue = string | number;\r\nexport type DropdownOption<T extends AcceptedDropdownValue> = {\r\n /**\r\n * Defines the visible part of the option\r\n */\r\n label: string;\r\n /**\r\n * Defines the value part of the option\r\n */\r\n value: T;\r\n};\r\n\r\nexport type DropdownProps<V extends AcceptedDropdownValue> = PrimitiveProps<V> & {\r\n options: readonly DropdownOption<V>[];\r\n};\r\n\r\n/**\r\n * Renders a fluent UI dropdown component for the options passed in, and an additional 'Not Defined' option if null is set to true\r\n * This component can handle both null and undefined values\r\n * @param props\r\n * @returns dropdown component\r\n */\r\nexport const Dropdown: FunctionComponent<DropdownProps<AcceptedDropdownValue>> = (props) => {\r\n Dropdown.displayName = \"Dropdown\";\r\n const classes = useDropdownStyles();\r\n const { options, value } = props;\r\n const [defaultVal, setDefaultVal] = useState(props.value);\r\n const { size } = useContext(ToolContext);\r\n\r\n useEffect(() => {\r\n setDefaultVal(value);\r\n }, [props.value]);\r\n const id = useId(\"dropdown\");\r\n\r\n const mergedClassName = mergeClasses(classes.container, props.className);\r\n\r\n const optionLabel = options.find((o) => o.value === defaultVal)?.label;\r\n\r\n return (\r\n <div className={mergedClassName}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentDropdown\r\n id={id}\r\n disabled={props.disabled}\r\n size={size}\r\n className={classes.dropdown}\r\n button={<span className={classes.dropdownText}>{optionLabel}</span>}\r\n onOptionSelect={(evt, data) => {\r\n const value = typeof props.value === \"number\" ? Number(data.optionValue) : data.optionValue;\r\n if (value !== undefined) {\r\n setDefaultVal(value);\r\n props.onChange(value);\r\n }\r\n }}\r\n selectedOptions={[defaultVal.toString()]}\r\n value={optionLabel}\r\n >\r\n {options.map((option: DropdownOption<AcceptedDropdownValue>) => (\r\n <Option key={option.label} value={option.value.toString()} disabled={false}>\r\n {option.label}\r\n </Option>\r\n ))}\r\n </FluentDropdown>\r\n </div>\r\n );\r\n};\r\n\r\nexport const NumberDropdown = Dropdown as FunctionComponent<DropdownProps<number>>;\r\nexport const StringDropdown = Dropdown as FunctionComponent<DropdownProps<string>>;\r\n"]}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { SpinButton as FluentSpinButton, mergeClasses, useId } from "@fluentui/react-components";
|
|
3
|
-
import { useEffect, useState, useRef } from "react";
|
|
3
|
+
import { useEffect, useState, useRef, useContext } from "react";
|
|
4
4
|
import { InfoLabel } from "./infoLabel.js";
|
|
5
5
|
import { CalculatePrecision, HandleKeyDown, HandleOnBlur, useInputStyles } from "./utils.js";
|
|
6
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
6
7
|
export const SpinButton = (props) => {
|
|
7
8
|
SpinButton.displayName = "SpinButton";
|
|
8
9
|
const classes = useInputStyles();
|
|
10
|
+
const { size } = useContext(ToolContext);
|
|
9
11
|
const { min, max } = props;
|
|
10
12
|
const [value, setValue] = useState(props.value);
|
|
11
13
|
const lastCommittedValue = useRef(props.value);
|
|
@@ -49,6 +51,6 @@ export const SpinButton = (props) => {
|
|
|
49
51
|
};
|
|
50
52
|
const id = useId("spin-button");
|
|
51
53
|
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
52
|
-
return (_jsxs("div", { className: classes.container, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentSpinButton, { ...props, input: { className: classes.inputSlot }, step: step, id: id, size:
|
|
54
|
+
return (_jsxs("div", { className: classes.container, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentSpinButton, { ...props, input: { className: classes.inputSlot }, step: step, id: id, size: size, precision: precision, displayValue: `${value.toFixed(precision)}${props.unit ? " " + props.unit : ""}`, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
53
55
|
};
|
|
54
56
|
//# 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,IAAI,gBAAgB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAGjG,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"spinButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/spinButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { SpinButton as FluentSpinButton, mergeClasses, useId } from \"@fluentui/react-components\";\r\nimport type { SpinButtonOnChangeData, SpinButtonChangeEvent } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, KeyboardEvent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { CalculatePrecision, HandleKeyDown, HandleOnBlur, useInputStyles } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\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 SpinButton.displayName = \"SpinButton\";\r\n const classes = useInputStyles();\r\n const { size } = useContext(ToolContext);\r\n\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 const precision = Math.min(4, step !== undefined ? Math.max(0, CalculatePrecision(step)) : 2); // If no step, set precision to 2. Regardless, cap precision at 4 to avoid wild numbers\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 const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : \"\", props.className);\r\n\r\n return (\r\n <div className={classes.container}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentSpinButton\r\n {...props}\r\n input={{ className: classes.inputSlot }}\r\n step={step}\r\n id={id}\r\n size={size}\r\n precision={precision}\r\n displayValue={`${value.toFixed(precision)}${props.unit ? \" \" + props.unit : \"\"}`}\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={mergedClassName}\r\n />\r\n </div>\r\n );\r\n};\r\n"]}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { makeStyles, Switch as FluentSwitch } from "@fluentui/react-components";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { makeStyles, Switch as FluentSwitch, mergeClasses } from "@fluentui/react-components";
|
|
3
|
+
import { useContext, useEffect, useState } from "react";
|
|
4
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
4
5
|
const useSwitchStyles = makeStyles({
|
|
5
6
|
switch: {
|
|
6
7
|
marginLeft: "auto",
|
|
7
8
|
},
|
|
9
|
+
switchSmall: {
|
|
10
|
+
transform: `scale(.85)`, // workaround since we cannot resize fluent switch
|
|
11
|
+
transformOrigin: "right",
|
|
12
|
+
},
|
|
8
13
|
indicator: {
|
|
9
14
|
margin: 0, // Remove the default right margin so the switch aligns well on the right side inside panels like the properties pane.
|
|
10
15
|
},
|
|
@@ -16,6 +21,7 @@ const useSwitchStyles = makeStyles({
|
|
|
16
21
|
*/
|
|
17
22
|
export const Switch = (props) => {
|
|
18
23
|
Switch.displayName = "Switch";
|
|
24
|
+
const { size } = useContext(ToolContext);
|
|
19
25
|
const classes = useSwitchStyles();
|
|
20
26
|
const [checked, setChecked] = useState(() => props.value ?? false);
|
|
21
27
|
useEffect(() => {
|
|
@@ -27,6 +33,6 @@ export const Switch = (props) => {
|
|
|
27
33
|
props.onChange && props.onChange(event.target.checked);
|
|
28
34
|
setChecked(event.target.checked);
|
|
29
35
|
};
|
|
30
|
-
return _jsx(FluentSwitch, { className: classes.switch, indicator: { className: classes.indicator }, checked: checked, disabled: props.disabled, onChange: onChange });
|
|
36
|
+
return (_jsx(FluentSwitch, { className: mergeClasses(classes.switch, size === "small" && classes.switchSmall), indicator: { className: classes.indicator }, checked: checked, disabled: props.disabled, onChange: onChange }));
|
|
31
37
|
};
|
|
32
38
|
//# sourceMappingURL=switch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/switch.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/switch.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,eAAe,GAAG,UAAU,CAAC;IAC/B,MAAM,EAAE;QACJ,UAAU,EAAE,MAAM;KACrB;IACD,WAAW,EAAE;QACT,SAAS,EAAE,YAAY,EAAE,kDAAkD;QAC3E,eAAe,EAAE,OAAO;KAC3B;IACD,SAAS,EAAE;QACP,MAAM,EAAE,CAAC,EAAE,sHAAsH;KACpI;CACJ,CAAC,CAAC;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAmC,CAAC,KAAK,EAAE,EAAE;IAC5D,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;IAEnE,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;YAC3B,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,gDAAgD;QAC7E,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,MAAM,QAAQ,GAAG,CAAC,KAAoC,EAAE,CAAqB,EAAE,EAAE;QAC7E,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvD,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,OAAO,CACH,KAAC,YAAY,IACT,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,EAChF,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAC3C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,QAAQ,EAAE,QAAQ,GACpB,CACL,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { SwitchOnChangeData } from \"@fluentui/react-components\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nimport { makeStyles, Switch as FluentSwitch, mergeClasses } from \"@fluentui/react-components\";\r\nimport { useContext, useEffect, useState } from \"react\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useSwitchStyles = makeStyles({\r\n switch: {\r\n marginLeft: \"auto\",\r\n },\r\n switchSmall: {\r\n transform: `scale(.85)`, // workaround since we cannot resize fluent switch\r\n transformOrigin: \"right\",\r\n },\r\n indicator: {\r\n margin: 0, // Remove the default right margin so the switch aligns well on the right side inside panels like the properties pane.\r\n },\r\n});\r\n\r\nexport type SwitchProps = PrimitiveProps<boolean>;\r\n\r\n/**\r\n * This is a primitive fluent boolean switch component whose only knowledge is the shared styling across all tools\r\n * @param props\r\n * @returns Switch component\r\n */\r\nexport const Switch: FunctionComponent<SwitchProps> = (props) => {\r\n Switch.displayName = \"Switch\";\r\n const { size } = useContext(ToolContext);\r\n const classes = useSwitchStyles();\r\n const [checked, setChecked] = useState(() => props.value ?? false);\r\n\r\n useEffect(() => {\r\n if (props.value != undefined) {\r\n setChecked(props.value); // Update local state when props.checked changes\r\n }\r\n }, [props.value]);\r\n\r\n const onChange = (event: ChangeEvent<HTMLInputElement>, _: SwitchOnChangeData) => {\r\n props.onChange && props.onChange(event.target.checked);\r\n setChecked(event.target.checked);\r\n };\r\n\r\n return (\r\n <FluentSwitch\r\n className={mergeClasses(classes.switch, size === \"small\" && classes.switchSmall)}\r\n indicator={{ className: classes.indicator }}\r\n checked={checked}\r\n disabled={props.disabled}\r\n onChange={onChange}\r\n />\r\n );\r\n};\r\n"]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { makeStyles, Slider } from "@fluentui/react-components";
|
|
3
3
|
import { SpinButton } from "./spinButton.js";
|
|
4
|
-
import { useEffect, useState, useRef } from "react";
|
|
4
|
+
import { useEffect, useState, useRef, useContext } from "react";
|
|
5
5
|
import { InfoLabel } from "./infoLabel.js";
|
|
6
6
|
import { CustomTokens } from "./utils.js";
|
|
7
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
7
8
|
const useSyncedSliderStyles = makeStyles({
|
|
8
9
|
container: { display: "flex" },
|
|
9
10
|
syncedSlider: {
|
|
@@ -26,6 +27,7 @@ export const SyncedSliderInput = (props) => {
|
|
|
26
27
|
SyncedSliderInput.displayName = "SyncedSliderInput";
|
|
27
28
|
const { infoLabel, ...passthroughProps } = props;
|
|
28
29
|
const classes = useSyncedSliderStyles();
|
|
30
|
+
const { size } = useContext(ToolContext);
|
|
29
31
|
const [value, setValue] = useState(props.value);
|
|
30
32
|
const pendingValueRef = useRef(undefined);
|
|
31
33
|
const isDraggingRef = useRef(false);
|
|
@@ -64,6 +66,6 @@ export const SyncedSliderInput = (props) => {
|
|
|
64
66
|
setValue(value);
|
|
65
67
|
props.onChange(value); // Input always updates immediately
|
|
66
68
|
};
|
|
67
|
-
return (_jsxs("div", { className: classes.container, children: [infoLabel && _jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), _jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [props.min !== undefined && props.max !== undefined && (_jsx(Slider, { ...passthroughProps, className: classes.slider, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(SpinButton, { ...passthroughProps, value: value, onChange: handleInputChange, step: props.step })] })] }));
|
|
69
|
+
return (_jsxs("div", { className: classes.container, children: [infoLabel && _jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), _jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [props.min !== undefined && props.max !== undefined && (_jsx(Slider, { ...passthroughProps, className: classes.slider, size: size, min: min / step, max: max / step, step: undefined, value: value / step, onChange: handleSliderChange, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), _jsx(SpinButton, { ...passthroughProps, value: value, onChange: handleInputChange, step: props.step })] })] }));
|
|
68
70
|
};
|
|
69
71
|
//# 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,4BAA4B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
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 } from \"@fluentui/react-components\";\r\nimport { SpinButton } from \"./spinButton\";\r\nimport type { ChangeEvent, FunctionComponent } from \"react\";\r\nimport { useEffect, useState, useRef, useContext } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { CustomTokens } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nconst useSyncedSliderStyles = makeStyles({\r\n container: { display: \"flex\" },\r\n syncedSlider: {\r\n flex: \"1 1 0\",\r\n flexDirection: \"row\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n },\r\n slider: {\r\n minWidth: CustomTokens.sliderMinWidth, // Minimum width for slider to remain usable\r\n maxWidth: CustomTokens.sliderMaxWidth,\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 SyncedSliderInput.displayName = \"SyncedSliderInput\";\r\n const { infoLabel, ...passthroughProps } = props;\r\n const classes = useSyncedSliderStyles();\r\n const { size } = useContext(ToolContext);\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.container}>\r\n {infoLabel && <InfoLabel {...infoLabel} htmlFor={\"syncedSlider\"} />}\r\n <div id=\"syncedSlider\" className={classes.syncedSlider}>\r\n {props.min !== undefined && props.max !== undefined && (\r\n <Slider\r\n {...passthroughProps}\r\n className={classes.slider}\r\n size={size}\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 {...passthroughProps} value={value} onChange={handleInputChange} step={props.step} />\r\n </div>\r\n </div>\r\n );\r\n};\r\n"]}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useContext, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Input as FluentInput, mergeClasses, useId } from "@fluentui/react-components";
|
|
4
4
|
import { InfoLabel } from "./infoLabel.js";
|
|
5
5
|
import { HandleOnBlur, HandleKeyDown, useInputStyles } from "./utils.js";
|
|
6
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
6
7
|
export const TextInput = (props) => {
|
|
7
8
|
TextInput.displayName = "TextInput";
|
|
8
9
|
const classes = useInputStyles();
|
|
9
10
|
const [value, setValue] = useState(props.value);
|
|
10
11
|
const lastCommittedValue = useRef(props.value);
|
|
12
|
+
const { size } = useContext(ToolContext);
|
|
11
13
|
useEffect(() => {
|
|
12
14
|
if (props.value !== lastCommittedValue.current) {
|
|
13
15
|
setValue(props.value); // Update local state when props.value changes
|
|
@@ -37,6 +39,6 @@ export const TextInput = (props) => {
|
|
|
37
39
|
};
|
|
38
40
|
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
39
41
|
const id = useId("input-button");
|
|
40
|
-
return (_jsxs("div", { className: classes.container, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentInput, { ...props, input: { className: classes.inputSlot }, id: id, size:
|
|
42
|
+
return (_jsxs("div", { className: classes.container, children: [props.infoLabel && _jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), _jsx(FluentInput, { ...props, input: { className: classes.inputSlot }, id: id, size: size, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
41
43
|
};
|
|
42
44
|
//# sourceMappingURL=textInput.js.map
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"textInput.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent, KeyboardEvent, ChangeEvent } from \"react\";\r\nimport { useContext, useEffect, useRef, useState } from \"react\";\r\nimport type { InputOnChangeData } from \"@fluentui/react-components\";\r\nimport { Input as FluentInput, mergeClasses, useId } from \"@fluentui/react-components\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport { InfoLabel } from \"./infoLabel\";\r\nimport { HandleOnBlur, HandleKeyDown, useInputStyles } from \"./utils\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\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 TextInput.displayName = \"TextInput\";\r\n const classes = useInputStyles();\r\n const [value, setValue] = useState(props.value);\r\n const lastCommittedValue = useRef(props.value);\r\n const { size } = useContext(ToolContext);\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 const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : \"\", props.className);\r\n\r\n const id = useId(\"input-button\");\r\n return (\r\n <div className={classes.container}>\r\n {props.infoLabel && <InfoLabel {...props.infoLabel} htmlFor={id} />}\r\n <FluentInput\r\n {...props}\r\n input={{ className: classes.inputSlot }}\r\n id={id}\r\n size={size}\r\n value={value}\r\n onChange={handleChange}\r\n onKeyUp={handleKeyUp}\r\n onKeyDown={HandleKeyDown}\r\n onBlur={HandleOnBlur}\r\n className={mergedClassName}\r\n />\r\n </div>\r\n );\r\n};\r\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ToggleButton as FluentToggleButton } from "@fluentui/react-components";
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useCallback, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
4
5
|
/**
|
|
5
6
|
* Toggles between two states using a button with icons.
|
|
6
7
|
* If no disabledIcon is provided, the button will toggle between visual enabled/disabled states without an icon change
|
|
@@ -11,6 +12,7 @@ import { useCallback, useEffect, useState } from "react";
|
|
|
11
12
|
export const ToggleButton = (props) => {
|
|
12
13
|
ToggleButton.displayName = "ToggleButton";
|
|
13
14
|
const { value, onChange, title, appearance = "subtle" } = props;
|
|
15
|
+
const { size } = useContext(ToolContext);
|
|
14
16
|
const [checked, setChecked] = useState(value);
|
|
15
17
|
const toggle = useCallback(() => {
|
|
16
18
|
setChecked((prev) => {
|
|
@@ -22,6 +24,6 @@ export const ToggleButton = (props) => {
|
|
|
22
24
|
useEffect(() => {
|
|
23
25
|
setChecked(props.value);
|
|
24
26
|
}, [props.value]);
|
|
25
|
-
return (_jsx(FluentToggleButton, { title: title, icon: checked ? _jsx(props.checkedIcon, {}) : props.uncheckedIcon ? _jsx(props.uncheckedIcon, {}) : _jsx(props.checkedIcon, {}), appearance: appearance, checked: checked, onClick: toggle }));
|
|
27
|
+
return (_jsx(FluentToggleButton, { title: title, size: size, icon: checked ? _jsx(props.checkedIcon, {}) : props.uncheckedIcon ? _jsx(props.uncheckedIcon, {}) : _jsx(props.checkedIcon, {}), appearance: appearance, checked: checked, onClick: toggle }));
|
|
26
28
|
};
|
|
27
29
|
//# sourceMappingURL=toggleButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggleButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/toggleButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"toggleButton.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/toggleButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AASvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAyC,CAAC,KAAK,EAAE,EAAE;IACxE,YAAY,CAAC,WAAW,GAAG,cAAc,CAAC;IAC1C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,QAAQ,EAAE,GAAG,KAAK,CAAC;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC;YACtB,QAAQ,CAAC,OAAO,CAAC,CAAC;YAClB,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACX,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,CACH,KAAC,kBAAkB,IACf,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,WAAW,KAAG,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,aAAa,KAAG,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,WAAW,KAAG,EAC7G,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,GACjB,CACL,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { ToggleButton as FluentToggleButton } from \"@fluentui/react-components\";\r\nimport type { ButtonProps } from \"./button\";\r\nimport { useCallback, useContext, useEffect, useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\ntype ToggleButtonProps = Omit<ButtonProps, \"icon\" | \"onClick\"> & {\r\n value: boolean;\r\n checkedIcon: FluentIcon;\r\n uncheckedIcon?: FluentIcon;\r\n onChange: (checked: boolean) => void;\r\n};\r\n\r\n/**\r\n * Toggles between two states using a button with icons.\r\n * If no disabledIcon is provided, the button will toggle between visual enabled/disabled states without an icon change\r\n *\r\n * @param props\r\n * @returns\r\n */\r\nexport const ToggleButton: FunctionComponent<ToggleButtonProps> = (props) => {\r\n ToggleButton.displayName = \"ToggleButton\";\r\n const { value, onChange, title, appearance = \"subtle\" } = props;\r\n const { size } = useContext(ToolContext);\r\n const [checked, setChecked] = useState(value);\r\n const toggle = useCallback(() => {\r\n setChecked((prev) => {\r\n const enabled = !prev;\r\n onChange(enabled);\r\n return enabled;\r\n });\r\n }, [setChecked]);\r\n\r\n useEffect(() => {\r\n setChecked(props.value);\r\n }, [props.value]);\r\n\r\n return (\r\n <FluentToggleButton\r\n title={title}\r\n size={size}\r\n icon={checked ? <props.checkedIcon /> : props.uncheckedIcon ? <props.uncheckedIcon /> : <props.checkedIcon />}\r\n appearance={appearance}\r\n checked={checked}\r\n onClick={toggle}\r\n />\r\n );\r\n};\r\n"]}
|
|
@@ -3,13 +3,16 @@ import type { KeyboardEvent, FocusEvent } from "react";
|
|
|
3
3
|
export declare const CustomTokens: {
|
|
4
4
|
inputWidth: string;
|
|
5
5
|
lineHeight: string;
|
|
6
|
+
lineHeightSmall: string;
|
|
7
|
+
dividerGap: string;
|
|
8
|
+
dividerGapSmall: string;
|
|
6
9
|
labelMinWidth: string;
|
|
7
10
|
sliderMinWidth: string;
|
|
8
11
|
sliderMaxWidth: string;
|
|
9
12
|
rightAlignOffset: string;
|
|
10
13
|
};
|
|
11
14
|
export declare const UniformWidthStyling: GriffelStyle;
|
|
12
|
-
export declare const useInputStyles: () => Record<"input" | "container" | "
|
|
15
|
+
export declare const useInputStyles: () => Record<"input" | "container" | "inputSlot" | "invalid", string>;
|
|
13
16
|
export declare function HandleOnBlur(event: FocusEvent<HTMLInputElement>): void;
|
|
14
17
|
export declare function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>): void;
|
|
15
18
|
/**
|
|
@@ -25,4 +28,4 @@ export declare function HandleKeyDown(event: KeyboardEvent<HTMLInputElement>): v
|
|
|
25
28
|
* @returns the calculated precision
|
|
26
29
|
*/
|
|
27
30
|
export declare function CalculatePrecision(value: number): number;
|
|
28
|
-
export declare function
|
|
31
|
+
export declare function ValidateColorHex(val: string): boolean;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { makeStyles, tokens } from "@fluentui/react-components";
|
|
2
2
|
export const CustomTokens = {
|
|
3
3
|
inputWidth: "150px",
|
|
4
|
-
lineHeight:
|
|
4
|
+
lineHeight: tokens.lineHeightHero700, // 36px
|
|
5
|
+
lineHeightSmall: tokens.lineHeightBase500, // 28px
|
|
6
|
+
dividerGap: tokens.fontSizeBase100, // "10px",
|
|
7
|
+
dividerGapSmall: tokens.borderRadiusMedium, // 4px",
|
|
5
8
|
labelMinWidth: "50px",
|
|
6
9
|
sliderMinWidth: "30px",
|
|
7
10
|
sliderMaxWidth: "80px",
|
|
8
|
-
rightAlignOffset:
|
|
11
|
+
rightAlignOffset: `-${tokens.borderRadiusXLarge}`, // -8px
|
|
9
12
|
};
|
|
10
13
|
export const UniformWidthStyling = { width: CustomTokens.inputWidth, boxSizing: "border-box" };
|
|
11
14
|
export const useInputStyles = makeStyles({
|
|
@@ -17,7 +20,6 @@ export const useInputStyles = makeStyles({
|
|
|
17
20
|
display: "flex",
|
|
18
21
|
flexDirection: "column",
|
|
19
22
|
justifyContent: "center", // align items vertically
|
|
20
|
-
gap: "4px",
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
25
|
export function HandleOnBlur(event) {
|
|
@@ -62,7 +64,7 @@ export function CalculatePrecision(value) {
|
|
|
62
64
|
return 0;
|
|
63
65
|
}
|
|
64
66
|
const HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/);
|
|
65
|
-
export function
|
|
67
|
+
export function ValidateColorHex(val) {
|
|
66
68
|
return val != "" && HEX_REGEX.test(val);
|
|
67
69
|
}
|
|
68
70
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAKhE,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,UAAU,EAAE,OAAO;IACnB,UAAU,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAKhE,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,UAAU,EAAE,OAAO;IACnB,UAAU,EAAE,MAAM,CAAC,iBAAiB,EAAE,OAAO;IAC7C,eAAe,EAAE,MAAM,CAAC,iBAAiB,EAAE,OAAO;IAClD,UAAU,EAAE,MAAM,CAAC,eAAe,EAAE,UAAU;IAC9C,eAAe,EAAE,MAAM,CAAC,kBAAkB,EAAE,QAAQ;IACpD,aAAa,EAAE,MAAM;IACrB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,gBAAgB,EAAE,IAAI,MAAM,CAAC,kBAAkB,EAAE,EAAE,OAAO;CAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAiB,EAAE,KAAK,EAAE,YAAY,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AAC7G,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;IACrC,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;IACjC,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,0BAA0B,EAAE;IAC/D,SAAS,EAAE;QACP,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,cAAc,EAAE,QAAQ,EAAE,yBAAyB;KACtD;CACJ,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,KAAmC;IAC5D,KAAK,CAAC,eAAe,EAAE,CAAC;IACxB,KAAK,CAAC,cAAc,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAsC;IAChE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;IAErD,oEAAoE;IACpE,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;IAC3B,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC5C;;;;;OAKG,CAAC,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,CAAC;IACb,CAAC;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,MAAM,SAAS,GAAG,MAAM,CAAC,mDAAmD,CAAC,CAAC;AAC9E,MAAM,UAAU,gBAAgB,CAAC,GAAW;IACxC,OAAO,GAAG,IAAI,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import { makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { GriffelStyle } from \"@fluentui/react-components\";\r\n\r\nimport type { KeyboardEvent, FocusEvent } from \"react\";\r\n\r\nexport const CustomTokens = {\r\n inputWidth: \"150px\",\r\n lineHeight: tokens.lineHeightHero700, // 36px\r\n lineHeightSmall: tokens.lineHeightBase500, // 28px\r\n dividerGap: tokens.fontSizeBase100, // \"10px\",\r\n dividerGapSmall: tokens.borderRadiusMedium, // 4px\",\r\n labelMinWidth: \"50px\",\r\n sliderMinWidth: \"30px\",\r\n sliderMaxWidth: \"80px\",\r\n rightAlignOffset: `-${tokens.borderRadiusXLarge}`, // -8px\r\n};\r\n\r\nexport const UniformWidthStyling: GriffelStyle = { width: CustomTokens.inputWidth, boxSizing: \"border-box\" };\r\nexport const useInputStyles = makeStyles({\r\n input: UniformWidthStyling,\r\n inputSlot: { textAlign: \"right\" },\r\n invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },\r\n container: {\r\n flex: 1,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"center\", // align items vertically\r\n },\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\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\nexport function 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\nconst HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/);\r\nexport function ValidateColorHex(val: string) {\r\n return val != \"\" && HEX_REGEX.test(val);\r\n}\r\n"]}
|