diff --git a/modules/preview-react/divider/lib/Divider.tsx b/modules/preview-react/divider/lib/Divider.tsx index 30b5da8f8e..86e74a4e07 100644 --- a/modules/preview-react/divider/lib/Divider.tsx +++ b/modules/preview-react/divider/lib/Divider.tsx @@ -13,24 +13,58 @@ export const dividerStencil = createStencil({ vars: { space: '', }, - base: ({space}) => { - return { - display: 'block', - height: px2rem(1), - border: 'none', - borderBlockStart: `1px solid ${system.legacy.color.border.default}`, - margin: `${calc.divide(cssVar(space, system.legacy.gap.xs), 2)} 0`, - }; + base: { + border: 'none', + }, + modifiers: { + /** + * Sets the orientation of the `Divider`. + * * `horizontal` - renders a horizontal rule with the `space` prop applied to the top and bottom margins. + * * `vertical` - renders a vertical rule with the `space` prop applied to the left and right margins. It + * stretches to fill the height of its container, so it should be placed inside an element with a defined + * height (e.g. a flex or grid container). + * + * @default 'horizontal' + */ + orientation: { + horizontal: ({space}) => ({ + display: 'block', + height: px2rem(1), + borderBlockStart: `1px solid ${system.legacy.color.border.default}`, + margin: `${calc.divide(cssVar(space, system.legacy.gap.xs), 2)} 0`, + }), + vertical: ({space}) => ({ + display: 'inline-block', + alignSelf: 'stretch', + width: px2rem(1), + height: 'auto', + borderInlineStart: `1px solid ${system.legacy.color.border.default}`, + margin: `0 ${calc.divide(cssVar(space, system.legacy.gap.xs), 2)}`, + }), + }, + }, + defaultModifiers: { + orientation: 'horizontal', }, }); export interface DividerProps extends CSProps { /** - * Applies top and bottom margin evenly. It divides the provided value by two and applies half to each end. - * E.g. `space="2rem"` would apply `1rem` margin to the top, and `1rem` margin to the bottom. + * Applies margin evenly to both ends of the `Divider`. It divides the provided value by two and applies half to each end. + * For a `horizontal` `Divider` this is the top and bottom margin, and for a `vertical` `Divider` it is the left and right margin. + * E.g. `space="2rem"` would apply `1rem` margin to each end. * @default `system.gap.md` (1rem) */ space?: string; + /** + * Sets the orientation of the `Divider`. + * * `horizontal` - renders a horizontal rule to segment stacked content. + * * `vertical` - renders a vertical rule to segment content laid out in a row. The `Divider` stretches to fill + * the height of its container, so it should be placed inside an element with a defined height (e.g. a flex or + * grid container). + * @default 'horizontal' + */ + orientation?: 'horizontal' | 'vertical'; } /** @@ -39,8 +73,8 @@ export interface DividerProps extends CSProps { * * [View Docs](https://workday.github.io/canvas-kit/?path=/docs/preview-divider--docs) * - * The `space` prop will equally apply top and bottom margin styles. - * In the example below, `system.gap.xs` (0.5rem), adds `0.25rem` margin to the top and `0.25rem` to the bottom + * The `space` prop will equally apply margin styles to both ends of the `Divider`. + * In the example below, `system.gap.xs` (0.5rem), adds `0.25rem` margin to the top and `0.25rem` to the bottom. * * @example * ```tsx @@ -49,11 +83,18 @@ export interface DividerProps extends CSProps { * * * + * // vertical + * + * * ``` */ export const Divider = createComponent('hr')({ displayName: 'Divider', - Component: ({space, ...elemProps}: DividerProps, ref, Element) => ( - + Component: ({space, orientation = 'horizontal', ...elemProps}: DividerProps, ref, Element) => ( + ), }); diff --git a/modules/preview-react/divider/stories/examples/Vertical.tsx b/modules/preview-react/divider/stories/examples/Vertical.tsx new file mode 100644 index 0000000000..e6647f5e40 --- /dev/null +++ b/modules/preview-react/divider/stories/examples/Vertical.tsx @@ -0,0 +1,50 @@ +import {Divider} from '@workday/canvas-kit-preview-react/divider'; +import {createStyles} from '@workday/canvas-kit-styling'; +import {system} from '@workday/canvas-tokens-web'; + +const rowStyles = createStyles({ + display: 'flex', + alignItems: 'center', + height: system.space.x16, +}); + +const statStyles = createStyles({ + display: 'flex', + flexDirection: 'column', + gap: system.gap.zero, +}); + +const labelStyles = createStyles({ + ...system.type.subtext.medium, + color: system.color.text.hint, + margin: 0, +}); + +const valueStyles = createStyles({ + ...system.type.body.large, + fontWeight: system.fontWeight.bold, + margin: 0, +}); + +export const Vertical = () => { + const lastIndex = stats.length - 1; + return ( +
+ {stats.map((stat, index) => ( + <> +
+

{stat.label}

+

{stat.value}

+
+ {index !== lastIndex && } + + ))} +
+ ); +}; + +const stats = [ + {label: 'Components', value: '128'}, + {label: 'Contributors', value: '64'}, + {label: 'Releases', value: '512'}, +];