UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

127 lines (126 loc) • 5.84 kB
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 };