@babylonjs/shared-ui-components 8.38.0 → 8.39.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.
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { FunctionComponent, PropsWithChildren } from "react";
|
|
1
|
+
import type { ForwardRefExoticComponent, FunctionComponent, PropsWithChildren, RefAttributes } from "react";
|
|
2
2
|
export type AccordionSectionProps = {
|
|
3
3
|
title: string;
|
|
4
4
|
collapseByDefault?: boolean;
|
|
5
5
|
};
|
|
6
6
|
export declare const AccordionSection: FunctionComponent<PropsWithChildren<AccordionSectionProps>>;
|
|
7
|
-
export
|
|
7
|
+
export type AccordionProps = {
|
|
8
|
+
highlightSections?: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
export declare const Accordion: ForwardRefExoticComponent<AccordionProps & {
|
|
11
|
+
children?: import("react").ReactNode | undefined;
|
|
12
|
+
} & RefAttributes<HTMLDivElement>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Children, isValidElement, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { Children, forwardRef, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { AccordionHeader, AccordionItem, AccordionPanel, Divider, Accordion as FluentAccordion, Subtitle2Stronger, makeStyles, tokens } from "@fluentui/react-components";
|
|
4
4
|
import { CustomTokens } from "./utils.js";
|
|
5
5
|
import { ToolContext } from "../hoc/fluentToolWrapper.js";
|
|
@@ -25,17 +25,37 @@ const useStyles = makeStyles({
|
|
|
25
25
|
flexDirection: "column",
|
|
26
26
|
overflow: "hidden",
|
|
27
27
|
},
|
|
28
|
+
highlightDiv: {
|
|
29
|
+
borderRadius: tokens.borderRadiusLarge,
|
|
30
|
+
animationDuration: "1s",
|
|
31
|
+
animationTimingFunction: "ease-in-out",
|
|
32
|
+
animationIterationCount: "5",
|
|
33
|
+
animationFillMode: "forwards",
|
|
34
|
+
animationName: {
|
|
35
|
+
from: {
|
|
36
|
+
boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,
|
|
37
|
+
},
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
39
|
+
"50%": {
|
|
40
|
+
boxShadow: `inset 0 0 12px ${tokens.colorBrandBackground}`,
|
|
41
|
+
},
|
|
42
|
+
to: {
|
|
43
|
+
boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
28
47
|
});
|
|
29
48
|
export const AccordionSection = (props) => {
|
|
30
49
|
AccordionSection.displayName = "AccordionSection";
|
|
31
50
|
const classes = useStyles();
|
|
32
51
|
return _jsx("div", { className: classes.panelDiv, children: props.children });
|
|
33
52
|
};
|
|
34
|
-
|
|
53
|
+
const StringAccordion = FluentAccordion;
|
|
54
|
+
export const Accordion = forwardRef((props, ref) => {
|
|
35
55
|
Accordion.displayName = "Accordion";
|
|
36
56
|
const classes = useStyles();
|
|
37
57
|
const { size } = useContext(ToolContext);
|
|
38
|
-
const { children, ...rest } = props;
|
|
58
|
+
const { children, highlightSections, ...rest } = props;
|
|
39
59
|
const validChildren = useMemo(() => {
|
|
40
60
|
return (Children.map(children, (child) => {
|
|
41
61
|
if (isValidElement(child)) {
|
|
@@ -56,6 +76,19 @@ export const Accordion = (props) => {
|
|
|
56
76
|
// Tracks closed items, which is needed so that when the children change, we only update the open/closed state
|
|
57
77
|
// (depending on the collapseByDefault prop) for items that have not been explicitly opened or closed.
|
|
58
78
|
const [closedItems, setClosedItems] = useState(validChildren.filter((child) => child.collapseByDefault).map((child) => child.title));
|
|
79
|
+
const internalOpenItemsRef = useRef(openItems);
|
|
80
|
+
// When highlight sections is requested, we temporarily override the open items, but if highlight sections is cleared,
|
|
81
|
+
// then we revert back to the normal open items tracking.
|
|
82
|
+
useLayoutEffect(() => {
|
|
83
|
+
if (highlightSections) {
|
|
84
|
+
internalOpenItemsRef.current = [...openItems];
|
|
85
|
+
setOpenItems([...highlightSections]);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
setOpenItems([...(internalOpenItemsRef.current ?? [])]);
|
|
89
|
+
internalOpenItemsRef.current = undefined;
|
|
90
|
+
}
|
|
91
|
+
}, [highlightSections]);
|
|
59
92
|
useEffect(() => {
|
|
60
93
|
for (const defaultOpenItem of validChildren.filter((child) => !child.collapseByDefault).map((child) => child.title)) {
|
|
61
94
|
// If a child is not marked as collapseByDefault, then it should be opened by default, and
|
|
@@ -75,8 +108,9 @@ export const Accordion = (props) => {
|
|
|
75
108
|
setOpenItems((prev) => prev.filter((item) => item !== data.value));
|
|
76
109
|
}
|
|
77
110
|
}, []);
|
|
78
|
-
return (_jsx(
|
|
79
|
-
|
|
111
|
+
return (_jsx(StringAccordion, { ref: ref, className: classes.accordion, collapsible: true, multiple: true, onToggle: onToggle, openItems: openItems, ...rest, children: validChildren.map((child, index) => {
|
|
112
|
+
const isHighlighted = highlightSections?.includes(child.title);
|
|
113
|
+
return (_jsxs(AccordionItem, { value: child.title, children: [_jsxs("div", { className: isHighlighted ? classes.highlightDiv : undefined, 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));
|
|
80
114
|
}) }));
|
|
81
|
-
};
|
|
115
|
+
});
|
|
82
116
|
//# sourceMappingURL=accordion.js.map
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7I,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC1K,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,SAAS,EAAE;QACP,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,MAAM;QACjB,aAAa,EAAE,MAAM,CAAC,gBAAgB,EAAE,yDAAyD;QACjG,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,MAAM;KACjB;IACD,OAAO,EAAE;QACL,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,aAAa,EAAE,YAAY,CAAC,UAAU;KACzC;IACD,YAAY,EAAE;QACV,UAAU,EAAE,YAAY,CAAC,eAAe;QACxC,aAAa,EAAE,YAAY,CAAC,eAAe;KAC9C;IACD,QAAQ,EAAE;QACN,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,QAAQ,EAAE,QAAQ;KACrB;IACD,YAAY,EAAE;QACV,YAAY,EAAE,MAAM,CAAC,iBAAiB;QACtC,iBAAiB,EAAE,IAAI;QACvB,uBAAuB,EAAE,aAAa;QACtC,uBAAuB,EAAE,GAAG;QAC5B,iBAAiB,EAAE,UAAU;QAC7B,aAAa,EAAE;YACX,IAAI,EAAE;gBACF,SAAS,EAAE,iBAAiB,MAAM,CAAC,0BAA0B,EAAE;aAClE;YACD,gEAAgE;YAChE,KAAK,EAAE;gBACH,SAAS,EAAE,kBAAkB,MAAM,CAAC,oBAAoB,EAAE;aAC7D;YACD,EAAE,EAAE;gBACA,SAAS,EAAE,iBAAiB,MAAM,CAAC,0BAA0B,EAAE;aAClE;SACJ;KACJ;CACJ,CAAC,CAAC;AAOH,MAAM,CAAC,MAAM,gBAAgB,GAAgE,CAAC,KAAK,EAAE,EAAE;IACnG,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC;IAClD,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,OAAO,cAAK,SAAS,EAAE,OAAO,CAAC,QAAQ,YAAG,KAAK,CAAC,QAAQ,GAAO,CAAC;AACpE,CAAC,CAAC;AAMF,MAAM,eAAe,GAAG,eAA0G,CAAC;AAEnI,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAoD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAClG,SAAS,CAAC,WAAW,GAAG,WAAW,CAAC;IACpC,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,OAAO,CACH,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAC7B,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAuC,CAAC;gBACjE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,OAAO;wBACH,KAAK,EAAE,UAAU,CAAC,KAAK;wBACvB,iBAAiB,EAAE,UAAU,CAAC,iBAAiB;wBAC/C,OAAO,EAAE,KAAK;qBACjB,CAAC;gBACN,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAC5B,CAAC;IACN,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,uFAAuF;IACvF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElI,8GAA8G;IAC9G,sGAAsG;IACtG,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAErI,MAAM,oBAAoB,GAAG,MAAM,CAAuB,SAAS,CAAC,CAAC;IAErE,sHAAsH;IACtH,yDAAyD;IACzD,eAAe,CAAC,GAAG,EAAE;QACjB,IAAI,iBAAiB,EAAE,CAAC;YACpB,oBAAoB,CAAC,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;YAC9C,YAAY,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACJ,YAAY,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxD,oBAAoB,CAAC,OAAO,GAAG,SAAS,CAAC;QAC7C,CAAC;IACL,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAExB,SAAS,CAAC,GAAG,EAAE;QACX,KAAK,MAAM,eAAe,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClH,0FAA0F;YAC1F,gGAAgG;YAChG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBACjF,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;YACvD,CAAC;QACL,CAAC;IACL,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,KAA2B,EAAE,IAAiC,EAAE,EAAE;QAC5F,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAChD,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACH,KAAC,eAAe,IAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,WAAW,QAAC,QAAQ,QAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,KAAM,IAAI,YAC3H,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChC,MAAM,aAAa,GAAG,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/D,OAAO,CACH,MAAC,aAAa,IAAyB,KAAK,EAAE,KAAK,CAAC,KAAK,aACrD,eAAK,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,aAC5D,KAAC,eAAe,IAAC,IAAI,EAAE,IAAI,YACvB,KAAC,iBAAiB,cAAE,KAAK,CAAC,KAAK,GAAqB,GACtC,EAClB,KAAC,cAAc,cACX,cAAK,SAAS,EAAE,OAAO,CAAC,QAAQ,YAAG,KAAK,CAAC,OAAO,GAAO,GAC1C,IACf,EACL,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,KAAC,OAAO,IAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,GAAI,KATnH,KAAK,CAAC,OAAO,CAAC,GAAG,CAUrB,CACnB,CAAC;QACN,CAAC,CAAC,GACY,CACrB,CAAC;AACN,CAAC,CAAC,CAAC","sourcesContent":["import type { AccordionToggleData, AccordionToggleEvent, AccordionProps as FluentAccordionProps } from \"@fluentui/react-components\";\r\nimport type { ForwardRefExoticComponent, FunctionComponent, PropsWithChildren, RefAttributes } from \"react\";\r\n\r\nimport { Children, forwardRef, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, 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\n\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 highlightDiv: {\r\n borderRadius: tokens.borderRadiusLarge,\r\n animationDuration: \"1s\",\r\n animationTimingFunction: \"ease-in-out\",\r\n animationIterationCount: \"5\",\r\n animationFillMode: \"forwards\",\r\n animationName: {\r\n from: {\r\n boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,\r\n },\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n \"50%\": {\r\n boxShadow: `inset 0 0 12px ${tokens.colorBrandBackground}`,\r\n },\r\n to: {\r\n boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,\r\n },\r\n },\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 type AccordionProps = {\r\n highlightSections?: readonly string[];\r\n};\r\n\r\nconst StringAccordion = FluentAccordion as ForwardRefExoticComponent<FluentAccordionProps<string> & RefAttributes<HTMLDivElement>>;\r\n\r\nexport const Accordion = forwardRef<HTMLDivElement, PropsWithChildren<AccordionProps>>((props, ref) => {\r\n Accordion.displayName = \"Accordion\";\r\n const classes = useStyles();\r\n const { size } = useContext(ToolContext);\r\n const { children, highlightSections, ...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 const internalOpenItemsRef = useRef<string[] | undefined>(openItems);\r\n\r\n // When highlight sections is requested, we temporarily override the open items, but if highlight sections is cleared,\r\n // then we revert back to the normal open items tracking.\r\n useLayoutEffect(() => {\r\n if (highlightSections) {\r\n internalOpenItemsRef.current = [...openItems];\r\n setOpenItems([...highlightSections]);\r\n } else {\r\n setOpenItems([...(internalOpenItemsRef.current ?? [])]);\r\n internalOpenItemsRef.current = undefined;\r\n }\r\n }, [highlightSections]);\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 <StringAccordion ref={ref} className={classes.accordion} collapsible multiple onToggle={onToggle} openItems={openItems} {...rest}>\r\n {validChildren.map((child, index) => {\r\n const isHighlighted = highlightSections?.includes(child.title);\r\n return (\r\n <AccordionItem key={child.content.key} value={child.title}>\r\n <div className={isHighlighted ? classes.highlightDiv : undefined}>\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 </div>\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 </StringAccordion>\r\n );\r\n});\r\n"]}
|