✨(LabelledBox) add classic variant support
- Add variant prop to LabelledBox component - Ignore labelAsPlaceholder in classic mode - Add CSS styles for .labelled-box--classic - Add unit tests for both variants Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,4 +77,30 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--classic {
|
||||
label {
|
||||
position: static;
|
||||
margin-bottom: var(
|
||||
--c--components--forms-labelledbox--classic-label-margin-bottom
|
||||
);
|
||||
font-size: var(
|
||||
--c--components--forms-labelledbox--classic-label-font-size
|
||||
);
|
||||
color: var(--c--components--forms-labelledbox--label-color--small);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.labelled-box__children {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&.labelled-box--disabled {
|
||||
label {
|
||||
color: var(
|
||||
--c--components--forms-labelledbox--label-color--small--disabled
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
124
packages/react/src/components/Forms/LabelledBox/index.spec.tsx
Normal file
124
packages/react/src/components/Forms/LabelledBox/index.spec.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { expect } from "vitest";
|
||||
import { LabelledBox } from "./index";
|
||||
|
||||
describe("<LabelledBox/>", () => {
|
||||
describe("floating variant (default)", () => {
|
||||
it("renders with floating variant by default", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label">
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const container = document.querySelector(".labelled-box");
|
||||
expect(container).not.toHaveClass("labelled-box--classic");
|
||||
});
|
||||
|
||||
it("applies placeholder class when labelAsPlaceholder is true", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" labelAsPlaceholder={true}>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const label = screen.getByText("Test Label");
|
||||
expect(label.closest("label")).toHaveClass("placeholder");
|
||||
});
|
||||
|
||||
it("does not apply placeholder class when labelAsPlaceholder is false", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" labelAsPlaceholder={false}>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const label = screen.getByText("Test Label");
|
||||
expect(label.closest("label")).not.toHaveClass("placeholder");
|
||||
});
|
||||
});
|
||||
|
||||
describe("classic variant", () => {
|
||||
it("renders with classic variant class", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" variant="classic">
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const container = document.querySelector(".labelled-box");
|
||||
expect(container).toHaveClass("labelled-box--classic");
|
||||
});
|
||||
|
||||
it("ignores labelAsPlaceholder in classic variant", () => {
|
||||
render(
|
||||
<LabelledBox
|
||||
label="Test Label"
|
||||
variant="classic"
|
||||
labelAsPlaceholder={true}
|
||||
>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const label = screen.getByText("Test Label");
|
||||
// In classic variant, placeholder class should NOT be applied even if labelAsPlaceholder is true
|
||||
expect(label.closest("label")).not.toHaveClass("placeholder");
|
||||
});
|
||||
|
||||
it("label is always static in classic variant regardless of labelAsPlaceholder", () => {
|
||||
const { rerender } = render(
|
||||
<LabelledBox
|
||||
label="Test Label"
|
||||
variant="classic"
|
||||
labelAsPlaceholder={false}
|
||||
>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
let label = screen.getByText("Test Label");
|
||||
expect(label.closest("label")).not.toHaveClass("placeholder");
|
||||
|
||||
rerender(
|
||||
<LabelledBox
|
||||
label="Test Label"
|
||||
variant="classic"
|
||||
labelAsPlaceholder={true}
|
||||
>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
label = screen.getByText("Test Label");
|
||||
expect(label.closest("label")).not.toHaveClass("placeholder");
|
||||
});
|
||||
});
|
||||
|
||||
describe("other props work with both variants", () => {
|
||||
it("applies disabled class in floating variant", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" disabled>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const container = document.querySelector(".labelled-box");
|
||||
expect(container).toHaveClass("labelled-box--disabled");
|
||||
});
|
||||
|
||||
it("applies disabled class in classic variant", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" variant="classic" disabled>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const container = document.querySelector(".labelled-box");
|
||||
expect(container).toHaveClass("labelled-box--classic");
|
||||
expect(container).toHaveClass("labelled-box--disabled");
|
||||
});
|
||||
|
||||
it("applies hideLabel in classic variant", () => {
|
||||
render(
|
||||
<LabelledBox label="Test Label" variant="classic" hideLabel>
|
||||
<input type="text" />
|
||||
</LabelledBox>,
|
||||
);
|
||||
const label = screen.getByText("Test Label");
|
||||
expect(label.closest("label")).toHaveClass("c__offscreen");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,10 @@
|
||||
import React, { PropsWithChildren } from "react";
|
||||
import classNames from "classnames";
|
||||
import type { FieldVariant } from ":/components/Forms/types";
|
||||
|
||||
export interface Props extends PropsWithChildren {
|
||||
label?: string;
|
||||
variant?: FieldVariant;
|
||||
labelAsPlaceholder?: boolean;
|
||||
htmlFor?: string;
|
||||
labelId?: string;
|
||||
@@ -14,6 +16,7 @@ export interface Props extends PropsWithChildren {
|
||||
export const LabelledBox = ({
|
||||
children,
|
||||
label,
|
||||
variant = "floating",
|
||||
labelAsPlaceholder,
|
||||
htmlFor,
|
||||
labelId,
|
||||
@@ -21,9 +24,12 @@ export const LabelledBox = ({
|
||||
horizontal,
|
||||
disabled,
|
||||
}: Props) => {
|
||||
const isClassic = variant === "classic";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames("labelled-box", {
|
||||
"labelled-box--classic": isClassic,
|
||||
"labelled-box--no-label": hideLabel,
|
||||
"labelled-box--horizontal": horizontal,
|
||||
"labelled-box--disabled": disabled,
|
||||
@@ -32,7 +38,8 @@ export const LabelledBox = ({
|
||||
{label && (
|
||||
<label
|
||||
className={classNames("labelled-box__label", {
|
||||
placeholder: labelAsPlaceholder,
|
||||
// In classic variant, labelAsPlaceholder is ignored (label is always static)
|
||||
placeholder: !isClassic && labelAsPlaceholder,
|
||||
c__offscreen: hideLabel,
|
||||
})}
|
||||
htmlFor={htmlFor}
|
||||
|
||||
Reference in New Issue
Block a user