diff --git a/packages/react/src/components/Forms/LabelledBox/_index.scss b/packages/react/src/components/Forms/LabelledBox/_index.scss index 6f07a6b..d3536e5 100644 --- a/packages/react/src/components/Forms/LabelledBox/_index.scss +++ b/packages/react/src/components/Forms/LabelledBox/_index.scss @@ -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 + ); + } + } + } } diff --git a/packages/react/src/components/Forms/LabelledBox/index.spec.tsx b/packages/react/src/components/Forms/LabelledBox/index.spec.tsx new file mode 100644 index 0000000..d590839 --- /dev/null +++ b/packages/react/src/components/Forms/LabelledBox/index.spec.tsx @@ -0,0 +1,124 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { expect } from "vitest"; +import { LabelledBox } from "./index"; + +describe("", () => { + describe("floating variant (default)", () => { + it("renders with floating variant by default", () => { + render( + + + , + ); + const container = document.querySelector(".labelled-box"); + expect(container).not.toHaveClass("labelled-box--classic"); + }); + + it("applies placeholder class when labelAsPlaceholder is true", () => { + render( + + + , + ); + const label = screen.getByText("Test Label"); + expect(label.closest("label")).toHaveClass("placeholder"); + }); + + it("does not apply placeholder class when labelAsPlaceholder is false", () => { + render( + + + , + ); + const label = screen.getByText("Test Label"); + expect(label.closest("label")).not.toHaveClass("placeholder"); + }); + }); + + describe("classic variant", () => { + it("renders with classic variant class", () => { + render( + + + , + ); + const container = document.querySelector(".labelled-box"); + expect(container).toHaveClass("labelled-box--classic"); + }); + + it("ignores labelAsPlaceholder in classic variant", () => { + render( + + + , + ); + 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( + + + , + ); + let label = screen.getByText("Test Label"); + expect(label.closest("label")).not.toHaveClass("placeholder"); + + rerender( + + + , + ); + 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( + + + , + ); + const container = document.querySelector(".labelled-box"); + expect(container).toHaveClass("labelled-box--disabled"); + }); + + it("applies disabled class in classic variant", () => { + render( + + + , + ); + 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( + + + , + ); + const label = screen.getByText("Test Label"); + expect(label.closest("label")).toHaveClass("c__offscreen"); + }); + }); +}); diff --git a/packages/react/src/components/Forms/LabelledBox/index.tsx b/packages/react/src/components/Forms/LabelledBox/index.tsx index db1a22d..fd173c7 100644 --- a/packages/react/src/components/Forms/LabelledBox/index.tsx +++ b/packages/react/src/components/Forms/LabelledBox/index.tsx @@ -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 (