From 230133415bf186ad6c15640ad90aeca4db829746 Mon Sep 17 00:00:00 2001 From: Mats Bosson Date: Sun, 29 Mar 2026 07:06:29 +0700 Subject: [PATCH] Separator component --- .../core/src/components/separator/index.ts | 2 ++ .../src/components/separator/separator.tsx | 28 +++++++++++++++ .../components/separator/separator.test.tsx | 36 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 packages/core/src/components/separator/index.ts create mode 100644 packages/core/src/components/separator/separator.tsx create mode 100644 packages/core/tests/components/separator/separator.test.tsx diff --git a/packages/core/src/components/separator/index.ts b/packages/core/src/components/separator/index.ts new file mode 100644 index 0000000..487149a --- /dev/null +++ b/packages/core/src/components/separator/index.ts @@ -0,0 +1,2 @@ +export { Separator } from "./separator"; +export type { SeparatorProps } from "./separator"; diff --git a/packages/core/src/components/separator/separator.tsx b/packages/core/src/components/separator/separator.tsx new file mode 100644 index 0000000..84171e4 --- /dev/null +++ b/packages/core/src/components/separator/separator.tsx @@ -0,0 +1,28 @@ +import type { JSX } from "solid-js"; +import { splitProps } from "solid-js"; + +export interface SeparatorProps extends JSX.HTMLAttributes { + /** Visual and ARIA orientation. @default "horizontal" */ + orientation?: "horizontal" | "vertical"; + /** When true, renders role=none (purely visual, not announced). @default false */ + decorative?: boolean; +} + +/** + * A visual divider between sections of content. + * Non-decorative separators are announced by screen readers. + */ +export function Separator(props: SeparatorProps): JSX.Element { + const [local, rest] = splitProps(props, ["orientation", "decorative"]); + const orientation = () => local.orientation ?? "horizontal"; + const isDecorative = () => local.decorative ?? false; + + return ( +
+ ); +} diff --git a/packages/core/tests/components/separator/separator.test.tsx b/packages/core/tests/components/separator/separator.test.tsx new file mode 100644 index 0000000..c850a0d --- /dev/null +++ b/packages/core/tests/components/separator/separator.test.tsx @@ -0,0 +1,36 @@ +import { render, screen } from "@solidjs/testing-library"; +import { describe, expect, it } from "vitest"; +import { Separator } from "../../../src/components/separator/index"; + +describe("Separator", () => { + it("renders with role=separator by default", () => { + render(() => ); + expect(screen.getByRole("separator")).toBeTruthy(); + }); + + it("renders with role=none when decorative", () => { + render(() => ); + expect(screen.queryByRole("separator")).toBeNull(); + expect(screen.getByTestId("sep").getAttribute("role")).toBe("none"); + }); + + it("has data-orientation=horizontal by default", () => { + render(() => ); + expect(screen.getByTestId("sep").getAttribute("data-orientation")).toBe("horizontal"); + }); + + it("has data-orientation=vertical when set", () => { + render(() => ); + expect(screen.getByTestId("sep").getAttribute("data-orientation")).toBe("vertical"); + }); + + it("has aria-orientation=vertical when vertical and not decorative", () => { + render(() => ); + expect(screen.getByTestId("sep").getAttribute("aria-orientation")).toBe("vertical"); + }); + + it("does not have aria-orientation when horizontal (default)", () => { + render(() => ); + expect(screen.getByTestId("sep").getAttribute("aria-orientation")).toBeNull(); + }); +});