diff --git a/modules/react/_examples/stories/mdx/Density.mdx b/modules/react/_examples/stories/mdx/Density.mdx index d6dd49a532..44d5bc5717 100644 --- a/modules/react/_examples/stories/mdx/Density.mdx +++ b/modules/react/_examples/stories/mdx/Density.mdx @@ -1,5 +1,6 @@ import {ExampleCodeBlock} from '@workday/canvas-kit-docs'; import {Density} from './examples/Density'; +import {DensityComponents} from './examples/DensityComponents'; @@ -10,3 +11,7 @@ options to users, especially in the context of forms. Below is an example of how from elements to achieve the desired density. + +To view how density is being applied to components, view below. + + diff --git a/modules/react/_examples/stories/mdx/examples/Density.tsx b/modules/react/_examples/stories/mdx/examples/Density.tsx index edbd9e842e..30db216185 100644 --- a/modules/react/_examples/stories/mdx/examples/Density.tsx +++ b/modules/react/_examples/stories/mdx/examples/Density.tsx @@ -1,253 +1,15 @@ import React from 'react'; -import {FormField, FormFieldGroup} from '@workday/canvas-kit-react/form-field'; -import {TextInput} from '@workday/canvas-kit-react/text-input'; -import {Select} from '@workday/canvas-kit-react/select'; -import {Switch} from '@workday/canvas-kit-react/switch'; + import {Heading, Text} from '@workday/canvas-kit-react/text'; import {SegmentedControl} from '@workday/canvas-kit-preview-react/segmented-control'; -import {calc, createStencil, createStyles, px2rem} from '@workday/canvas-kit-styling'; +import {createStyles} from '@workday/canvas-kit-styling'; import {system} from '@workday/canvas-tokens-web'; - -const formStyles = createStyles({ - margin: `${system.space.x3} ${system.space.zero}`, - maxWidth: px2rem(600), - minWidth: system.space.zero, -}); - -const formFieldGroupListStyles = createStyles({ - display: 'inline-flex', - flexDirection: 'row', - flexWrap: 'wrap', -}); - -const sideBySideInputs = createStencil({ - base: { - display: 'inline-flex', - gap: system.space.x2, - justifyContent: 'space-between', - }, - modifiers: { - labelOrientation: { - horizontalStart: { - display: 'flex', - flexDirection: 'column', - }, - horizontalEnd: { - display: 'flex', - flexDirection: 'column', - }, - vertical: { - display: 'inline-flex', - }, - }, - density: { - high: {}, - medium: {}, - low: {}, - }, - }, - compound: [ - { - modifiers: {labelOrientation: 'horizontalStart', density: 'high'}, - styles: { - gap: system.space.x4, - }, - }, - { - modifiers: {labelOrientation: 'horizontalStart', density: 'medium'}, - styles: { - gap: system.space.x6, - }, - }, - { - modifiers: {labelOrientation: 'horizontalStart', density: 'low'}, - styles: { - gap: system.space.x8, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'high'}, - styles: { - gap: system.space.x4, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'medium'}, - styles: { - gap: system.space.x6, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'low'}, - styles: { - gap: system.space.x8, - }, - }, - ], -}); - -const zipCodeInput = createStyles({ - minWidth: px2rem(90), -}); - -const zipCodeContainerStyles = createStyles({ - minWidth: system.space.zero, -}); - -const formFieldStencil = createStencil({ - base: {}, - modifiers: { - density: { - high: { - gap: px2rem(2), - }, - medium: { - gap: system.space.x1, - }, - low: { - gap: system.space.x2, - }, - }, - labelOrientation: { - horizontalStart: {}, - horizontalEnd: {}, - vertical: {}, - }, - }, - compound: [ - { - modifiers: {labelOrientation: 'horizontalStart', density: 'high'}, - styles: { - gap: system.space.x4, - }, - }, - { - modifiers: {labelOrientation: 'horizontalStart', density: 'medium'}, - styles: { - gap: system.space.x6, - }, - }, - { - modifiers: {labelOrientation: 'horizontalStart', density: 'low'}, - styles: { - gap: system.space.x8, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'high'}, - styles: { - gap: system.space.x4, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'medium'}, - styles: { - gap: system.space.x6, - }, - }, - { - modifiers: {labelOrientation: 'horizontalEnd', density: 'low'}, - styles: { - gap: system.space.x8, - }, - }, - ], -}); - -const selectStencil = createStencil({ - base: {}, - modifiers: { - density: { - high: { - height: system.space.x8, - padding: `${system.space.x1} ${system.space.x2}`, - '& + div': { - height: system.space.x8, - }, - }, - medium: { - height: system.space.x10, - padding: `${system.space.x2}`, - }, - low: { - height: calc.add(system.space.x10, system.space.x2), - padding: `${system.space.x3} ${system.space.x2}`, - '& + div': { - height: calc.add(system.space.x10, system.space.x2), - }, - }, - }, - }, -}); - -const inputStencil = createStencil({ - base: { - minWidth: px2rem(200), - }, - modifiers: { - density: { - high: { - height: system.space.x8, - padding: `${system.space.x1} ${system.space.x2}`, - }, - medium: { - height: system.space.x10, - padding: `${system.space.x2}`, - }, - - low: { - height: calc.add(system.space.x10, system.space.x2), - padding: `${system.space.x3} ${system.space.x2}`, - }, - }, - }, -}); - -const creditCardInputStencil = createStencil({ - extends: inputStencil, - base: { - width: calc.add(system.space.x10, system.space.x10), - minWidth: calc.add(system.space.x10, system.space.x10), - textAlign: 'center', - }, -}); - -const flexContainerStencil = createStencil({ - base: { - display: 'flex', - flexDirection: 'column', - minWidth: 0, - }, - modifiers: { - density: { - high: { - gap: system.space.x4, - }, - medium: { - gap: system.space.x6, - }, - low: { - gap: system.space.x8, - }, - }, - }, -}); - -const containerAlignmentStencil = createStencil({ - base: { - display: 'flex', - }, - modifiers: { - alignment: { - left: { - justifyContent: 'flex-start', - }, - center: { - justifyContent: 'center', - }, - }, - }, -}); +import {DensityComponents} from './DensityComponents'; +import { + CanvasProvider, + PartialEmotionCanvasTheme, + useTheme, +} from '@workday/canvas-kit-react/common'; const optionStyles = createStyles({ display: 'flex', @@ -285,8 +47,19 @@ export const Density = () => { setLabelOrientation(data.id); }; + const canvasTheme: PartialEmotionCanvasTheme = useTheme({ + custom: { + density, + containerAlignment, + labelOrientation, + }, + canvas: { + // Switch to `ContentDirection.RTL` to change direction + }, + }); + return ( -
+ Choose Your Density and Alignment
@@ -321,122 +94,7 @@ export const Density = () => {
- -
-
-
- - Choose Country - - - - Full Name - - - - Phone Number - - - - Street Address - - - - City - - -
- - State - - - - Zip Code - - -
- - Enable Fast Shipping - - - - - - Credit Card - - - - - - - - - -
-
-
-
+ + ); }; diff --git a/modules/react/_examples/stories/mdx/examples/DensityComponents.tsx b/modules/react/_examples/stories/mdx/examples/DensityComponents.tsx new file mode 100644 index 0000000000..8c34ba1bbf --- /dev/null +++ b/modules/react/_examples/stories/mdx/examples/DensityComponents.tsx @@ -0,0 +1,417 @@ +import React from 'react'; +import {FormField, FormFieldGroup} from '@workday/canvas-kit-react/form-field'; +import {TextInput} from '@workday/canvas-kit-react/text-input'; +import {Select} from '@workday/canvas-kit-react/select'; +import {Switch} from '@workday/canvas-kit-react/switch'; + +import {calc, createStencil, createStyles, px2rem} from '@workday/canvas-kit-styling'; +import {system} from '@workday/canvas-tokens-web'; +import {useCanvasProvider} from '@workday/canvas-kit-react/common'; + +const formStyles = createStyles({ + margin: `${system.space.x3} ${system.space.zero}`, + maxWidth: px2rem(600), + minWidth: system.space.zero, +}); + +const formFieldGroupListStyles = createStyles({ + display: 'inline-flex', + flexDirection: 'row', + flexWrap: 'wrap', +}); + +const sideBySideInputs = createStencil({ + base: { + display: 'inline-flex', + gap: system.space.x2, + justifyContent: 'space-between', + }, + modifiers: { + labelOrientation: { + horizontalStart: { + display: 'flex', + flexDirection: 'column', + }, + horizontalEnd: { + display: 'flex', + flexDirection: 'column', + }, + vertical: { + display: 'inline-flex', + }, + }, + density: { + high: {}, + medium: {}, + low: {}, + }, + }, + compound: [ + { + modifiers: {labelOrientation: 'horizontalStart', density: 'high'}, + styles: { + gap: system.space.x4, + }, + }, + { + modifiers: {labelOrientation: 'horizontalStart', density: 'medium'}, + styles: { + gap: system.space.x6, + }, + }, + { + modifiers: {labelOrientation: 'horizontalStart', density: 'low'}, + styles: { + gap: system.space.x8, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'high'}, + styles: { + gap: system.space.x4, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'medium'}, + styles: { + gap: system.space.x6, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'low'}, + styles: { + gap: system.space.x8, + }, + }, + ], +}); + +const zipCodeInput = createStyles({ + minWidth: px2rem(90), +}); + +const zipCodeContainerStyles = createStyles({ + minWidth: system.space.zero, +}); + +const formFieldStencil = createStencil({ + base: {}, + modifiers: { + density: { + high: { + gap: px2rem(2), + }, + medium: { + gap: system.space.x1, + }, + low: { + gap: system.space.x2, + }, + }, + labelOrientation: { + horizontalStart: {}, + horizontalEnd: {}, + vertical: {}, + }, + }, + compound: [ + { + modifiers: {labelOrientation: 'horizontalStart', density: 'high'}, + styles: { + gap: system.space.x4, + }, + }, + { + modifiers: {labelOrientation: 'horizontalStart', density: 'medium'}, + styles: { + gap: system.space.x6, + }, + }, + { + modifiers: {labelOrientation: 'horizontalStart', density: 'low'}, + styles: { + gap: system.space.x8, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'high'}, + styles: { + gap: system.space.x4, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'medium'}, + styles: { + gap: system.space.x6, + }, + }, + { + modifiers: {labelOrientation: 'horizontalEnd', density: 'low'}, + styles: { + gap: system.space.x8, + }, + }, + ], +}); + +const selectStencil = createStencil({ + base: {}, + modifiers: { + density: { + high: { + height: system.space.x8, + padding: `${system.space.x1} ${system.space.x2}`, + '& + div': { + height: system.space.x8, + }, + }, + medium: { + height: system.space.x10, + padding: `${system.space.x2}`, + }, + low: { + height: calc.add(system.space.x10, system.space.x2), + padding: `${system.space.x3} ${system.space.x2}`, + '& + div': { + height: calc.add(system.space.x10, system.space.x2), + }, + }, + }, + }, +}); + +const inputStencil = createStencil({ + base: { + minWidth: px2rem(200), + }, + modifiers: { + density: { + high: { + height: system.space.x8, + padding: `${system.space.x1} ${system.space.x2}`, + }, + medium: { + height: system.space.x10, + padding: `${system.space.x2}`, + }, + + low: { + height: calc.add(system.space.x10, system.space.x2), + padding: `${system.space.x3} ${system.space.x2}`, + }, + }, + }, +}); + +const creditCardInputStencil = createStencil({ + extends: inputStencil, + base: { + width: calc.add(system.space.x10, system.space.x10), + minWidth: calc.add(system.space.x10, system.space.x10), + textAlign: 'center', + }, +}); + +const flexContainerStencil = createStencil({ + base: { + display: 'flex', + flexDirection: 'column', + minWidth: 0, + }, + modifiers: { + density: { + high: { + gap: system.space.x4, + }, + medium: { + gap: system.space.x6, + }, + low: { + gap: system.space.x8, + }, + }, + }, +}); + +const containerAlignmentStencil = createStencil({ + base: { + display: 'flex', + }, + modifiers: { + alignment: { + left: { + justifyContent: 'flex-start', + }, + center: { + justifyContent: 'center', + }, + }, + }, +}); + +// high = 32px height on inputs, space between inputs is 16px +// medium 40px height on inputs, space between inputs is 24px +// low = 48px height on inputs, space between inputs is 32px + +export const DensityComponents = () => { + const {theme} = useCanvasProvider(); + console.log(theme.custom); + if (!theme.custom) { + return; + } + return ( +
+
+
+ + Choose Country + + + + Full Name + + + + Phone Number + + + + Street Address + + + + City + + +
+ + State + + + + Zip Code + + +
+ + Enable Fast Shipping + + + + + + Credit Card + + + + + + + + + +
+
+
+ ); +}; diff --git a/modules/react/button/stories/visual-testing/PrimaryButton.stories.tsx b/modules/react/button/stories/visual-testing/PrimaryButton.stories.tsx index dad869830e..b55f07824d 100644 --- a/modules/react/button/stories/visual-testing/PrimaryButton.stories.tsx +++ b/modules/react/button/stories/visual-testing/PrimaryButton.stories.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {PartialEmotionCanvasTheme} from '@workday/canvas-kit-react/common'; +import {PartialEmotionCanvasTheme, useCanvasProvider} from '@workday/canvas-kit-react/common'; import { ComponentStatesTable, permutateProps, @@ -20,45 +20,47 @@ export default { }, }; -const PrimaryButtonTest = (props: {theme?: PartialEmotionCanvasTheme}) => ( - - (props.iconPosition && props.icon) || (!props.icon && !props.iconPosition) - )} - columnProps={stateTableColumnProps} - > - {props => ( - - Test - - )} - - -); +const PrimaryButtonTest = (props: {theme?: PartialEmotionCanvasTheme}) => { + return ( + + (props.iconPosition && props.icon) || (!props.icon && !props.iconPosition) + )} + columnProps={stateTableColumnProps} + > + {props => ( + + Test + + )} + + + ); +}; const PrimaryIconButtonTest = (props: {theme?: PartialEmotionCanvasTheme}) => ( diff --git a/modules/react/common/lib/CanvasProvider.tsx b/modules/react/common/lib/CanvasProvider.tsx index 95c69ddc34..540c4a66d8 100644 --- a/modules/react/common/lib/CanvasProvider.tsx +++ b/modules/react/common/lib/CanvasProvider.tsx @@ -7,8 +7,15 @@ import {createStyles, getCache} from '@workday/canvas-kit-styling'; export interface CanvasProviderProps { theme?: PartialEmotionCanvasTheme; + density?: 'low' | 'medium' | 'high' | undefined; } +export const DensityContext = React.createContext('medium'); + +export const useDensityContext = (): CanvasProviderProps['density'] => { + return React.useContext(DensityContext); +}; + // copied from brand/_variables.css const defaultBranding = createStyles({ [brand.error.darkest]: 'rgba(128,22,14,1)', @@ -85,21 +92,24 @@ export const useCanvasThemeToCssVars = ( export const CanvasProvider = ({ children, theme = {canvas: defaultCanvasTheme}, + density = 'medium', ...props }: CanvasProviderProps & React.HTMLAttributes) => { const elemProps = useCanvasThemeToCssVars(theme, props); const cache = getCache(); return ( - - -
)} - > - {children} -
-
+ + + +
)} + > + {children} +
+
+
); }; diff --git a/modules/react/common/lib/theming/types.ts b/modules/react/common/lib/theming/types.ts index 8e7c8be176..d1fe7790b7 100644 --- a/modules/react/common/lib/theming/types.ts +++ b/modules/react/common/lib/theming/types.ts @@ -236,10 +236,12 @@ export interface CanvasTheme { only: (key: BreakpointFnParam) => string; }; direction: ContentDirection; + // custom: {[key: string]: any}; } /** * Indicates a component is themeable with a CanvasTheme + * @deprecated We shouldn't extend themeable anyone since it doesn't work with static styling */ export interface Themeable { theme?: EmotionCanvasTheme; @@ -254,10 +256,11 @@ type RecursivePartial = { export type PartialCanvasTheme = RecursivePartial; export type PartialCanvasThemePalette = RecursivePartial; -export type PartialEmotionCanvasTheme = {canvas?: PartialCanvasTheme}; +export type PartialEmotionCanvasTheme = {canvas?: PartialCanvasTheme; custom: {[key: string]: any}}; declare module '@emotion/react' { export interface Theme { canvas: CanvasTheme; + custom: {[key: string]: any}; } } -export type EmotionCanvasTheme = {canvas: CanvasTheme}; +export type EmotionCanvasTheme = {canvas: CanvasTheme; custom: {[key: string]: any}};