Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(switch): enhances Switch component to allow inline variant in new validation redesign #7023

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/__internal__/checkable-input/checkable-input.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import styled, { css } from "styled-components";

import FieldHelpStyle from "../field-help/field-help.style";
import { FieldLineStyle } from "../form-field/form-field.style";
import HiddenCheckableInputStyle from "./hidden-checkable-input.style";
import LabelStyle, { StyledLabelContainer } from "../label/label.style";
import StyledHelp from "../../components/help/help.style";
import StyledValidationIcon from "../validations/validation-icon.style";
import StyledHelp from "../../components/help/help.style";

import HiddenCheckableInputStyle from "./hidden-checkable-input.style";

const StyledCheckableInput = styled.div`
display: inline-block;
Expand All @@ -30,6 +31,8 @@ const StyledCheckableInputWrapper = styled.div<StyledCheckableInputWrapperProps>
labelInline,
reverse,
}) => css`
width: 100% !important;
damienrobson-sage marked this conversation as resolved.
Show resolved Hide resolved

${FieldLineStyle} {
display: flex;
}
Expand Down Expand Up @@ -105,6 +108,7 @@ const StyledCheckableInputWrapper = styled.div<StyledCheckableInputWrapperProps>
css`
${StyledCheckableInput} {
width: ${inputWidth}% !important;
damienrobson-sage marked this conversation as resolved.
Show resolved Hide resolved
min-width: 67px;
}
`}

Expand Down
4 changes: 4 additions & 0 deletions src/__internal__/label/label.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export interface LabelProps
className?: string;
/** Sets aria-label for label element */
"aria-label"?: string;
/** Whether this component is shown against a dark background */
isDarkBackground?: boolean;
}

