orcs-design-system
Version:
TeamForm's Design System, aka: ORCS
333 lines (328 loc) • 8.68 kB
JavaScript
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { ComponentContainer, PanelBar, PanelBarDivider, PanelContainer } from "./FloatingPanels.styles";
import { Panel, PanelBarIcon } from "./Panel";
import PropTypes from "prop-types";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const FloatingPanels = _ref => {
let {
panels,
containerHeight = "100%",
position = {
right: 0,
top: 0
},
centered = false,
alignPanels = "right",
zIndex = 2,
disablePanelSelect = false,
defaultSelectedPanelId = null,
onClick = () => {},
eventBus = null
} = _ref;
const [selectedPanelId, setSelectedPanelId] = useState(defaultSelectedPanelId);
useEffect(() => {
// create events
const SetSelectedPanel = paneId => {
setSelectedPanelId(paneId);
};
// register event listeners
eventBus?.on("FloatingPanels_SetSelectedPanel", SetSelectedPanel);
// on unmount, deregister event listeners
return () => {
eventBus?.off("FloatingPanels_SetSelectedPanel", SetSelectedPanel);
};
}, [eventBus]);
useEffect(() => {
// external consumers can respond to changes in selected panel if they want
eventBus?.emit("FloatingPanels_SelectedPanelChanged", selectedPanelId);
}, [eventBus, selectedPanelId]);
useEffect(() => {
if (disablePanelSelect) {
return;
}
const selectedPanel = panels.find(panel => panel.selected);
if (selectedPanel?.id && !selectedPanel.noActiveState) {
setSelectedPanelId(selectedPanel.id);
}
}, [disablePanelSelect, panels]);
const togglePanel = useCallback(panelId => {
const selectedPanel = panels.find(panel => panel.id === panelId);
// no panel?
if (!selectedPanel) {
return;
}
onClick(panelId);
if (!disablePanelSelect) {
// panel not already selected?
if (panelId !== selectedPanelId) {
// has content (selectable)?
if (selectedPanel.content) {
// select panel
setSelectedPanelId(panelId);
}
}
// already selected?
else {
// toggle off
setSelectedPanelId(null);
}
}
}, [selectedPanelId, disablePanelSelect, onClick, panels]);
const panelBarItems = useMemo(() => {
const items = [];
let prevPanel = null;
for (const panel of panels) {
// grouping has changed?
if (prevPanel !== null && panel.grouping !== prevPanel.grouping) {
// add divider first
items.push(/*#__PURE__*/_jsx(PanelBarDivider, {}, `${panel.grouping}_${panel.id}`));
}
// add bar item
items.push(/*#__PURE__*/_jsx(PanelBarIcon, {
iconName: panel.iconName,
title: panel.title,
isExpanded: selectedPanelId === panel.id,
forceHighlight: panel.forceHighlight ?? false,
toggleExpanded: () => togglePanel(panel.id)
}, panel?.id));
// update prevPanel
prevPanel = panel;
}
return items;
}, [panels, selectedPanelId, togglePanel]);
return /*#__PURE__*/_jsxs(ComponentContainer, {
centered: centered,
alignPanels: alignPanels,
containerHeight: containerHeight,
position: position,
zIndex: zIndex,
children: [/*#__PURE__*/_jsx(PanelBar, {
children: panelBarItems
}), /*#__PURE__*/_jsx(PanelContainer, {
containerHeight: containerHeight,
children: panels.map(panel => /*#__PURE__*/_jsx(Panel, {
title: panel.title,
iconName: panel.iconName,
content: panel.content,
containerHeight: containerHeight,
isExpanded: selectedPanelId === panel.id,
toggleExpanded: () => togglePanel(panel.id)
}, panel?.id))
})]
});
};
FloatingPanels.propTypes = {
panels: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
iconName: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
content: PropTypes.node.isRequired,
grouping: PropTypes.string,
forceHighlight: PropTypes.bool
})).isRequired,
containerHeight: PropTypes.string,
position: PropTypes.shape({
top: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
right: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
bottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
left: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}),
onClick: PropTypes.func,
centered: PropTypes.bool,
alignPanels: PropTypes.oneOf(["left", "center", "right"]),
zIndex: PropTypes.number,
defaultSelectedPanelId: PropTypes.string,
disablePanelSelect: PropTypes.bool,
eventBus: PropTypes.object
};
FloatingPanels.__docgenInfo = {
"description": "",
"methods": [],
"displayName": "FloatingPanels",
"props": {
"containerHeight": {
"defaultValue": {
"value": "\"100%\"",
"computed": false
},
"description": "",
"type": {
"name": "string"
},
"required": false
},
"position": {
"defaultValue": {
"value": "{ right: 0, top: 0 }",
"computed": false
},
"description": "",
"type": {
"name": "shape",
"value": {
"top": {
"name": "union",
"value": [{
"name": "number"
}, {
"name": "string"
}],
"required": false
},
"right": {
"name": "union",
"value": [{
"name": "number"
}, {
"name": "string"
}],
"required": false
},
"bottom": {
"name": "union",
"value": [{
"name": "number"
}, {
"name": "string"
}],
"required": false
},
"left": {
"name": "union",
"value": [{
"name": "number"
}, {
"name": "string"
}],
"required": false
}
}
},
"required": false
},
"centered": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "",
"type": {
"name": "bool"
},
"required": false
},
"alignPanels": {
"defaultValue": {
"value": "\"right\"",
"computed": false
},
"description": "",
"type": {
"name": "enum",
"value": [{
"value": "\"left\"",
"computed": false
}, {
"value": "\"center\"",
"computed": false
}, {
"value": "\"right\"",
"computed": false
}]
},
"required": false
},
"zIndex": {
"defaultValue": {
"value": "2",
"computed": false
},
"description": "",
"type": {
"name": "number"
},
"required": false
},
"disablePanelSelect": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "",
"type": {
"name": "bool"
},
"required": false
},
"defaultSelectedPanelId": {
"defaultValue": {
"value": "null",
"computed": false
},
"description": "",
"type": {
"name": "string"
},
"required": false
},
"onClick": {
"defaultValue": {
"value": "() => {}",
"computed": false
},
"description": "",
"type": {
"name": "func"
},
"required": false
},
"eventBus": {
"defaultValue": {
"value": "null",
"computed": false
},
"description": "",
"type": {
"name": "object"
},
"required": false
},
"panels": {
"description": "",
"type": {
"name": "arrayOf",
"value": {
"name": "shape",
"value": {
"id": {
"name": "string",
"required": true
},
"iconName": {
"name": "string",
"required": true
},
"title": {
"name": "string",
"required": true
},
"content": {
"name": "node",
"required": true
},
"grouping": {
"name": "string",
"required": false
},
"forceHighlight": {
"name": "bool",
"required": false
}
}
}
},
"required": true
}
}
};
export default FloatingPanels;