Skip to content
This repository has been archived by the owner on Jun 8, 2023. It is now read-only.

Commit

Permalink
feat: Implement Page Spinner (#159)
Browse files Browse the repository at this point in the history
* default color is black for spinner now

* initial page spinner

* black color

* page spinner setup

* scss preset

* way more accurate story

* clean up tests
  • Loading branch information
Tiernebre committed Jul 27, 2021
1 parent 0876130 commit 108ddd0
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 19 deletions.
17 changes: 6 additions & 11 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ const path = require("path");

module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-controls",
"@storybook/preset-scss",
],
typescript: {
reactDocgen: "react-docgen",
},
webpackFinal: async (config) => {
// add SCSS support for CSS Modules
config.module.rules.push({
test: /\.scss$/,
use: ["style-loader", "css-loader?modules&importLoaders", "sass-loader"],
include: path.resolve(__dirname, "../"),
});

return config;
},
};
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from "./image";
export * from "./level";
export * from "./navigation";
export * from "./notification";
export * from "./page-spinner";
export * from "./smart-alerts";
export * from "./spinner";
export * from "./table";
Expand Down
7 changes: 7 additions & 0 deletions src/components/page-spinner/PageSpinner.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.container {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
32 changes: 32 additions & 0 deletions src/components/page-spinner/PageSpinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { screen, render } from "@testing-library/react";
import { PageSpinner } from ".";
import { Color, colors, Size, sizes } from "../../types";
import styles from "../spinner/Spinner.module.scss";

it("by default is white", () => {
render(<PageSpinner />);
expect(screen.getByRole("alert")).toHaveClass(styles["is-black"]);
});

it("by default is labeled with 'Loading...'", () => {
render(<PageSpinner />);
const spinner = screen.getByRole("alert");
expect(spinner).toHaveAttribute("aria-label", "Loading...");
});

it("supports a custom label", () => {
const label = "Loading Test...";
render(<PageSpinner label={label} />);
const spinner = screen.getByRole("alert");
expect(spinner).toHaveAttribute("aria-label", label);
});

it.each<Color>(colors)("can be colored in %p", (color: Color) => {
render(<PageSpinner color={color} />);
expect(screen.getByRole("alert")).toHaveClass(styles[`is-${color}`]);
});

it.each<Size>(sizes)("can be sized in %p", (size: Size) => {
render(<PageSpinner size={size} />);
expect(screen.getByRole("alert")).toHaveClass(styles[`is-${size}`]);
});
12 changes: 12 additions & 0 deletions src/components/page-spinner/PageSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Spinner, SpinnerProps } from "..";
import styles from "./PageSpinner.module.scss";

export type PageSpinnerProps = SpinnerProps;

export const PageSpinner = (props: PageSpinnerProps): JSX.Element => {
return (
<div className={styles.container}>
<Spinner {...props} />
</div>
);
};
1 change: 1 addition & 0 deletions src/components/page-spinner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PageSpinner";
2 changes: 1 addition & 1 deletion src/components/spinner/Spinner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styles from "./Spinner.module.scss";

it("by default is white", () => {
render(<Spinner />);
expect(screen.getByRole("alert")).toHaveClass(styles["is-white"]);
expect(screen.getByRole("alert")).toHaveClass(styles["is-black"]);
});

it("by default is labeled with 'Loading...'", () => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/spinner/Spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const SpinnerDot = (): JSX.Element => (
<div className={styles.spinner_dot} aria-hidden="true" />
);

type SpinnerProps = {
export type SpinnerProps = {
label?: string;
color?: Color;
size?: Size;
Expand All @@ -23,7 +23,7 @@ const classNameMapping: ClassNameTransformMap<SpinnerProps> = new Map([

export const Spinner = ({
label = "Loading...",
color = "white",
color = "black",
size = "normal",
}: SpinnerProps): JSX.Element => {
const className = createClassNameFromProps(
Expand Down
3 changes: 3 additions & 0 deletions src/stories/PageSpinner.stories.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.root {
height: 100%;
}
32 changes: 32 additions & 0 deletions src/stories/PageSpinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Story, Meta } from "@storybook/react";
import { colors, sizes } from "..";
import { PageSpinner, PageSpinnerProps } from "../components";
import "./PageSpinner.stories.scss";

export default {
component: PageSpinner,
title: "Example/PageSpinner",
argTypes: {
color: {
control: {
type: "select",
options: colors,
},
},
size: {
control: {
type: "select",
options: sizes,
},
},
},
} as Meta<PageSpinnerProps>;

const Template: Story = (args) => (
<div style={{ height: "100vh" }}>
<PageSpinner {...args} />
</div>
);

export const InteractivePageSpinner = Template.bind({});
InteractivePageSpinner.args = {};
25 changes: 20 additions & 5 deletions src/stories/Spinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import { Story, Meta } from "@storybook/react";
import { Spinner } from "../components";
import { colors, sizes } from "..";
import { Spinner, SpinnerProps } from "../components";

export default {
component: Spinner,
title: "Example/Spinner",
} as Meta;
argTypes: {
color: {
control: {
type: "select",
options: colors,
},
},
size: {
control: {
type: "select",
options: sizes,
},
},
},
} as Meta<SpinnerProps>;

const Template: Story = () => <Spinner color="primary" size="medium" />;
const Template: Story = (args) => <Spinner {...args} />;

export const DefaultSpinner = Template.bind({});
DefaultSpinner.args = {};
export const InteractiveSpinner = Template.bind({});
InteractiveSpinner.args = {};

0 comments on commit 108ddd0

Please sign in to comment.