Skip to content

Commit

Permalink
feat: Add backgroundColor var on LoadingDots (#2991)
Browse files Browse the repository at this point in the history
Fixes: #2990 

https://canvas.workdaydesign.com/components/indicators/loading-dots/ shows a circle variant for use on gray/dark/image-based backgrounds. Our LoadingDots component styling needed some TLC to allow consumers to set the background color to match this pattern, and our Storybook entries can be updated to show how to achieve this variant.

I also noticed some links to docs were broken in the codebase so I updated that too.

[category:Components
Documentation]

Release Note:
Adds capability to LoadingDots to accept a `loadingDotColor` prop to change loading dots color, with the capability to override that var with a stencil - intended for use with the circle variant for dark backgrounds/images, which is now shown in Storybook with Custom Shape story.
Also adds a `animationDurationMs` prop in the same pattern, with a Custom Color and Animation story in storybook demonstrating the use of both these new props.

Co-authored-by: @mannycarrera4 <[email protected]>
Co-authored-by: manuel.carrera <[email protected]>
Co-authored-by: @NicholasBoll <[email protected]>
Co-authored-by: @alanbsmith <[email protected]>
Co-authored-by: @alanbsmith <[email protected]>
Co-authored-by: @mannycarrera4 <[email protected]>
  • Loading branch information
6 people authored Nov 1, 2024
1 parent d5be4cb commit 2ad2b08
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Optional breaking changes message. If your PR includes breaking changes. It is e

## Checklist

- [ ] MDX documentation adheres to Canvas Kit's [Documentation Guidelines](https://workday.github.io/canvas-kit/?path=/docs/guides-documentation-guidelines--page)
- [ ] MDX documentation adheres to Canvas Kit's [Documentation Guidelines](https://workday.github.io/canvas-kit/?path=/docs/guides-documentation-guidelines--docs)
- [ ] Label `ready for review` has been added to PR

## For the Reviewer
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contributing to Canvas

You may read our contribution guidelines
[here](https://workday.github.io/canvas-kit/?path=/docs/guides-contributing--page).
[here](https://workday.github.io/canvas-kit/?path=/docs/guides-contributing--docs).
94 changes: 52 additions & 42 deletions modules/react/loading-dots/lib/LoadingDots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,61 +15,71 @@ const keyframesLoading = keyframes({
},
});

const singleLoadingDotStencil = createStencil({
export interface LoadingDotsProps extends CSProps {
/**
* Applies backgroundColor to loading dots, intended for use with the circle variant design on grey/dark/image-based backgrounds.
* @default `system.color.bg.alt.strong`
*/
loadingDotColor?: string;
/**
* Duration of the loading animation in milliseconds.
* @default `40ms`
*/
animationDurationMs?: string;
}

export const loadingDotsStencil = createStencil({
vars: {
animationDurationMs: '40ms',
loadingDotColor: system.color.bg.alt.strong,
},
base: ({animationDurationMs}) => ({
backgroundColor: system.color.bg.alt.strong,
width: system.space.x4,
height: system.space.x4,
fontSize: system.space.zero,
borderRadius: system.shape.round,
transform: 'scale(0)',
display: 'inline-block',
animationName: keyframesLoading,
animationDuration: calc.multiply(animationDurationMs, 35),
animationIterationCount: 'infinite',
animationTimingFunction: 'ease-in-out',
animationFillMode: 'both',
'&:nth-child(1)': {
animationDelay: '0ms',
},
'&:nth-child(2)': {
animationDelay: calc.multiply(animationDurationMs, 4),
},
'&:nth-child(3)': {
animationDelay: calc.multiply(animationDurationMs, 8),
},
}),
});

/**
* The actual loading dot div.
*/
const LoadingAnimationDot = () => <div {...singleLoadingDotStencil()} />;

/**
* A simple container for the loading dots.
*/
const loadingDotsStencil = createStencil({
base: {
base: ({loadingDotColor, animationDurationMs}) => ({
display: 'inline-flex',
gap: system.space.x2,
},
'& [data-part="loading-animation-dot"]': {
backgroundColor: loadingDotColor,
width: system.space.x4,
height: system.space.x4,
fontSize: system.space.zero,
borderRadius: system.shape.round,
transform: 'scale(0)',
display: 'inline-block',
animationName: keyframesLoading,
animationDuration: calc.multiply(animationDurationMs, 35),
animationIterationCount: 'infinite',
animationTimingFunction: 'ease-in-out',
animationFillMode: 'both',
'&:nth-child(1)': {
animationDelay: '0ms',
},
'&:nth-child(2)': {
animationDelay: calc.multiply(animationDurationMs, 4),
},
'&:nth-child(3)': {
animationDelay: calc.multiply(animationDurationMs, 8),
},
},
}),
});

/**
* A simple component that displays three horizontal dots, to be used when some data is loading.
*/
export const LoadingDots = createComponent('div')({
displayName: 'LoadingDots',
Component: (elemProps: CSProps, ref, Element) => {
Component: (
{loadingDotColor, animationDurationMs, ...elemProps}: LoadingDotsProps,
ref,
Element
) => {
return (
<Element ref={ref} {...handleCsProp(elemProps, loadingDotsStencil())}>
<LoadingAnimationDot />
<LoadingAnimationDot />
<LoadingAnimationDot />
<Element
ref={ref}
{...handleCsProp(elemProps, loadingDotsStencil({loadingDotColor, animationDurationMs}))}
>
<div data-part="loading-animation-dot" />
<div data-part="loading-animation-dot" />
<div data-part="loading-animation-dot" />
</Element>
);
},
Expand Down
23 changes: 17 additions & 6 deletions modules/react/loading-dots/stories/LoadingDots.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {ExampleCodeBlock} from '@workday/canvas-kit-docs';
import {ExampleCodeBlock, SymbolDoc} from '@workday/canvas-kit-docs';
import {Basic} from './examples/Basic';
import {RTL} from './examples/RTL';
import {Accessible} from './examples/Accessible';
import {CustomShape} from './examples/CustomShape';
import {CustomColorAndAnimation} from './examples/CustomColorAndAnimation';
import * as LoadingDotsStories from './LoadingDots.stories';

<Meta of={LoadingDotsStories} />
Expand All @@ -11,7 +13,7 @@ import * as LoadingDotsStories from './LoadingDots.stories';
Loading Dots make users aware that content is currently being loaded, processing, or that change
will occur on the page.

[> Workday Design Reference](https://design.workday.com/components/indicators/loading-dots)
[> Workday Design Reference](https://canvas.workdaydesign.com/components/indicators/loading-dots/)

## Installation

Expand All @@ -29,10 +31,20 @@ yarn add @workday/canvas-kit-react

<ExampleCodeBlock code={RTL} />

### Custom Shape

<ExampleCodeBlock code={CustomShape} />

### Custom Color and Animation

<ExampleCodeBlock code={CustomColorAndAnimation} />

### Custom Styles

Loading Dots supports custom styling via the `cs` prop. For more information, check our
["How To Customize Styles"](https://workday.github.io/canvas-kit/?path=/docs/styling-how-to-customize-styles--page).
["How To Customize Styles"](https://workday.github.io/canvas-kit/?path=/docs/styling-how-to-customize-styles--docs).

Custom styling is also supported through the [Loading Dots documented props below](#props).

### Adding screen reader support to loading animations

Expand All @@ -50,7 +62,6 @@ components included in Canvas to describe both the appearance and disappearance

<ExampleCodeBlock code={Accessible} />

## Props
## Component API

Loading Dots does not have any documented props. Undocumented props are spread to its outermost
element.
<SymbolDoc name="LoadingDots" fileName="/react/" />
8 changes: 8 additions & 0 deletions modules/react/loading-dots/stories/LoadingDots.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {LoadingDots} from '@workday/canvas-kit-react/loading-dots';
import {Basic as BasicExample} from './examples/Basic';
import {RTL as RTLExample} from './examples/RTL';
import {Accessible as AccessibleExample} from './examples/Accessible';
import {CustomShape as CustomShapeExample} from './examples/CustomShape';
import {CustomColorAndAnimation as CustomColorAndAnimationExample} from './examples/CustomColorAndAnimation';

export default {
title: 'Components/Indicators/Loading Dots',
Expand All @@ -30,3 +32,9 @@ export const RTL: Story = {
export const Accessible: Story = {
render: AccessibleExample,
};
export const CustomShape: Story = {
render: CustomShapeExample,
};
export const CustomColorAndAnimation: Story = {
render: CustomColorAndAnimationExample,
};
2 changes: 1 addition & 1 deletion modules/react/loading-dots/stories/examples/Accessible.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import {LoadingDots} from '@workday/canvas-kit-react/loading-dots';
import {base, system} from '@workday/canvas-tokens-web';
import {system} from '@workday/canvas-tokens-web';
import {Flex} from '@workday/canvas-kit-react/layout';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {createStyles} from '@workday/canvas-kit-styling';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import {LoadingDots} from '@workday/canvas-kit-react/loading-dots';
import {system} from '@workday/canvas-tokens-web';
import {createStyles} from '@workday/canvas-kit-styling';

const styleOverrides = {
parentContainer: createStyles({
display: 'flex',
gap: system.space.x4,
}),
};

export const CustomColorAndAnimation = () => {
return (
<div className={styleOverrides.parentContainer}>
<LoadingDots loadingDotColor={system.color.fg.primary.default} animationDurationMs="60ms" />
</div>
);
};
32 changes: 32 additions & 0 deletions modules/react/loading-dots/stories/examples/CustomShape.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import {LoadingDots, loadingDotsStencil} from '@workday/canvas-kit-react/loading-dots';
import {system} from '@workday/canvas-tokens-web';
import {createStyles, createStencil} from '@workday/canvas-kit-styling';

const styleOverrides = {
parentContainer: createStyles({
display: 'flex',
gap: system.space.x4,
}),
};

const loadingStencil = createStencil({
base: {
borderRadius: system.shape.round,
backgroundColor: system.color.bg.overlay,
height: 80,
width: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
[loadingDotsStencil.vars.loadingDotColor]: system.color.icon.inverse,
},
});

export const CustomShape = () => {
return (
<div className={styleOverrides.parentContainer}>
<LoadingDots cs={loadingStencil()} />
</div>
);
};

0 comments on commit 2ad2b08

Please sign in to comment.