diff --git a/cypress/features/regression/accessibility/accessibilityDesignSystem.feature b/cypress/features/regression/accessibility/accessibilityDesignSystem.feature index 0575eda2ef..4f8da11cc6 100644 --- a/cypress/features/regression/accessibility/accessibilityDesignSystem.feature +++ b/cypress/features/regression/accessibility/accessibilityDesignSystem.feature @@ -123,6 +123,7 @@ Feature: Accessibility tests - Design System folder | Flat Table | | Hr | | Image | + | Loader Bar | | Loader | | Pager | | Simple color picker | diff --git a/cypress/features/regression/test/loader.feature b/cypress/features/regression/test/loader.feature index 60f3ce0385..c7786a8eac 100644 --- a/cypress/features/regression/test/loader.feature +++ b/cypress/features/regression/test/loader.feature @@ -4,20 +4,22 @@ Feature: Loader default component @positive Scenario Outline: I set Loader component size to When I open Test default "Loader" component in noIFrame with "loader" json from "commonComponents" using "" object name - Then Loader width is set to 1366 px and height is set to px + Then Loader width and height is set to px and margin is set to px Examples: - | size | height | nameOfObject | - | small | 17 | sizeSmall | - | large | 19 | sizeLarge | + | size | height | margin | nameOfObject | + | small | 12 | 6 | sizeSmall | + | default | 16 | 8 | sizeDefault | + | large | 20 | 8 | sizeLarge | @positive - Scenario Outline: Verify size of button with loader + Scenario Outline: Verify size of button with loader When I open Test default "Loader" component in noIFrame with "loader" json from "commonComponents" using "" object name Then button with loader width is set to px and height is set to 40 px Examples: - | size | width | nameOfObject | - | small | 88 | isInsideButtonSmall | - | large | 120 | isInsideButtonLarge | + | size | width | nameOfObject | + | small | 100 | isInsideButtonSmall | + | default | 116 | isInsideButtonDefault | + | large | 128 | isInsideButtonLarge | @positive Scenario: Loader isInsideButton diff --git a/cypress/features/regression/test/loaderBar.feature b/cypress/features/regression/test/loaderBar.feature new file mode 100644 index 0000000000..de3147c181 --- /dev/null +++ b/cypress/features/regression/test/loaderBar.feature @@ -0,0 +1,12 @@ +Feature: Loader Bar default component + I want to test Loader Bar component properties + + @positive + Scenario Outline: I set Loader Bar component size to + When I open Test default "Loader Bar" component in noIFrame with "loaderBar" json from "commonComponents" using "" object name + Then Loader Bar height is set to px + Examples: + | size | height | nameOfObject | + | small | 4 | sizeSmall | + | default | 8 | sizeDefault | + | large | 16 | sizeLarge | \ No newline at end of file diff --git a/cypress/features/regression/themes/themes.feature b/cypress/features/regression/themes/themes.feature index e002764d6d..c3d455ce04 100644 --- a/cypress/features/regression/themes/themes.feature +++ b/cypress/features/regression/themes/themes.feature @@ -52,6 +52,16 @@ Feature: Theming addon | aegean | themeAegean | | none | themeNone | + @positive + Scenario Outline: I set Loader Bar component theme to + When I open Test default "Loader Bar" component in noIFrame with "themeNames" json from "themes" using "" object name + Then Loader Bar component css background color is set to "" + Examples: + | theme | nameOfObject | + | mint | themeMint | + | aegean | themeAegean | + | none | themeNone | + @positive Scenario Outline: I set Multiaction Button component theme to When I open default-story "Multi action button" component in noIFrame with "themeNames" json from "themes" using "" object name diff --git a/cypress/fixtures/commonComponents/loader.json b/cypress/fixtures/commonComponents/loader.json index c9288813ff..825a386720 100644 --- a/cypress/fixtures/commonComponents/loader.json +++ b/cypress/fixtures/commonComponents/loader.json @@ -1,4 +1,7 @@ { + "sizeDefault": { + + }, "sizeSmall": { "size": "small" }, @@ -9,6 +12,10 @@ "isInsideButton": true, "size": "small" }, + "isInsideButtonDefault": { + "isInsideButton": true, + "size": "medium" + }, "isInsideButtonLarge": { "isInsideButton": true, "size": "large" diff --git a/cypress/fixtures/commonComponents/loaderBar.json b/cypress/fixtures/commonComponents/loaderBar.json new file mode 100644 index 0000000000..a7b72a6f19 --- /dev/null +++ b/cypress/fixtures/commonComponents/loaderBar.json @@ -0,0 +1,11 @@ +{ + "sizeDefault": { + + }, + "sizeSmall": { + "size": "small" + }, + "sizeLarge": { + "size": "large" + } +} \ No newline at end of file diff --git a/cypress/fixtures/themes/themes.json b/cypress/fixtures/themes/themes.json index 3af841f70b..0625f68dcd 100644 --- a/cypress/fixtures/themes/themes.json +++ b/cypress/fixtures/themes/themes.json @@ -13,5 +13,10 @@ "mint": "rgb(0, 126, 91)", "aegean": "rgb(0, 92, 154)", "none": "rgb(0, 130, 0)" + }, + "loader-bar": { + "mint": "rgb(179, 227, 214)", + "aegean": "rgb(179, 214, 239)", + "none": "rgb(179, 224, 179)" } } \ No newline at end of file diff --git a/cypress/locators/loader-bar/index.js b/cypress/locators/loader-bar/index.js new file mode 100644 index 0000000000..3658c1a75c --- /dev/null +++ b/cypress/locators/loader-bar/index.js @@ -0,0 +1,5 @@ +import LOADER_BAR from "./locators"; + +const loaderBar = () => cy.get(LOADER_BAR); + +export default loaderBar; diff --git a/cypress/locators/loader-bar/locators.js b/cypress/locators/loader-bar/locators.js new file mode 100644 index 0000000000..93465b04e8 --- /dev/null +++ b/cypress/locators/loader-bar/locators.js @@ -0,0 +1,4 @@ +// component preview locators +const LOADER_BAR = '[data-component="loader-bar"]'; + +export default LOADER_BAR; diff --git a/cypress/locators/loader/index.js b/cypress/locators/loader/index.js index 2aba2c3bc9..8d430358d2 100644 --- a/cypress/locators/loader/index.js +++ b/cypress/locators/loader/index.js @@ -1,5 +1,5 @@ import LOADER from "./locators"; import { BUTTON_DATA_COMPONENT_PREVIEW } from "../button/locators"; -export const loader = () => cy.get(LOADER); +export const loader = (index) => cy.get(LOADER).find("div").eq(index); export const loaderInsideButton = () => cy.get(BUTTON_DATA_COMPONENT_PREVIEW); diff --git a/cypress/locators/themes/index.js b/cypress/locators/themes/index.js index f8ca71f1d1..a9cdb60747 100644 --- a/cypress/locators/themes/index.js +++ b/cypress/locators/themes/index.js @@ -2,6 +2,7 @@ import { getComponent } from ".."; export const theme = (themeName) => cy.get(`[data-theme="${themeName}"]`); export const buttonToggleComponent = () => -getComponent("button-toggle").first().find("label"); + getComponent("button-toggle").first().find("label"); export const linkComponent = () => getComponent("link"); export const loaderComponent = () => getComponent("loader").find("div"); +export const loaderBarComponent = () => getComponent("loader-bar"); diff --git a/cypress/support/step-definitions/loader-bar-steps.js b/cypress/support/step-definitions/loader-bar-steps.js new file mode 100644 index 0000000000..500db29294 --- /dev/null +++ b/cypress/support/step-definitions/loader-bar-steps.js @@ -0,0 +1,11 @@ +import loaderBar from "../../locators/loader-bar"; + +Then("Loader Bar height is set to {int} px", (height) => { + loaderBar().children().should("have.css", "height", `${height}px`); + loaderBar() + .children() + .children() + .should("have.css", "height", `${height}px`) + .and("have.css", "animation-duration", "2s") + .and("have.css", "animation-play-state", "running"); +}); diff --git a/cypress/support/step-definitions/loader-steps.js b/cypress/support/step-definitions/loader-steps.js index 8c5b64fc07..67796e0f9d 100644 --- a/cypress/support/step-definitions/loader-steps.js +++ b/cypress/support/step-definitions/loader-steps.js @@ -1,11 +1,23 @@ import { loader, loaderInsideButton } from "../../locators/loader"; Then( - "Loader width is set to {int} px and height is set to {int} px", - (width, height) => { - loader() - .should("have.css", "height", `${height}px`) - .and("have.css", "width", `${width}px`); + "Loader width and height is set to {int} px and margin is set to {int} px", + (widthAndHeight, margin) => { + loader(0) + .should("have.css", "height", `${widthAndHeight}px`) + .and("have.css", "width", `${widthAndHeight}px`) + .and("have.css", "animation-delay", "0s") + .and("have.css", "margin-right", `${margin}px`); + loader(1) + .should("have.css", "height", `${widthAndHeight}px`) + .and("have.css", "width", `${widthAndHeight}px`) + .and("have.css", "animation-delay", "0.2s") + .and("have.css", "margin-right", `${margin}px`); + loader(2) + .should("have.css", "height", `${widthAndHeight}px`) + .and("have.css", "width", `${widthAndHeight}px`) + .and("have.css", "animation-delay", "0.4s") + .and("have.css", "margin-right", "0px"); } ); diff --git a/cypress/support/step-definitions/select-steps.js b/cypress/support/step-definitions/select-steps.js index 90218a66b1..c2be8670f5 100644 --- a/cypress/support/step-definitions/select-steps.js +++ b/cypress/support/step-definitions/select-steps.js @@ -159,7 +159,9 @@ When("I click on Select input with lazy loading in no iframe", () => { }); Then("Lazy loading is visible", () => { - loader().should("be.visible"); + for (let i = 0; i < 3; i++) { + loader(i).should("be.visible"); + } }); When("I scroll to the {string} of Select List", (direction) => { diff --git a/cypress/support/step-definitions/themes-steps.js b/cypress/support/step-definitions/themes-steps.js index 929f15835c..c72d0f090b 100644 --- a/cypress/support/step-definitions/themes-steps.js +++ b/cypress/support/step-definitions/themes-steps.js @@ -1,10 +1,8 @@ -import { - getComponent, - getElement, -} from "../../locators"; +import { getComponent, getElement } from "../../locators"; import { buttonToggleComponent, linkComponent, + loaderBarComponent, loaderComponent, } from "../../locators/themes"; @@ -85,3 +83,18 @@ Then( }); } ); + +Then( + "Loader Bar component css background color is set to {string}", + (themeName) => { + cy.fixture("themes/themes.json").then((json) => { + loaderBarComponent() + .children() + .should("have.css", BACKGROUND_COLOR, json["loader-bar"][themeName]); + loaderBarComponent() + .children() + .children() + .should("have.css", BACKGROUND_COLOR, json.common[themeName]); + }); + } +); diff --git a/src/components/loader-bar/index.d.ts b/src/components/loader-bar/index.d.ts new file mode 100644 index 0000000000..2e2f5d32b6 --- /dev/null +++ b/src/components/loader-bar/index.d.ts @@ -0,0 +1 @@ +export { default } from "./loader-bar"; diff --git a/src/components/loader-bar/index.js b/src/components/loader-bar/index.js new file mode 100644 index 0000000000..35ffdece0f --- /dev/null +++ b/src/components/loader-bar/index.js @@ -0,0 +1 @@ +export { default } from "./loader-bar.component"; diff --git a/src/components/loader-bar/loader-bar-test.stories.mdx b/src/components/loader-bar/loader-bar-test.stories.mdx new file mode 100644 index 0000000000..8b44a4ce5b --- /dev/null +++ b/src/components/loader-bar/loader-bar-test.stories.mdx @@ -0,0 +1,36 @@ +import { Meta, Story, Preview } from "@storybook/addon-docs"; +import LoaderBar from "."; +import Button from "../button"; +import { LOADER_BAR_SIZES } from "./loader-bar.config"; + + + +export const LoaderStory = ({ size, ...args }) => { + return ; +}; + +# LoaderBar + +### Default + + + + {LoaderStory.bind({})} + + diff --git a/src/components/loader-bar/loader-bar.component.js b/src/components/loader-bar/loader-bar.component.js new file mode 100644 index 0000000000..35f67f05af --- /dev/null +++ b/src/components/loader-bar/loader-bar.component.js @@ -0,0 +1,28 @@ +import React from "react"; +import PropTypes from "prop-types"; +import styledSystemPropTypes from "@styled-system/prop-types"; +import tagComponent from "../../utils/helpers/tags"; +import StyledLoaderBar, { InnerBar, StyledLoader } from "./loader-bar.style"; +import { filterStyledSystemMarginProps } from "../../style/utils"; + +const marginPropTypes = filterStyledSystemMarginProps( + styledSystemPropTypes.space +); + +const LoaderBar = ({ size = "medium", ...rest }) => { + return ( + + + + + + ); +}; + +LoaderBar.propTypes = { + ...marginPropTypes, + /** Size of the loader. */ + size: PropTypes.oneOf(["small", "medium", "large"]), +}; + +export default LoaderBar; diff --git a/src/components/loader-bar/loader-bar.config.js b/src/components/loader-bar/loader-bar.config.js new file mode 100644 index 0000000000..2cbe0163c7 --- /dev/null +++ b/src/components/loader-bar/loader-bar.config.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/prefer-default-export +export const LOADER_BAR_SIZES = ["small", "medium", "large"]; diff --git a/src/components/loader-bar/loader-bar.d.ts b/src/components/loader-bar/loader-bar.d.ts new file mode 100644 index 0000000000..dc79e48746 --- /dev/null +++ b/src/components/loader-bar/loader-bar.d.ts @@ -0,0 +1,10 @@ +import { MarginProps } from "styled-system"; + +export interface LoaderBarProps extends MarginProps { + /** Size of the loaderBar. */ + size?: "small" | "medium" | "large"; +} + +declare function LoaderBar(props: LoaderBarProps): JSX.Element; + +export default LoaderBar; diff --git a/src/components/loader-bar/loader-bar.spec.js b/src/components/loader-bar/loader-bar.spec.js new file mode 100644 index 0000000000..857f29693f --- /dev/null +++ b/src/components/loader-bar/loader-bar.spec.js @@ -0,0 +1,78 @@ +import React from "react"; +import { mount } from "enzyme"; +import StyledLoaderBar, { InnerBar } from "./loader-bar.style"; +import { assertStyleMatch } from "../../__spec_helper__/test-utils"; +import baseTheme from "../../style/themes/base"; +import LoaderBar from "./loader-bar.component"; + +describe("LoaderBar", () => { + let wrapper; + it("renders component as expected", () => { + wrapper = mount(); + const innerBar = wrapper.find(InnerBar); + expect(innerBar).toBeTruthy(); + }); + + describe("when size is not specified", () => { + beforeEach(() => { + wrapper = mount(); + }); + it("renders outer bar as expected", () => { + assertStyleMatch( + { + backgroundColor: baseTheme.colors.loadingBarBackground, + width: "256px", + height: "8px", + }, + wrapper.find(StyledLoaderBar) + ); + }); + it("renders inner bar as expected", () => { + assertStyleMatch( + { + backgroundColor: baseTheme.colors.primary, + width: "128px", + height: "8px", + }, + wrapper.find(InnerBar) + ); + }); + }); + + describe("when size is set to small", () => { + beforeEach(() => { + wrapper = mount(); + }); + it("applies proper width and height to outer bar", () => { + assertStyleMatch( + { width: "256px", height: "4px" }, + wrapper.find(StyledLoaderBar) + ); + }); + + it("applies proper width and height to inner bar", () => { + assertStyleMatch( + { width: "128px", height: "4px" }, + wrapper.find(InnerBar) + ); + }); + }); + describe("when size is set to large", () => { + beforeEach(() => { + wrapper = mount(); + }); + it("applies proper width and height to outer bar", () => { + assertStyleMatch( + { width: "256px", height: "16px" }, + wrapper.find(StyledLoaderBar) + ); + }); + + it("applies proper width and height to inner bar", () => { + assertStyleMatch( + { width: "128px", height: "16px" }, + wrapper.find(InnerBar) + ); + }); + }); +}); diff --git a/src/components/loader-bar/loader-bar.stories.mdx b/src/components/loader-bar/loader-bar.stories.mdx new file mode 100644 index 0000000000..ba497c5566 --- /dev/null +++ b/src/components/loader-bar/loader-bar.stories.mdx @@ -0,0 +1,68 @@ +import { useState } from "react"; +import { Meta, Story, Preview, Props } from "@storybook/addon-docs"; +import LoaderBar from "."; +import Button from "../button"; +import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; + + + +# LoaderBar + +Use the LoaderBar component to let users know a task or loading data is still in progress. +Showing a LoaderBar helps the user to understand that they should wait, rather than reload the page or abandon a process. +In general, place a LoaderBar in the centre and middle of the page or container it relates to. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quick Start + +Import `LoaderBar` into the project. + +```javascript +import LoaderBar from "carbon-react/lib/components/loader-bar"; +``` + +## Examples + +## Default bar + +This example of the LoaderBar component demonstrates how it will appear as default. + + + + + + + +### Small bar + +This is an example of a small LoaderBar component. + + + + + + + +### Large bar + +This is an example of a large LoaderBar component. + + + + + + + +## Props + +### LoaderBar + + diff --git a/src/components/loader-bar/loader-bar.style.js b/src/components/loader-bar/loader-bar.style.js new file mode 100644 index 0000000000..b6e6650959 --- /dev/null +++ b/src/components/loader-bar/loader-bar.style.js @@ -0,0 +1,78 @@ +import styled, { css, keyframes } from "styled-components"; +import PropTypes from "prop-types"; +import { margin } from "styled-system"; +import baseTheme from "../../style/themes/base"; +import { LOADER_BAR_SIZES } from "./loader-bar.config"; + +const INNER_BAR_LENGTH = "128px"; +const OUTER_BAR_LENGTH = "256px"; + +const StyledLoader = styled.div` + ${margin} + text-align: center; + white-space: nowrap; + line-height: 0; + font-size: 0; +`; + +const innerBarAnimation = keyframes` + 0% { + left: -${INNER_BAR_LENGTH} + } + 100% { + left: ${OUTER_BAR_LENGTH} + } +`; + +const StyledLoaderBar = styled.div` + ${({ size, theme }) => css` + display: inline-block; + height: ${getHeight(size)}; + width: ${OUTER_BAR_LENGTH}; + background-color: ${theme.colors.loadingBarBackground}; + overflow: hidden; + position: relative; + `} +`; + +const InnerBar = styled.div` + ${({ theme, size }) => css` + position: absolute; + background-color: ${theme.colors.primary}; + width: ${INNER_BAR_LENGTH}; + height: ${getHeight(size)}; + animation: 2s ${innerBarAnimation} linear 0s infinite normal none running; + `} +`; + +function getHeight(size) { + switch (size) { + case "small": + return "4px"; + case "large": + return "16px"; + default: + return "8px"; + } +} + +StyledLoader.defaultProps = { + theme: baseTheme, +}; + +StyledLoaderBar.defaultProps = { + theme: baseTheme, + size: "medium", +}; + +InnerBar.defaultProps = { + theme: baseTheme, + size: "medium", +}; + +StyledLoaderBar.propTypes = { + size: PropTypes.oneOf(LOADER_BAR_SIZES), +}; + +export { InnerBar, StyledLoader }; +export default StyledLoaderBar; diff --git a/src/components/loader/loader-square.spec.js b/src/components/loader/loader-square.spec.js index 38b8b249af..06947a183f 100644 --- a/src/components/loader/loader-square.spec.js +++ b/src/components/loader/loader-square.spec.js @@ -15,8 +15,8 @@ describe("Loader square", () => { assertStyleMatch( { backgroundColor: baseTheme.colors.primary, - height: "8px", - width: "8px", + height: "12px", + width: "12px", marginRight: "6px", }, wrapper.toJSON() @@ -50,11 +50,25 @@ describe("Loader square", () => { describe("when size is set to large", () => { it("applies proper width, height and margin", () => { wrapper = render({ size: "large" }); + assertStyleMatch( + { + height: "20px", + width: "20px", + marginRight: "8px", + }, + wrapper.toJSON() + ); + }); + }); + + describe("when size is set to medium", () => { + it("applies proper width, height and margin", () => { + wrapper = render({ size: "medium" }); assertStyleMatch( { height: "16px", width: "16px", - marginRight: "10px", + marginRight: "8px", }, wrapper.toJSON() ); diff --git a/src/components/loader/loader-square.style.js b/src/components/loader/loader-square.style.js index fa9558d553..51317cc95d 100644 --- a/src/components/loader/loader-square.style.js +++ b/src/components/loader/loader-square.style.js @@ -14,14 +14,35 @@ const loaderAnimation = keyframes` } `; +const getDimentions = (size) => { + let width; + let marginRight; + switch (size) { + case "medium": + width = "16px"; + marginRight = "8px"; + break; + case "large": + width = "20px"; + marginRight = "8px"; + break; + default: + width = "12px"; + marginRight = "6px"; + } + return ` + width: ${width}; + height: ${width}; + margin-right: ${marginRight}; + `; +}; + const StyledLoaderSquare = styled.div` ${({ theme, size, isInsideButton, isActive }) => css` animation: ${loaderAnimation} 1s infinite ease-in-out both; background-color: ${theme.colors.primary}; display: inline-block; - height: ${size === "large" ? "16px" : "8px"}; - width: ${size === "large" ? "16px" : "8px"}; - margin-right: ${size === "large" ? "10px" : "6px"}; + ${getDimentions(size)} ${isInsideButton && css` diff --git a/src/components/loader/loader.component.js b/src/components/loader/loader.component.js index 2ba0fb1cb6..119fded7d8 100644 --- a/src/components/loader/loader.component.js +++ b/src/components/loader/loader.component.js @@ -33,7 +33,7 @@ const Loader = ({ isInsideButton, isActive, size, ...rest }) => { }; Loader.defaultProps = { - size: "small", + size: "medium", isInsideButton: false, isActive: true, }; @@ -41,7 +41,7 @@ Loader.defaultProps = { Loader.propTypes = { ...marginPropTypes, /** Size of the loader. */ - size: PropTypes.oneOf(["small", "large"]), + size: PropTypes.oneOf(["small", "medium", "large"]), /** Applies white color. */ isInsideButton: PropTypes.bool, /** Applies slate color. Available only when isInsideButton is true. */ diff --git a/src/components/loader/loader.config.js b/src/components/loader/loader.config.js index 70ed8480a9..1743caf1de 100644 --- a/src/components/loader/loader.config.js +++ b/src/components/loader/loader.config.js @@ -1,2 +1,2 @@ // eslint-disable-next-line import/prefer-default-export -export const LOADER_SIZES = ["small", "large"]; +export const LOADER_SIZES = ["small", "medium", "large"]; diff --git a/src/components/loader/loader.d.ts b/src/components/loader/loader.d.ts index 05e6d20088..7a23538d3c 100644 --- a/src/components/loader/loader.d.ts +++ b/src/components/loader/loader.d.ts @@ -2,7 +2,7 @@ import { MarginProps } from "styled-system"; export interface LoaderProps extends MarginProps { /** Size of the loader. */ - size?: "small" | "large"; + size?: "small" | "medium" | "large"; /** Applies white color. */ isInsideButton?: boolean; /** Applies slate color. Available only when isInsideButton is true. */ diff --git a/src/style/themes/aegean/aegean-theme.config.js b/src/style/themes/aegean/aegean-theme.config.js index b2138bade1..5dd86fe8ff 100644 --- a/src/style/themes/aegean/aegean-theme.config.js +++ b/src/style/themes/aegean/aegean-theme.config.js @@ -15,6 +15,7 @@ export default (palette) => { withOpacity: baseWithOpacity(0.55), hoveredTabKeyline: palette.productBlueTint(30), disabled: palette.productBlueTint(40), + loadingBarBackground: palette.productBlueTint(70), }, stepSequence: { diff --git a/src/style/themes/base/base-theme.config.js b/src/style/themes/base/base-theme.config.js index 0303680db0..468070708c 100644 --- a/src/style/themes/base/base-theme.config.js +++ b/src/style/themes/base/base-theme.config.js @@ -22,6 +22,7 @@ export default (palette) => { disabled: palette.genericGreenTint(40), whiteMix: palette.genericGreenTint(90), withOpacity: baseWithOpacity(0.55), + loadingBarBackground: palette.genericGreenTint(70), // generic black: "#000000", diff --git a/src/style/themes/mint/mint-theme.config.js b/src/style/themes/mint/mint-theme.config.js index 58007c89f4..82c0a084c5 100644 --- a/src/style/themes/mint/mint-theme.config.js +++ b/src/style/themes/mint/mint-theme.config.js @@ -10,6 +10,7 @@ export default (palette) => { whiteMix: palette.productGreenTint(90), hoveredTabKeyline: palette.productGreenTint(30), disabled: palette.productGreenTint(40), + loadingBarBackground: palette.productGreenTint(70), }, stepSequence: {