Skip to content
Permalink
Browse files
feat(progress): added a small state to the CircularProgress
Realized it would be really helpful to have the smaller version from
`v1` available again as an option out of the box since the new one is a
bit too big.
  • Loading branch information
mlaursen committed Aug 23, 2020
1 parent 46bd8b6 commit 6884a3ab762216313330dfb01f386c87a5cd5b88
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 18 deletions.
@@ -0,0 +1,2 @@
The `CircularProgress` also supports a `small` state which defaults to the same
size as icons from the #icon package.
@@ -0,0 +1,21 @@
import React, { ReactElement, useEffect } from "react";
import { useTimeout, useToggle } from "@react-md/utils";
import { Button } from "@react-md/button";
import { CircularProgress } from "@react-md/progress";

export default function SmallCircularProgress(): ReactElement | null {
const [loading, enable, disable] = useToggle(false);
const [start] = useTimeout(disable, 10000);
useEffect(() => {
if (loading) {
start();
}
}, [loading, start]);

return (
<>
<Button onClick={enable}>Show</Button>
{loading && <CircularProgress id="small-circular-progress" small />}
</>
);
}
@@ -8,6 +8,9 @@ import simpleIndeterminateExamples from "./SimpleIndeterminateExamples.md";
import SimpleDeterminateExamples from "./SimpleDeterminateExamples";
import simpleDeterminateExamples from "./SimpleDeterminateExamples.md";

import SmallCircularProgress from "./SmallCircularProgress";
import smallCircularProgress from "./SmallCircularProgress.md";

import { WithSuspense, withSuspense } from "./WithSuspense";