const shouldDisplayValidationIcon = ({
Expand Down Expand Up @@ -70,6 +72,7 @@ export const Label = ({
htmlFor,
info,
inline,
isDarkBackground = false,
isRequired,
labelId,
optional,
Expand Down Expand Up @@ -165,6 +168,7 @@ export const Label = ({
isRequired={isRequired}
as={as}
aria-label={ariaLabel}
isDarkBackground={isDarkBackground}
>
{children}
</StyledLabel>
Expand Down
8 changes: 7 additions & 1 deletion src/__internal__/label/label.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ export interface StyledLabelProps {
disabled?: boolean;
/** Flag to configure component as mandatory */
isRequired?: boolean;
/** Flag to determine whether to use colours for dark backgrounds */
isDarkBackground?: boolean;
}

const StyledLabel = styled.label<StyledLabelProps>`
color: var(--colorsUtilityYin090);
${({ isDarkBackground }) => css`
color: ${isDarkBackground
? "var(--colorsUtilityYang100)"
: "var(--colorsUtilityYin090)"};
`}
display: block;
font-weight: var(--fontWeights500);

Expand Down
18 changes: 18 additions & 0 deletions src/__internal__/label/label.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,21 @@ test("renders with expected styles when `inline` is true and `align` is 'left'",
justifyContent: "flex-start",
});
});

// coverage
test("renders with dark background styles when `isDarkBackground` is true", () => {
render(<Label isDarkBackground>foo</Label>);

expect(screen.getByTestId("label-container").childNodes[0]).toHaveStyle({
color: "var(--colorsUtilityYang100)",
});
});

// coverage
test("renders with normal styles when `isDarkBackground` is false", () => {
render(<Label isDarkBackground={false}>foo</Label>);

expect(screen.getByTestId("label-container").childNodes[0]).toHaveStyle({
color: "var(--colorsUtilityYin090)",
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ export interface ValidationMessageProps {
/** Indicate that warning has occurred
Pass string to display hint with warning */
warning?: boolean | string;
/** Whether this component resides on a dark background */
isDarkBackground?: boolean;
}

const ValidationMessage = ({
error,
validationId,
warning,
isDarkBackground,
}: ValidationMessageProps) => {
const validation = error || warning;
const isStringValidation = typeof validation === "string";
Expand All @@ -25,6 +28,7 @@ const ValidationMessage = ({
id={validationId}
isWarning={!!(!error && warning)}
data-role="validation-message"
isDarkBackground={isDarkBackground}
>
{validation}
</StyledValidationMessage>
Expand Down
20 changes: 12 additions & 8 deletions src/__internal__/validation-message/validation-message.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ import styled, { css } from "styled-components";

interface StyledValidationMessageProps {
isWarning?: boolean;
isDarkBackground?: boolean;
}

const StyledValidationMessage = styled.p<StyledValidationMessageProps>`
${({ isWarning }) => css`
color: ${isWarning
? "var(--colorsSemanticCaution600)"
: "var(--colorsSemanticNegative500)"};
font-weight: ${isWarning ? "normal" : "500"};
margin-top: 0px;
margin-bottom: 8px;
`}
${({ isWarning, isDarkBackground }) => {
const darkBgColour = isDarkBackground
? "var(--colorsSemanticNegative450)"
: "var(--colorsSemanticNegative500)";
return css`
color: ${isWarning ? "var(--colorsSemanticCaution600)" : darkBgColour};
font-weight: ${isWarning ? "normal" : "500"};
margin-top: 0px;
margin-bottom: 8px;
`;
}}
`;

export default StyledValidationMessage;
18 changes: 18 additions & 0 deletions src/__internal__/validation-message/validation-message.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,21 @@ test("sets the 'id' attribute to the value of the `validationId` prop", () => {
const validationMessage = screen.getByTestId("validation-message");
expect(validationMessage).toHaveAttribute("id", "foo");
});

// coverage
test("renders with the correct colour when `isDarkBackground` is true", () => {
render(<ValidationMessage error="error" isDarkBackground />);

expect(screen.getByTestId("validation-message")).toHaveStyle({
color: "var(--colorsSemanticNegative450)",
});
});

// coverage
test("renders with the correct colour when `isDarkBackground` is false", () => {
render(<ValidationMessage error="error" isDarkBackground={false} />);

expect(screen.getByTestId("validation-message")).toHaveStyle({
color: "var(--colorsSemanticNegative500)",
});
});
18 changes: 13 additions & 5 deletions src/components/switch/__internal__/switch-slider-panel.style.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import styled, { css } from "styled-components";

import StyledLoader from "../../loader/loader.style";
import StyledLoaderSquare from "../../loader/loader-square.style";
import { SwitchProps } from "../switch.component";
import StyledLoaderSquare from "../../loader/loader-square.style";
import StyledLoader from "../../loader/loader.style";

export interface SwitchSliderPanelProps {
isLoading?: boolean;
size?: SwitchProps["size"];
isDarkBackground?: boolean;
}

const SwitchSliderPanel = styled.div`
${({ isLoading, size }: SwitchSliderPanelProps) => css`
${({ isLoading, size, isDarkBackground }: SwitchSliderPanelProps) => css`
border: 0;
color: var(--colorsActionMinorYang100);
color: ${isDarkBackground
? "var(--colorsUtilityYin100)"
: "var(--colorsActionMinorYang100)"};
margin: auto;
position: absolute;
left: 0;

&[type="on"] {
color: ${isDarkBackground
? "var(--colorsUtilityYin100)"
: "var(--colorsUtilityYang100)"};
margin-left: 9px;
padding-right: ${size === "large" ? "43px" : "27px"};
}

&[type="off"] {
color: var(--colorsActionMinor500);
color: ${isDarkBackground
? "var(--colorsUtilityYang100)"
: "var(--colorsActionMinor500)"};
margin-right: 9px;
padding-left: ${size === "large" ? "43px" : "27px"};
}
Expand Down
18 changes: 18 additions & 0 deletions src/components/switch/__internal__/switch-slider-panel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,21 @@ describe("when the theme is set to sageTheme", () => {
);
});
});

// coverage
test("renders with normal styles when `isDarkBackground` is false", () => {
render(<Switch onChange={() => {}} isDarkBackground={false} />);

const switchPanel = screen.getByTestId("slider-panel");

expect(switchPanel).toHaveStyleRule("color: var(--colorsActionMinorYang100)");
});

// coverage
test("renders with dark background styles when `isDarkBackground` is true", () => {
render(<Switch onChange={() => {}} isDarkBackground />);

const switchPanel = screen.getByTestId("slider-panel");

expect(switchPanel).toHaveStyleRule("color: var(--colorsUtilityYin100)");
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface SwitchSliderProps extends ValidationProps {
loading?: boolean;
size?: "small" | "large";
useValidationIcon?: boolean;
isDarkBackground?: boolean;
}

const SwitchSlider = ({
Expand All @@ -24,6 +25,7 @@ const SwitchSlider = ({
warning,
info,
useValidationIcon,
isDarkBackground,
}: SwitchSliderProps) => {
const locale = useLocale();
const onText = locale.switch.on();
Expand All @@ -45,13 +47,15 @@ const SwitchSlider = ({
error,
warning,
info,
isDarkBackground,
};

const sliderPanelStyleProps = {
isLoading: loading,
size,
type: checked ? "on" : "off",
disabled,
isDarkBackground,
};

const loaderProps = {
Expand Down
27 changes: 21 additions & 6 deletions src/components/switch/__internal__/switch-slider.style.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import styled, { css } from "styled-components";

import SwitchSliderPanel from "./switch-slider-panel.style";
import StyledValidationIcon from "../../../__internal__/validations/validation-icon.style";
import { SwitchSliderProps } from "./switch-slider.component";
import baseTheme, { ThemeObject } from "../../../style/themes/base";

import SwitchSliderPanel from "./switch-slider-panel.style";
import { SwitchSliderProps } from "./switch-slider.component";

interface StyledSwitchSliderProps
extends Pick<
SwitchSliderProps,
"checked" | "disabled" | "size" | "error" | "warning"
> {
isLoading?: boolean;
theme?: Partial<ThemeObject>;
isDarkBackground?: boolean;
}

const StyledSwitchSlider = styled.div`
Expand All @@ -23,6 +25,7 @@ const StyledSwitchSlider = styled.div`
error,
warning,
theme,
isDarkBackground,
}: StyledSwitchSliderProps) => css`
display: flex;
font-size: 12px;
Expand All @@ -39,14 +42,22 @@ const StyledSwitchSlider = styled.div`
theme?.roundedCornersOptOut ? "90px" : "var(--borderRadius400)"
};
border-style: solid;
border-color: var(--colorsActionMinor400);
border-color: ${
isDarkBackground
? "var(--colorsUtilityYang100)"
: "var(--colorsActionMinor400)"
};
border-width: var(--borderWidth200);
box-sizing: border-box;
margin-top: ${size === "large" ? "-47px" : "-28px"};
align-items: center;

&::before {
background-color: var(--colorsActionMinor400);
background-color: ${
isDarkBackground
? "var(--colorsUtilityYang100)"
: "var(--colorsActionMinor400)"
};
bottom: 4px;
content: "";
height: ${size === "large" ? "var(--spacing400)" : "var(--spacing200)"};
Expand All @@ -61,15 +72,19 @@ const StyledSwitchSlider = styled.div`
${
checked &&
css`
background-color: var(--colorsActionMinor500);
background-color: ${isDarkBackground
? "var(--colorsUtilityYang100)"
: "var(--colorsActionMinor500)"};
border-color: var(--colorsActionMinorTransparent);

&::before {
margin-left: calc(
100% -
${size === "large" ? "var(--spacing500)" : "var(--spacing300)"}
);
background-color: var(--colorsActionMinorYang100);
background-color: ${isDarkBackground
? "var(--colorsUtilityYin100)"
: "var(--colorsActionMinorYang100)"};
}
`
}
Expand Down
27 changes: 27 additions & 0 deletions src/components/switch/__internal__/switch-slider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,30 @@ test("when `size` is large and the consumer has opted out of rounded corners sty

expect(switchPanel).toHaveStyle("border-radius: 30px");
});

// coverage
test("renders with normal styles when `isDarkBackground` is false", () => {
render(<SwitchSlider isDarkBackground={false} />);

const switchPanel = screen.getByTestId("slider");

expect(switchPanel).toHaveStyleRule("color: var(--colorsActionMinorYang100)");
});

// coverage
test("renders with dark background styles when `isDarkBackground` is true", () => {
render(<SwitchSlider isDarkBackground />);

const switchPanel = screen.getByTestId("slider");

expect(switchPanel).toHaveStyleRule("color: var(--colorsUtilityYin100)");
});

// coverage
test("renders with dark background styles when `isDarkBackground` is true and checked is true", () => {
render(<SwitchSlider isDarkBackground checked />);

const switchPanel = screen.getByTestId("slider");

expect(switchPanel).toHaveStyleRule("color: var(--colorsUtilityYang100)");
});
Loading
Loading