@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
251 lines • 14.5 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { useEffect, useRef, useState } from 'react';
import { useStableCallback } from '@awsui/component-toolkit/internal';
import { fireNonCancelableEvent } from '../../internal/events';
import { useControllable } from '../../internal/hooks/use-controllable';
import { awsuiPluginsInternal } from '../../internal/plugins/api';
import { sortByPriority } from '../../internal/plugins/helpers/utils';
import { convertRuntimeDrawers } from '../runtime-drawer';
import { togglesConfig } from '../toggles';
export const TOOLS_DRAWER_ID = 'awsui-internal-tools';
function getToolsDrawerItem(props) {
if (props.toolsHide) {
return null;
}
const { iconName, getLabels } = togglesConfig.tools;
const { mainLabel, closeLabel, openLabel } = getLabels(props.ariaLabels);
return {
id: TOOLS_DRAWER_ID,
content: props.tools,
resizable: false,
ariaLabels: {
triggerButton: openLabel,
closeButton: closeLabel,
drawerName: mainLabel !== null && mainLabel !== void 0 ? mainLabel : '',
},
trigger: {
iconName: iconName,
},
};
}
const DRAWERS_LIMIT = 2;
const DEFAULT_ON_CHANGE_PARAMS = { initiatedByUserAction: true };
function useRuntimeDrawers(disableRuntimeDrawers, activeDrawerId, onActiveDrawerChange, activeGlobalDrawersIds, onActiveGlobalDrawersChange) {
const [runtimeDrawers, setRuntimeDrawers] = useState({
localBefore: [],
localAfter: [],
global: [],
});
const onLocalDrawerChangeStable = useStableCallback(onActiveDrawerChange);
const onGlobalDrawersChangeStable = useStableCallback(onActiveGlobalDrawersChange);
const localDrawerWasOpenRef = useRef(false);
localDrawerWasOpenRef.current = localDrawerWasOpenRef.current || !!activeDrawerId;
const activeGlobalDrawersIdsRef = useRef([]);
activeGlobalDrawersIdsRef.current = activeGlobalDrawersIds;
useEffect(() => {
if (disableRuntimeDrawers) {
return;
}
const unsubscribe = awsuiPluginsInternal.appLayout.onDrawersRegistered(drawers => {
const localDrawers = drawers.filter(drawer => drawer.type !== 'global');
const globalDrawers = drawers.filter(drawer => drawer.type === 'global');
setRuntimeDrawers(convertRuntimeDrawers(localDrawers, globalDrawers));
if (!localDrawerWasOpenRef.current) {
const defaultActiveLocalDrawer = sortByPriority(localDrawers).find(drawer => drawer.defaultActive);
if (defaultActiveLocalDrawer) {
onLocalDrawerChangeStable(defaultActiveLocalDrawer.id, { initiatedByUserAction: false });
}
}
const drawersNotActiveByDefault = globalDrawers.filter(drawer => !drawer.defaultActive);
const hasDrawersOpenByUserAction = drawersNotActiveByDefault.find(drawer => activeGlobalDrawersIdsRef.current.includes(drawer.id));
if (hasDrawersOpenByUserAction || activeGlobalDrawersIdsRef.current.length === DRAWERS_LIMIT) {
return;
}
const defaultActiveGlobalDrawers = sortByPriority(globalDrawers).filter(drawer => !activeGlobalDrawersIdsRef.current.includes(drawer.id) && drawer.defaultActive);
defaultActiveGlobalDrawers.forEach(drawer => {
onGlobalDrawersChangeStable(drawer.id, { initiatedByUserAction: false });
});
});
return () => {
unsubscribe();
setRuntimeDrawers({ localBefore: [], localAfter: [], global: [] });
};
}, [disableRuntimeDrawers, onGlobalDrawersChangeStable, onLocalDrawerChangeStable]);
return runtimeDrawers;
}
function useDrawerRuntimeOpenClose(disableRuntimeDrawers, localDrawers, globalDrawers, activeDrawerId, onActiveDrawerChange, activeGlobalDrawersIds, onActiveGlobalDrawersChange) {
const onDrawerOpened = useStableCallback((drawerId, params = DEFAULT_ON_CHANGE_PARAMS) => {
const localDrawer = localDrawers === null || localDrawers === void 0 ? void 0 : localDrawers.find(drawer => drawer.id === drawerId);
const globalDrawer = globalDrawers.find(drawer => drawer.id === drawerId);
if (localDrawer && activeDrawerId !== drawerId) {
onActiveDrawerChange(drawerId, params);
}
if (globalDrawer && !activeGlobalDrawersIds.includes(drawerId)) {
onActiveGlobalDrawersChange(drawerId, params);
}
});
const onDrawerClosed = useStableCallback((drawerId, params = DEFAULT_ON_CHANGE_PARAMS) => {
const localDrawer = localDrawers === null || localDrawers === void 0 ? void 0 : localDrawers.find(drawer => drawer.id === drawerId);
const globalDrawer = globalDrawers.find(drawer => drawer.id === drawerId);
if (localDrawer && activeDrawerId === drawerId) {
onActiveDrawerChange(null, params);
}
if (globalDrawer && activeGlobalDrawersIds.includes(drawerId)) {
onActiveGlobalDrawersChange(drawerId, params);
}
});
useEffect(() => {
if (disableRuntimeDrawers) {
return;
}
return awsuiPluginsInternal.appLayout.onDrawerOpened(onDrawerOpened);
}, [disableRuntimeDrawers, onDrawerOpened]);
useEffect(() => {
if (disableRuntimeDrawers) {
return;
}
return awsuiPluginsInternal.appLayout.onDrawerClosed(onDrawerClosed);
}, [disableRuntimeDrawers, onDrawerClosed]);
}
function useDrawerRuntimeResize(disableRuntimeDrawers, onActiveDrawerResize) {
const onRuntimeDrawerResize = useStableCallback((drawerId, size) => {
onActiveDrawerResize({ id: drawerId, size });
});
useEffect(() => {
if (disableRuntimeDrawers) {
return;
}
return awsuiPluginsInternal.appLayout.onDrawerResize(onRuntimeDrawerResize);
}, [disableRuntimeDrawers, onRuntimeDrawerResize]);
}
function applyToolsDrawer(toolsProps, runtimeDrawers) {
const drawers = [...runtimeDrawers.localBefore, ...runtimeDrawers.localAfter];
if (drawers.length === 0 && toolsProps.disableDrawersMerge) {
return null;
}
const toolsItem = getToolsDrawerItem(toolsProps);
if (toolsItem) {
drawers.unshift(toolsItem);
}
return drawers;
}
export const MIN_DRAWER_SIZE = 290;
export function useDrawers({ drawers, activeDrawerId: controlledActiveDrawerId, onDrawerChange, onGlobalDrawerFocus, onAddNewActiveDrawer, expandedDrawerId, setExpandedDrawerId, __disableRuntimeDrawers: disableRuntimeDrawers, }, ariaLabels, toolsProps) {
var _a, _b, _c, _d;
const [activeDrawerId = null, setActiveDrawerId] = useControllable(controlledActiveDrawerId, onDrawerChange, null, {
componentName: 'AppLayout',
controlledProp: 'activeDrawerId',
changeHandler: 'onChange',
});
const [activeGlobalDrawersIds, setActiveGlobalDrawersIds] = useState([]);
const [drawerSizes, setDrawerSizes] = useState({});
// FIFO queue that keeps track of open drawers, where the first element is the most recently opened drawer
const drawersOpenQueue = useRef([]);
function onActiveDrawerResize({ id, size }) {
setDrawerSizes(oldSizes => ({ ...oldSizes, [id]: size }));
if ((activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.id) === id) {
fireNonCancelableEvent(activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.onResize, { id, size });
}
const activeGlobalDrawer = runtimeGlobalDrawers.find(drawer => drawer.id === id);
fireNonCancelableEvent(activeGlobalDrawer === null || activeGlobalDrawer === void 0 ? void 0 : activeGlobalDrawer.onResize, { id, size });
}
function onActiveDrawerChange(newDrawerId, { initiatedByUserAction } = DEFAULT_ON_CHANGE_PARAMS) {
var _a, _b;
setActiveDrawerId(newDrawerId);
if (newDrawerId) {
onAddNewActiveDrawer === null || onAddNewActiveDrawer === void 0 ? void 0 : onAddNewActiveDrawer(newDrawerId);
}
if (hasOwnDrawers) {
fireNonCancelableEvent(onDrawerChange, { activeDrawerId: newDrawerId });
}
else if (!toolsProps.toolsHide) {
toolsProps.onToolsToggle(newDrawerId === TOOLS_DRAWER_ID);
}
if (newDrawerId) {
drawersOpenQueue.current = [newDrawerId, ...drawersOpenQueue.current];
const newDrawer = (_a = [...runtimeDrawers.localBefore, ...runtimeDrawers.localAfter]) === null || _a === void 0 ? void 0 : _a.find(drawer => drawer.id === newDrawerId);
fireNonCancelableEvent(newDrawer === null || newDrawer === void 0 ? void 0 : newDrawer.onToggle, { isOpen: true, initiatedByUserAction });
}
if (activeDrawerId) {
drawersOpenQueue.current = drawersOpenQueue.current.filter(id => id !== activeDrawerId);
const activeDrawer = (_b = [...runtimeDrawers.localBefore, ...runtimeDrawers.localAfter]) === null || _b === void 0 ? void 0 : _b.find(drawer => drawer.id === activeDrawerId);
fireNonCancelableEvent(activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.onToggle, { isOpen: false, initiatedByUserAction });
}
}
function onActiveGlobalDrawersChange(drawerId, { initiatedByUserAction } = DEFAULT_ON_CHANGE_PARAMS) {
const drawer = runtimeGlobalDrawers.find(drawer => drawer.id === drawerId);
if (activeGlobalDrawersIds.includes(drawerId)) {
setActiveGlobalDrawersIds(currentState => currentState.filter(id => id !== drawerId));
onGlobalDrawerFocus === null || onGlobalDrawerFocus === void 0 ? void 0 : onGlobalDrawerFocus(drawerId, false);
drawersOpenQueue.current = drawersOpenQueue.current.filter(id => id !== drawerId);
fireNonCancelableEvent(drawer === null || drawer === void 0 ? void 0 : drawer.onToggle, { isOpen: false, initiatedByUserAction });
if (drawerId === expandedDrawerId) {
setExpandedDrawerId === null || setExpandedDrawerId === void 0 ? void 0 : setExpandedDrawerId(null);
}
}
else if (drawerId) {
onAddNewActiveDrawer === null || onAddNewActiveDrawer === void 0 ? void 0 : onAddNewActiveDrawer(drawerId);
setActiveGlobalDrawersIds(currentState => [drawerId, ...currentState].slice(0, DRAWERS_LIMIT));
onGlobalDrawerFocus === null || onGlobalDrawerFocus === void 0 ? void 0 : onGlobalDrawerFocus(drawerId, true);
drawersOpenQueue.current = [drawerId, ...drawersOpenQueue.current];
fireNonCancelableEvent(drawer === null || drawer === void 0 ? void 0 : drawer.onToggle, { isOpen: true, initiatedByUserAction });
}
}
const hasOwnDrawers = !!drawers;
// support toolsOpen in runtime-drawers-only mode
let activeDrawerIdResolved = (toolsProps === null || toolsProps === void 0 ? void 0 : toolsProps.toolsOpen) && !hasOwnDrawers
? TOOLS_DRAWER_ID
: activeDrawerId !== TOOLS_DRAWER_ID
? activeDrawerId
: null;
const runtimeDrawers = useRuntimeDrawers(disableRuntimeDrawers, activeDrawerIdResolved, onActiveDrawerChange, activeGlobalDrawersIds, onActiveGlobalDrawersChange);
const { localBefore, localAfter, global: runtimeGlobalDrawers } = runtimeDrawers;
const combinedLocalDrawers = drawers
? [...localBefore, ...drawers, ...localAfter]
: applyToolsDrawer(toolsProps, runtimeDrawers);
const activeDrawer = combinedLocalDrawers === null || combinedLocalDrawers === void 0 ? void 0 : combinedLocalDrawers.find(drawer => drawer.id === activeDrawerIdResolved);
// ensure that id is only defined when the drawer exists
activeDrawerIdResolved = (_a = activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.id) !== null && _a !== void 0 ? _a : null;
const activeGlobalDrawers = runtimeGlobalDrawers.filter(drawer => activeGlobalDrawersIds.includes(drawer.id));
useDrawerRuntimeOpenClose(disableRuntimeDrawers, combinedLocalDrawers, runtimeGlobalDrawers, activeDrawerId, onActiveDrawerChange, activeGlobalDrawersIds, onActiveGlobalDrawersChange);
useDrawerRuntimeResize(disableRuntimeDrawers, onActiveDrawerResize);
const activeDrawerSize = activeDrawerIdResolved
? ((_c = (_b = drawerSizes[activeDrawerIdResolved]) !== null && _b !== void 0 ? _b : activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.defaultSize) !== null && _c !== void 0 ? _c : toolsProps.toolsWidth)
: toolsProps.toolsWidth;
const activeGlobalDrawersSizes = activeGlobalDrawersIds.reduce((acc, currentGlobalDrawerId) => {
var _a, _b;
const currentGlobalDrawer = runtimeGlobalDrawers.find(drawer => drawer.id === currentGlobalDrawerId);
return {
...acc,
[currentGlobalDrawerId]: (_b = (_a = drawerSizes[currentGlobalDrawerId]) !== null && _a !== void 0 ? _a : currentGlobalDrawer === null || currentGlobalDrawer === void 0 ? void 0 : currentGlobalDrawer.defaultSize) !== null && _b !== void 0 ? _b : MIN_DRAWER_SIZE,
};
}, {});
const minGlobalDrawersSizes = runtimeGlobalDrawers.reduce((acc, globalDrawer) => {
var _a;
return {
...acc,
[globalDrawer.id]: Math.min((_a = globalDrawer.defaultSize) !== null && _a !== void 0 ? _a : MIN_DRAWER_SIZE, MIN_DRAWER_SIZE),
};
}, {});
const minDrawerSize = Math.min((toolsProps === null || toolsProps === void 0 ? void 0 : toolsProps.toolsOpen) ? toolsProps.toolsWidth : ((_d = activeDrawer === null || activeDrawer === void 0 ? void 0 : activeDrawer.defaultSize) !== null && _d !== void 0 ? _d : MIN_DRAWER_SIZE), MIN_DRAWER_SIZE);
return {
ariaLabelsWithDrawers: ariaLabels,
drawers: combinedLocalDrawers || undefined,
activeDrawer,
activeDrawerId: activeDrawerIdResolved,
globalDrawers: runtimeGlobalDrawers,
activeGlobalDrawers: activeGlobalDrawers,
activeGlobalDrawersIds,
activeGlobalDrawersSizes,
activeDrawerSize,
minDrawerSize,
minGlobalDrawersSizes,
drawerSizes,
drawersOpenQueue,
onActiveDrawerChange,
onActiveDrawerResize,
onActiveGlobalDrawersChange,
};
}
//# sourceMappingURL=use-drawers.js.map