import WithinButtons from "./WithinButtons";
@@ -24,6 +27,11 @@ const demos = [
description: simpleDeterminateExamples,
children: <SimpleDeterminateExamples />,
},
{
name: "Small Circular Progress",
description: smallCircularProgress,
children: <SmallCircularProgress />,
},
{
name: "With Suspense",
description: withSuspense,
@@ -1613,6 +1613,14 @@ const metadata: ReadonlyArray<RouteMetadata> = [
pageUrl: "/packages/progress/demos#simple-determinate-examples-title",
pathname: "/packages/progress/demos#simple-determinate-examples-title",
},
{
title: "Progress Demo - Small Circular Progress",
summary:
"The CircularProgress also supports a small state which defaults to the same size as icons from the @react-md/icon package.",
type: "demo",
pageUrl: "/packages/progress/demos#small-circular-progress-title",
pathname: "/packages/progress/demos#small-circular-progress-title",
},
{
title: "Progress Demo - With Suspense",
summary:
@@ -2729,6 +2729,10 @@ const tocs: TOCRecord = {
anchor: "#simple-determinate-examples",
title: "Simple Determinate Examples",
},
{
anchor: "#small-circular-progress",
title: "Small Circular Progress",
},
{
anchor: "#with-suspense",
title: "With Suspense",
@@ -0,0 +1,53 @@
{
"public/index.html": {
"content": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, shrink-to-fit=no\"\n />\n <meta name=\"theme-color\" content=\"#000000\" />\n <link\n rel=\"stylesheet\"\n href=\"https://fonts.googleapis.com/css?family=Material+Icons|Roboto:400,500,700|Source+Code+Pro\"\n />\n <link\n rel=\"stylesheet\"\n href=\"https://unpkg.com/react-md@{{RMD_VERSION}}/dist/css/react-md.teal-pink-200-light.min.css\"\n />\n <title>Progress Example - Small Circular Progress</title>\n </head>\n <body>\n <noscript>You need to enable JavaScript to run this app.</noscript>\n <div id=\"root\"></div>\n </body>\n</html>\n",
"isBinary": false
},
"src/index.tsx": {
"content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Configuration } from \"@react-md/layout\";\n\nimport Demo from \"./Demo\";\n\nconst App = () => (\n <Configuration>\n <Demo />\n </Configuration>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n",
"isBinary": false
},
"src/styles.scss": {
"content": "@import \"variables\";\n@import \"~@react-md/button/dist/mixins\";\n@import \"~@react-md/layout/dist/mixins\";\n@import \"~@react-md/progress/dist/mixins\";\n@import \"~@react-md/states/dist/mixins\";\n@import \"~@react-md/theme/dist/mixins\";\n@import \"~@react-md/typography/dist/mixins\";\n@import \"~@react-md/utils/dist/mixins\";\n\n@include react-md-utils;\n",
"isBinary": false
},
"src/_variables.scss": {
"content": "@import \"~@react-md/theme/dist/color-palette\";\n\n$rmd-theme-light: true;\n$rmd-theme-primary: $rmd-teal-500;\n$rmd-theme-secondary: $rmd-pink-a-200;\n",
"isBinary": false
},
"package.json": {
"content": {
"title": "Progress Example - Small Circular Progress",
"description": "Example from https://react-md.dev/packages/progress/demos#small-circular-progress",
"main": "src/index.tsx",
"dependencies": {
"@react-md/button": "latest",
"@react-md/layout": "latest",
"@react-md/progress": "latest",
"@react-md/states": "latest",
"@react-md/theme": "latest",
"@react-md/typography": "latest",
"@react-md/utils": "latest",
"react": "latest",
"react-dom": "latest"
},
"devDependencies": {
"@types/jest": "latest",
"@types/node": "latest",
"@types/react": "latest",
"@types/react-dom": "latest",
"node-sass": "latest",
"react-scripts": "latest",
"typescript": "latest"
},
"scripts": {
"start": "react-scripts start"
}
},
"isBinary": false
},
"src/Demo.tsx": {
"content": "import React, { ReactElement, useEffect } from \"react\";\nimport { useTimeout, useToggle } from \"@react-md/utils\";\nimport { Button } from \"@react-md/button\";\nimport { CircularProgress } from \"@react-md/progress\";\n\nexport default function SmallCircularProgress(): ReactElement | null {\n const [loading, enable, disable] = useToggle(false);\n const [start] = useTimeout(disable, 10000);\n useEffect(() => {\n if (loading) {\n start();\n }\n }, [loading, start]);\n\n return (\n <>\n <Button onClick={enable}>Show</Button>\n {loading && <CircularProgress id=\"small-circular-progress\" small />}\n </>\n );\n}\n",
"isBinary": false
}
}
@@ -214,6 +214,8 @@ const sandboxes: Sandboxes = {
resolve(import("./Progress-SimpleDeterminateExamples.json")),
SimpleIndeterminateExamples: () =>
resolve(import("./Progress-SimpleIndeterminateExamples.json")),
SmallCircularProgress: () =>
resolve(import("./Progress-SmallCircularProgress.json")),
WithinButtons: () => resolve(import("./Progress-WithinButtons.json")),
WithSuspense: () => resolve(import("./Progress-WithSuspense.json")),
},
@@ -151,6 +151,11 @@ const sassdoc: PackageSassDoc = {
{ name: "rmd-button", type: "mixin", packageName: "button" },
{ name: "rmd-chip", type: "mixin", packageName: "chip" },
{ name: "rmd-switch", type: "mixin", packageName: "form" },
{
name: "rmd-circular-progress",
type: "mixin",
packageName: "progress",
},
],
requires: [
{
@@ -347,18 +352,28 @@ const sassdoc: PackageSassDoc = {
"rmd-circular-progress": {
name: "rmd-circular-progress",
description: "",
source: "packages/progress/src/_mixins.scss#L221-L283",
source: "packages/progress/src/_mixins.scss#L221-L289",
usedBy: [
{ name: "react-md-progress", type: "mixin", packageName: "progress" },
],
requires: [
{ name: "rmd-progress-theme", type: "mixin", packageName: "progress" },
{
name: "rmd-progress-theme-update-var",
type: "mixin",
packageName: "progress",
},
{ name: "rmd-transition", type: "mixin", packageName: "transition" },
{
name: "rmd-progress-animation",
type: "mixin",
packageName: "progress",
},
{
name: "rmd-circular-progress-small-size",
type: "variable",
packageName: "progress",
},
{
name: "rmd-circular-progress-transition-duration",
type: "variable",
@@ -383,13 +398,13 @@ const sassdoc: PackageSassDoc = {
packageName: "progress",
code: "@mixin rmd-circular-progress { … }",
sourceCode:
"@mixin rmd-circular-progress {\n .rmd-circular-progress {\n @include rmd-progress-theme(height, circular-size);\n @include rmd-progress-theme(width, circular-size);\n\n // add border radius and overflow-hidden so that different stroke-widths\n // are still circular. For some reason it isn't always the case.\n align-items: center;\n border-radius: 50%;\n display: inline-flex;\n justify-content: center;\n overflow: hidden;\n\n &--centered {\n display: flex;\n margin-left: auto;\n margin-right: auto;\n }\n\n &__svg {\n height: inherit;\n width: inherit;\n\n &--animate {\n @include rmd-transition(standard);\n\n transition: transform 0.1s;\n }\n\n &--indeterminate {\n animation: rmd-progress-rotate\n $rmd-circular-progress-transition-duration linear infinite;\n }\n }\n\n &__circle {\n @include rmd-progress-theme(stroke, color);\n @include rmd-progress-theme(stroke-width, circular-width);\n\n fill: none;\n stroke-dasharray: $rmd-circular-progress-dasharray;\n stroke-linecap: round;\n\n &--animate {\n @include rmd-transition(standard);\n\n transition: stroke-dashoffset 0.1s;\n }\n\n &--indeterminate {\n animation: rmd-circular-progress-size\n $rmd-circular-progress-transition-duration ease-in-out infinite;\n }\n }\n\n @keyframes rmd-progress-rotate {\n @include rmd-progress-animation($rmd-circular-progress-rotate-styles);\n }\n\n @keyframes rmd-circular-progress-size {\n @include rmd-progress-animation($rmd-circular-progress-dash-styles);\n }\n }\n}\n",
"@mixin rmd-circular-progress {\n .rmd-circular-progress {\n @include rmd-progress-theme(height, circular-size);\n @include rmd-progress-theme(width, circular-size);\n\n // add border radius and overflow-hidden so that different stroke-widths\n // are still circular. For some reason it isn't always the case.\n align-items: center;\n border-radius: 50%;\n display: inline-flex;\n justify-content: center;\n overflow: hidden;\n\n &--centered {\n display: flex;\n margin-left: auto;\n margin-right: auto;\n }\n\n @if $rmd-circular-progress-small-size != null {\n &--small {\n @include rmd-progress-theme-update-var(\n circular-size,\n $rmd-circular-progress-small-size\n );\n }\n }\n\n &__svg {\n height: inherit;\n width: inherit;\n\n &--animate {\n @include rmd-transition(standard);\n\n transition: transform 0.1s;\n }\n\n &--indeterminate {\n animation: rmd-progress-rotate\n $rmd-circular-progress-transition-duration linear infinite;\n }\n }\n\n &__circle {\n @include rmd-progress-theme(stroke, color);\n @include rmd-progress-theme(stroke-width, circular-width);\n\n fill: none;\n stroke-dasharray: $rmd-circular-progress-dasharray;\n stroke-linecap: round;\n\n &--animate {\n @include rmd-transition(standard);\n\n transition: stroke-dashoffset 0.1s;\n }\n\n &--indeterminate {\n animation: rmd-circular-progress-size\n $rmd-circular-progress-transition-duration ease-in-out infinite;\n }\n }\n }\n\n @keyframes rmd-progress-rotate {\n @include rmd-progress-animation($rmd-circular-progress-rotate-styles);\n }\n\n @keyframes rmd-circular-progress-size {\n @include rmd-progress-animation($rmd-circular-progress-dash-styles);\n }\n}\n",
type: "mixin",
},
"react-md-progress": {
name: "react-md-progress",
description: "Creates all the styles for the progress package.\n",
source: "packages/progress/src/_mixins.scss#L286-L296",
source: "packages/progress/src/_mixins.scss#L292-L302",
usedBy: [{ name: "react-md-utils", type: "mixin", packageName: "utils" }],
requires: [
{
@@ -652,11 +667,29 @@ const sassdoc: PackageSassDoc = {
value: "3rem",
overridable: true,
},
"rmd-circular-progress-small-size": {
name: "rmd-circular-progress-small-size",
description:
"The size for a small circular progress svg. This is really the same size as the `$rmd-icon-size` so it could be used instead if the `@react-md/icon` package has also been installed.",
source: "packages/progress/src/_variables.scss#L217",
since: "2.3.0",
usedBy: [
{
name: "rmd-circular-progress",
type: "mixin",
packageName: "progress",
},
],
packageName: "progress",
type: "String|Number",
value: "1.5rem",
overridable: true,
},
"rmd-circular-progress-stroke-width": {
name: "rmd-circular-progress-stroke-width",
description:
"The stroke width for the circular svg. I wouldn't change this value unless you also update the `viewbox` for the `CircularProgress` component.\n",
source: "packages/progress/src/_variables.scss#L214",
source: "packages/progress/src/_variables.scss#L222",
packageName: "progress",
type: "Number",
value: "6",
@@ -666,7 +699,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-dasharray",
description:
"The dasharray fro the circular svg. I don't really know how this works so good luck changing it to something else. If this value is changed, you'll aslo need to update the `dasharray` prop for the `CircularProgress` component.\n",
source: "packages/progress/src/_variables.scss#L221",
source: "packages/progress/src/_variables.scss#L229",
usedBy: [
{
name: "rmd-circular-progress",
@@ -683,7 +716,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-transition-duration",
description:
"The entire transition duration for the circular progress. This is really the full time for the change in the `stroke-dashoffset` as the default rotation will rotate `720deg` over this time.\n",
source: "packages/progress/src/_variables.scss#L227",
source: "packages/progress/src/_variables.scss#L235",
usedBy: [
{
name: "rmd-circular-progress",
@@ -700,7 +733,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-start-offset",
description:
"The starting dashoffset for the ciruclar progress animation. This will be used for the `0%` and `100%` values in the animation keyframes by default.\n",
source: "packages/progress/src/_variables.scss#L232",
source: "packages/progress/src/_variables.scss#L240",
packageName: "progress",
type: "Number",
value: "$rmd-circular-progress-dasharray",
@@ -711,7 +744,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-end-offset",
description:
"The ending dashoffset for the ciruclar progress animation. This will be used for the `50%` value in the animation keyframes by default.\n",
source: "packages/progress/src/_variables.scss#L237",
source: "packages/progress/src/_variables.scss#L245",
packageName: "progress",
type: "Number",
value: "$rmd-circular-progress-dasharray / 4",
@@ -722,7 +755,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-rotate-styles",
description:
"The circular progress styles to apply for the rotation transition. Each key in this map will be set immediately at the root of the `keyframes` and then each child map will be considered a map of property: value.\n",
source: "packages/progress/src/_variables.scss#L243-L256",
source: "packages/progress/src/_variables.scss#L251-L264",
usedBy: [
{
name: "rmd-circular-progress",
@@ -740,7 +773,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-circular-progress-dash-styles",
description:
"The circular progress styles to apply for the dashoffset transition. Each key in this map will be set immediately at the root of the `keyframes` and then each child map will be considered a map of property: value.\n",
source: "packages/progress/src/_variables.scss#L262-L272",
source: "packages/progress/src/_variables.scss#L270-L280",
usedBy: [
{
name: "rmd-circular-progress",
@@ -760,7 +793,7 @@ const sassdoc: PackageSassDoc = {
name: "rmd-progress-theme-values",
description:
'A Map of all the "themeable" parts of the progress package. Every key in this map will be used to create a css variable to dynamically update the values of the icon as needed.\n',
source: "packages/progress/src/_variables.scss#L278-L284",
source: "packages/progress/src/_variables.scss#L286-L292",
usedBy: [
{
name: "rmd-progress-theme",
@@ -78,6 +78,13 @@ export interface CircularProgressProps
* margins.
*/
centered?: boolean;

/**
* Boolean if the smaller size should be used instead.
*
* @since 2.3.0
*/
small?: boolean;
}

const block = bem("rmd-circular-progress");
@@ -100,6 +107,7 @@ const CircularProgress = forwardRef<HTMLSpanElement, CircularProgressProps>(
animate = true,
centered = true,
maxRotation = 360 * 1.75,
small = false,
...props
},
ref
@@ -144,7 +152,7 @@ const CircularProgress = forwardRef<HTMLSpanElement, CircularProgressProps>(
aria-valuemin={min}
aria-valuemax={max}
aria-valuenow={value}
className={cn(block({ centered }), className)}
className={cn(block({ centered, small }), className)}
>
<svg
style={svgStyle}
@@ -198,6 +206,7 @@ if (process.env.NODE_ENV !== "production") {
centered: PropTypes.bool,
maxRotation: PropTypes.number,
dashoffset: PropTypes.number,
small: PropTypes.bool,
viewBox: PropTypes.string,
};
} catch (e) {}
@@ -29,4 +29,21 @@ describe("CircularProgress", () => {
expect(progress.style.transform).toContain(style.transform);
expect(progress).toMatchSnapshot();
});

it("should support a small variant", () => {
const { getByRole, rerender } = render(
<CircularProgress id="small=pgoress" small />
);
const progress = getByRole("progressbar");

expect(progress.className).toContain("rmd-circular-progress--small");
expect(progress).toMatchSnapshot();

rerender(
<CircularProgress id="small-circular-progress" small centered={false} />
);

expect(progress.className).toContain("rmd-circular-progress--small");
expect(progress).toMatchSnapshot();
});
});
@@ -97,3 +97,47 @@ exports[`CircularProgress should render correctly 3`] = `
</span>
</div>
`;

exports[`CircularProgress should support a small variant 1`] = `
<span
aria-valuemax="100"
aria-valuemin="0"
class="rmd-circular-progress rmd-circular-progress--centered rmd-circular-progress--small"
id="small=pgoress"
role="progressbar"
>
<svg
class="rmd-circular-progress__svg rmd-circular-progress__svg--indeterminate"
viewBox="0 0 66 66"
>
<circle
class="rmd-circular-progress__circle rmd-circular-progress__circle--indeterminate"
cx="33"
cy="33"
r="30"
/>
</svg>
</span>
`;

exports[`CircularProgress should support a small variant 2`] = `
<span
aria-valuemax="100"
aria-valuemin="0"
class="rmd-circular-progress rmd-circular-progress--small"
id="small-circular-progress"
role="progressbar"
>
<svg
class="rmd-circular-progress__svg rmd-circular-progress__svg--indeterminate"
viewBox="0 0 66 66"
>
<circle
class="rmd-circular-progress__circle rmd-circular-progress__circle--indeterminate"
cx="33"
cy="33"
r="30"
/>
</svg>
</span>
`;

0 comments on commit 6884a3a

Please sign in to comment.