@workday/canvas-kit-react
Version:
The parent module that contains all Workday Canvas Kit React components
127 lines (126 loc) • 5.84 kB
JavaScript
import * as React from 'react';
import styled from '@emotion/styled';
import { colors, space } from '@workday/canvas-kit-react/tokens';
import { TertiaryButton } from '@workday/canvas-kit-react/button';
import { chevronLeftIcon, chevronRightIcon } from '@workday/canvas-system-icons-web';
import { Heading } from '@workday/canvas-kit-react/text';
export var SidePanelOpenDirection;
(function (SidePanelOpenDirection) {
SidePanelOpenDirection[SidePanelOpenDirection["Left"] = 0] = "Left";
SidePanelOpenDirection[SidePanelOpenDirection["Right"] = 1] = "Right";
})(SidePanelOpenDirection || (SidePanelOpenDirection = {}));
export var SidePanelBackgroundColor;
(function (SidePanelBackgroundColor) {
SidePanelBackgroundColor[SidePanelBackgroundColor["White"] = 0] = "White";
SidePanelBackgroundColor[SidePanelBackgroundColor["Transparent"] = 1] = "Transparent";
SidePanelBackgroundColor[SidePanelBackgroundColor["Gray"] = 2] = "Gray";
})(SidePanelBackgroundColor || (SidePanelBackgroundColor = {}));
const closedWidth = space.xxl;
const SidePanelContainer = styled('div')({
overflow: 'hidden',
height: '100%',
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
transition: 'width 200ms ease',
position: 'absolute',
}, ({ open }) => ({
alignItems: open ? undefined : 'center',
boxShadow: open ? undefined : '0 8px 16px -8px rgba(0, 0, 0, 0.16)',
}), ({ open, backgroundColor }) => {
let openBackgroundColor;
switch (backgroundColor) {
case SidePanelBackgroundColor.Transparent:
openBackgroundColor = 'transparent';
break;
case SidePanelBackgroundColor.Gray:
openBackgroundColor = colors.soap100;
break;
case SidePanelBackgroundColor.White:
default:
openBackgroundColor = colors.frenchVanilla100;
break;
}
return {
backgroundColor: open ? openBackgroundColor : colors.frenchVanilla100,
};
}, ({ open, openWidth }) => ({
width: open ? openWidth : closedWidth,
}), ({ open, padding }) => ({
padding: open ? padding || space.m : `${space.s} 0`,
}), ({ openDirection }) => ({
right: openDirection === SidePanelOpenDirection.Right ? space.zero : undefined,
left: openDirection === SidePanelOpenDirection.Left ? space.zero : undefined,
}));
const ChildrenContainer = styled('div')({
transition: 'none',
zIndex: 1, // show above SidePanelFooter when screen is small vertically
}, ({ open, openWidth }) => ({
width: open ? openWidth : closedWidth,
}));
const ToggleButton = styled(TertiaryButton, { shouldForwardProp: prop => prop !== 'openDirection' })({
position: 'absolute',
bottom: space.s,
}, ({ openDirection }) => ({
right: openDirection === SidePanelOpenDirection.Left ? space.s : '',
left: openDirection === SidePanelOpenDirection.Right ? space.s : '',
}));
const SidePanelFooter = styled('div')({
position: 'absolute',
bottom: '0',
height: 120,
left: 0,
background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.0001) 0%, #FFFFFF 100%)',
}, ({ open, openWidth }) => ({
width: open ? openWidth : space.xxl,
}));
class SidePanel extends React.Component {
constructor(props) {
super(props);
this.state = {
screenSize: typeof window !== 'undefined' ? window.innerWidth : 0,
};
this.handleResize = () => {
if (!this.props.onBreakpointChange || !this.props.breakpoint) {
return;
}
if (window.innerWidth > this.props.breakpoint && !this.props.open) {
this.props.onBreakpointChange(true);
}
if (window.innerWidth <= this.props.breakpoint && this.props.open) {
this.props.onBreakpointChange(false);
}
};
this.onToggleClick = () => {
if (this.props.onToggleClick) {
this.props.onToggleClick();
}
};
this.toggleButtonDirection = (open, openDirection) => {
if (openDirection !== SidePanelOpenDirection.Right) {
return open ? chevronLeftIcon : chevronRightIcon;
}
else {
return open ? chevronRightIcon : chevronLeftIcon;
}
};
this.handleResize = this.handleResize.bind(this);
}
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
render() {
const { backgroundColor = SidePanelBackgroundColor.White, openNavigationAriaLabel = 'open navigation', closeNavigationAriaLabel = 'close navigation', openDirection = SidePanelOpenDirection.Left, breakpoint = 768, openWidth = 300, header, onToggleClick, open, padding, onBreakpointChange, ...elemProps } = this.props;
return (React.createElement(SidePanelContainer, { role: "region", padding: padding, openDirection: openDirection, openWidth: openWidth, backgroundColor: backgroundColor, open: open, ...elemProps },
React.createElement(ChildrenContainer, { open: open, openWidth: openWidth },
header && open ? (React.createElement(Heading, { as: "h2", size: "small", marginTop: "zero" }, header)) : null,
this.props.children),
React.createElement(SidePanelFooter, { openWidth: openWidth, open: open }, onToggleClick && (React.createElement(ToggleButton, { openDirection: openDirection, "aria-label": open ? closeNavigationAriaLabel : openNavigationAriaLabel, onClick: this.onToggleClick, icon: this.toggleButtonDirection(open, openDirection) })))));
}
}
SidePanel.OpenDirection = SidePanelOpenDirection;
SidePanel.BackgroundColor = SidePanelBackgroundColor;
export { SidePanel };