@workday/canvas-kit-react
Version:
The parent module that contains all Workday Canvas Kit React components
116 lines (115 loc) • 3.57 kB
JavaScript
import * as React from 'react';
import styled from '@emotion/styled';
import isPropValid from '@emotion/is-prop-valid';
import { createComponent, useConstant } from '@workday/canvas-kit-react/common';
import { handleCsProp } from '@workday/canvas-kit-styling';
// style props
import { background } from './utils/background';
import { border } from './utils/border';
import { color } from './utils/color';
import { depth } from './utils/depth';
import { flexItem } from './utils/flexItem';
import { gridItem } from './utils/gridItem';
import { layout } from './utils/layout';
import { other } from './utils/other';
import { position } from './utils/position';
import { space } from './utils/space';
import { text } from './utils/text';
const omittedProps = [
'display',
'color',
'height',
'overflow',
'width',
'border',
'background',
'fontSize',
'fontWeight',
'fontFamily',
'letterSpacing',
'lineHeight',
'textAlign',
'opacity',
'textDecoration',
'textOverflow',
'textTransform',
'textShadow',
'whiteSpace',
'wordBreak',
];
const shouldForwardProp = (prop) => {
return isPropValid(prop) && !omittedProps.includes(prop);
};
/**
* A function that allows us to call Box styles on an element and reduce the amount of elements in the React Dom tree.
* Instead of using the `as` in a styled function, you can just call this instead to pass those props to the styled element
* @example
* ```
* import { boxStyleFn } from '@workday/canvas-kit-react/layout';
* const StyledHeader = styled('h1')(
* boxStyleFn,
* {
* fontWeight: 400,
* }
* )
*
* ...
*
* <StyledHeader color='red'>Hello World</StyledHeader>
* ```
*/
export const boxStyleFn = (props) => {
return [
{
boxSizing: 'border-box',
},
background,
border,
color,
depth,
flexItem,
gridItem,
layout,
other,
position,
space,
text,
].reduce((result, style) => {
// @ts-ignore
const temp = typeof style === 'function' ? style(props) : style;
// eslint-disable-next-line guard-for-in
for (const key in temp) {
// @ts-ignore
result[key] = temp[key];
}
return result;
}, {});
};
// Meant to be used with elements. The `shouldForwardProps` will remove all style props
const StyledBoxElement = styled('div', { shouldForwardProp })(boxStyleFn);
// Meant to be used with components. There is no `shouldForwardProps` - all props will be forwarded to the component
const StyledBoxComponent = styled('div')(boxStyleFn);
/**
* `Box` is a primitive component that provides a common, ergonomic API around Canvas design tokens.
* It is highly flexible, and its primary purpose is to build other components.
*
* @example
* import { Box, BoxProps } from '@workday/canvas-kit-react/layout';
*
* interface CardProps extends BoxProps {
* // card-specific props
* }
*
* // `Card`'s default values are set using `BoxProps`
* const Card = (props: CardProps) => (
* <Box depth={1} padding="m" borderRadius="l" {...props}>Hello, Card!</Box>
* );
*
*/
export const Box = createComponent('div')({
displayName: 'Box',
Component: ({ children, ...elemProps }, ref, Element) => {
const BoxComponent = useConstant(() => typeof Element === 'string' ? StyledBoxElement : StyledBoxComponent);
return (React.createElement(BoxComponent, { as: Element, ref: ref, ...handleCsProp(elemProps) }, children));
},
});