@onerjs/shared-ui-components 8.41.6 → 8.41.7
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/childWindow.js +3 -16
- package/fluent/hoc/childWindow.js.map +1 -1
- package/fluent/hoc/propertyLines/propertyLine.js +15 -2
- package/fluent/hoc/propertyLines/propertyLine.js.map +1 -1
- package/fluent/primitives/accordion.contexts.js +3 -3
- package/fluent/primitives/accordion.contexts.js.map +1 -1
- package/fluent/primitives/accordion.js +6 -1
- package/fluent/primitives/accordion.js.map +1 -1
- package/fluent/primitives/spinButton.js +54 -20
- package/fluent/primitives/spinButton.js.map +1 -1
- package/fluent/primitives/toast.js +1 -1
- package/fluent/primitives/toast.js.map +1 -1
- package/fluent/primitives/toggleButton.js +3 -3
- package/fluent/primitives/toggleButton.js.map +1 -1
- package/nodeGraphSystem/graphFrame.d.ts +0 -2
- package/nodeGraphSystem/graphFrame.js +15 -18
- package/nodeGraphSystem/graphFrame.js.map +1 -1
- package/nodeGraphSystem/graphFrame.module.scss +5 -10
- package/nodeGraphSystem/graphNode.module.scss +3 -5
- package/package.json +1 -1
|
@@ -107,22 +107,9 @@ export const ChildWindow = (props) => {
|
|
|
107
107
|
body.style.padding = "0";
|
|
108
108
|
body.style.display = "flex";
|
|
109
109
|
body.style.overflow = "hidden";
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
onOpenChange?.(true);
|
|
114
|
-
};
|
|
115
|
-
// Once the child window document is ready, setup the window state which will trigger another effect that renders into the child window.
|
|
116
|
-
if (childWindow.document.readyState === "complete") {
|
|
117
|
-
applyWindowState();
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
const onChildWindowLoad = () => {
|
|
121
|
-
applyWindowState();
|
|
122
|
-
};
|
|
123
|
-
childWindow.addEventListener("load", onChildWindowLoad, { once: true });
|
|
124
|
-
disposeActions.push(() => childWindow.removeEventListener("load", onChildWindowLoad));
|
|
125
|
-
}
|
|
110
|
+
// Setup the window state, including creating a Fluent/Griffel "renderer" for managing runtime styles/classes in the child window.
|
|
111
|
+
setWindowState({ mountNode: body, renderer: createDOMRenderer(childWindow.document) });
|
|
112
|
+
onOpenChange?.(true);
|
|
126
113
|
// When the child window is closed for any reason, transition back to a closed state.
|
|
127
114
|
const onChildWindowUnload = () => {
|
|
128
115
|
setWindowState(undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"childWindow.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/childWindow.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { GriffelRenderer } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, PropsWithChildren, Ref } from \"react\";\r\n\r\nimport { createDOMRenderer, FluentProvider, Portal, RendererProvider } from \"@fluentui/react-components\";\r\nimport { useCallback, useEffect, useImperativeHandle, useState } from \"react\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ToastProvider } from \"../primitives/toast\";\r\n\r\nfunction ToFeaturesString(options: ChildWindowOptions) {\r\n const { defaultWidth, defaultHeight, defaultLeft, defaultTop } = options;\r\n\r\n const features: { key: string; value: string }[] = [];\r\n\r\n if (defaultWidth !== undefined) {\r\n features.push({ key: \"width\", value: defaultWidth.toString() });\r\n }\r\n if (defaultHeight !== undefined) {\r\n features.push({ key: \"height\", value: defaultHeight.toString() });\r\n }\r\n if (defaultLeft !== undefined) {\r\n features.push({ key: \"left\", value: defaultLeft.toString() });\r\n }\r\n if (defaultTop !== undefined) {\r\n features.push({ key: \"top\", value: defaultTop.toString() });\r\n }\r\n features.push({ key: \"location\", value: \"no\" });\r\n\r\n return features.map((feature) => `${feature.key}=${feature.value}`).join(\",\");\r\n}\r\n\r\nexport type ChildWindowOptions = {\r\n /**\r\n * The default width of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultWidth?: number;\r\n\r\n /**\r\n * The default height of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultHeight?: number;\r\n\r\n /**\r\n * The default left position of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultLeft?: number;\r\n\r\n /**\r\n * The default top position of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultTop?: number;\r\n\r\n /**\r\n * The title of the child window.\r\n * @remarks If not provided, the id will be used instead (if any).\r\n */\r\n title?: string;\r\n};\r\n\r\nexport type ChildWindow = {\r\n /**\r\n * Opens the child window.\r\n * @param options Options for opening the child window.\r\n */\r\n open: (options?: ChildWindowOptions) => void;\r\n\r\n /**\r\n * Closes the child window.\r\n */\r\n close: () => void;\r\n};\r\n\r\nexport type ChildWindowProps = {\r\n /**\r\n * An optional unique identity for the child window.\r\n * @remarks If provided, the child window's bounds will be saved/restored using this identity.\r\n */\r\n id?: string;\r\n\r\n /**\r\n * Called when the open state of the child window changes.\r\n * @param isOpen Whether the child window is open.\r\n */\r\n onOpenChange?: (isOpen: boolean) => void;\r\n\r\n /**\r\n * A ref that exposes the ChildWindow imperative API.\r\n */\r\n imperativeRef?: Ref<ChildWindow>;\r\n};\r\n\r\n/**\r\n * Allows displaying a child window that can contain child components.\r\n * @param props Props for the child window.\r\n * @returns The child window component.\r\n */\r\nexport const ChildWindow: FunctionComponent<PropsWithChildren<ChildWindowProps>> = (props) => {\r\n const { id, children, onOpenChange, imperativeRef: imperativeRef } = props;\r\n\r\n const [windowState, setWindowState] = useState<{ mountNode: HTMLElement; renderer: GriffelRenderer }>();\r\n const [childWindow, setChildWindow] = useState<Window>();\r\n\r\n const storageKey = id ? `Babylon/Settings/ChildWindow/${id}/Bounds` : null;\r\n\r\n // This function is just for creating the child window itself. It is a function because\r\n // it must be called synchronously in response to a user interaction (e.g. button click),\r\n // otherwise the browser will block it as a scripted popup.\r\n const createWindow = useCallback(\r\n (options: ChildWindowOptions = {}) => {\r\n if (storageKey) {\r\n // If we are persisting window bounds, but the window is already open, just use the existing bounds.\r\n // Otherwise, try to load bounds from storage.\r\n if (childWindow) {\r\n options.defaultLeft = childWindow.screenX;\r\n options.defaultTop = childWindow.screenY;\r\n options.defaultWidth = childWindow.innerWidth;\r\n options.defaultHeight = childWindow.innerHeight;\r\n } else {\r\n const savedBounds = localStorage.getItem(storageKey);\r\n if (savedBounds) {\r\n try {\r\n const bounds = JSON.parse(savedBounds);\r\n options.defaultLeft = bounds.left;\r\n options.defaultTop = bounds.top;\r\n options.defaultWidth = bounds.width;\r\n options.defaultHeight = bounds.height;\r\n } catch {\r\n Logger.Warn(`Could not parse saved bounds for child window with key ${storageKey}`);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Half width by default.\r\n if (!options.defaultWidth) {\r\n options.defaultWidth = window.innerWidth * (2 / 3);\r\n }\r\n // Half height by default.\r\n if (!options.defaultHeight) {\r\n options.defaultHeight = window.innerHeight * (2 / 3);\r\n }\r\n // Horizontally centered by default.\r\n if (!options.defaultLeft) {\r\n options.defaultLeft = window.screenX + (window.innerWidth - options.defaultWidth) * (2 / 3);\r\n }\r\n // Vertically centered by default.\r\n if (!options.defaultTop) {\r\n options.defaultTop = window.screenY + (window.innerHeight - options.defaultHeight) * (2 / 3);\r\n }\r\n\r\n // Try to create the child window (can be null if popups are blocked).\r\n const newChildWindow = window.open(\"\", \"\", ToFeaturesString(options));\r\n if (newChildWindow) {\r\n // Set the title if provided.\r\n newChildWindow.document.title = options.title ?? id ?? \"\";\r\n\r\n // Set the child window state.\r\n setChildWindow((current) => {\r\n // But first close any existing child window.\r\n current?.close();\r\n return newChildWindow;\r\n });\r\n }\r\n },\r\n [childWindow, storageKey]\r\n );\r\n\r\n useImperativeHandle(imperativeRef, () => {\r\n return {\r\n open: createWindow,\r\n close: () => setChildWindow(undefined),\r\n };\r\n }, [createWindow]);\r\n\r\n // This side effect runs any time the child window instance changes. It does the rest of the child window\r\n // setup work, including creating resources and state needed to properly render the content of the child window.\r\n useEffect(() => {\r\n const disposeActions: (() => void)[] = [];\r\n\r\n if (childWindow) {\r\n const body = childWindow.document.body;\r\n body.style.width = \"100%\";\r\n body.style.height = \"100%\";\r\n body.style.margin = \"0\";\r\n body.style.padding = \"0\";\r\n body.style.display = \"flex\";\r\n body.style.overflow = \"hidden\";\r\n\r\n const applyWindowState = () => {\r\n // Setup the window state, including creating a Fluent/Griffel \"renderer\" for managing runtime styles/classes in the child window.\r\n setWindowState({ mountNode: body, renderer: createDOMRenderer(childWindow.document) });\r\n onOpenChange?.(true);\r\n };\r\n\r\n // Once the child window document is ready, setup the window state which will trigger another effect that renders into the child window.\r\n if (childWindow.document.readyState === \"complete\") {\r\n applyWindowState();\r\n } else {\r\n const onChildWindowLoad = () => {\r\n applyWindowState();\r\n };\r\n childWindow.addEventListener(\"load\", onChildWindowLoad, { once: true });\r\n disposeActions.push(() => childWindow.removeEventListener(\"load\", onChildWindowLoad));\r\n }\r\n\r\n // When the child window is closed for any reason, transition back to a closed state.\r\n const onChildWindowUnload = () => {\r\n setWindowState(undefined);\r\n setChildWindow(undefined);\r\n onOpenChange?.(false);\r\n };\r\n childWindow.addEventListener(\"unload\", onChildWindowUnload, { once: true });\r\n disposeActions.push(() => childWindow.removeEventListener(\"unload\", onChildWindowUnload));\r\n\r\n // If the main window closes, close any open child windows as well (don't leave them orphaned).\r\n const onParentWindowUnload = () => {\r\n childWindow.close();\r\n };\r\n window.addEventListener(\"unload\", onParentWindowUnload, { once: true });\r\n disposeActions.push(() => window.removeEventListener(\"unload\", onParentWindowUnload));\r\n\r\n // On dispose, close the child window.\r\n disposeActions.push(() => childWindow.close());\r\n\r\n // On dispose, save the window bounds.\r\n disposeActions.push(() => {\r\n if (storageKey) {\r\n localStorage.setItem(\r\n storageKey,\r\n JSON.stringify({\r\n left: childWindow.screenX,\r\n top: childWindow.screenY,\r\n width: childWindow.innerWidth,\r\n height: childWindow.innerHeight,\r\n })\r\n );\r\n }\r\n });\r\n }\r\n\r\n return () => {\r\n disposeActions.reverse().forEach((dispose) => dispose());\r\n };\r\n }, [childWindow]);\r\n\r\n if (!windowState) {\r\n return null;\r\n }\r\n\r\n const { mountNode, renderer } = windowState;\r\n\r\n return (\r\n // Portal targets the body of the child window.\r\n <Portal mountNode={mountNode}>\r\n {/* RenderProvider manages Fluent style/class state. */}\r\n <RendererProvider renderer={renderer} targetDocument={mountNode.ownerDocument}>\r\n {/* Fluent Provider is needed for managing other Fluent state and applying the current theme mode. */}\r\n <FluentProvider\r\n style={{\r\n display: \"flex\",\r\n flexGrow: 1,\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n }}\r\n applyStylesToPortals={false}\r\n targetDocument={mountNode.ownerDocument}\r\n >\r\n <ToastProvider>{children}</ToastProvider>\r\n </FluentProvider>\r\n </RendererProvider>\r\n </Portal>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"childWindow.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/childWindow.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { GriffelRenderer } from \"@fluentui/react-components\";\r\nimport type { FunctionComponent, PropsWithChildren, Ref } from \"react\";\r\n\r\nimport { createDOMRenderer, FluentProvider, Portal, RendererProvider } from \"@fluentui/react-components\";\r\nimport { useCallback, useEffect, useImperativeHandle, useState } from \"react\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ToastProvider } from \"../primitives/toast\";\r\n\r\nfunction ToFeaturesString(options: ChildWindowOptions) {\r\n const { defaultWidth, defaultHeight, defaultLeft, defaultTop } = options;\r\n\r\n const features: { key: string; value: string }[] = [];\r\n\r\n if (defaultWidth !== undefined) {\r\n features.push({ key: \"width\", value: defaultWidth.toString() });\r\n }\r\n if (defaultHeight !== undefined) {\r\n features.push({ key: \"height\", value: defaultHeight.toString() });\r\n }\r\n if (defaultLeft !== undefined) {\r\n features.push({ key: \"left\", value: defaultLeft.toString() });\r\n }\r\n if (defaultTop !== undefined) {\r\n features.push({ key: \"top\", value: defaultTop.toString() });\r\n }\r\n features.push({ key: \"location\", value: \"no\" });\r\n\r\n return features.map((feature) => `${feature.key}=${feature.value}`).join(\",\");\r\n}\r\n\r\nexport type ChildWindowOptions = {\r\n /**\r\n * The default width of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultWidth?: number;\r\n\r\n /**\r\n * The default height of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultHeight?: number;\r\n\r\n /**\r\n * The default left position of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultLeft?: number;\r\n\r\n /**\r\n * The default top position of the child window in pixels.\r\n * @remarks Ignored if the ChildWindow was passed an id and previous bounds were saved.\r\n */\r\n defaultTop?: number;\r\n\r\n /**\r\n * The title of the child window.\r\n * @remarks If not provided, the id will be used instead (if any).\r\n */\r\n title?: string;\r\n};\r\n\r\nexport type ChildWindow = {\r\n /**\r\n * Opens the child window.\r\n * @param options Options for opening the child window.\r\n */\r\n open: (options?: ChildWindowOptions) => void;\r\n\r\n /**\r\n * Closes the child window.\r\n */\r\n close: () => void;\r\n};\r\n\r\nexport type ChildWindowProps = {\r\n /**\r\n * An optional unique identity for the child window.\r\n * @remarks If provided, the child window's bounds will be saved/restored using this identity.\r\n */\r\n id?: string;\r\n\r\n /**\r\n * Called when the open state of the child window changes.\r\n * @param isOpen Whether the child window is open.\r\n */\r\n onOpenChange?: (isOpen: boolean) => void;\r\n\r\n /**\r\n * A ref that exposes the ChildWindow imperative API.\r\n */\r\n imperativeRef?: Ref<ChildWindow>;\r\n};\r\n\r\n/**\r\n * Allows displaying a child window that can contain child components.\r\n * @param props Props for the child window.\r\n * @returns The child window component.\r\n */\r\nexport const ChildWindow: FunctionComponent<PropsWithChildren<ChildWindowProps>> = (props) => {\r\n const { id, children, onOpenChange, imperativeRef: imperativeRef } = props;\r\n\r\n const [windowState, setWindowState] = useState<{ mountNode: HTMLElement; renderer: GriffelRenderer }>();\r\n const [childWindow, setChildWindow] = useState<Window>();\r\n\r\n const storageKey = id ? `Babylon/Settings/ChildWindow/${id}/Bounds` : null;\r\n\r\n // This function is just for creating the child window itself. It is a function because\r\n // it must be called synchronously in response to a user interaction (e.g. button click),\r\n // otherwise the browser will block it as a scripted popup.\r\n const createWindow = useCallback(\r\n (options: ChildWindowOptions = {}) => {\r\n if (storageKey) {\r\n // If we are persisting window bounds, but the window is already open, just use the existing bounds.\r\n // Otherwise, try to load bounds from storage.\r\n if (childWindow) {\r\n options.defaultLeft = childWindow.screenX;\r\n options.defaultTop = childWindow.screenY;\r\n options.defaultWidth = childWindow.innerWidth;\r\n options.defaultHeight = childWindow.innerHeight;\r\n } else {\r\n const savedBounds = localStorage.getItem(storageKey);\r\n if (savedBounds) {\r\n try {\r\n const bounds = JSON.parse(savedBounds);\r\n options.defaultLeft = bounds.left;\r\n options.defaultTop = bounds.top;\r\n options.defaultWidth = bounds.width;\r\n options.defaultHeight = bounds.height;\r\n } catch {\r\n Logger.Warn(`Could not parse saved bounds for child window with key ${storageKey}`);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Half width by default.\r\n if (!options.defaultWidth) {\r\n options.defaultWidth = window.innerWidth * (2 / 3);\r\n }\r\n // Half height by default.\r\n if (!options.defaultHeight) {\r\n options.defaultHeight = window.innerHeight * (2 / 3);\r\n }\r\n // Horizontally centered by default.\r\n if (!options.defaultLeft) {\r\n options.defaultLeft = window.screenX + (window.innerWidth - options.defaultWidth) * (2 / 3);\r\n }\r\n // Vertically centered by default.\r\n if (!options.defaultTop) {\r\n options.defaultTop = window.screenY + (window.innerHeight - options.defaultHeight) * (2 / 3);\r\n }\r\n\r\n // Try to create the child window (can be null if popups are blocked).\r\n const newChildWindow = window.open(\"\", \"\", ToFeaturesString(options));\r\n if (newChildWindow) {\r\n // Set the title if provided.\r\n newChildWindow.document.title = options.title ?? id ?? \"\";\r\n\r\n // Set the child window state.\r\n setChildWindow((current) => {\r\n // But first close any existing child window.\r\n current?.close();\r\n return newChildWindow;\r\n });\r\n }\r\n },\r\n [childWindow, storageKey]\r\n );\r\n\r\n useImperativeHandle(imperativeRef, () => {\r\n return {\r\n open: createWindow,\r\n close: () => setChildWindow(undefined),\r\n };\r\n }, [createWindow]);\r\n\r\n // This side effect runs any time the child window instance changes. It does the rest of the child window\r\n // setup work, including creating resources and state needed to properly render the content of the child window.\r\n useEffect(() => {\r\n const disposeActions: (() => void)[] = [];\r\n\r\n if (childWindow) {\r\n const body = childWindow.document.body;\r\n body.style.width = \"100%\";\r\n body.style.height = \"100%\";\r\n body.style.margin = \"0\";\r\n body.style.padding = \"0\";\r\n body.style.display = \"flex\";\r\n body.style.overflow = \"hidden\";\r\n\r\n // Setup the window state, including creating a Fluent/Griffel \"renderer\" for managing runtime styles/classes in the child window.\r\n setWindowState({ mountNode: body, renderer: createDOMRenderer(childWindow.document) });\r\n onOpenChange?.(true);\r\n\r\n // When the child window is closed for any reason, transition back to a closed state.\r\n const onChildWindowUnload = () => {\r\n setWindowState(undefined);\r\n setChildWindow(undefined);\r\n onOpenChange?.(false);\r\n };\r\n childWindow.addEventListener(\"unload\", onChildWindowUnload, { once: true });\r\n disposeActions.push(() => childWindow.removeEventListener(\"unload\", onChildWindowUnload));\r\n\r\n // If the main window closes, close any open child windows as well (don't leave them orphaned).\r\n const onParentWindowUnload = () => {\r\n childWindow.close();\r\n };\r\n window.addEventListener(\"unload\", onParentWindowUnload, { once: true });\r\n disposeActions.push(() => window.removeEventListener(\"unload\", onParentWindowUnload));\r\n\r\n // On dispose, close the child window.\r\n disposeActions.push(() => childWindow.close());\r\n\r\n // On dispose, save the window bounds.\r\n disposeActions.push(() => {\r\n if (storageKey) {\r\n localStorage.setItem(\r\n storageKey,\r\n JSON.stringify({\r\n left: childWindow.screenX,\r\n top: childWindow.screenY,\r\n width: childWindow.innerWidth,\r\n height: childWindow.innerHeight,\r\n })\r\n );\r\n }\r\n });\r\n }\r\n\r\n return () => {\r\n disposeActions.reverse().forEach((dispose) => dispose());\r\n };\r\n }, [childWindow]);\r\n\r\n if (!windowState) {\r\n return null;\r\n }\r\n\r\n const { mountNode, renderer } = windowState;\r\n\r\n return (\r\n // Portal targets the body of the child window.\r\n <Portal mountNode={mountNode}>\r\n {/* RenderProvider manages Fluent style/class state. */}\r\n <RendererProvider renderer={renderer} targetDocument={mountNode.ownerDocument}>\r\n {/* Fluent Provider is needed for managing other Fluent state and applying the current theme mode. */}\r\n <FluentProvider\r\n style={{\r\n display: \"flex\",\r\n flexGrow: 1,\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n }}\r\n applyStylesToPortals={false}\r\n targetDocument={mountNode.ownerDocument}\r\n >\r\n <ToastProvider>{children}</ToastProvider>\r\n </FluentProvider>\r\n </RendererProvider>\r\n </Portal>\r\n );\r\n};\r\n"]}
|
|
@@ -71,7 +71,7 @@ const usePropertyLineStyles = makeStyles({
|
|
|
71
71
|
*/
|
|
72
72
|
export const PropertyLine = forwardRef((props, ref) => {
|
|
73
73
|
PropertyLine.displayName = "PropertyLine";
|
|
74
|
-
const {
|
|
74
|
+
const { size } = useContext(ToolContext);
|
|
75
75
|
const classes = usePropertyLineStyles();
|
|
76
76
|
const { label, uniqueId, onCopy, expandedContent, children, nullable, ignoreNullable } = props;
|
|
77
77
|
const [expanded, setExpanded] = useState("expandByDefault" in props ? props.expandByDefault : false);
|
|
@@ -109,7 +109,7 @@ export const PropertyLine = forwardRef((props, ref) => {
|
|
|
109
109
|
cachedVal.current = props.value;
|
|
110
110
|
props.onChange(null);
|
|
111
111
|
}
|
|
112
|
-
} }) })), _jsx("div", { className: classes.childWrapper, children: processedChildren }), onCopy &&
|
|
112
|
+
} }) })), _jsx("div", { className: classes.childWrapper, children: processedChildren }), onCopy && _jsx(CopyButton, { onCopy: handleCopy })] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
|
|
113
113
|
});
|
|
114
114
|
const useLineStyles = makeStyles({
|
|
115
115
|
container: {
|
|
@@ -138,6 +138,19 @@ export const LineContainer = forwardRef((props, ref) => {
|
|
|
138
138
|
const classes = useLineStyles();
|
|
139
139
|
return (_jsx(AccordionSectionItem, { uniqueId: uniqueId, label: label, children: _jsx("div", { ref: ref, className: mergeClasses(classes.container, size == "small" ? classes.containerSmall : undefined), ...rest, children: children }) }));
|
|
140
140
|
});
|
|
141
|
+
/**
|
|
142
|
+
* Copy button that reads ToolContext at its own position in the tree.
|
|
143
|
+
* This allows AccordionSectionItem's ToolContext.Provider override (e.g. ctrl+hover) to control visibility.
|
|
144
|
+
* @returns The copy button element.
|
|
145
|
+
*/
|
|
146
|
+
const CopyButton = ({ onCopy }) => {
|
|
147
|
+
const { disableCopy, size } = useContext(ToolContext);
|
|
148
|
+
const classes = usePropertyLineStyles();
|
|
149
|
+
if (disableCopy) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return (_jsx(Tooltip, { content: "Copy to Clipboard", children: _jsx(Button, { className: classes.copy, appearance: "transparent", icon: size === "small" ? Copy16Regular : CopyRegular, onClick: onCopy }) }));
|
|
153
|
+
};
|
|
141
154
|
export const PlaceholderPropertyLine = (props) => {
|
|
142
155
|
return (_jsx(PropertyLine, { ...props, children: _jsx(Body1, { children: props.value }) }));
|
|
143
156
|
};
|
|
@@ -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, Checkbox, makeStyles, tokens, mergeClasses } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n CopyRegular,\r\n Copy16Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren, MouseEvent } from \"react\";\r\nimport type { AccordionSectionItemProps } from \"../../primitives/accordion\";\r\nimport { AccordionSectionItem } from \"../../primitives/accordion\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef, useCallback } 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 { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens, TokenMap } from \"../../primitives/utils\";\r\nimport { InfoLabel } from \"../../primitives/infoLabel\";\r\nimport { Tooltip } from \"../../primitives/tooltip\";\r\nimport { useToast } from \"../../primitives/toast\";\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 rightContent: {\r\n flex: \"0 1 auto\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n childWrapper: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\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 paddingLeft: tokens.spacingHorizontalM,\r\n },\r\n checkbox: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n marginRight: tokens.spacingHorizontalXS,\r\n },\r\n checkboxIndicator: {\r\n margin: TokenMap.px2,\r\n width: TokenMap.px12,\r\n height: TokenMap.px12,\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 * The ID of the property line to be used when the label cannot be used as a persistent ID.\r\n *\r\n * Note that when a property line is used within an accordion section, this ID must be unique within that section in order\r\n * for property pinning and filtering to work correctly. If not, error will be shown in console.\r\n */\r\n uniqueId?: 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, uniqueId, 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 { showToast } = useToast();\r\n\r\n const handleCopy = useCallback(() => {\r\n if (onCopy) {\r\n copyCommandToClipboard(onCopy());\r\n showToast(\"Copied property to clipboard\");\r\n }\r\n }, [onCopy, showToast]);\r\n\r\n const handleContextMenu = useCallback(\r\n (e: MouseEvent) => {\r\n e.preventDefault();\r\n handleCopy();\r\n },\r\n [handleCopy]\r\n );\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description ? <Body1>{props.description}</Body1> : undefined;\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} uniqueId={uniqueId ?? label} label={label}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel className={classes.infoLabel} htmlFor=\"property\" info={description} label={label} flexLabel onContextMenu={onCopy ? handleContextMenu : undefined} />\r\n <div className={classes.rightContent} id=\"property\">\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 <Tooltip content={props.value == null ? \"Enable property\" : \"Disable property (set to null)\"}>\r\n <Checkbox\r\n className={classes.checkbox}\r\n indicator={{ className: classes.checkboxIndicator }}\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 />\r\n </Tooltip>\r\n )}\r\n <div className={classes.childWrapper}>{processedChildren}</div>\r\n {onCopy && !disableCopy && (\r\n <Tooltip content=\"Copy to Clipboard\">\r\n <Button className={classes.copy} appearance=\"transparent\" icon={size === \"small\" ? Copy16Regular : CopyRegular} onClick={handleCopy} />\r\n </Tooltip>\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 borderTop: `1px solid transparent`,\r\n borderBottom: `1px solid transparent`,\r\n \":hover\": {\r\n borderTopColor: tokens.colorNeutralStroke2,\r\n borderBottomColor: tokens.colorNeutralStroke2,\r\n },\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> & AccordionSectionItemProps>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const { children, uniqueId, label, ...rest } = props;\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <AccordionSectionItem uniqueId={uniqueId} label={label}>\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...rest}>\r\n {children}\r\n </div>\r\n </AccordionSectionItem>\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, Checkbox, makeStyles, tokens, mergeClasses } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n CopyRegular,\r\n Copy16Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren, MouseEvent } from \"react\";\r\nimport type { AccordionSectionItemProps } from \"../../primitives/accordion\";\r\nimport { AccordionSectionItem } from \"../../primitives/accordion\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef, useCallback } 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 { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens, TokenMap } from \"../../primitives/utils\";\r\nimport { InfoLabel } from \"../../primitives/infoLabel\";\r\nimport { Tooltip } from \"../../primitives/tooltip\";\r\nimport { useToast } from \"../../primitives/toast\";\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 rightContent: {\r\n flex: \"0 1 auto\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n childWrapper: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\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 paddingLeft: tokens.spacingHorizontalM,\r\n },\r\n checkbox: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n marginRight: tokens.spacingHorizontalXS,\r\n },\r\n checkboxIndicator: {\r\n margin: TokenMap.px2,\r\n width: TokenMap.px12,\r\n height: TokenMap.px12,\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 * The ID of the property line to be used when the label cannot be used as a persistent ID.\r\n *\r\n * Note that when a property line is used within an accordion section, this ID must be unique within that section in order\r\n * for property pinning and filtering to work correctly. If not, error will be shown in console.\r\n */\r\n uniqueId?: 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 { size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, uniqueId, 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 { showToast } = useToast();\r\n\r\n const handleCopy = useCallback(() => {\r\n if (onCopy) {\r\n copyCommandToClipboard(onCopy());\r\n showToast(\"Copied property to clipboard\");\r\n }\r\n }, [onCopy, showToast]);\r\n\r\n const handleContextMenu = useCallback(\r\n (e: MouseEvent) => {\r\n e.preventDefault();\r\n handleCopy();\r\n },\r\n [handleCopy]\r\n );\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description ? <Body1>{props.description}</Body1> : undefined;\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} uniqueId={uniqueId ?? label} label={label}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel className={classes.infoLabel} htmlFor=\"property\" info={description} label={label} flexLabel onContextMenu={onCopy ? handleContextMenu : undefined} />\r\n <div className={classes.rightContent} id=\"property\">\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 <Tooltip content={props.value == null ? \"Enable property\" : \"Disable property (set to null)\"}>\r\n <Checkbox\r\n className={classes.checkbox}\r\n indicator={{ className: classes.checkboxIndicator }}\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 />\r\n </Tooltip>\r\n )}\r\n <div className={classes.childWrapper}>{processedChildren}</div>\r\n {onCopy && <CopyButton onCopy={handleCopy} />}\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 borderTop: `1px solid transparent`,\r\n borderBottom: `1px solid transparent`,\r\n \":hover\": {\r\n borderTopColor: tokens.colorNeutralStroke2,\r\n borderBottomColor: tokens.colorNeutralStroke2,\r\n },\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> & AccordionSectionItemProps>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const { children, uniqueId, label, ...rest } = props;\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <AccordionSectionItem uniqueId={uniqueId} label={label}>\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...rest}>\r\n {children}\r\n </div>\r\n </AccordionSectionItem>\r\n );\r\n});\r\n\r\n/**\r\n * Copy button that reads ToolContext at its own position in the tree.\r\n * This allows AccordionSectionItem's ToolContext.Provider override (e.g. ctrl+hover) to control visibility.\r\n * @returns The copy button element.\r\n */\r\nconst CopyButton: FunctionComponent<{ onCopy: () => void }> = ({ onCopy }) => {\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n\r\n if (disableCopy) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Tooltip content=\"Copy to Clipboard\">\r\n <Button className={classes.copy} appearance=\"transparent\" icon={size === \"small\" ? Copy16Regular : CopyRegular} onClick={onCopy} />\r\n </Tooltip>\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"]}
|
|
@@ -178,9 +178,9 @@ export function useAccordionSectionItemState(props) {
|
|
|
178
178
|
}
|
|
179
179
|
prevItemIdRef.current = itemId;
|
|
180
180
|
}, [itemId, sectionCtx?.sectionId]);
|
|
181
|
-
// Register item and detect duplicates
|
|
181
|
+
// Register item and detect duplicates (skip nested items, as children of other AccordionSectionItem should not participate in pin/hide/search).
|
|
182
182
|
useEffect(() => {
|
|
183
|
-
if (!accordionCtx || !itemUniqueId) {
|
|
183
|
+
if (!accordionCtx || !itemUniqueId || isNested) {
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
const { registeredItemIds } = accordionCtx;
|
|
@@ -192,7 +192,7 @@ export function useAccordionSectionItemState(props) {
|
|
|
192
192
|
return () => {
|
|
193
193
|
registeredItemIds.delete(itemUniqueId);
|
|
194
194
|
};
|
|
195
|
-
}, [accordionCtx, itemUniqueId, itemId, itemLabel, sectionCtx?.sectionId]);
|
|
195
|
+
}, [accordionCtx, itemUniqueId, itemId, itemLabel, sectionCtx?.sectionId, isNested]);
|
|
196
196
|
// If no context, static item, or nested, return undefined
|
|
197
197
|
if (!accordionCtx || staticItem) {
|
|
198
198
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.contexts.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.contexts.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { RefObject } from \"react\";\nimport type { AccordionProps, AccordionSectionBlockProps, AccordionSectionItemProps } from \"./accordion\";\nimport { createContext, useContext, useEffect, useMemo, useReducer, useRef } from \"react\";\nimport { DataStorage } from \"core/Misc/dataStorage\";\nimport { Logger } from \"core/Misc/logger\";\n\n// ============================================================================\n// Storage Helpers\n// ============================================================================\n\nconst STORAGE_KEY_ROOT = \"Babylon/Accordion\";\n\nconst ReadFromStorage = <T,>(path: string, initial: T): T => {\n try {\n const stored = DataStorage.ReadString(`${STORAGE_KEY_ROOT}/${path}`, \"\");\n return stored ? JSON.parse(stored) : initial;\n } catch {\n return initial;\n }\n};\n\nconst WriteToStorage = (path: string, data: unknown): void => {\n DataStorage.WriteString(`${STORAGE_KEY_ROOT}/${path}`, JSON.stringify(data));\n};\n\n// ============================================================================\n// State Types\n// ============================================================================\n\n/**\n * Immutable state for the Accordion.\n */\nexport type AccordionState = {\n /** IDs of pinned items (persisted to localStorage). */\n pinnedIds: string[];\n /** IDs of hidden items (persisted to localStorage). */\n hiddenIds: string[];\n /** Current search/filter term. */\n searchTerm: string;\n /** Whether edit mode is active (shows pin/hide controls). */\n editMode: boolean;\n};\n\n/**\n * Actions that can be dispatched to update accordion state.\n */\nexport type AccordionAction =\n | { type: \"SET_SEARCH_TERM\"; term: string }\n | { type: \"SET_EDIT_MODE\"; enabled: boolean }\n | { type: \"TOGGLE_PINNED\"; itemId: string }\n | { type: \"TOGGLE_HIDDEN\"; itemId: string }\n | { type: \"MOVE_PINNED_UP\"; itemId: string }\n | { type: \"REMOVE_STALE_IDS\"; activeIds: Set<string> }\n | { type: \"SHOW_ALL\" }\n | { type: \"HIDE_ALL_VISIBLE\"; visibleItemIds: string[] };\n\n/**\n * Feature flags for the Accordion (immutable after initialization).\n */\nexport type AccordionFeatures = {\n /** Whether pinning is enabled. */\n pinning: boolean;\n /** Whether hiding is enabled. */\n hiding: boolean;\n /** Whether search is enabled. */\n search: boolean;\n};\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\nconst AccordionReducer = (state: AccordionState, action: AccordionAction): AccordionState => {\n switch (action.type) {\n case \"SET_SEARCH_TERM\":\n return { ...state, searchTerm: action.term };\n\n case \"SET_EDIT_MODE\":\n return { ...state, editMode: action.enabled };\n\n case \"TOGGLE_PINNED\": {\n const isPinned = state.pinnedIds.includes(action.itemId);\n return {\n ...state,\n pinnedIds: isPinned ? state.pinnedIds.filter((id) => id !== action.itemId) : [...state.pinnedIds, action.itemId],\n };\n }\n\n case \"TOGGLE_HIDDEN\": {\n const isHidden = state.hiddenIds.includes(action.itemId);\n return {\n ...state,\n hiddenIds: isHidden ? state.hiddenIds.filter((id) => id !== action.itemId) : [...state.hiddenIds, action.itemId],\n };\n }\n\n case \"MOVE_PINNED_UP\": {\n const index = state.pinnedIds.indexOf(action.itemId);\n if (index <= 0) {\n return state;\n }\n const newPinnedIds = [...state.pinnedIds];\n [newPinnedIds[index - 1], newPinnedIds[index]] = [newPinnedIds[index], newPinnedIds[index - 1]];\n return { ...state, pinnedIds: newPinnedIds };\n }\n\n case \"REMOVE_STALE_IDS\": {\n const pinnedIds = state.pinnedIds.filter((id) => action.activeIds.has(id));\n const hiddenIds = state.hiddenIds.filter((id) => action.activeIds.has(id));\n if (pinnedIds.length === state.pinnedIds.length && hiddenIds.length === state.hiddenIds.length) {\n return state;\n }\n return { ...state, pinnedIds, hiddenIds };\n }\n\n case \"SHOW_ALL\":\n return { ...state, hiddenIds: [] };\n\n case \"HIDE_ALL_VISIBLE\":\n return {\n ...state,\n hiddenIds: [...new Set([...state.hiddenIds, ...action.visibleItemIds])],\n };\n\n default:\n return state;\n }\n};\n\n// ============================================================================\n// Accordion Context\n// ============================================================================\n\n/**\n * Context value for the Accordion component.\n */\nexport type AccordionContextValue = {\n /** The unique ID of the Accordion instance. */\n accordionId: string;\n /** State for the Accordion, managed via dispatch function. */\n state: AccordionState;\n /** Dispatch function to update state. */\n dispatch: React.Dispatch<AccordionAction>;\n /** Feature flags. */\n features: AccordionFeatures;\n /** Ref for the pinned items portal container. */\n pinnedContainerRef: RefObject<HTMLDivElement>;\n /** Map of registered item IDs to labels (for duplicate detection and section empty checks). */\n registeredItemIds: Map<string, string>;\n};\n\nexport const AccordionContext = createContext<AccordionContextValue | undefined>(undefined);\n\n/**\n * Hook to create and manage the AccordionContext value.\n *\n * @param props - AccordionProps\n * @returns AccordionContextValue, or undefined if no features are enabled or no uniqueId is provided.\n */\nexport function useAccordionContext(props: AccordionProps): AccordionContextValue | undefined {\n const { uniqueId: accordionId, enablePinnedItems, enableHiddenItems, enableSearchItems } = props;\n\n const features: AccordionFeatures = useMemo(\n () => ({\n pinning: enablePinnedItems ?? false,\n hiding: enableHiddenItems ?? false,\n search: enableSearchItems ?? false,\n }),\n [enablePinnedItems, enableHiddenItems, enableSearchItems]\n );\n\n const hasFeatures = features.pinning || features.hiding || features.search;\n\n // Initialize state from localStorage\n const initialState = useMemo((): AccordionState => {\n if (!accordionId || !hasFeatures) {\n return { pinnedIds: [], hiddenIds: [], searchTerm: \"\", editMode: false };\n }\n return {\n pinnedIds: features.pinning ? ReadFromStorage<string[]>(`Pinned/${accordionId}`, []) : [],\n hiddenIds: features.hiding ? ReadFromStorage<string[]>(`Hidden/${accordionId}`, []) : [],\n searchTerm: \"\",\n editMode: false,\n };\n }, [accordionId, hasFeatures, features.pinning, features.hiding]);\n\n const [state, dispatch] = useReducer(AccordionReducer, initialState);\n\n const pinnedContainerRef = useRef<HTMLDivElement>(null);\n const registeredItemIds = useRef<Map<string, string>>(new Map());\n\n // Persist pinnedIds to localStorage when they change\n useEffect(() => {\n if (accordionId && features.pinning) {\n WriteToStorage(`Pinned/${accordionId}`, state.pinnedIds);\n }\n }, [accordionId, features.pinning, state.pinnedIds]);\n\n // Persist hiddenIds to localStorage when they change\n useEffect(() => {\n if (accordionId && features.hiding) {\n WriteToStorage(`Hidden/${accordionId}`, state.hiddenIds);\n }\n }, [accordionId, features.hiding, state.hiddenIds]);\n\n // Clean stale IDs from localStorage on mount. Parent effects run after\n // children's, so all items will have registered by the time this fires.\n useEffect(() => {\n if (accordionId && hasFeatures) {\n dispatch({ type: \"REMOVE_STALE_IDS\", activeIds: new Set(registeredItemIds.current.keys()) });\n }\n }, [accordionId, hasFeatures]);\n\n // Return undefined if no accordionId or no features enabled\n if (!accordionId || !hasFeatures) {\n return undefined;\n }\n\n return {\n accordionId,\n state,\n dispatch,\n features,\n pinnedContainerRef,\n registeredItemIds: registeredItemIds.current,\n };\n}\n\n// ============================================================================\n// Section Context\n// ============================================================================\n\n/**\n * Context value for an AccordionSectionBlock.\n */\nexport type AccordionSectionBlockContextValue = {\n /** The section ID. */\n sectionId: string;\n};\n\nexport const AccordionSectionBlockContext = createContext<AccordionSectionBlockContextValue | undefined>(undefined);\n\n/**\n * Hook to create the AccordionSectionBlockContext value.\n *\n * @param props - AccordionSectionBlockProps\n * @returns AccordionSectionBlockContextValue and isEmpty state\n */\nexport function useAccordionSectionBlockContext(props: AccordionSectionBlockProps): {\n context: AccordionSectionBlockContextValue;\n isEmpty: boolean;\n} {\n const { sectionId } = props;\n const context = useMemo(() => ({ sectionId }), [sectionId]);\n const isEmpty = useIsSectionEmpty(sectionId);\n\n return { context, isEmpty };\n}\n\n// ============================================================================\n// Item Depth Context (to detect nested AccordionSectionItems)\n// ============================================================================\n\n/**\n * Context to track whether we're inside an AccordionSectionItem.\n * Used to prevent nested items from being individually manageable.\n */\nexport const AccordionItemDepthContext = createContext<boolean>(false);\n\n// ============================================================================\n// Item Context Hook\n// ============================================================================\n\n/**\n * Derived item state, computed from the accordion state during render.\n */\nexport type AccordionItemState = {\n /** The globally unique item ID. */\n itemUniqueId: string;\n /** Whether this item is nested inside another AccordionSectionItem. */\n isNested: boolean;\n /** Whether this item is pinned. */\n isPinned: boolean;\n /** Whether this item is hidden. */\n isHidden: boolean;\n /** Whether this item matches the current search term. */\n isMatch: boolean;\n /** The index of this item in the pinned list (for ordering). */\n pinnedIndex: number;\n /** Whether this pinned item can be moved up (is not first in the pinned list). */\n canMoveUp: boolean;\n /** Whether edit mode is active. */\n inEditMode: boolean;\n /** Callbacks to modify state. */\n actions: {\n togglePinned: () => void;\n toggleHidden: () => void;\n movePinnedUp: () => void;\n };\n};\n\n/**\n * Hook to compute item state from accordion context.\n *\n * @param props - AccordionSectionItemProps\n * @returns AccordionItemState, or undefined if no accordion context or nested item.\n */\nexport function useAccordionSectionItemState(props: AccordionSectionItemProps): AccordionItemState | undefined {\n const { uniqueId: itemId, label: itemLabel, staticItem } = props;\n\n const accordionCtx = useContext(AccordionContext);\n const sectionCtx = useContext(AccordionSectionBlockContext);\n const isNested = useContext(AccordionItemDepthContext);\n\n // Build the globally unique item ID\n const itemUniqueId = useMemo(() => {\n if (!accordionCtx || !sectionCtx) {\n return \"\";\n }\n return `${accordionCtx.accordionId}/${sectionCtx.sectionId}/${itemId}`;\n }, [accordionCtx?.accordionId, sectionCtx?.sectionId, itemId]);\n\n // Debug: warn if itemId changes (should be stable)\n const prevItemIdRef = useRef(itemId);\n useEffect(() => {\n if (prevItemIdRef.current !== itemId) {\n Logger.Warn(\n `Accordion: The uniqueId \"${itemId}\" in section \"${sectionCtx?.sectionId}\" has changed from \"${prevItemIdRef.current}\". ` +\n `Each item must have a unique, stable ID for pin/hide persistence to work correctly.`\n );\n }\n prevItemIdRef.current = itemId;\n }, [itemId, sectionCtx?.sectionId]);\n\n // Register item and detect duplicates\n useEffect(() => {\n if (!accordionCtx || !itemUniqueId) {\n return;\n }\n const { registeredItemIds } = accordionCtx;\n if (registeredItemIds.has(itemUniqueId)) {\n Logger.Warn(\n `Accordion: Duplicate uniqueId \"${itemId}\" detected in section \"${sectionCtx?.sectionId}\". ` +\n `Each item must have a unique ID within its section for pin/hide persistence to work correctly.`\n );\n }\n registeredItemIds.set(itemUniqueId, itemLabel ?? itemId);\n return () => {\n registeredItemIds.delete(itemUniqueId);\n };\n }, [accordionCtx, itemUniqueId, itemId, itemLabel, sectionCtx?.sectionId]);\n\n // If no context, static item, or nested, return undefined\n if (!accordionCtx || staticItem) {\n return undefined;\n }\n\n const { state, dispatch, features } = accordionCtx;\n const { pinnedIds, hiddenIds, searchTerm, editMode } = state;\n\n // Compute derived state\n const isPinned = features.pinning && pinnedIds.includes(itemUniqueId);\n const isHidden = features.hiding && hiddenIds.includes(itemUniqueId);\n const pinnedIndex = isPinned ? pinnedIds.indexOf(itemUniqueId) : -1;\n\n const canMoveUp = isPinned && pinnedIndex > 0;\n\n // Search matching\n const searchText = (itemLabel ?? itemId).toLowerCase();\n const isMatch = !features.search || !searchTerm || searchText.includes(searchTerm.toLowerCase());\n\n return {\n itemUniqueId,\n isNested,\n isPinned,\n isHidden,\n isMatch,\n pinnedIndex,\n canMoveUp,\n inEditMode: editMode,\n actions: {\n togglePinned: () => dispatch({ type: \"TOGGLE_PINNED\", itemId: itemUniqueId }),\n toggleHidden: () => dispatch({ type: \"TOGGLE_HIDDEN\", itemId: itemUniqueId }),\n movePinnedUp: () => dispatch({ type: \"MOVE_PINNED_UP\", itemId: itemUniqueId }),\n },\n };\n}\n/**\n * Hook to determine if a section is empty (has no visible items).\n * Derived from accordion state + globally registered items filtered by section prefix.\n *\n * @param sectionId - The section ID to check.\n * @returns Whether the section has no visible items.\n */\nfunction useIsSectionEmpty(sectionId: string): boolean {\n const accordionCtx = useContext(AccordionContext);\n\n if (!accordionCtx) {\n return false;\n }\n\n const { state, features, accordionId, registeredItemIds } = accordionCtx;\n const { pinnedIds, hiddenIds, searchTerm, editMode } = state;\n\n if (editMode) {\n return false;\n }\n\n const sectionPrefix = `${accordionId}/${sectionId}/`;\n let hasItems = false;\n\n for (const [itemId, itemLabel] of registeredItemIds) {\n if (!itemId.startsWith(sectionPrefix)) {\n continue;\n }\n hasItems = true;\n const isPinned = features.pinning && pinnedIds.includes(itemId);\n const isHidden = features.hiding && hiddenIds.includes(itemId);\n const searchText = (itemLabel || itemId).toLowerCase();\n const isMatch = !features.search || !searchTerm || searchText.includes(searchTerm.toLowerCase());\n if (!isPinned && !isHidden && isMatch) {\n return false;\n }\n }\n\n return hasItems;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"accordion.contexts.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.contexts.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { RefObject } from \"react\";\nimport type { AccordionProps, AccordionSectionBlockProps, AccordionSectionItemProps } from \"./accordion\";\nimport { createContext, useContext, useEffect, useMemo, useReducer, useRef } from \"react\";\nimport { DataStorage } from \"core/Misc/dataStorage\";\nimport { Logger } from \"core/Misc/logger\";\n\n// ============================================================================\n// Storage Helpers\n// ============================================================================\n\nconst STORAGE_KEY_ROOT = \"Babylon/Accordion\";\n\nconst ReadFromStorage = <T,>(path: string, initial: T): T => {\n try {\n const stored = DataStorage.ReadString(`${STORAGE_KEY_ROOT}/${path}`, \"\");\n return stored ? JSON.parse(stored) : initial;\n } catch {\n return initial;\n }\n};\n\nconst WriteToStorage = (path: string, data: unknown): void => {\n DataStorage.WriteString(`${STORAGE_KEY_ROOT}/${path}`, JSON.stringify(data));\n};\n\n// ============================================================================\n// State Types\n// ============================================================================\n\n/**\n * Immutable state for the Accordion.\n */\nexport type AccordionState = {\n /** IDs of pinned items (persisted to localStorage). */\n pinnedIds: string[];\n /** IDs of hidden items (persisted to localStorage). */\n hiddenIds: string[];\n /** Current search/filter term. */\n searchTerm: string;\n /** Whether edit mode is active (shows pin/hide controls). */\n editMode: boolean;\n};\n\n/**\n * Actions that can be dispatched to update accordion state.\n */\nexport type AccordionAction =\n | { type: \"SET_SEARCH_TERM\"; term: string }\n | { type: \"SET_EDIT_MODE\"; enabled: boolean }\n | { type: \"TOGGLE_PINNED\"; itemId: string }\n | { type: \"TOGGLE_HIDDEN\"; itemId: string }\n | { type: \"MOVE_PINNED_UP\"; itemId: string }\n | { type: \"REMOVE_STALE_IDS\"; activeIds: Set<string> }\n | { type: \"SHOW_ALL\" }\n | { type: \"HIDE_ALL_VISIBLE\"; visibleItemIds: string[] };\n\n/**\n * Feature flags for the Accordion (immutable after initialization).\n */\nexport type AccordionFeatures = {\n /** Whether pinning is enabled. */\n pinning: boolean;\n /** Whether hiding is enabled. */\n hiding: boolean;\n /** Whether search is enabled. */\n search: boolean;\n};\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\nconst AccordionReducer = (state: AccordionState, action: AccordionAction): AccordionState => {\n switch (action.type) {\n case \"SET_SEARCH_TERM\":\n return { ...state, searchTerm: action.term };\n\n case \"SET_EDIT_MODE\":\n return { ...state, editMode: action.enabled };\n\n case \"TOGGLE_PINNED\": {\n const isPinned = state.pinnedIds.includes(action.itemId);\n return {\n ...state,\n pinnedIds: isPinned ? state.pinnedIds.filter((id) => id !== action.itemId) : [...state.pinnedIds, action.itemId],\n };\n }\n\n case \"TOGGLE_HIDDEN\": {\n const isHidden = state.hiddenIds.includes(action.itemId);\n return {\n ...state,\n hiddenIds: isHidden ? state.hiddenIds.filter((id) => id !== action.itemId) : [...state.hiddenIds, action.itemId],\n };\n }\n\n case \"MOVE_PINNED_UP\": {\n const index = state.pinnedIds.indexOf(action.itemId);\n if (index <= 0) {\n return state;\n }\n const newPinnedIds = [...state.pinnedIds];\n [newPinnedIds[index - 1], newPinnedIds[index]] = [newPinnedIds[index], newPinnedIds[index - 1]];\n return { ...state, pinnedIds: newPinnedIds };\n }\n\n case \"REMOVE_STALE_IDS\": {\n const pinnedIds = state.pinnedIds.filter((id) => action.activeIds.has(id));\n const hiddenIds = state.hiddenIds.filter((id) => action.activeIds.has(id));\n if (pinnedIds.length === state.pinnedIds.length && hiddenIds.length === state.hiddenIds.length) {\n return state;\n }\n return { ...state, pinnedIds, hiddenIds };\n }\n\n case \"SHOW_ALL\":\n return { ...state, hiddenIds: [] };\n\n case \"HIDE_ALL_VISIBLE\":\n return {\n ...state,\n hiddenIds: [...new Set([...state.hiddenIds, ...action.visibleItemIds])],\n };\n\n default:\n return state;\n }\n};\n\n// ============================================================================\n// Accordion Context\n// ============================================================================\n\n/**\n * Context value for the Accordion component.\n */\nexport type AccordionContextValue = {\n /** The unique ID of the Accordion instance. */\n accordionId: string;\n /** State for the Accordion, managed via dispatch function. */\n state: AccordionState;\n /** Dispatch function to update state. */\n dispatch: React.Dispatch<AccordionAction>;\n /** Feature flags. */\n features: AccordionFeatures;\n /** Ref for the pinned items portal container. */\n pinnedContainerRef: RefObject<HTMLDivElement>;\n /** Map of registered item IDs to labels (for duplicate detection and section empty checks). */\n registeredItemIds: Map<string, string>;\n};\n\nexport const AccordionContext = createContext<AccordionContextValue | undefined>(undefined);\n\n/**\n * Hook to create and manage the AccordionContext value.\n *\n * @param props - AccordionProps\n * @returns AccordionContextValue, or undefined if no features are enabled or no uniqueId is provided.\n */\nexport function useAccordionContext(props: AccordionProps): AccordionContextValue | undefined {\n const { uniqueId: accordionId, enablePinnedItems, enableHiddenItems, enableSearchItems } = props;\n\n const features: AccordionFeatures = useMemo(\n () => ({\n pinning: enablePinnedItems ?? false,\n hiding: enableHiddenItems ?? false,\n search: enableSearchItems ?? false,\n }),\n [enablePinnedItems, enableHiddenItems, enableSearchItems]\n );\n\n const hasFeatures = features.pinning || features.hiding || features.search;\n\n // Initialize state from localStorage\n const initialState = useMemo((): AccordionState => {\n if (!accordionId || !hasFeatures) {\n return { pinnedIds: [], hiddenIds: [], searchTerm: \"\", editMode: false };\n }\n return {\n pinnedIds: features.pinning ? ReadFromStorage<string[]>(`Pinned/${accordionId}`, []) : [],\n hiddenIds: features.hiding ? ReadFromStorage<string[]>(`Hidden/${accordionId}`, []) : [],\n searchTerm: \"\",\n editMode: false,\n };\n }, [accordionId, hasFeatures, features.pinning, features.hiding]);\n\n const [state, dispatch] = useReducer(AccordionReducer, initialState);\n\n const pinnedContainerRef = useRef<HTMLDivElement>(null);\n const registeredItemIds = useRef<Map<string, string>>(new Map());\n\n // Persist pinnedIds to localStorage when they change\n useEffect(() => {\n if (accordionId && features.pinning) {\n WriteToStorage(`Pinned/${accordionId}`, state.pinnedIds);\n }\n }, [accordionId, features.pinning, state.pinnedIds]);\n\n // Persist hiddenIds to localStorage when they change\n useEffect(() => {\n if (accordionId && features.hiding) {\n WriteToStorage(`Hidden/${accordionId}`, state.hiddenIds);\n }\n }, [accordionId, features.hiding, state.hiddenIds]);\n\n // Clean stale IDs from localStorage on mount. Parent effects run after\n // children's, so all items will have registered by the time this fires.\n useEffect(() => {\n if (accordionId && hasFeatures) {\n dispatch({ type: \"REMOVE_STALE_IDS\", activeIds: new Set(registeredItemIds.current.keys()) });\n }\n }, [accordionId, hasFeatures]);\n\n // Return undefined if no accordionId or no features enabled\n if (!accordionId || !hasFeatures) {\n return undefined;\n }\n\n return {\n accordionId,\n state,\n dispatch,\n features,\n pinnedContainerRef,\n registeredItemIds: registeredItemIds.current,\n };\n}\n\n// ============================================================================\n// Section Context\n// ============================================================================\n\n/**\n * Context value for an AccordionSectionBlock.\n */\nexport type AccordionSectionBlockContextValue = {\n /** The section ID. */\n sectionId: string;\n};\n\nexport const AccordionSectionBlockContext = createContext<AccordionSectionBlockContextValue | undefined>(undefined);\n\n/**\n * Hook to create the AccordionSectionBlockContext value.\n *\n * @param props - AccordionSectionBlockProps\n * @returns AccordionSectionBlockContextValue and isEmpty state\n */\nexport function useAccordionSectionBlockContext(props: AccordionSectionBlockProps): {\n context: AccordionSectionBlockContextValue;\n isEmpty: boolean;\n} {\n const { sectionId } = props;\n const context = useMemo(() => ({ sectionId }), [sectionId]);\n const isEmpty = useIsSectionEmpty(sectionId);\n\n return { context, isEmpty };\n}\n\n// ============================================================================\n// Item Depth Context (to detect nested AccordionSectionItems)\n// ============================================================================\n\n/**\n * Context to track whether we're inside an AccordionSectionItem.\n * Used to prevent nested items from being individually manageable.\n */\nexport const AccordionItemDepthContext = createContext<boolean>(false);\n\n// ============================================================================\n// Item Context Hook\n// ============================================================================\n\n/**\n * Derived item state, computed from the accordion state during render.\n */\nexport type AccordionItemState = {\n /** The globally unique item ID. */\n itemUniqueId: string;\n /** Whether this item is nested inside another AccordionSectionItem. */\n isNested: boolean;\n /** Whether this item is pinned. */\n isPinned: boolean;\n /** Whether this item is hidden. */\n isHidden: boolean;\n /** Whether this item matches the current search term. */\n isMatch: boolean;\n /** The index of this item in the pinned list (for ordering). */\n pinnedIndex: number;\n /** Whether this pinned item can be moved up (is not first in the pinned list). */\n canMoveUp: boolean;\n /** Whether edit mode is active. */\n inEditMode: boolean;\n /** Callbacks to modify state. */\n actions: {\n togglePinned: () => void;\n toggleHidden: () => void;\n movePinnedUp: () => void;\n };\n};\n\n/**\n * Hook to compute item state from accordion context.\n *\n * @param props - AccordionSectionItemProps\n * @returns AccordionItemState, or undefined if no accordion context or nested item.\n */\nexport function useAccordionSectionItemState(props: AccordionSectionItemProps): AccordionItemState | undefined {\n const { uniqueId: itemId, label: itemLabel, staticItem } = props;\n\n const accordionCtx = useContext(AccordionContext);\n const sectionCtx = useContext(AccordionSectionBlockContext);\n const isNested = useContext(AccordionItemDepthContext);\n\n // Build the globally unique item ID\n const itemUniqueId = useMemo(() => {\n if (!accordionCtx || !sectionCtx) {\n return \"\";\n }\n return `${accordionCtx.accordionId}/${sectionCtx.sectionId}/${itemId}`;\n }, [accordionCtx?.accordionId, sectionCtx?.sectionId, itemId]);\n\n // Debug: warn if itemId changes (should be stable)\n const prevItemIdRef = useRef(itemId);\n useEffect(() => {\n if (prevItemIdRef.current !== itemId) {\n Logger.Warn(\n `Accordion: The uniqueId \"${itemId}\" in section \"${sectionCtx?.sectionId}\" has changed from \"${prevItemIdRef.current}\". ` +\n `Each item must have a unique, stable ID for pin/hide persistence to work correctly.`\n );\n }\n prevItemIdRef.current = itemId;\n }, [itemId, sectionCtx?.sectionId]);\n\n // Register item and detect duplicates (skip nested items, as children of other AccordionSectionItem should not participate in pin/hide/search).\n useEffect(() => {\n if (!accordionCtx || !itemUniqueId || isNested) {\n return;\n }\n const { registeredItemIds } = accordionCtx;\n if (registeredItemIds.has(itemUniqueId)) {\n Logger.Warn(\n `Accordion: Duplicate uniqueId \"${itemId}\" detected in section \"${sectionCtx?.sectionId}\". ` +\n `Each item must have a unique ID within its section for pin/hide persistence to work correctly.`\n );\n }\n registeredItemIds.set(itemUniqueId, itemLabel ?? itemId);\n return () => {\n registeredItemIds.delete(itemUniqueId);\n };\n }, [accordionCtx, itemUniqueId, itemId, itemLabel, sectionCtx?.sectionId, isNested]);\n\n // If no context, static item, or nested, return undefined\n if (!accordionCtx || staticItem) {\n return undefined;\n }\n\n const { state, dispatch, features } = accordionCtx;\n const { pinnedIds, hiddenIds, searchTerm, editMode } = state;\n\n // Compute derived state\n const isPinned = features.pinning && pinnedIds.includes(itemUniqueId);\n const isHidden = features.hiding && hiddenIds.includes(itemUniqueId);\n const pinnedIndex = isPinned ? pinnedIds.indexOf(itemUniqueId) : -1;\n\n const canMoveUp = isPinned && pinnedIndex > 0;\n\n // Search matching\n const searchText = (itemLabel ?? itemId).toLowerCase();\n const isMatch = !features.search || !searchTerm || searchText.includes(searchTerm.toLowerCase());\n\n return {\n itemUniqueId,\n isNested,\n isPinned,\n isHidden,\n isMatch,\n pinnedIndex,\n canMoveUp,\n inEditMode: editMode,\n actions: {\n togglePinned: () => dispatch({ type: \"TOGGLE_PINNED\", itemId: itemUniqueId }),\n toggleHidden: () => dispatch({ type: \"TOGGLE_HIDDEN\", itemId: itemUniqueId }),\n movePinnedUp: () => dispatch({ type: \"MOVE_PINNED_UP\", itemId: itemUniqueId }),\n },\n };\n}\n/**\n * Hook to determine if a section is empty (has no visible items).\n * Derived from accordion state + globally registered items filtered by section prefix.\n *\n * @param sectionId - The section ID to check.\n * @returns Whether the section has no visible items.\n */\nfunction useIsSectionEmpty(sectionId: string): boolean {\n const accordionCtx = useContext(AccordionContext);\n\n if (!accordionCtx) {\n return false;\n }\n\n const { state, features, accordionId, registeredItemIds } = accordionCtx;\n const { pinnedIds, hiddenIds, searchTerm, editMode } = state;\n\n if (editMode) {\n return false;\n }\n\n const sectionPrefix = `${accordionId}/${sectionId}/`;\n let hasItems = false;\n\n for (const [itemId, itemLabel] of registeredItemIds) {\n if (!itemId.startsWith(sectionPrefix)) {\n continue;\n }\n hasItems = true;\n const isPinned = features.pinning && pinnedIds.includes(itemId);\n const isHidden = features.hiding && hiddenIds.includes(itemId);\n const searchText = (itemLabel || itemId).toLowerCase();\n const isMatch = !features.search || !searchTerm || searchText.includes(searchTerm.toLowerCase());\n if (!isPinned && !isHidden && isMatch) {\n return false;\n }\n }\n\n return hasItems;\n}\n"]}
|
|
@@ -146,6 +146,11 @@ export const AccordionSectionItem = (props) => {
|
|
|
146
146
|
useEffect(() => {
|
|
147
147
|
setCtrlMode(ctrlPressed && mouseOver);
|
|
148
148
|
}, [ctrlPressed, mouseOver]);
|
|
149
|
+
// Override disableCopy so copy buttons appear when ctrl+hovering on this item or when edit mode is active
|
|
150
|
+
const parentToolContext = useContext(ToolContext);
|
|
151
|
+
const editMode = accordionCtx?.state.editMode ?? false;
|
|
152
|
+
const showCopy = ctrlMode || editMode;
|
|
153
|
+
const itemToolContext = useMemo(() => (showCopy ? { ...parentToolContext, disableCopy: false } : parentToolContext), [parentToolContext, showCopy]);
|
|
149
154
|
// If static item or no context, just render children
|
|
150
155
|
if (staticItem || !accordionCtx || !itemState) {
|
|
151
156
|
return _jsx(_Fragment, { children: children });
|
|
@@ -162,7 +167,7 @@ export const AccordionSectionItem = (props) => {
|
|
|
162
167
|
}
|
|
163
168
|
const pinnedContainer = isPinned ? pinnedContainerRef.current : null;
|
|
164
169
|
const showControls = inEditMode || ctrlMode;
|
|
165
|
-
const itemElement = (_jsxs("div", { className: classes.sectionItemContainer, style: isPinned ? { order: pinnedIndex } : undefined, onMouseMove: () => setMouseOver(true), onMouseLeave: () => setMouseOver(false), children: [showControls && (_jsxs("div", { className: classes.sectionItemButtons, children: [features.hiding && (_jsx(Button, { title: isHidden ? "Unhide" : "Hide", icon: isHidden ? EyeOffRegular : EyeFilled, appearance: "transparent", onClick: actions.toggleHidden })), features.pinning && (_jsxs(_Fragment, { children: [_jsx(Button, { title: isPinned ? "Unpin" : "Pin", icon: isPinned ? PinFilled : PinRegular, appearance: "transparent", onClick: actions.togglePinned }), isPinned && _jsx(Button, { icon: ArrowCircleUpRegular, appearance: "transparent", disabled: !canMoveUp, onClick: actions.movePinnedUp })] }))] })), _jsx(AccordionItemDepthContext.Provider, { value: true, children: _jsx("div", { className: classes.sectionItemContent, children: children }) })] }));
|
|
170
|
+
const itemElement = (_jsx(ToolContext.Provider, { value: itemToolContext, children: _jsxs("div", { className: classes.sectionItemContainer, style: isPinned ? { order: pinnedIndex } : undefined, onMouseMove: () => setMouseOver(true), onMouseLeave: () => setMouseOver(false), children: [showControls && (_jsxs("div", { className: classes.sectionItemButtons, children: [features.hiding && (_jsx(Button, { title: isHidden ? "Unhide" : "Hide", icon: isHidden ? EyeOffRegular : EyeFilled, appearance: "transparent", onClick: actions.toggleHidden })), features.pinning && (_jsxs(_Fragment, { children: [_jsx(Button, { title: isPinned ? "Unpin" : "Pin", icon: isPinned ? PinFilled : PinRegular, appearance: "transparent", onClick: actions.togglePinned }), isPinned && _jsx(Button, { icon: ArrowCircleUpRegular, appearance: "transparent", disabled: !canMoveUp, onClick: actions.movePinnedUp })] }))] })), _jsx(AccordionItemDepthContext.Provider, { value: true, children: _jsx("div", { className: classes.sectionItemContent, children: children }) })] }) }));
|
|
166
171
|
return pinnedContainer ? _jsx(Portal, { mountNode: pinnedContainer, children: itemElement }) : itemElement;
|
|
167
172
|
};
|
|
168
173
|
/**
|
|
@@ -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 { AccordionPanelProps, AccordionToggleData, AccordionToggleEvent, AccordionProps as FluentAccordionProps } from \"@fluentui/react-components\";\r\nimport type { ForwardRefExoticComponent, FunctionComponent, PropsWithChildren, RefAttributes } from \"react\";\r\n\r\nimport {\r\n AccordionHeader,\r\n AccordionItem,\r\n AccordionPanel,\r\n Divider,\r\n Accordion as FluentAccordion,\r\n MessageBar,\r\n MessageBarBody,\r\n Portal,\r\n SearchBox,\r\n Subtitle2Stronger,\r\n makeStyles,\r\n tokens,\r\n} from \"@fluentui/react-components\";\r\nimport { ArrowCircleUpRegular, CheckmarkFilled, EditRegular, EyeFilled, EyeOffRegular, FilterRegular, PinFilled, PinRegular } from \"@fluentui/react-icons\";\r\nimport { Children, forwardRef, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { useKeyState } from \"../hooks/keyboardHooks\";\r\nimport {\r\n AccordionContext,\r\n AccordionItemDepthContext,\r\n AccordionSectionBlockContext,\r\n useAccordionContext,\r\n useAccordionSectionBlockContext,\r\n useAccordionSectionItemState,\r\n} from \"./accordion.contexts\";\r\nimport { Button } from \"./button\";\r\nimport { CustomTokens } from \"./utils\";\r\n\r\nconst useStyles = makeStyles({\r\n accordion: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n },\r\n accordionBody: {\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 },\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 menuBar: {\r\n display: \"flex\",\r\n },\r\n menuBarControls: {\r\n display: \"flex\",\r\n flexGrow: 1,\r\n justifyContent: \"end\",\r\n },\r\n sectionItemContainer: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n },\r\n sectionItemContent: {\r\n flexGrow: 1,\r\n minWidth: 0, // Allow content to shrink below its intrinsic width when buttons are shown\r\n overflow: \"hidden\",\r\n },\r\n sectionItemButtons: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n marginRight: tokens.spacingHorizontalXS,\r\n },\r\n pinnedContainer: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n },\r\n pinnedContainerEmpty: {\r\n \"&:not(:only-child)\": {\r\n display: \"none\",\r\n },\r\n },\r\n searchBox: {\r\n width: \"100%\",\r\n },\r\n});\r\n\r\n/**\r\n * Renders the menu bar and control buttons.\r\n *\r\n * @returns `div`, or `undefined` if all features are disabled.\r\n */\r\nconst AccordionMenuBar: FunctionComponent = () => {\r\n AccordionMenuBar.displayName = \"AccordionMenuBar\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n if (!accordionCtx) {\r\n return null;\r\n }\r\n\r\n const { state, dispatch, features } = accordionCtx;\r\n const { editMode } = state;\r\n\r\n return (\r\n <div className={classes.menuBar}>\r\n <AccordionSearchBox />\r\n <div className={classes.menuBarControls}>\r\n {features.hiding && editMode && (\r\n <>\r\n <Button title=\"Show all\" icon={EyeFilled} appearance=\"subtle\" onClick={() => dispatch({ type: \"SHOW_ALL\" })} />\r\n <Button\r\n title=\"Hide all\"\r\n icon={EyeOffRegular}\r\n appearance=\"subtle\"\r\n onClick={() => {\r\n // Hide all visible (non-hidden) items using the registered item IDs\r\n const { registeredItemIds, state: currentState } = accordionCtx;\r\n const visibleItemIds = Array.from(registeredItemIds.keys()).filter((id) => !currentState.hiddenIds.includes(id));\r\n dispatch({ type: \"HIDE_ALL_VISIBLE\", visibleItemIds });\r\n }}\r\n />\r\n </>\r\n )}\r\n {(features.pinning || features.hiding) && (\r\n <Button\r\n title=\"Edit mode\"\r\n icon={editMode ? CheckmarkFilled : EditRegular}\r\n appearance={editMode ? \"primary\" : \"subtle\"}\r\n onClick={() => dispatch({ type: \"SET_EDIT_MODE\", enabled: !editMode })}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Props: `AccordionSectionBlock`.\r\n */\r\nexport type AccordionSectionBlockProps = {\r\n /** The ID of the `AccordionSectionBlock`, unique within the `Accordion` instance. */\r\n sectionId: string;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate the section headers and panels.\r\n * - Stores the section ID for use in `AccordionSectionItem`.\r\n *\r\n * @param props - `AccordionSectionBlockProps`\r\n * @returns `AccordionSectionBlockContext.Provider`, or `AccordionItem` if all features are disabled.\r\n */\r\nconst AccordionSectionBlock: FunctionComponent<PropsWithChildren<AccordionSectionBlockProps>> = (props) => {\r\n AccordionSectionBlock.displayName = \"AccordionSectionBlock\";\r\n const { children, sectionId } = props;\r\n const accordionCtx = useContext(AccordionContext);\r\n const { context: sectionContext, isEmpty } = useAccordionSectionBlockContext(props);\r\n\r\n if (accordionCtx) {\r\n return (\r\n <AccordionSectionBlockContext.Provider value={sectionContext}>\r\n {!isEmpty && <AccordionItem value={sectionId}>{children}</AccordionItem>}\r\n </AccordionSectionBlockContext.Provider>\r\n );\r\n }\r\n\r\n return <AccordionItem value={sectionId}>{children}</AccordionItem>;\r\n};\r\n\r\n/**\r\n * Props: `AccordionSectionItem`.\r\n */\r\nexport type AccordionSectionItemProps = {\r\n /** The ID of the `AccordionSectionItem`, unique within the `AccordionSectionBlock` instance. */\r\n uniqueId: string;\r\n /** The searchable text label for the item. */\r\n label?: string;\r\n /** Whether the item is not interactable. */\r\n staticItem?: boolean;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate individual items.\r\n * - Renders the pin button and tracks the pinned state of the item.\r\n * - Renders the hide button and tracks the hidden state of the item.\r\n * - Filters items based on the current search term.\r\n *\r\n * @param props - `AccordionSectionItemProps`\r\n * @returns `Portal` if pinned; `null` if hidden/filtered; `children` otherwise.\r\n */\r\nexport const AccordionSectionItem: FunctionComponent<PropsWithChildren<AccordionSectionItemProps>> = (props) => {\r\n AccordionSectionItem.displayName = \"AccordionSectionItem\";\r\n const { children, staticItem } = props;\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n const itemState = useAccordionSectionItemState(props);\r\n const [ctrlMode, setCtrlMode] = useState(false);\r\n const ctrlPressed = useKeyState(\"Control\");\r\n const [mouseOver, setMouseOver] = useState(false);\r\n\r\n useEffect(() => {\r\n setCtrlMode(ctrlPressed && mouseOver);\r\n }, [ctrlPressed, mouseOver]);\r\n\r\n // If static item or no context, just render children\r\n if (staticItem || !accordionCtx || !itemState) {\r\n return <>{children}</>;\r\n }\r\n\r\n const { pinnedContainerRef, features } = accordionCtx;\r\n const { isNested, isPinned, isHidden, isMatch, pinnedIndex, canMoveUp, inEditMode, actions } = itemState;\r\n\r\n // Nested items just render children (don't show controls)\r\n if (isNested) {\r\n return <>{children}</>;\r\n }\r\n\r\n // If hidden (and not in edit mode) or doesn't match search, don't render\r\n if ((isHidden && !inEditMode) || !isMatch) {\r\n return null;\r\n }\r\n\r\n const pinnedContainer = isPinned ? pinnedContainerRef.current : null;\r\n const showControls = inEditMode || ctrlMode;\r\n\r\n const itemElement = (\r\n <div\r\n className={classes.sectionItemContainer}\r\n style={isPinned ? { order: pinnedIndex } : undefined}\r\n onMouseMove={() => setMouseOver(true)}\r\n onMouseLeave={() => setMouseOver(false)}\r\n >\r\n {showControls && (\r\n <div className={classes.sectionItemButtons}>\r\n {features.hiding && (\r\n <Button title={isHidden ? \"Unhide\" : \"Hide\"} icon={isHidden ? EyeOffRegular : EyeFilled} appearance=\"transparent\" onClick={actions.toggleHidden} />\r\n )}\r\n {features.pinning && (\r\n <>\r\n <Button title={isPinned ? \"Unpin\" : \"Pin\"} icon={isPinned ? PinFilled : PinRegular} appearance=\"transparent\" onClick={actions.togglePinned} />\r\n {isPinned && <Button icon={ArrowCircleUpRegular} appearance=\"transparent\" disabled={!canMoveUp} onClick={actions.movePinnedUp} />}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n <AccordionItemDepthContext.Provider value={true}>\r\n <div className={classes.sectionItemContent}>{children}</div>\r\n </AccordionItemDepthContext.Provider>\r\n </div>\r\n );\r\n\r\n return pinnedContainer ? <Portal mountNode={pinnedContainer}>{itemElement}</Portal> : itemElement;\r\n};\r\n\r\n/**\r\n * Renders the Pinned section container and defines the portal target for the pinned items.\r\n *\r\n * @returns `div`\r\n */\r\nconst AccordionPinnedContainer: FunctionComponent = () => {\r\n AccordionPinnedContainer.displayName = \"AccordionPinnedContainer\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n return (\r\n <div ref={accordionCtx?.pinnedContainerRef} className={classes.pinnedContainer}>\r\n <MessageBar className={classes.pinnedContainerEmpty}>\r\n <MessageBarBody>No pinned items</MessageBarBody>\r\n </MessageBar>\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Renders the search box for filtering items.\r\n *\r\n * @returns `SearchBox`, or `null` if the feature is disabled.\r\n */\r\nconst AccordionSearchBox: FunctionComponent = () => {\r\n AccordionSearchBox.displayName = \"AccordionSearchBox\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n if (!accordionCtx?.features.search) {\r\n return null;\r\n }\r\n\r\n const { state, dispatch } = accordionCtx;\r\n\r\n return (\r\n <SearchBox\r\n className={classes.searchBox}\r\n appearance=\"underline\"\r\n contentBefore={<FilterRegular />}\r\n placeholder=\"Filter\"\r\n value={state.searchTerm}\r\n onChange={(_, data) => dispatch({ type: \"SET_SEARCH_TERM\", term: data.value })}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * Props: `AccordionSection`.\r\n */\r\nexport type AccordionSectionProps = {\r\n /** The text label shown in the section header. */\r\n title: string;\r\n /** Indicates whether the `AccordionSection` is initially collapsed. */\r\n collapseByDefault?: boolean;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate the section body.\r\n *\r\n * @param props - `AccordionSectionProps`\r\n * @returns `div`\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\n/**\r\n * Props: `Accordion`.\r\n */\r\nexport type AccordionProps = {\r\n /** The unique ID of the `Accordion` instance. */\r\n uniqueId?: string;\r\n /** The list of sections to be highlighted. */\r\n highlightSections?: readonly string[];\r\n /** Enables the pinned items feature. */\r\n enablePinnedItems?: boolean;\r\n /** Enables the hidden items feature. */\r\n enableHiddenItems?: boolean;\r\n /** Enables the search items feature. */\r\n enableSearchItems?: boolean;\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 { children, highlightSections, ...rest } = props;\r\n const classes = useStyles();\r\n const { size } = useContext(ToolContext);\r\n const accordionCtx = useAccordionContext(props);\r\n const hasPinning = accordionCtx?.features.pinning ?? false;\r\n\r\n const pinnedSectionElement = useMemo(() => {\r\n return (\r\n hasPinning && (\r\n <AccordionSection title=\"Pinned\" collapseByDefault={false}>\r\n <AccordionPinnedContainer />\r\n </AccordionSection>\r\n )\r\n );\r\n }, [hasPinning]);\r\n\r\n // Prevents sections contents from unmounting when closed, allowing their elements to be used in the Pinned section.\r\n const preventUnmountMotion: AccordionPanelProps[\"collapseMotion\"] = useMemo(() => {\r\n // https://github.com/microsoft/fluentui/issues/34309#issuecomment-2824364945\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n return hasPinning ? { children: (Component, props) => <Component {...props} unmountOnExit={false} /> } : undefined;\r\n }, [hasPinning]);\r\n\r\n const validChildren = useMemo(() => {\r\n return (\r\n Children.map([pinnedSectionElement, 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 <AccordionContext.Provider value={accordionCtx}>\r\n <AccordionMenuBar />\r\n <div className={classes.accordionBody}>\r\n {validChildren.map((child, index) => {\r\n const isHighlighted = highlightSections?.includes(child.title);\r\n return (\r\n <AccordionSectionBlock key={child.content.key ?? child.title} sectionId={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 collapseMotion={preventUnmountMotion}>\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 </AccordionSectionBlock>\r\n );\r\n })}\r\n </div>\r\n </AccordionContext.Provider>\r\n </StringAccordion>\r\n );\r\n});\r\n"]}
|
|
1
|
+
{"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/accordion.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { AccordionPanelProps, AccordionToggleData, AccordionToggleEvent, AccordionProps as FluentAccordionProps } from \"@fluentui/react-components\";\r\nimport type { ForwardRefExoticComponent, FunctionComponent, PropsWithChildren, RefAttributes } from \"react\";\r\n\r\nimport {\r\n AccordionHeader,\r\n AccordionItem,\r\n AccordionPanel,\r\n Divider,\r\n Accordion as FluentAccordion,\r\n MessageBar,\r\n MessageBarBody,\r\n Portal,\r\n SearchBox,\r\n Subtitle2Stronger,\r\n makeStyles,\r\n tokens,\r\n} from \"@fluentui/react-components\";\r\nimport { ArrowCircleUpRegular, CheckmarkFilled, EditRegular, EyeFilled, EyeOffRegular, FilterRegular, PinFilled, PinRegular } from \"@fluentui/react-icons\";\r\nimport { Children, forwardRef, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { useKeyState } from \"../hooks/keyboardHooks\";\r\nimport {\r\n AccordionContext,\r\n AccordionItemDepthContext,\r\n AccordionSectionBlockContext,\r\n useAccordionContext,\r\n useAccordionSectionBlockContext,\r\n useAccordionSectionItemState,\r\n} from \"./accordion.contexts\";\r\nimport { Button } from \"./button\";\r\nimport { CustomTokens } from \"./utils\";\r\n\r\nconst useStyles = makeStyles({\r\n accordion: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n },\r\n accordionBody: {\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 },\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 menuBar: {\r\n display: \"flex\",\r\n },\r\n menuBarControls: {\r\n display: \"flex\",\r\n flexGrow: 1,\r\n justifyContent: \"end\",\r\n },\r\n sectionItemContainer: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n },\r\n sectionItemContent: {\r\n flexGrow: 1,\r\n minWidth: 0, // Allow content to shrink below its intrinsic width when buttons are shown\r\n overflow: \"hidden\",\r\n },\r\n sectionItemButtons: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n marginRight: tokens.spacingHorizontalXS,\r\n },\r\n pinnedContainer: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n },\r\n pinnedContainerEmpty: {\r\n \"&:not(:only-child)\": {\r\n display: \"none\",\r\n },\r\n },\r\n searchBox: {\r\n width: \"100%\",\r\n },\r\n});\r\n\r\n/**\r\n * Renders the menu bar and control buttons.\r\n *\r\n * @returns `div`, or `undefined` if all features are disabled.\r\n */\r\nconst AccordionMenuBar: FunctionComponent = () => {\r\n AccordionMenuBar.displayName = \"AccordionMenuBar\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n if (!accordionCtx) {\r\n return null;\r\n }\r\n\r\n const { state, dispatch, features } = accordionCtx;\r\n const { editMode } = state;\r\n\r\n return (\r\n <div className={classes.menuBar}>\r\n <AccordionSearchBox />\r\n <div className={classes.menuBarControls}>\r\n {features.hiding && editMode && (\r\n <>\r\n <Button title=\"Show all\" icon={EyeFilled} appearance=\"subtle\" onClick={() => dispatch({ type: \"SHOW_ALL\" })} />\r\n <Button\r\n title=\"Hide all\"\r\n icon={EyeOffRegular}\r\n appearance=\"subtle\"\r\n onClick={() => {\r\n // Hide all visible (non-hidden) items using the registered item IDs\r\n const { registeredItemIds, state: currentState } = accordionCtx;\r\n const visibleItemIds = Array.from(registeredItemIds.keys()).filter((id) => !currentState.hiddenIds.includes(id));\r\n dispatch({ type: \"HIDE_ALL_VISIBLE\", visibleItemIds });\r\n }}\r\n />\r\n </>\r\n )}\r\n {(features.pinning || features.hiding) && (\r\n <Button\r\n title=\"Edit mode\"\r\n icon={editMode ? CheckmarkFilled : EditRegular}\r\n appearance={editMode ? \"primary\" : \"subtle\"}\r\n onClick={() => dispatch({ type: \"SET_EDIT_MODE\", enabled: !editMode })}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Props: `AccordionSectionBlock`.\r\n */\r\nexport type AccordionSectionBlockProps = {\r\n /** The ID of the `AccordionSectionBlock`, unique within the `Accordion` instance. */\r\n sectionId: string;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate the section headers and panels.\r\n * - Stores the section ID for use in `AccordionSectionItem`.\r\n *\r\n * @param props - `AccordionSectionBlockProps`\r\n * @returns `AccordionSectionBlockContext.Provider`, or `AccordionItem` if all features are disabled.\r\n */\r\nconst AccordionSectionBlock: FunctionComponent<PropsWithChildren<AccordionSectionBlockProps>> = (props) => {\r\n AccordionSectionBlock.displayName = \"AccordionSectionBlock\";\r\n const { children, sectionId } = props;\r\n const accordionCtx = useContext(AccordionContext);\r\n const { context: sectionContext, isEmpty } = useAccordionSectionBlockContext(props);\r\n\r\n if (accordionCtx) {\r\n return (\r\n <AccordionSectionBlockContext.Provider value={sectionContext}>\r\n {!isEmpty && <AccordionItem value={sectionId}>{children}</AccordionItem>}\r\n </AccordionSectionBlockContext.Provider>\r\n );\r\n }\r\n\r\n return <AccordionItem value={sectionId}>{children}</AccordionItem>;\r\n};\r\n\r\n/**\r\n * Props: `AccordionSectionItem`.\r\n */\r\nexport type AccordionSectionItemProps = {\r\n /** The ID of the `AccordionSectionItem`, unique within the `AccordionSectionBlock` instance. */\r\n uniqueId: string;\r\n /** The searchable text label for the item. */\r\n label?: string;\r\n /** Whether the item is not interactable. */\r\n staticItem?: boolean;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate individual items.\r\n * - Renders the pin button and tracks the pinned state of the item.\r\n * - Renders the hide button and tracks the hidden state of the item.\r\n * - Filters items based on the current search term.\r\n *\r\n * @param props - `AccordionSectionItemProps`\r\n * @returns `Portal` if pinned; `null` if hidden/filtered; `children` otherwise.\r\n */\r\nexport const AccordionSectionItem: FunctionComponent<PropsWithChildren<AccordionSectionItemProps>> = (props) => {\r\n AccordionSectionItem.displayName = \"AccordionSectionItem\";\r\n const { children, staticItem } = props;\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n const itemState = useAccordionSectionItemState(props);\r\n const [ctrlMode, setCtrlMode] = useState(false);\r\n const ctrlPressed = useKeyState(\"Control\");\r\n const [mouseOver, setMouseOver] = useState(false);\r\n\r\n useEffect(() => {\r\n setCtrlMode(ctrlPressed && mouseOver);\r\n }, [ctrlPressed, mouseOver]);\r\n\r\n // Override disableCopy so copy buttons appear when ctrl+hovering on this item or when edit mode is active\r\n const parentToolContext = useContext(ToolContext);\r\n const editMode = accordionCtx?.state.editMode ?? false;\r\n const showCopy = ctrlMode || editMode;\r\n const itemToolContext = useMemo(() => (showCopy ? { ...parentToolContext, disableCopy: false } : parentToolContext), [parentToolContext, showCopy]);\r\n\r\n // If static item or no context, just render children\r\n if (staticItem || !accordionCtx || !itemState) {\r\n return <>{children}</>;\r\n }\r\n\r\n const { pinnedContainerRef, features } = accordionCtx;\r\n const { isNested, isPinned, isHidden, isMatch, pinnedIndex, canMoveUp, inEditMode, actions } = itemState;\r\n\r\n // Nested items just render children (don't show controls)\r\n if (isNested) {\r\n return <>{children}</>;\r\n }\r\n\r\n // If hidden (and not in edit mode) or doesn't match search, don't render\r\n if ((isHidden && !inEditMode) || !isMatch) {\r\n return null;\r\n }\r\n\r\n const pinnedContainer = isPinned ? pinnedContainerRef.current : null;\r\n const showControls = inEditMode || ctrlMode;\r\n\r\n const itemElement = (\r\n <ToolContext.Provider value={itemToolContext}>\r\n <div\r\n className={classes.sectionItemContainer}\r\n style={isPinned ? { order: pinnedIndex } : undefined}\r\n onMouseMove={() => setMouseOver(true)}\r\n onMouseLeave={() => setMouseOver(false)}\r\n >\r\n {showControls && (\r\n <div className={classes.sectionItemButtons}>\r\n {features.hiding && (\r\n <Button title={isHidden ? \"Unhide\" : \"Hide\"} icon={isHidden ? EyeOffRegular : EyeFilled} appearance=\"transparent\" onClick={actions.toggleHidden} />\r\n )}\r\n {features.pinning && (\r\n <>\r\n <Button title={isPinned ? \"Unpin\" : \"Pin\"} icon={isPinned ? PinFilled : PinRegular} appearance=\"transparent\" onClick={actions.togglePinned} />\r\n {isPinned && <Button icon={ArrowCircleUpRegular} appearance=\"transparent\" disabled={!canMoveUp} onClick={actions.movePinnedUp} />}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n <AccordionItemDepthContext.Provider value={true}>\r\n <div className={classes.sectionItemContent}>{children}</div>\r\n </AccordionItemDepthContext.Provider>\r\n </div>\r\n </ToolContext.Provider>\r\n );\r\n\r\n return pinnedContainer ? <Portal mountNode={pinnedContainer}>{itemElement}</Portal> : itemElement;\r\n};\r\n\r\n/**\r\n * Renders the Pinned section container and defines the portal target for the pinned items.\r\n *\r\n * @returns `div`\r\n */\r\nconst AccordionPinnedContainer: FunctionComponent = () => {\r\n AccordionPinnedContainer.displayName = \"AccordionPinnedContainer\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n return (\r\n <div ref={accordionCtx?.pinnedContainerRef} className={classes.pinnedContainer}>\r\n <MessageBar className={classes.pinnedContainerEmpty}>\r\n <MessageBarBody>No pinned items</MessageBarBody>\r\n </MessageBar>\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Renders the search box for filtering items.\r\n *\r\n * @returns `SearchBox`, or `null` if the feature is disabled.\r\n */\r\nconst AccordionSearchBox: FunctionComponent = () => {\r\n AccordionSearchBox.displayName = \"AccordionSearchBox\";\r\n const classes = useStyles();\r\n const accordionCtx = useContext(AccordionContext);\r\n\r\n if (!accordionCtx?.features.search) {\r\n return null;\r\n }\r\n\r\n const { state, dispatch } = accordionCtx;\r\n\r\n return (\r\n <SearchBox\r\n className={classes.searchBox}\r\n appearance=\"underline\"\r\n contentBefore={<FilterRegular />}\r\n placeholder=\"Filter\"\r\n value={state.searchTerm}\r\n onChange={(_, data) => dispatch({ type: \"SET_SEARCH_TERM\", term: data.value })}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * Props: `AccordionSection`.\r\n */\r\nexport type AccordionSectionProps = {\r\n /** The text label shown in the section header. */\r\n title: string;\r\n /** Indicates whether the `AccordionSection` is initially collapsed. */\r\n collapseByDefault?: boolean;\r\n};\r\n\r\n/**\r\n * Wrapper component that must encapsulate the section body.\r\n *\r\n * @param props - `AccordionSectionProps`\r\n * @returns `div`\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\n/**\r\n * Props: `Accordion`.\r\n */\r\nexport type AccordionProps = {\r\n /** The unique ID of the `Accordion` instance. */\r\n uniqueId?: string;\r\n /** The list of sections to be highlighted. */\r\n highlightSections?: readonly string[];\r\n /** Enables the pinned items feature. */\r\n enablePinnedItems?: boolean;\r\n /** Enables the hidden items feature. */\r\n enableHiddenItems?: boolean;\r\n /** Enables the search items feature. */\r\n enableSearchItems?: boolean;\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 { children, highlightSections, ...rest } = props;\r\n const classes = useStyles();\r\n const { size } = useContext(ToolContext);\r\n const accordionCtx = useAccordionContext(props);\r\n const hasPinning = accordionCtx?.features.pinning ?? false;\r\n\r\n const pinnedSectionElement = useMemo(() => {\r\n return (\r\n hasPinning && (\r\n <AccordionSection title=\"Pinned\" collapseByDefault={false}>\r\n <AccordionPinnedContainer />\r\n </AccordionSection>\r\n )\r\n );\r\n }, [hasPinning]);\r\n\r\n // Prevents sections contents from unmounting when closed, allowing their elements to be used in the Pinned section.\r\n const preventUnmountMotion: AccordionPanelProps[\"collapseMotion\"] = useMemo(() => {\r\n // https://github.com/microsoft/fluentui/issues/34309#issuecomment-2824364945\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n return hasPinning ? { children: (Component, props) => <Component {...props} unmountOnExit={false} /> } : undefined;\r\n }, [hasPinning]);\r\n\r\n const validChildren = useMemo(() => {\r\n return (\r\n Children.map([pinnedSectionElement, 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 <AccordionContext.Provider value={accordionCtx}>\r\n <AccordionMenuBar />\r\n <div className={classes.accordionBody}>\r\n {validChildren.map((child, index) => {\r\n const isHighlighted = highlightSections?.includes(child.title);\r\n return (\r\n <AccordionSectionBlock key={child.content.key ?? child.title} sectionId={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 collapseMotion={preventUnmountMotion}>\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 </AccordionSectionBlock>\r\n );\r\n })}\r\n </div>\r\n </AccordionContext.Provider>\r\n </StringAccordion>\r\n );\r\n});\r\n"]}
|