communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
66 lines • 4.23 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { merge, Stack } from '@fluentui/react';
import React, { useCallback, useMemo, useState } from 'react';
import { useTheme } from '../../theming/FluentThemeProvider';
import { DrawerMenuItem } from './DrawerMenuItem';
import { _DrawerSurface } from './DrawerSurface';
const isDrawerMenuItem = (item) => {
return item.onRendererContent === undefined;
};
/**
* Takes a set of menu items and returns a created menu inside a {@link _DrawerSurface}.
*
* @internal
*/
export const _DrawerMenu = (props) => {
var _a, _b;
// This component breaks from a pure component pattern in order to internally support sub menus.
// When a sub menu item is clicked the menu items displayed is updated to be that of the submenu.
// To track this state we store a list of the keys clicked up until this point.
const [selectedKeyPath, setSelectedKeyPath] = useState([]);
// Get the menu items that should be rendered
const menuItemsToRender = useMemo(() => {
var _a;
let items = props.items;
for (const subMenuKey of selectedKeyPath) {
items = (_a = items === null || items === void 0 ? void 0 : items.find((item) => isDrawerMenuItem(item) && item.itemKey === subMenuKey)) === null || _a === void 0 ? void 0 : _a.subMenuProps;
}
return items;
}, [props.items, selectedKeyPath]);
// When an item is clicked and it contains a submenu, push the key for the submenu. This will ensure
// a new render is triggered, menuItemsToRender will be re-calculated and the submenu will render.
const onItemClick = useCallback((item, ev, itemKey) => {
var _a;
if (item.subMenuProps) {
setSelectedKeyPath([...selectedKeyPath, item.itemKey]);
}
(_a = item.onItemClick) === null || _a === void 0 ? void 0 : _a.call(item, ev, itemKey);
}, [selectedKeyPath]);
// Ensure the first item has a border radius that matches the DrawerSurface
const borderRadius = useTheme().effects.roundedCorner4;
const firstItemStyle = (menuItemsToRender === null || menuItemsToRender === void 0 ? void 0 : menuItemsToRender[0]) && ((_a = menuItemsToRender[0]) === null || _a === void 0 ? void 0 : _a.styles);
const modifiedFirstItemStyle = useMemo(() => merge(firstItemStyle !== null && firstItemStyle !== void 0 ? firstItemStyle : {}, {
root: {
borderTopRightRadius: borderRadius,
borderTopLeftRadius: borderRadius
}
}), [firstItemStyle, borderRadius]);
return (React.createElement(_DrawerSurface, { disableMaxHeight: props.disableMaxHeight, styles: (_b = props.styles) === null || _b === void 0 ? void 0 : _b.drawerSurfaceStyles, onLightDismiss: props.onLightDismiss, heading: props.heading, "data-ui-id": "drawer-menu" },
React.createElement(Stack, { styles: props.styles, role: "menu", "data-ui-id": "drawer-menu" }, menuItemsToRender === null || menuItemsToRender === void 0 ? void 0 :
menuItemsToRender.slice(0, 1).map((item) => {
var _a;
return isDrawerMenuItem(item) ? (React.createElement(DrawerMenuItem, Object.assign({}, item, { key: `${item.itemKey}` + '0', shouldFocusOnMount: item.itemKey === 'reactions' ? false : true, styles: modifiedFirstItemStyle, onItemClick: item.itemKey === 'reactions'
? undefined
: (ev, itemKey) => {
onItemClick(item, ev, itemKey);
} }))) : ((_a = item.onRendererContent) === null || _a === void 0 ? void 0 : _a.call(item));
}), menuItemsToRender === null || menuItemsToRender === void 0 ? void 0 :
menuItemsToRender.slice(1).map((item, i) => {
var _a;
return isDrawerMenuItem(item) ? (React.createElement(DrawerMenuItem, Object.assign({}, item, { key: `${item.itemKey}` + `${i + 1}`, onItemClick: (ev, itemKey) => {
onItemClick(item, ev, itemKey);
} }))) : ((_a = item.onRendererContent) === null || _a === void 0 ? void 0 : _a.call(item));
}))));
};
//# sourceMappingURL=DrawerMenu.js.map