Skip to content

Commit

Permalink
refactor: [M3-7575] CircleProgress and ColorPalette storybook v7 migr…
Browse files Browse the repository at this point in the history
…ations (linode#10015)

* circle progress story and test

* color palette

* Added changeset: ColorPalette and CircleProgress v7 storybook migration

* update color palette test
  • Loading branch information
coliu-akamai authored Dec 21, 2023
1 parent d5ed30b commit c471eac
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

ColorPalette and CircleProgress v7 storybook migration ([#10015](https://github.com/linode/manager/pull/10015))

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

import { CircleProgress } from './CircleProgress';

import type { Meta, StoryObj } from '@storybook/react';

type Story = StoryObj<typeof CircleProgress>;

export const Default: Story = {
render: (args) => <CircleProgress {...args} />,
};

const meta: Meta<typeof CircleProgress> = {
component: CircleProgress,
title: 'Components/Loading States/Circle Progress',
};

export default meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';

import { renderWithTheme } from 'src/utilities/testHelpers';

import { CircleProgress } from './CircleProgress';

const CONTENT_LOADING = 'Content is loading';

describe('CircleProgress', () => {
it('renders a CircleProgress properly', () => {
const screen = renderWithTheme(<CircleProgress />);

const circleProgress = screen.getByLabelText(CONTENT_LOADING);
expect(circleProgress).toBeVisible();
const circle = screen.getByTestId('circle-progress');
expect(circle).toBeInTheDocument();
expect(circle).toHaveStyle('width: 124px; height: 124px;');
const innerCircle = screen.getByTestId('inner-circle-progress');
expect(innerCircle).toBeInTheDocument();
});

it('renders a mini CircleProgress', () => {
const screen = renderWithTheme(<CircleProgress mini />);

const circleProgress = screen.getByLabelText(CONTENT_LOADING);
expect(circleProgress).toBeVisible();
expect(circleProgress).toHaveStyle('width: 40px; height: 40px;');
});

it('sets a mini CircleProgress with no padding', () => {
const screen = renderWithTheme(<CircleProgress mini noPadding />);

const circleProgress = screen.getByLabelText(CONTENT_LOADING);
expect(circleProgress).toBeVisible();
expect(circleProgress).toHaveStyle('width: 22px; height: 22px;');
});

it('sets a mini CircleProgress with a custom size', () => {
const screen = renderWithTheme(<CircleProgress mini size={25} />);

const circleProgress = screen.getByLabelText(CONTENT_LOADING);
expect(circleProgress).toBeVisible();
expect(circleProgress).toHaveStyle('width: 25px; height: 25px;');
});

it('renders a CircleProgress without the inner circle', () => {
const screen = renderWithTheme(<CircleProgress noInner />);

const circleProgress = screen.getByLabelText(CONTENT_LOADING);
expect(circleProgress).toBeVisible();
const innerCircle = screen.queryByTestId('inner-circle-progress');
expect(innerCircle).not.toBeInTheDocument();
});
});
41 changes: 24 additions & 17 deletions packages/manager/src/components/CircleProgress/CircleProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,37 @@ import {
import { omittedProps } from 'src/utilities/omittedProps';

interface CircleProgressProps extends CircularProgressProps {
/**
* Additional child elements to pass in
*/
children?: JSX.Element;
className?: string;
/**
* Displays a smaller version of the circle progress.
*/
mini?: boolean;
/**
* If true, will not show an inner circle beneath the spinning circle
*/
noInner?: boolean;
/**
* Removes the padding for `mini` circle progresses only.
*/
noPadding?: boolean;
/**
* To be primarily used with mini and noPadding. Set spinner to a custom size.
*/
size?: number;
/**
* Additional styles to apply to the root element.
*/
sx?: SxProps;
}

/**
* Use for short, indeterminate activities requiring user attention.
*/
const CircleProgress = (props: CircleProgressProps) => {
const {
children,
className,
mini,
noInner,
noPadding,
size,
sx,
...rest
} = props;
const { children, mini, noInner, noPadding, size, sx, ...rest } = props;

const variant =
typeof props.value === 'number' ? 'determinate' : 'indeterminate';
Expand All @@ -48,16 +59,12 @@ const CircleProgress = (props: CircleProgressProps) => {
}

return (
<StyledRootDiv
aria-label="Content is loading"
className={className}
sx={sx}
>
<StyledRootDiv aria-label="Content is loading" sx={sx}>
{children !== undefined && (
<Box sx={{ marginTop: 4, position: 'absolute' }}>{children}</Box>
)}
{noInner !== true && (
<StyledTopWrapperDiv>
<StyledTopWrapperDiv data-testid="inner-circle-progress">
<StyledTopDiv />
</StyledTopWrapperDiv>
)}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

import { ColorPalette } from './ColorPalette';

import type { Meta, StoryObj } from '@storybook/react';

export const Default: StoryObj<typeof ColorPalette> = {
render: () => <ColorPalette />,
};

const meta: Meta<typeof ColorPalette> = {
component: ColorPalette,
title: 'Design System/Color Palette',
};

export default meta;
132 changes: 132 additions & 0 deletions packages/manager/src/components/ColorPalette/ColorPalette.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from 'react';

import { renderWithTheme } from 'src/utilities/testHelpers';

import { ColorPalette } from './ColorPalette';

describe('Color Palette', () => {
it('renders the Color Palette', () => {
const { getAllByText, getByText } = renderWithTheme(<ColorPalette />);

// primary colors
getByText('Primary Colors');
getByText('theme.palette.primary.main');
const mainHash = getAllByText('#3683dc');
expect(mainHash).toHaveLength(2);
getByText('theme.palette.primary.light');
getByText('#4d99f1');
getByText('theme.palette.primary.dark');
getByText('#2466b3');
getByText('theme.palette.text.primary');
const primaryHash = getAllByText('#606469');
expect(primaryHash).toHaveLength(3);
getByText('theme.color.headline');
const headlineHash = getAllByText('#32363c');
expect(headlineHash).toHaveLength(2);
getByText('theme.palette.divider');
const dividerHash = getAllByText('#f4f4f4');
expect(dividerHash).toHaveLength(2);
const whiteColor = getAllByText('theme.color.white');
expect(whiteColor).toHaveLength(2);
const whiteHash = getAllByText('#fff');
expect(whiteHash).toHaveLength(3);

// etc
getByText('Etc.');
getByText('theme.color.red');
getByText('#ca0813');
getByText('theme.color.orange');
getByText('#ffb31a');
getByText('theme.color.yellow');
getByText('#fecf2f');
getByText('theme.color.green');
getByText('#00b159');
getByText('theme.color.teal');
getByText('#17cf73');
getByText('theme.color.border2');
getByText('#c5c6c8');
getByText('theme.color.border3');
getByText('#eee');
getByText('theme.color.grey1');
getByText('#abadaf');
getByText('theme.color.grey2');
getByText('#e7e7e7');
getByText('theme.color.grey3');
getByText('#ccc');
getByText('theme.color.grey4');
getByText('#8C929D');
getByText('theme.color.grey5');
getByText('#f5f5f5');
getByText('theme.color.grey6');
const borderGreyHash = getAllByText('#e3e5e8');
expect(borderGreyHash).toHaveLength(3);
getByText('theme.color.grey7');
getByText('#e9eaef');
getByText('theme.color.grey8');
getByText('#dbdde1');
getByText('theme.color.grey9');
const borderGrey9Hash = getAllByText('#f4f5f6');
expect(borderGrey9Hash).toHaveLength(3);
getByText('theme.color.black');
getByText('#222');
getByText('theme.color.offBlack');
getByText('#444');
getByText('theme.color.boxShadow');
getByText('#ddd');
getByText('theme.color.boxShadowDark');
getByText('#aaa');
getByText('theme.color.blueDTwhite');
getByText('theme.color.tableHeaderText');
getByText('rgba(0, 0, 0, 0.54)');
getByText('theme.color.drawerBackdrop');
getByText('rgba(255, 255, 255, 0.5)');
getByText('theme.color.label');
getByText('#555');
getByText('theme.color.disabledText');
getByText('#c9cacb');
getByText('theme.color.tagButton');
getByText('#f1f7fd');
getByText('theme.color.tagIcon');
getByText('#7daee8');

// background colors
getByText('Background Colors');
getByText('theme.bg.app');
getByText('theme.bg.main');
getByText('theme.bg.offWhite');
getByText('#fbfbfb');
getByText('theme.bg.lightBlue1');
getByText('#f0f7ff');
getByText('theme.bg.lightBlue2');
getByText('#e5f1ff');
getByText('theme.bg.white');
getByText('theme.bg.tableHeader');
getByText('#f9fafa');
getByText('theme.bg.primaryNavPaper');
getByText('#3a3f46');
getByText('theme.bg.mainContentBanner');
getByText('#33373d');
getByText('theme.bg.bgPaper');
getByText('#ffffff');
getByText('theme.bg.bgAccessRow');
getByText('#fafafa');
getByText('theme.bg.bgAccessRowTransparentGradient');
getByText('rgb(255, 255, 255, .001)');

// typography colors
getByText('Typography Colors');
getByText('theme.textColors.linkActiveLight');
getByText('#2575d0');
getByText('theme.textColors.headlineStatic');
getByText('theme.textColors.tableHeader');
getByText('#888f91');
getByText('theme.textColors.tableStatic');
getByText('theme.textColors.textAccessTable');

// border colors
getByText('Border Colors');
getByText('theme.borderColors.borderTypography');
getByText('theme.borderColors.borderTable');
getByText('theme.borderColors.divider');
});
});
10 changes: 10 additions & 0 deletions packages/manager/src/components/ColorPalette/ColorPalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ const useStyles = makeStyles()((theme: Theme) => ({
},
}));

/**
* Add a new color to the palette, especially another tint of gray or blue, only after exhausting the option of using an existing color.
*
* - Colors used in light mode are located in `foundations/light.ts
* - Colors used in dark mode are located in `foundations/dark.ts`
*
* If a color does not exist in the current palette and is only used once, consider applying the color conditionally:
*
* `theme.name === 'light' ? '#fff' : '#000'`
*/
export const ColorPalette = () => {
const { classes } = useStyles();
const theme = useTheme();
Expand Down

0 comments on commit c471eac

Please sign in to comment.