@babylonjs/shared-ui-components 8.22.2 → 8.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fluent/hoc/gradientList.js +53 -59
- package/fluent/hoc/gradientList.js.map +1 -1
- package/fluent/hoc/propertyLines/propertyLine.js +1 -1
- package/fluent/hoc/propertyLines/propertyLine.js.map +1 -1
- package/fluent/primitives/list.d.ts +4 -4
- package/fluent/primitives/list.js +2 -2
- package/fluent/primitives/list.js.map +1 -1
- package/fluent/primitives/textarea.js +7 -1
- package/fluent/primitives/textarea.js.map +1 -1
- package/fluent/primitives/toggleButton.d.ts +16 -0
- package/fluent/primitives/toggleButton.js +26 -0
- package/fluent/primitives/toggleButton.js.map +1 -0
- package/historyStack.d.ts +5 -1
- package/historyStack.js +26 -12
- package/historyStack.js.map +1 -1
- package/package.json +1 -1
@@ -11,66 +11,60 @@ function GradientsToListItems(gradients) {
|
|
11
11
|
sortBy: gradient.gradient,
|
12
12
|
})) ?? []);
|
13
13
|
}
|
14
|
-
const
|
15
|
-
const { gradients
|
14
|
+
export const FactorGradientList = (props) => {
|
15
|
+
const { gradients } = props;
|
16
16
|
const items = GradientsToListItems(gradients);
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
const addNewStep = () => {
|
21
|
-
if (items.length === 0) {
|
22
|
-
props.addGradient(); // Default
|
23
|
-
}
|
24
|
-
else {
|
25
|
-
switch (props.type) {
|
26
|
-
case "Factor": {
|
27
|
-
const newStep = new FactorGradient(1, 1, 1);
|
28
|
-
props.addGradient(newStep);
|
29
|
-
break;
|
30
|
-
}
|
31
|
-
case "Color3": {
|
32
|
-
const newStepColor3 = new Color3Gradient(1, Color3.White());
|
33
|
-
props.addGradient(newStepColor3);
|
34
|
-
break;
|
35
|
-
}
|
36
|
-
case "Color4": {
|
37
|
-
const newStepColor = new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1));
|
38
|
-
props.addGradient(newStepColor);
|
39
|
-
break;
|
40
|
-
}
|
17
|
+
return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
18
|
+
if (items.length === 0) {
|
19
|
+
props.addGradient(); // Default
|
41
20
|
}
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
21
|
+
else {
|
22
|
+
props.addGradient(new FactorGradient(1, 1, 1));
|
23
|
+
}
|
24
|
+
}, renderItem: (item) => {
|
25
|
+
return (_jsx(FactorGradientComponent, { value: item.data, onChange: (newGradient) => {
|
26
|
+
item.data.gradient = newGradient.gradient;
|
27
|
+
item.data.factor1 = newGradient.factor1;
|
28
|
+
item.data.factor2 = newGradient.factor2;
|
29
|
+
props.onChange(newGradient);
|
30
|
+
} }));
|
31
|
+
} }, "Factor"));
|
32
|
+
};
|
33
|
+
export const Color3GradientList = (props) => {
|
34
|
+
const { gradients } = props;
|
35
|
+
const items = GradientsToListItems(gradients);
|
36
|
+
return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
37
|
+
if (items.length === 0) {
|
38
|
+
props.addGradient(); // Default
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
props.addGradient(new Color3Gradient(1, Color3.White()));
|
42
|
+
}
|
43
|
+
}, renderItem: (item) => {
|
44
|
+
return (_jsx(Color3GradientComponent, { value: item.data, onChange: (newGradient) => {
|
45
|
+
item.data.gradient = newGradient.gradient;
|
46
|
+
item.data.color = newGradient.color;
|
47
|
+
props.onChange(newGradient);
|
48
|
+
} }));
|
49
|
+
} }, "Color3"));
|
50
|
+
};
|
51
|
+
export const Color4GradientList = (props) => {
|
52
|
+
const { gradients } = props;
|
53
|
+
const items = GradientsToListItems(gradients);
|
54
|
+
return (_jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
55
|
+
if (items.length === 0) {
|
56
|
+
props.addGradient(); // Default
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
props.addGradient(new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1)));
|
60
|
+
}
|
61
|
+
}, renderItem: (item) => {
|
62
|
+
return (_jsx(Color4GradientComponent, { value: item.data, onChange: (newGradient) => {
|
63
|
+
item.data.gradient = newGradient.gradient;
|
64
|
+
item.data.color1 = newGradient.color1;
|
65
|
+
item.data.color2 = newGradient.color2;
|
66
|
+
props.onChange(newGradient);
|
67
|
+
} }));
|
68
|
+
} }, "Color4"));
|
69
69
|
};
|
70
|
-
const FactorGradientCast = GradientList;
|
71
|
-
const Color3GradientCast = GradientList;
|
72
|
-
const Color4GradientCast = GradientList;
|
73
|
-
export const FactorGradientList = (props) => _jsx(FactorGradientCast, { ...props, type: "Factor" });
|
74
|
-
export const Color3GradientList = (props) => _jsx(Color3GradientCast, { ...props, type: "Color3" });
|
75
|
-
export const Color4GradientList = (props) => _jsx(Color4GradientCast, { ...props, type: "Color4" });
|
76
70
|
//# sourceMappingURL=gradientList.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"gradientList.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/gradientList.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,cAAc,EAAE,aAAa,IAAI,cAAc,EAAE,cAAc,EAAE,0CAA4B;AAGtG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,4CAA8B;
|
1
|
+
{"version":3,"file":"gradientList.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/gradientList.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent } from \"react\";\r\n\r\nimport { List } from \"../primitives/list\";\r\nimport { Color3GradientComponent, Color4GradientComponent, FactorGradientComponent } from \"../primitives/gradient\";\r\nimport { Color3Gradient, ColorGradient as Color4Gradient, FactorGradient } from \"core/Misc/gradients\";\r\nimport type { IValueGradient } from \"core/Misc/gradients\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\n\r\ntype GradientListProps<T extends FactorGradient | Color3Gradient | Color4Gradient> = {\r\n label: string;\r\n gradients: Nullable<Array<T>>;\r\n addGradient: (step?: T) => void;\r\n removeGradient: (step: T) => void;\r\n onChange: (newGradient: T) => void;\r\n};\r\n\r\n// Convert gradients to LineList items and sort by gradient value\r\nfunction GradientsToListItems<T extends IValueGradient>(gradients: Nullable<Array<T>>) {\r\n return (\r\n gradients?.map((gradient, index) => ({\r\n id: index,\r\n data: gradient,\r\n sortBy: gradient.gradient,\r\n })) ?? []\r\n );\r\n}\r\nexport const FactorGradientList: FunctionComponent<GradientListProps<FactorGradient>> = (props) => {\r\n const { gradients } = props;\r\n const items = GradientsToListItems<FactorGradient>(gradients);\r\n return (\r\n <List\r\n key=\"Factor\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new FactorGradient(1, 1, 1));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <FactorGradientComponent\r\n value={item.data}\r\n onChange={(newGradient: FactorGradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.factor1 = newGradient.factor1;\r\n item.data.factor2 = newGradient.factor2;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color3GradientList: FunctionComponent<GradientListProps<Color3Gradient>> = (props) => {\r\n const { gradients } = props;\r\n const items = GradientsToListItems<Color3Gradient>(gradients);\r\n return (\r\n <List\r\n key=\"Color3\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color3Gradient(1, Color3.White()));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <Color3GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color3Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color = newGradient.color;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const Color4GradientList: FunctionComponent<GradientListProps<Color4Gradient>> = (props) => {\r\n const { gradients } = props;\r\n const items = GradientsToListItems<Color4Gradient>(gradients);\r\n return (\r\n <List\r\n key=\"Color4\"\r\n addButtonLabel={items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`}\r\n items={items}\r\n onDelete={(item) => props.removeGradient(item.data)}\r\n onAdd={() => {\r\n if (items.length === 0) {\r\n props.addGradient(); // Default\r\n } else {\r\n props.addGradient(new Color4Gradient(1, new Color4(1, 1, 1, 1), new Color4(1, 1, 1, 1)));\r\n }\r\n }}\r\n renderItem={(item) => {\r\n return (\r\n <Color4GradientComponent\r\n value={item.data}\r\n onChange={(newGradient: Color4Gradient) => {\r\n item.data.gradient = newGradient.gradient;\r\n item.data.color1 = newGradient.color1;\r\n item.data.color2 = newGradient.color2;\r\n props.onChange(newGradient);\r\n }}\r\n />\r\n );\r\n }}\r\n />\r\n );\r\n};\r\n"]}
|
@@ -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, Body1Strong, Button, InfoLabel, Link, ToggleButton, Checkbox, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { AddFilled, CopyRegular, SubtractFilled } 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\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 padding: `${tokens.spacingVerticalXS} 0px`,\r\n borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,\r\n },\r\n line: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n label: {\r\n flex: \"1 1 0\",\r\n minWidth: \"50px\",\r\n textAlign: \"left\",\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\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 gap: tokens.spacingHorizontalS,\r\n },\r\n button: {\r\n marginLeft: tokens.spacingHorizontalXXS,\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n minWidth: 0,\r\n },\r\n fillRestOfRightContentWidth: {\r\n flex: 1,\r\n display: \"flex\",\r\n justifyContent: \"flex-end\",\r\n alignItems: \"center\",\r\n },\r\n expandButton: {\r\n margin: 0,\r\n },\r\n expandedContent: {\r\n paddingLeft: \"20px\",\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 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.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.line}>\r\n <InfoLabel className={classes.label} info={description} title={label}>\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\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 <div className={classes.fillRestOfRightContentWidth}>{processedChildren}</div>\r\n\r\n {expandedContent && (\r\n <ToggleButton\r\n appearance=\"transparent\"\r\n icon={expanded ? <SubtractFilled /> : <AddFilled />}\r\n className={classes.button}\r\n checked={expanded}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setExpanded((expanded) => !expanded);\r\n }}\r\n />\r\n )}\r\n\r\n {onCopy && !disableCopy && (\r\n <Button className={classes.button} id=\"copyProperty\" icon={<CopyRegular />} onClick={() => copyCommandToClipboard(onCopy())} title=\"Copy to clipboard\" />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContent}>{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":";AAAA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACrI,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE/E,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/F,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,MAAM,qBAAqB,GAAG,UAAU,CAAC;IACrC,SAAS,EAAE;QACP,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ,EAAE,gCAAgC;QACzD,OAAO,EAAE,GAAG,MAAM,CAAC,iBAAiB,MAAM;QAC1C,YAAY,EAAE,GAAG,MAAM,CAAC,eAAe,UAAU,MAAM,CAAC,mBAAmB,EAAE;KAChF;IACD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,YAAY;QAC5B,KAAK,EAAE,MAAM;KAChB;IACD,KAAK,EAAE;QACH,IAAI,EAAE,OAAO,EAAE,mDAAmD;QAClE,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,QAAQ;QACpB,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,UAAU;KAC3B;IACD,SAAS,EAAE;QACP,UAAU,EAAE,QAAQ;KACvB;IACD,YAAY,EAAE;QACV,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,UAAU;QAC1B,GAAG,EAAE,MAAM,CAAC,kBAAkB;KACjC;IACD,MAAM,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC,oBAAoB;QACvC,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,QAAQ,EAAE,CAAC;KACd;IACD,2BAA2B,EAAE;QACzB,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,MAAM;QACf,cAAc,EAAE,UAAU;QAC1B,UAAU,EAAE,QAAQ;KACvB;IACD,YAAY,EAAE;QACV,MAAM,EAAE,CAAC;KACZ;IACD,eAAe,EAAE;QACb,WAAW,EAAE,MAAM;KACtB;CACJ,CAAC,CAAC;AAiEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAA4D,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC7G,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IACxC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAErF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACrG,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAExD,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,IAAI,EAAE,KAAK,CAAC,OAAO,YAAG,KAAK,CAAC,WAAW,IAAI,MAAM,GAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAE/I,6HAA6H;IAC7H,MAAM,iBAAiB,GACnB,CAAC,QAAQ,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC;QACpD,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE;YACnB,GAAG,QAAQ,CAAC,KAAK;YACjB,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC;YACtE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,YAAY;YACxC,YAAY,EAAE,SAAS,EAAE,sIAAsI;SAClK,CAAC;QACJ,CAAC,CAAC,QAAQ,CAAC;IAEnB,OAAO,CACH,MAAC,aAAa,IAAC,GAAG,EAAE,GAAG,aACnB,eAAK,SAAS,EAAE,OAAO,CAAC,IAAI,aACxB,KAAC,SAAS,IAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,YAChE,KAAC,WAAW,IAAC,SAAS,EAAE,OAAO,CAAC,SAAS,YAAG,KAAK,GAAe,GACxD,EACZ,eAAK,SAAS,EAAE,OAAO,CAAC,YAAY,aAC/B,QAAQ,IAAI,CAAC,cAAc,IAAI;4BAC5B,qIAAqI;4BACrI,KAAC,QAAQ,IACL,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;oCAClB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wCACf,wHAAwH;wCACxH,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oCACvG,CAAC;yCAAM,CAAC;wCACJ,oHAAoH;wCACpH,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC;wCAChC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oCACzB,CAAC;gCACL,CAAC,EACD,KAAK,EAAC,mBAAmB,GAC3B,CACL,EACD,cAAK,SAAS,EAAE,OAAO,CAAC,2BAA2B,YAAG,iBAAiB,GAAO,EAE7E,eAAe,IAAI,CAChB,KAAC,YAAY,IACT,UAAU,EAAC,aAAa,EACxB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAC,cAAc,KAAG,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,EACnD,SAAS,EAAE,OAAO,CAAC,MAAM,EACzB,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;oCACX,CAAC,CAAC,eAAe,EAAE,CAAC;oCACpB,WAAW,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;gCACzC,CAAC,GACH,CACL,EAEA,MAAM,IAAI,CAAC,WAAW,IAAI,CACvB,KAAC,MAAM,IAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,EAAC,cAAc,EAAC,IAAI,EAAE,KAAC,WAAW,KAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAC,mBAAmB,GAAG,CAC5J,IACC,IACJ,EACL,eAAe,IAAI,CAChB,KAAC,QAAQ,IAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,YACzB,cAAK,SAAS,EAAE,OAAO,CAAC,eAAe,YAAG,eAAe,GAAO,GACzD,CACd,IACW,CACnB,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAA+D,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjH,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IACxC,OAAO,CACH,cAAK,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,KAAM,KAAK,YACjD,KAAK,CAAC,QAAQ,GACb,CACT,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAoE,CAAC,KAAK,EAAE,EAAE;IAC9G,OAAO,CACH,KAAC,YAAY,OAAK,KAAK,YACnB,KAAC,KAAK,cAAE,KAAK,CAAC,KAAK,GAAS,GACjB,CAClB,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { Body1, Body1Strong, Button, InfoLabel, Link, ToggleButton, Checkbox, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { AddFilled, CopyRegular, SubtractFilled } 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\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 padding: `${tokens.spacingVerticalXS} 0px`,\r\n borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,\r\n },\r\n line: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n label: {\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: \"50px\",\r\n textAlign: \"left\",\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\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 gap: tokens.spacingHorizontalS,\r\n },\r\n button: {\r\n marginLeft: tokens.spacingHorizontalXXS,\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n minWidth: 0,\r\n },\r\n fillRestOfRightContentWidth: {\r\n flex: 1,\r\n display: \"flex\",\r\n justifyContent: \"flex-end\",\r\n alignItems: \"center\",\r\n },\r\n expandButton: {\r\n margin: 0,\r\n },\r\n expandedContent: {\r\n paddingLeft: \"20px\",\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 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.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.line}>\r\n <InfoLabel className={classes.label} info={description} title={label}>\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\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 <div className={classes.fillRestOfRightContentWidth}>{processedChildren}</div>\r\n\r\n {expandedContent && (\r\n <ToggleButton\r\n appearance=\"transparent\"\r\n icon={expanded ? <SubtractFilled /> : <AddFilled />}\r\n className={classes.button}\r\n checked={expanded}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setExpanded((expanded) => !expanded);\r\n }}\r\n />\r\n )}\r\n\r\n {onCopy && !disableCopy && (\r\n <Button className={classes.button} id=\"copyProperty\" icon={<CopyRegular />} onClick={() => copyCommandToClipboard(onCopy())} title=\"Copy to clipboard\" />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContent}>{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,8 +1,8 @@
|
|
1
|
-
import type {
|
1
|
+
import type { ReactNode, ReactElement } from "react";
|
2
2
|
/**
|
3
3
|
* Represents an item in a list
|
4
4
|
*/
|
5
|
-
export type ListItem<T
|
5
|
+
export type ListItem<T> = {
|
6
6
|
/** Unique identifier for the item */
|
7
7
|
id: number;
|
8
8
|
/** The data associated with the item */
|
@@ -10,7 +10,7 @@ export type ListItem<T = any> = {
|
|
10
10
|
/** Value to use for sorting the list */
|
11
11
|
sortBy: number;
|
12
12
|
};
|
13
|
-
type ListProps<T
|
13
|
+
type ListProps<T> = {
|
14
14
|
items: ListItem<T>[];
|
15
15
|
renderItem: (item: ListItem<T>, index: number) => ReactNode;
|
16
16
|
onDelete: (item: ListItem<T>, index: number) => void;
|
@@ -22,5 +22,5 @@ type ListProps<T = any> = {
|
|
22
22
|
* @returns A React component that renders a list of items with add/delete functionality
|
23
23
|
* @param props - The properties for the List component
|
24
24
|
*/
|
25
|
-
export declare
|
25
|
+
export declare function List<T>(props: ListProps<T>): ReactElement;
|
26
26
|
export {};
|
@@ -33,11 +33,11 @@ const useListStyles = makeStyles({
|
|
33
33
|
* @returns A React component that renders a list of items with add/delete functionality
|
34
34
|
* @param props - The properties for the List component
|
35
35
|
*/
|
36
|
-
export
|
36
|
+
export function List(props) {
|
37
37
|
const { items, renderItem, onDelete, onAdd, addButtonLabel = "Add new item" } = props;
|
38
38
|
const classes = useListStyles();
|
39
39
|
return (_jsxs("div", { children: [_jsx(ButtonLine, { label: addButtonLabel, onClick: () => props.onAdd() }), _jsx("div", { className: classes.list, children: items
|
40
40
|
.sort((a, b) => a.sortBy - b.sortBy)
|
41
41
|
.map((item, index) => (_jsxs("div", { className: classes.item, children: [_jsxs(Body1Strong, { className: classes.itemId, children: ["#", index] }), _jsx("div", { className: classes.itemContent, children: renderItem(item, index) }), _jsxs("div", { className: classes.iconContainer, children: [_jsx(CopyRegular, { onClick: () => onAdd(item) }), _jsx(DeleteRegular, { onClick: () => onDelete(item, index) })] })] }, item.id))) })] }));
|
42
|
-
}
|
42
|
+
}
|
43
43
|
//# sourceMappingURL=list.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE7E,MAAM,aAAa,GAAG,UAAU,CAAC;IAC7B,IAAI,EAAE;QACF,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK,EAAE,6BAA6B;QACnD,UAAU,EAAE,QAAQ,EAAE,0BAA0B;QAChD,GAAG,EAAE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B;QAC7D,YAAY,EAAE,GAAG,MAAM,CAAC,eAAe,UAAU,MAAM,CAAC,mBAAmB,EAAE;KAChF;IACD,MAAM,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC,kBAAkB;KACnC;IACD,WAAW,EAAE;QACT,IAAI,EAAE,CAAC,EAAE,0BAA0B;QACnC,QAAQ,EAAE,CAAC,EAAE,qCAAqC;KACrD;IACD,aAAa,EAAE;QACX,OAAO,EAAE,MAAM;QACf,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,0BAA0B;QAC3D,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,CAAC,EAAE,oBAAoB;KACtC;IACD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM,CAAC,gBAAgB;KACnC;CACJ,CAAC,CAAC;AAsBH;;;;GAIG;AACH,MAAM,
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE7E,MAAM,aAAa,GAAG,UAAU,CAAC;IAC7B,IAAI,EAAE;QACF,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK,EAAE,6BAA6B;QACnD,UAAU,EAAE,QAAQ,EAAE,0BAA0B;QAChD,GAAG,EAAE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B;QAC7D,YAAY,EAAE,GAAG,MAAM,CAAC,eAAe,UAAU,MAAM,CAAC,mBAAmB,EAAE;KAChF;IACD,MAAM,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC,kBAAkB;KACnC;IACD,WAAW,EAAE;QACT,IAAI,EAAE,CAAC,EAAE,0BAA0B;QACnC,QAAQ,EAAE,CAAC,EAAE,qCAAqC;KACrD;IACD,aAAa,EAAE;QACX,OAAO,EAAE,MAAM;QACf,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,0BAA0B;QAC3D,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,CAAC,EAAE,oBAAoB;KACtC;IACD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM,CAAC,gBAAgB;KACnC;CACJ,CAAC,CAAC;AAsBH;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,KAAmB;IACvC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IACtF,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,OAAO,CACH,0BACI,KAAC,UAAU,IAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAI,EAEnE,cAAK,SAAS,EAAE,OAAO,CAAC,IAAI,YACvB,KAAK;qBACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;qBACnC,GAAG,CAAC,CAAC,IAAiB,EAAE,KAAa,EAAE,EAAE,CAAC,CACvC,eAAmB,SAAS,EAAE,OAAO,CAAC,IAAI,aACtC,MAAC,WAAW,IAAC,SAAS,EAAE,OAAO,CAAC,MAAM,kBAAI,KAAK,IAAe,EAC9D,cAAK,SAAS,EAAE,OAAO,CAAC,WAAW,YAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,GAAO,EACpE,eAAK,SAAS,EAAE,OAAO,CAAC,aAAa,aACjC,KAAC,WAAW,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAI,EAC3C,KAAC,aAAa,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,GAAI,IACrD,KANA,IAAI,CAAC,EAAE,CAOX,CACT,CAAC,GACJ,IACJ,CACT,CAAC;AACN,CAAC","sourcesContent":["import { CopyRegular, DeleteRegular } from \"@fluentui/react-icons\";\r\nimport type { ReactNode, ReactElement } from \"react\";\r\nimport { ButtonLine } from \"../hoc/buttonLine\";\r\nimport { Body1Strong, makeStyles, tokens } from \"@fluentui/react-components\";\r\n\r\nconst useListStyles = makeStyles({\r\n item: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"row\", // Arrange items horizontally\r\n alignItems: \"center\", // Center items vertically\r\n gap: tokens.spacingHorizontalS, // Add space between elements\r\n borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,\r\n },\r\n itemId: {\r\n width: tokens.spacingHorizontalM,\r\n },\r\n itemContent: {\r\n flex: 1, // Take up remaining space\r\n minWidth: 0, // Prevent flex item from overflowing\r\n },\r\n iconContainer: {\r\n display: \"flex\",\r\n gap: tokens.spacingHorizontalXS, // Small gap between icons\r\n alignItems: \"center\",\r\n flexShrink: 0, // Prevent shrinking\r\n },\r\n list: {\r\n padding: tokens.spacingVerticalS,\r\n },\r\n});\r\n\r\n/**\r\n * Represents an item in a list\r\n */\r\nexport type ListItem<T> = {\r\n /** Unique identifier for the item */\r\n id: number;\r\n /** The data associated with the item */\r\n data: T;\r\n /** Value to use for sorting the list */\r\n sortBy: number;\r\n};\r\n\r\ntype ListProps<T> = {\r\n items: ListItem<T>[];\r\n renderItem: (item: ListItem<T>, index: number) => ReactNode;\r\n onDelete: (item: ListItem<T>, index: number) => void;\r\n onAdd: (item?: ListItem<T>) => void;\r\n addButtonLabel?: string;\r\n};\r\n\r\n/**\r\n * For cases where you may want to add / remove items from a list via a trash can button / copy button, this HOC can be used\r\n * @returns A React component that renders a list of items with add/delete functionality\r\n * @param props - The properties for the List component\r\n */\r\nexport function List<T>(props: ListProps<T>): ReactElement {\r\n const { items, renderItem, onDelete, onAdd, addButtonLabel = \"Add new item\" } = props;\r\n const classes = useListStyles();\r\n\r\n return (\r\n <div>\r\n <ButtonLine label={addButtonLabel} onClick={() => props.onAdd()} />\r\n\r\n <div className={classes.list}>\r\n {items\r\n .sort((a, b) => a.sortBy - b.sortBy)\r\n .map((item: ListItem<T>, index: number) => (\r\n <div key={item.id} className={classes.item}>\r\n <Body1Strong className={classes.itemId}>#{index}</Body1Strong>\r\n <div className={classes.itemContent}>{renderItem(item, index)}</div>\r\n <div className={classes.iconContainer}>\r\n <CopyRegular onClick={() => onAdd(item)} />\r\n <DeleteRegular onClick={() => onDelete(item, index)} />\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
|
@@ -1,7 +1,13 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import { Textarea as FluentTextarea, makeStyles } from "@fluentui/react-components";
|
3
3
|
const useInputStyles = makeStyles({
|
4
|
-
textarea: {
|
4
|
+
textarea: {
|
5
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
6
|
+
"& textarea": {
|
7
|
+
minHeight: "100px",
|
8
|
+
maxHeight: "500px",
|
9
|
+
},
|
10
|
+
},
|
5
11
|
});
|
6
12
|
/**
|
7
13
|
* This is a texarea box that stops propagation of change/keydown events
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textarea.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAIpF,MAAM,cAAc,GAAG,UAAU,CAAC;IAC9B,QAAQ,EAAE,EAAE;
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textarea.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAIpF,MAAM,cAAc,GAAG,UAAU,CAAC;IAC9B,QAAQ,EAAE;QACN,gEAAgE;QAChE,YAAY,EAAE;YACV,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,OAAO;SACrB;KACJ;CACJ,CAAC,CAAC;AAMH;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAqC,CAAC,KAAK,EAAE,EAAE;IAChE,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,CAAC,KAAuC,EAAE,KAA2B,EAAE,EAAE;QAC1F,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;QACrD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACjB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,oDAAoD;QAC5F,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,KAAyC,EAAE,EAAE;QAChE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B;IACzD,CAAC,CAAC;IAEF,OAAO,KAAC,cAAc,OAAK,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,GAAI,CAAC;AACxH,CAAC,CAAC","sourcesContent":["import type { TextareaOnChangeData } from \"@fluentui/react-components\";\r\nimport { Textarea as FluentTextarea, makeStyles } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, KeyboardEvent, ChangeEvent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useInputStyles = makeStyles({\r\n textarea: {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n \"& textarea\": {\r\n minHeight: \"100px\",\r\n maxHeight: \"500px\",\r\n },\r\n },\r\n});\r\n\r\nexport type TextareaProps = PrimitiveProps<string> & {\r\n placeholder?: string;\r\n};\r\n\r\n/**\r\n * This is a texarea box that stops propagation of change/keydown events\r\n * @param props\r\n * @returns\r\n */\r\nexport const Textarea: FunctionComponent<TextareaProps> = (props) => {\r\n const classes = useInputStyles();\r\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>, _data: TextareaOnChangeData) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n if (props.onChange) {\r\n props.onChange(event.target.value); // Call the original onChange handler passed as prop\r\n }\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\r\n event.stopPropagation(); // Prevent event propagation\r\n };\r\n\r\n return <FluentTextarea {...props} className={classes.textarea} onChange={handleChange} onKeyDown={handleKeyDown} />;\r\n};\r\n"]}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { PrimitiveProps } from "./primitive.js";
|
2
|
+
import type { FunctionComponent } from "react";
|
3
|
+
import type { FluentIcon } from "@fluentui/react-icons";
|
4
|
+
type ToggleButtonProps = PrimitiveProps<boolean> & {
|
5
|
+
enabledIcon: FluentIcon;
|
6
|
+
disabledIcon?: FluentIcon;
|
7
|
+
};
|
8
|
+
/**
|
9
|
+
* Toggles between two states using a button with icons.
|
10
|
+
* If no disabledIcon is provided, the button will toggle between visual enabled/disabled states without an icon change
|
11
|
+
*
|
12
|
+
* @param props
|
13
|
+
* @returns
|
14
|
+
*/
|
15
|
+
export declare const ToggleButton: FunctionComponent<ToggleButtonProps>;
|
16
|
+
export {};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { ToggleButton as FluentToggleButton } from "@fluentui/react-components";
|
3
|
+
import { useCallback, useEffect, useState } from "react";
|
4
|
+
/**
|
5
|
+
* Toggles between two states using a button with icons.
|
6
|
+
* If no disabledIcon is provided, the button will toggle between visual enabled/disabled states without an icon change
|
7
|
+
*
|
8
|
+
* @param props
|
9
|
+
* @returns
|
10
|
+
*/
|
11
|
+
export const ToggleButton = (props) => {
|
12
|
+
const { value, onChange, title } = props;
|
13
|
+
const [checked, setChecked] = useState(value);
|
14
|
+
const toggle = useCallback(() => {
|
15
|
+
setChecked((prev) => {
|
16
|
+
const enabled = !prev;
|
17
|
+
onChange(enabled);
|
18
|
+
return enabled;
|
19
|
+
});
|
20
|
+
}, [setChecked]);
|
21
|
+
useEffect(() => {
|
22
|
+
setChecked(props.value);
|
23
|
+
}, [props.value]);
|
24
|
+
return (_jsx(FluentToggleButton, { title: title, icon: checked ? _jsx(props.enabledIcon, {}) : props.disabledIcon ? _jsx(props.disabledIcon, { opacity: 0.5 }) : _jsx(props.enabledIcon, { opacity: 0.5 }), appearance: "transparent", checked: checked, onClick: toggle }));
|
25
|
+
};
|
26
|
+
//# sourceMappingURL=toggleButton.js.map
|
@@ -0,0 +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;AASzD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAyC,CAAC,KAAK,EAAE,EAAE;IACxE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,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,OAAO,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,WAAW,KAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,YAAY,IAAC,OAAO,EAAE,GAAG,GAAI,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,WAAW,IAAC,OAAO,EAAE,GAAG,GAAI,EACvI,UAAU,EAAC,aAAa,EACxB,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 { PrimitiveProps } from \"./primitive\";\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\n\r\ntype ToggleButtonProps = PrimitiveProps<boolean> & {\r\n enabledIcon: FluentIcon; // Intentionally using FluentIcon so that we can control the visual toggle look/feel\r\n disabledIcon?: FluentIcon;\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 const { value, onChange, title } = props;\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 icon={checked ? <props.enabledIcon /> : props.disabledIcon ? <props.disabledIcon opacity={0.5} /> : <props.enabledIcon opacity={0.5} />}\r\n appearance=\"transparent\"\r\n checked={checked}\r\n onClick={toggle}\r\n />\r\n );\r\n};\r\n"]}
|
package/historyStack.d.ts
CHANGED
@@ -40,7 +40,11 @@ export declare class HistoryStack implements IDisposable {
|
|
40
40
|
/**
|
41
41
|
* Stores the current state
|
42
42
|
*/
|
43
|
-
|
43
|
+
storeAsync(): Promise<void>;
|
44
|
+
/**
|
45
|
+
* Checks if there is any data in the history stack
|
46
|
+
*/
|
47
|
+
get hasData(): boolean;
|
44
48
|
/**
|
45
49
|
* Undo the latest operation
|
46
50
|
*/
|
package/historyStack.js
CHANGED
@@ -51,7 +51,7 @@ export class HistoryStack {
|
|
51
51
|
this._historyStack = [];
|
52
52
|
this._redoStack = [];
|
53
53
|
this._activeData = null;
|
54
|
-
this.
|
54
|
+
void this.storeAsync();
|
55
55
|
}
|
56
56
|
/**
|
57
57
|
* Remove the n-1 element of the stack
|
@@ -157,23 +157,37 @@ export class HistoryStack {
|
|
157
157
|
/**
|
158
158
|
* Stores the current state
|
159
159
|
*/
|
160
|
-
|
160
|
+
async storeAsync() {
|
161
161
|
if (this._locked || !this.isEnabled) {
|
162
162
|
return;
|
163
163
|
}
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
164
|
+
this._locked = true;
|
165
|
+
try {
|
166
|
+
// _dataProvider can return T or Promise<T>; await handles both.
|
167
|
+
const provided = await this._dataProvider();
|
168
|
+
const data = this._copy(provided);
|
169
|
+
if (this._activeData) {
|
170
|
+
const diff = this._generateJSONDiff(data, this._activeData);
|
171
|
+
if (!diff) {
|
172
|
+
return; // finally will still run and release the lock
|
173
|
+
}
|
174
|
+
this._historyStack.push(JSON.stringify(diff));
|
175
|
+
}
|
176
|
+
this._activeData = data;
|
177
|
+
if (this._historyStack.length > this._maxHistoryLength) {
|
178
|
+
this._historyStack.shift();
|
169
179
|
}
|
170
|
-
this.
|
180
|
+
this._redoStack.length = 0;
|
171
181
|
}
|
172
|
-
|
173
|
-
|
174
|
-
this._historyStack.shift();
|
182
|
+
finally {
|
183
|
+
this._locked = false;
|
175
184
|
}
|
176
|
-
|
185
|
+
}
|
186
|
+
/**
|
187
|
+
* Checks if there is any data in the history stack
|
188
|
+
*/
|
189
|
+
get hasData() {
|
190
|
+
return this._historyStack.length > 0;
|
177
191
|
}
|
178
192
|
/**
|
179
193
|
* Undo the latest operation
|
package/historyStack.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"historyStack.js","sourceRoot":"","sources":["../../../dev/sharedUiComponents/src/historyStack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IDisposable } from \"core/scene\";\r\n\r\n/**\r\n * Class handling undo / redo operations\r\n */\r\nexport class HistoryStack implements IDisposable {\r\n private _historyStack: string[] = [];\r\n private _redoStack: string[] = [];\r\n private _activeData: any;\r\n private readonly _maxHistoryLength = 256;\r\n private _locked = false;\r\n private _dataProvider: () => any;\r\n private _applyUpdate: (data: any) => void;\r\n\r\n /**\r\n * Gets or sets a boolean indicating if the stack is enabled\r\n */\r\n public isEnabled = true;\r\n\r\n /**\r\n * Constructor\r\n * @param dataProvider defines the data provider function\r\n * @param applyUpdate defines the code to execute when undo/redo operation is required\r\n */\r\n constructor(dataProvider: () => any, applyUpdate: (data: any) => void) {\r\n this._dataProvider = dataProvider;\r\n this._applyUpdate = applyUpdate;\r\n }\r\n\r\n /**\r\n * Process key event to handle undo / redo\r\n * @param evt defines the keyboard event to process\r\n * @returns true if the event was processed\r\n */\r\n processKeyEvent(evt: KeyboardEvent): boolean {\r\n if (!this.isEnabled) {\r\n return false;\r\n }\r\n\r\n if (evt.ctrlKey || evt.metaKey) {\r\n if (evt.key === \"z\" || evt.key === \"Z\") {\r\n if (evt.shiftKey) {\r\n this.redo();\r\n return true;\r\n }\r\n\r\n this.undo();\r\n return true;\r\n }\r\n if (evt.key === \"y\" || evt.key === \"Y\") {\r\n this.redo();\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Resets the stack\r\n */\r\n public reset() {\r\n this._historyStack = [];\r\n this._redoStack = [];\r\n this._activeData = null;\r\n this.store();\r\n }\r\n\r\n /**\r\n * Remove the n-1 element of the stack\r\n */\r\n public collapseLastTwo() {\r\n if (this._historyStack.length < 2) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._historyStack.pop()!;\r\n const diff2 = this._historyStack.pop()!;\r\n\r\n let newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n newState = this._applyJSONDiff(newState, JSON.parse(diff2));\r\n\r\n this._historyStack.push(JSON.stringify(this._generateJSONDiff(this._activeData, newState)));\r\n\r\n this._locked = false;\r\n }\r\n\r\n private _generateJSONDiff(obj1: any, obj2: any): any {\r\n if (obj1 === obj2) {\r\n return undefined;\r\n }\r\n if (obj1 === null || obj2 === null || typeof obj1 !== \"object\" || typeof obj2 !== \"object\") {\r\n if (obj1 !== obj2 && obj2 === undefined) {\r\n return \"@d@\";\r\n }\r\n return obj2;\r\n }\r\n\r\n if (Array.isArray(obj1) && Array.isArray(obj2)) {\r\n const diff = [];\r\n const maxLength = Math.max(obj1.length, obj2.length);\r\n let hasChanges = false;\r\n\r\n for (let i = 0; i < maxLength; i++) {\r\n const localDiff = this._generateJSONDiff(obj1[i], obj2[i]);\r\n if (localDiff !== undefined) {\r\n diff[i] = localDiff;\r\n hasChanges = true;\r\n }\r\n }\r\n\r\n return hasChanges ? diff : undefined;\r\n }\r\n\r\n const diff: any = {};\r\n const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);\r\n let hasChanges = false;\r\n\r\n for (const key of keys) {\r\n if (!(key in obj1)) {\r\n diff[key] = obj2[key];\r\n hasChanges = true;\r\n } else if (!(key in obj2)) {\r\n diff[key] = \"@d@\"; // Mark for deletion\r\n hasChanges = true;\r\n } else {\r\n const nestedDiff = this._generateJSONDiff(obj1[key], obj2[key]);\r\n if (nestedDiff !== undefined) {\r\n diff[key] = nestedDiff;\r\n hasChanges = true;\r\n }\r\n }\r\n }\r\n\r\n return hasChanges ? diff : undefined;\r\n }\r\n\r\n private _applyJSONDiff(obj1: any, diff: any) {\r\n if (diff === undefined) {\r\n return obj1;\r\n }\r\n if (typeof diff !== \"object\" || diff === null || obj1 == null) {\r\n return diff;\r\n }\r\n\r\n const result: any = Array.isArray(obj1) ? [] : {};\r\n\r\n if (Array.isArray(diff)) {\r\n for (let i = 0; i < Math.max(obj1.length, diff.length); i++) {\r\n if (diff[i] === null && i < obj1.length) {\r\n result[i] = obj1[i];\r\n } else if (diff[i] !== \"@d@\") {\r\n result[i] = this._applyJSONDiff(obj1[i], diff[i]);\r\n }\r\n }\r\n } else {\r\n for (const key in obj1) {\r\n if (!(key in diff)) {\r\n result[key] = obj1[key];\r\n }\r\n }\r\n for (const key in diff) {\r\n if (diff[key] === \"@d@\") {\r\n // Skip this key (it's been deleted)\r\n } else if (typeof diff[key] === \"object\" && diff[key] !== null) {\r\n result[key] = this._applyJSONDiff(obj1[key], diff[key]);\r\n } else {\r\n result[key] = diff[key];\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _copy(source: any) {\r\n return JSON.parse(JSON.stringify(source));\r\n }\r\n\r\n /**\r\n * Stores the current state\r\n */\r\n public store() {\r\n if (this._locked || !this.isEnabled) {\r\n return;\r\n }\r\n\r\n const data = this._copy(this._dataProvider());\r\n\r\n if (this._activeData) {\r\n const diff = this._generateJSONDiff(data, this._activeData);\r\n if (!diff) {\r\n return;\r\n }\r\n this._historyStack.push(JSON.stringify(diff));\r\n }\r\n\r\n this._activeData = data;\r\n\r\n if (this._historyStack.length > this._maxHistoryLength) {\r\n this._historyStack.shift();\r\n }\r\n\r\n this._redoStack.length = 0;\r\n }\r\n\r\n /**\r\n * Undo the latest operation\r\n */\r\n public undo() {\r\n if (!this._historyStack.length) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._historyStack.pop()!;\r\n\r\n const newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n this._redoStack.push(JSON.stringify(this._generateJSONDiff(newState, this._activeData)));\r\n\r\n this._applyUpdate(this._copy(newState));\r\n\r\n this._activeData = newState;\r\n\r\n this._locked = false;\r\n }\r\n\r\n /**\r\n * Redo the latest undo operation\r\n */\r\n public redo() {\r\n if (!this._redoStack.length) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._redoStack.pop()!;\r\n\r\n const newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n this._historyStack.push(JSON.stringify(this._generateJSONDiff(newState, this._activeData)));\r\n\r\n this._applyUpdate(this._copy(newState));\r\n this._activeData = newState;\r\n\r\n this._locked = false;\r\n }\r\n\r\n /**\r\n * Disposes the stack\r\n */\r\n public dispose() {\r\n this._historyStack = [];\r\n this._redoStack = [];\r\n }\r\n}\r\n"]}
|
1
|
+
{"version":3,"file":"historyStack.js","sourceRoot":"","sources":["../../../dev/sharedUiComponents/src/historyStack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IDisposable } from \"core/scene\";\r\n\r\n/**\r\n * Class handling undo / redo operations\r\n */\r\nexport class HistoryStack implements IDisposable {\r\n private _historyStack: string[] = [];\r\n private _redoStack: string[] = [];\r\n private _activeData: any;\r\n private readonly _maxHistoryLength = 256;\r\n private _locked = false;\r\n private _dataProvider: () => any;\r\n private _applyUpdate: (data: any) => void;\r\n\r\n /**\r\n * Gets or sets a boolean indicating if the stack is enabled\r\n */\r\n public isEnabled = true;\r\n\r\n /**\r\n * Constructor\r\n * @param dataProvider defines the data provider function\r\n * @param applyUpdate defines the code to execute when undo/redo operation is required\r\n */\r\n constructor(dataProvider: () => any, applyUpdate: (data: any) => void) {\r\n this._dataProvider = dataProvider;\r\n this._applyUpdate = applyUpdate;\r\n }\r\n\r\n /**\r\n * Process key event to handle undo / redo\r\n * @param evt defines the keyboard event to process\r\n * @returns true if the event was processed\r\n */\r\n processKeyEvent(evt: KeyboardEvent): boolean {\r\n if (!this.isEnabled) {\r\n return false;\r\n }\r\n\r\n if (evt.ctrlKey || evt.metaKey) {\r\n if (evt.key === \"z\" || evt.key === \"Z\") {\r\n if (evt.shiftKey) {\r\n this.redo();\r\n return true;\r\n }\r\n\r\n this.undo();\r\n return true;\r\n }\r\n if (evt.key === \"y\" || evt.key === \"Y\") {\r\n this.redo();\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Resets the stack\r\n */\r\n public reset() {\r\n this._historyStack = [];\r\n this._redoStack = [];\r\n this._activeData = null;\r\n void this.storeAsync();\r\n }\r\n\r\n /**\r\n * Remove the n-1 element of the stack\r\n */\r\n public collapseLastTwo() {\r\n if (this._historyStack.length < 2) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._historyStack.pop()!;\r\n const diff2 = this._historyStack.pop()!;\r\n\r\n let newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n newState = this._applyJSONDiff(newState, JSON.parse(diff2));\r\n\r\n this._historyStack.push(JSON.stringify(this._generateJSONDiff(this._activeData, newState)));\r\n\r\n this._locked = false;\r\n }\r\n\r\n private _generateJSONDiff(obj1: any, obj2: any): any {\r\n if (obj1 === obj2) {\r\n return undefined;\r\n }\r\n if (obj1 === null || obj2 === null || typeof obj1 !== \"object\" || typeof obj2 !== \"object\") {\r\n if (obj1 !== obj2 && obj2 === undefined) {\r\n return \"@d@\";\r\n }\r\n return obj2;\r\n }\r\n\r\n if (Array.isArray(obj1) && Array.isArray(obj2)) {\r\n const diff = [];\r\n const maxLength = Math.max(obj1.length, obj2.length);\r\n let hasChanges = false;\r\n\r\n for (let i = 0; i < maxLength; i++) {\r\n const localDiff = this._generateJSONDiff(obj1[i], obj2[i]);\r\n if (localDiff !== undefined) {\r\n diff[i] = localDiff;\r\n hasChanges = true;\r\n }\r\n }\r\n\r\n return hasChanges ? diff : undefined;\r\n }\r\n\r\n const diff: any = {};\r\n const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);\r\n let hasChanges = false;\r\n\r\n for (const key of keys) {\r\n if (!(key in obj1)) {\r\n diff[key] = obj2[key];\r\n hasChanges = true;\r\n } else if (!(key in obj2)) {\r\n diff[key] = \"@d@\"; // Mark for deletion\r\n hasChanges = true;\r\n } else {\r\n const nestedDiff = this._generateJSONDiff(obj1[key], obj2[key]);\r\n if (nestedDiff !== undefined) {\r\n diff[key] = nestedDiff;\r\n hasChanges = true;\r\n }\r\n }\r\n }\r\n\r\n return hasChanges ? diff : undefined;\r\n }\r\n\r\n private _applyJSONDiff(obj1: any, diff: any) {\r\n if (diff === undefined) {\r\n return obj1;\r\n }\r\n if (typeof diff !== \"object\" || diff === null || obj1 == null) {\r\n return diff;\r\n }\r\n\r\n const result: any = Array.isArray(obj1) ? [] : {};\r\n\r\n if (Array.isArray(diff)) {\r\n for (let i = 0; i < Math.max(obj1.length, diff.length); i++) {\r\n if (diff[i] === null && i < obj1.length) {\r\n result[i] = obj1[i];\r\n } else if (diff[i] !== \"@d@\") {\r\n result[i] = this._applyJSONDiff(obj1[i], diff[i]);\r\n }\r\n }\r\n } else {\r\n for (const key in obj1) {\r\n if (!(key in diff)) {\r\n result[key] = obj1[key];\r\n }\r\n }\r\n for (const key in diff) {\r\n if (diff[key] === \"@d@\") {\r\n // Skip this key (it's been deleted)\r\n } else if (typeof diff[key] === \"object\" && diff[key] !== null) {\r\n result[key] = this._applyJSONDiff(obj1[key], diff[key]);\r\n } else {\r\n result[key] = diff[key];\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _copy(source: any) {\r\n return JSON.parse(JSON.stringify(source));\r\n }\r\n\r\n /**\r\n * Stores the current state\r\n */\r\n public async storeAsync() {\r\n if (this._locked || !this.isEnabled) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n try {\r\n // _dataProvider can return T or Promise<T>; await handles both.\r\n const provided = await this._dataProvider();\r\n const data = this._copy(provided);\r\n\r\n if (this._activeData) {\r\n const diff = this._generateJSONDiff(data, this._activeData);\r\n if (!diff) {\r\n return; // finally will still run and release the lock\r\n }\r\n this._historyStack.push(JSON.stringify(diff));\r\n }\r\n\r\n this._activeData = data;\r\n\r\n if (this._historyStack.length > this._maxHistoryLength) {\r\n this._historyStack.shift();\r\n }\r\n\r\n this._redoStack.length = 0;\r\n } finally {\r\n this._locked = false;\r\n }\r\n }\r\n\r\n /**\r\n * Checks if there is any data in the history stack\r\n */\r\n public get hasData(): boolean {\r\n return this._historyStack.length > 0;\r\n }\r\n\r\n /**\r\n * Undo the latest operation\r\n */\r\n public undo() {\r\n if (!this._historyStack.length) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._historyStack.pop()!;\r\n\r\n const newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n this._redoStack.push(JSON.stringify(this._generateJSONDiff(newState, this._activeData)));\r\n\r\n this._applyUpdate(this._copy(newState));\r\n\r\n this._activeData = newState;\r\n\r\n this._locked = false;\r\n }\r\n\r\n /**\r\n * Redo the latest undo operation\r\n */\r\n public redo() {\r\n if (!this._redoStack.length) {\r\n return;\r\n }\r\n\r\n this._locked = true;\r\n const diff = this._redoStack.pop()!;\r\n\r\n const newState = this._applyJSONDiff(this._activeData, JSON.parse(diff));\r\n this._historyStack.push(JSON.stringify(this._generateJSONDiff(newState, this._activeData)));\r\n\r\n this._applyUpdate(this._copy(newState));\r\n this._activeData = newState;\r\n\r\n this._locked = false;\r\n }\r\n\r\n /**\r\n * Disposes the stack\r\n */\r\n public dispose() {\r\n this._historyStack = [];\r\n this._redoStack = [];\r\n }\r\n}\r\n"]}
|