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 = () => {
-
-
-
+
+
);
};
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 (
+
+ );
+};
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}};