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 (