From 6cc2dee2cbf6c29f1863cf848e9d4fb1d0b8660f Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 11:12:02 +1200 Subject: [PATCH 01/33] feat: added docs for bg gradient --- .../src/content/components/bg-gradient.mdx | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/packages/demo/src/content/components/bg-gradient.mdx b/packages/demo/src/content/components/bg-gradient.mdx index 36a138e0..23d2dd0b 100644 --- a/packages/demo/src/content/components/bg-gradient.mdx +++ b/packages/demo/src/content/components/bg-gradient.mdx @@ -1,40 +1,72 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Background Gradient" -description: "Background Gradient with theme variants" +description: "Animated canvas background gradient with theme variants" --- import { BgGradientDemo } from "@demo/components/demo/bg-gradient"; ## Overview -The component supports all brand colors (primary, secondary, tertiary, red, yellow) and will automatically pick up new colors added to the `equality-tokens.json` file. The hex values are read directly from the JSON, keeping the component in sync with design tokens. +The Background Gradient renders a slowly animating field of soft, blurred colour blobs onto a full-viewport ``. It is intended as a decorative backdrop for hero sections, landing pages, and empty states, sitting behind foreground content. + +The gradient colour is driven directly by the brand colours in `equality-tokens.json`. The `theme` prop accepts any brand colour key (`primary`, `secondary`, `green`, `red`, `yellow`), and the component reads the corresponding hex value straight from the tokens — so any brand colours added in the future are picked up automatically. An unrecognised theme falls back to black. + +The `` is sized to the window and positioned by its container, so place `BgGradient` inside a `relative`, sized wrapper. + +## Usage + +Import the component: + +```tsx +import { BgGradient } from "@eqtylab/equality"; +``` + +Basic usage. `theme` is required; `placement` defaults to `"full"`. Wrap it in a positioned, sized container so the canvas has room to fill: + +```tsx +
+ +
+``` ## Theme Variants -### Theme Primary +Set the `theme` prop to any brand colour key to recolour the gradient. - +### Primary -### Theme Secondary + + +### Secondary -### Theme Tertiary +### Green - + -### Theme Red +### Red -### Theme Yellow +### Yellow +### Usage + +```tsx + + + + + +``` + ## Placement Variants -You can control where the background gradient appears by selecting its placement. Use the `placement` prop to choose between `"full"` (covering the entire container) or `"top"` (applying the gradient only to the top portion). This allows flexible use for backgrounds that need either total coverage or more subtle decoration across the top. +Use the `placement` prop to control where the blobs are distributed. `"full"` (the default) scatters four blobs around all four corners for total coverage, while `"top"` uses two blobs anchored near the top edge for a subtler decoration that leaves the lower area clear for content. ### Placement Full @@ -43,3 +75,17 @@ You can control where the background gradient appears by selecting its placement ### Placement Top + +### Usage + +```tsx + + +``` + +## Props + +| Name | Description | Type | Default | Required | +| ----------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ------- | -------- | +| `theme` | Brand colour used for the gradient blobs. Read from `equality-tokens.json`; unknown values fall back to black. | `primary`, `secondary`, `green`, `red`, `yellow` | — | ✅ | +| `placement` | Distribution of the gradient blobs. `full` covers the whole area; `top` anchors blobs near the top edge. | `full`, `top` | `full` | ❌ | From ecdf2d8158509a6106be835165cbe276a81b3ee0 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 11:28:22 +1200 Subject: [PATCH 02/33] feat: updated cards docs --- packages/demo/src/content/components/card.mdx | 125 +++++++++++++++--- 1 file changed, 103 insertions(+), 22 deletions(-) diff --git a/packages/demo/src/content/components/card.mdx b/packages/demo/src/content/components/card.mdx index 10b1b4a2..ac4dfda9 100644 --- a/packages/demo/src/content/components/card.mdx +++ b/packages/demo/src/content/components/card.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Card" -description: "Card with sizes and variants" +description: "Compound card container with elevations and hover states" --- import { @@ -15,7 +15,38 @@ import { ELEVATION, } from "@eqtylab/equality"; -## Content only (most used) +## Overview + +Card is a compound component for grouping related content into a surfaced container. It is built from a set of composable parts — `Card` (the wrapper) plus `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, and `CardFooter` — so you only include the sections you need. A content-only card is the most common usage. + +Cards sit on the elevation scale via the `elevation` prop (defaulting to `raised`). Passing an `onClick` handler makes the card clickable and adds a hover gradient. + +## Usage + +Import the parts you need: + +```tsx +import { + Card, + CardContent, + CardHeader, + CardTitle, + CardDescription, + CardFooter, +} from "@eqtylab/equality"; +``` + +A minimal, content-only card: + +```tsx + + Card content + +``` + +## Variants + +### Content only (most used) { @@ -31,7 +62,7 @@ import { } -## Header only +### Header only { @@ -43,23 +74,7 @@ import { } -## Content only interactive (hover) - -{ - - console.log("Card clicked")}> - -
-

Content-only Card

-

- This card only uses CardContent without header or footer. -

-
-
-
-} - -## Basic card +### Basic card { @@ -74,7 +89,7 @@ import { } -## With footer +### With footer { @@ -99,7 +114,28 @@ import { } -## Interactive (hover) +### Usage + +```tsx + + + Card with Footer + Includes footer actions + + +

This is the main content area of the card.

+
+ + + +
+``` + +### Interactive (hover) + +Passing an `onClick` handler makes the card clickable and adds a hover gradient. This works with any composition, including content-only cards. { @@ -114,8 +150,20 @@ import { } +#### Usage + +```tsx + handleSelect()}> + This card is clickable. + +``` + +The hover gradient can be restyled with the `hoverGradientClassName` prop. + ## Elevations +Use the `elevation` prop with the `ELEVATION` constant to place the card on the elevation scale. `raised` is the default. + ### Sunken { @@ -179,3 +227,36 @@ import { } + +### Usage + +```tsx +import { Card, CardContent, ELEVATION } from "@eqtylab/equality"; + + + Sunken card +; +``` + +## Slots + +Compose a card from the following parts. All are optional except that content generally lives inside `CardContent`. + +| Name | Description | +| ----------------- | ------------------------------------------------------------------ | +| `Card` | The outer container. Owns elevation, hover, and click behaviour. | +| `CardHeader` | Top section, typically wrapping `CardTitle` and `CardDescription`. | +| `CardTitle` | The card's heading text. | +| `CardDescription` | Secondary, muted supporting text shown beneath the title. | +| `CardContent` | The main body area of the card. | +| `CardFooter` | Bottom section, typically for actions such as buttons. | + +## Props + +These props apply to the top-level `Card`. The subcomponents accept standard `div` attributes (including `className`). + +| Name | Description | Type | Default | Required | +| ------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------- | -------- | -------- | +| `elevation` | Position on the elevation scale. Use the `ELEVATION` constant. | `sunken`, `base`, `raised`, `overlay` | `raised` | ❌ | +| `onClick` | Click handler. Providing it makes the card interactive and enables the hover gradient automatically. | `(e: MouseEvent) => void` | — | ❌ | +| `hoverGradientClassName` | Additional classes applied to the hover gradient element (only rendered when the card is interactive). | `string` | — | ❌ | From e1680e4942f0c899295fbb650376665b98071a49 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 11:50:02 +1200 Subject: [PATCH 03/33] feat: updated docs content descriptions --- packages/demo/src/content/components/alert.mdx | 2 +- packages/demo/src/content/components/avatar.mdx | 2 +- packages/demo/src/content/components/badge.mdx | 2 +- packages/demo/src/content/components/button.mdx | 2 +- packages/demo/src/content/components/card-content-header.mdx | 2 +- packages/demo/src/content/components/checkbox.mdx | 2 +- packages/demo/src/content/components/code-block.mdx | 2 +- packages/demo/src/content/components/command.mdx | 2 +- packages/demo/src/content/components/copy-button.mdx | 2 +- packages/demo/src/content/components/date-range-picker.mdx | 2 +- packages/demo/src/content/components/display-field.mdx | 2 +- packages/demo/src/content/components/drawer.mdx | 2 +- packages/demo/src/content/components/heading.mdx | 2 +- packages/demo/src/content/components/icon-button.mdx | 2 +- packages/demo/src/content/components/icon.mdx | 2 +- packages/demo/src/content/components/info-card.mdx | 2 +- packages/demo/src/content/components/input.mdx | 2 +- packages/demo/src/content/components/label.mdx | 2 +- .../demo/src/content/components/list-or-grid-view-toggle.mdx | 2 +- packages/demo/src/content/components/loading-overlay.mdx | 2 +- packages/demo/src/content/components/metric-card.mdx | 2 +- packages/demo/src/content/components/panel-label.mdx | 2 +- packages/demo/src/content/components/popover.mdx | 2 +- packages/demo/src/content/components/progress.mdx | 2 +- packages/demo/src/content/components/radial-graph.mdx | 2 +- packages/demo/src/content/components/radio-dropdown.mdx | 2 +- packages/demo/src/content/components/radio-group.mdx | 2 +- packages/demo/src/content/components/scroll-area.mdx | 2 +- packages/demo/src/content/components/search-bar.mdx | 2 +- packages/demo/src/content/components/section-heading.mdx | 2 +- packages/demo/src/content/components/select.mdx | 2 +- packages/demo/src/content/components/separator.mdx | 2 +- packages/demo/src/content/components/switch.mdx | 2 +- packages/demo/src/content/components/textarea.mdx | 2 +- packages/demo/src/content/components/toast.mdx | 2 +- packages/demo/src/content/components/tooltip.mdx | 2 +- 36 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/demo/src/content/components/alert.mdx b/packages/demo/src/content/components/alert.mdx index 9ff08a60..f590e260 100644 --- a/packages/demo/src/content/components/alert.mdx +++ b/packages/demo/src/content/components/alert.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Alert" -description: "Alert with sizes and variants" +description: "Message for communicating status, warnings, or errors" --- import { Alert } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/avatar.mdx b/packages/demo/src/content/components/avatar.mdx index d028c65d..960dd9e5 100644 --- a/packages/demo/src/content/components/avatar.mdx +++ b/packages/demo/src/content/components/avatar.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Avatar" -description: "Avatar with sizes and variants" +description: "Visual representation of a user or entity" --- import { diff --git a/packages/demo/src/content/components/badge.mdx b/packages/demo/src/content/components/badge.mdx index d33bb5f1..7f527e5a 100644 --- a/packages/demo/src/content/components/badge.mdx +++ b/packages/demo/src/content/components/badge.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Badge" -description: "Badge with sizes and variants" +description: "Compact label for communicating status or context" --- import { Badge, PanelLabel } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/button.mdx b/packages/demo/src/content/components/button.mdx index 2f531996..8cff569e 100644 --- a/packages/demo/src/content/components/button.mdx +++ b/packages/demo/src/content/components/button.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Button" -description: "Button with sizes and variants" +description: "Interactive element for triggering actions" --- import React from "react"; diff --git a/packages/demo/src/content/components/card-content-header.mdx b/packages/demo/src/content/components/card-content-header.mdx index 2e75a50b..e2950fac 100644 --- a/packages/demo/src/content/components/card-content-header.mdx +++ b/packages/demo/src/content/components/card-content-header.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Card Content Header" -description: "Card Content Header with sizes and variants" +description: "Header row for card content with icon, heading, and action" --- import { diff --git a/packages/demo/src/content/components/checkbox.mdx b/packages/demo/src/content/components/checkbox.mdx index ee8b04bd..72b8201e 100644 --- a/packages/demo/src/content/components/checkbox.mdx +++ b/packages/demo/src/content/components/checkbox.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Checkbox" -description: "Checkbox with sizes and variants" +description: "Toggle control for boolean or multi-select choices" --- import { Checkbox } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/code-block.mdx b/packages/demo/src/content/components/code-block.mdx index 06b80400..e83bf1da 100644 --- a/packages/demo/src/content/components/code-block.mdx +++ b/packages/demo/src/content/components/code-block.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Code Block" -description: "Code Block with sizes and variants" +description: "Syntax-highlighted code display with status variants" --- import { CodeBlock } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/command.mdx b/packages/demo/src/content/components/command.mdx index b222d641..34f74862 100644 --- a/packages/demo/src/content/components/command.mdx +++ b/packages/demo/src/content/components/command.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Command" -description: "Command with variants" +description: "Searchable command palette for running commands" --- import { CommandDemo } from "@demo/components/demo/command"; diff --git a/packages/demo/src/content/components/copy-button.mdx b/packages/demo/src/content/components/copy-button.mdx index 922d10f5..a694dda5 100644 --- a/packages/demo/src/content/components/copy-button.mdx +++ b/packages/demo/src/content/components/copy-button.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Copy Button" -description: "Copy Button with sizes and variants" +description: "Button that copies a value to the clipboard" --- import { CopyButton } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/date-range-picker.mdx b/packages/demo/src/content/components/date-range-picker.mdx index d6160f4e..0ba41433 100644 --- a/packages/demo/src/content/components/date-range-picker.mdx +++ b/packages/demo/src/content/components/date-range-picker.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Date Range Picker" -description: "Date Range Picker with sizes and variants" +description: "Input for selecting a start and end date" --- import { DateRangePickerDemo } from "@demo/components/demo/date-range-picker"; diff --git a/packages/demo/src/content/components/display-field.mdx b/packages/demo/src/content/components/display-field.mdx index eaaadac1..175e4ee8 100644 --- a/packages/demo/src/content/components/display-field.mdx +++ b/packages/demo/src/content/components/display-field.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Display Field" -description: "Display Field with sizes and variants" +description: "Read-only field showing a value with copy action" --- import { diff --git a/packages/demo/src/content/components/drawer.mdx b/packages/demo/src/content/components/drawer.mdx index aff7ffa8..be63fb15 100644 --- a/packages/demo/src/content/components/drawer.mdx +++ b/packages/demo/src/content/components/drawer.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Drawer" -description: "Drawer with sizes and variants" +description: "Slide-out panel overlaid from a screen edge" --- import { DrawerDemo } from "@demo/components/demo/drawer"; diff --git a/packages/demo/src/content/components/heading.mdx b/packages/demo/src/content/components/heading.mdx index 99a1a541..25ef40c0 100644 --- a/packages/demo/src/content/components/heading.mdx +++ b/packages/demo/src/content/components/heading.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Heading" -description: "Heading with sizes and variants" +description: "Semantic heading with configurable visual level" --- import { HeadingDemo } from "@demo/components/demo/heading"; diff --git a/packages/demo/src/content/components/icon-button.mdx b/packages/demo/src/content/components/icon-button.mdx index 1d849f39..b7e55231 100644 --- a/packages/demo/src/content/components/icon-button.mdx +++ b/packages/demo/src/content/components/icon-button.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Icon Button" -description: "Icon Button with sizes and variants" +description: "Icon-only button with an accessible label" --- import { IconButton } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/icon.mdx b/packages/demo/src/content/components/icon.mdx index 420768cf..b02217e2 100644 --- a/packages/demo/src/content/components/icon.mdx +++ b/packages/demo/src/content/components/icon.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Icon" -description: "Icon with sizes and variants" +description: "Renders a named icon at various sizes" --- import React from "react"; diff --git a/packages/demo/src/content/components/info-card.mdx b/packages/demo/src/content/components/info-card.mdx index c30c0860..738eeb82 100644 --- a/packages/demo/src/content/components/info-card.mdx +++ b/packages/demo/src/content/components/info-card.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Info Card" -description: "InfoCard with sizes and variants" +description: "Card displaying a labeled piece of information" --- import { InfoCard } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/input.mdx b/packages/demo/src/content/components/input.mdx index 7ce7e082..c6b9823f 100644 --- a/packages/demo/src/content/components/input.mdx +++ b/packages/demo/src/content/components/input.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Input" -description: "Input with sizes and variants" +description: "Single-line text input field" --- import React from "react"; diff --git a/packages/demo/src/content/components/label.mdx b/packages/demo/src/content/components/label.mdx index a69fcfe1..55a449f5 100644 --- a/packages/demo/src/content/components/label.mdx +++ b/packages/demo/src/content/components/label.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Label" -description: "Label with sizes and variants" +description: "Text label for a form control" --- import { LabelDemo } from "@demo/components/demo/label"; diff --git a/packages/demo/src/content/components/list-or-grid-view-toggle.mdx b/packages/demo/src/content/components/list-or-grid-view-toggle.mdx index 19474498..215bd20a 100644 --- a/packages/demo/src/content/components/list-or-grid-view-toggle.mdx +++ b/packages/demo/src/content/components/list-or-grid-view-toggle.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "List or Grid View Toggle" -description: "List or Grid View Toggle with sizes and variants" +description: "Toggle for switching between list and grid views" --- import { ListOrGridViewToggle } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/loading-overlay.mdx b/packages/demo/src/content/components/loading-overlay.mdx index 812a048e..6d03995d 100644 --- a/packages/demo/src/content/components/loading-overlay.mdx +++ b/packages/demo/src/content/components/loading-overlay.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Loading Overlay" -description: "Loading Overlay with sizes and variants" +description: "Overlay indicating content is loading" --- import { LoadingOverlayDemo } from "@demo/components/demo/loading-overlay"; diff --git a/packages/demo/src/content/components/metric-card.mdx b/packages/demo/src/content/components/metric-card.mdx index 364a3044..73282727 100644 --- a/packages/demo/src/content/components/metric-card.mdx +++ b/packages/demo/src/content/components/metric-card.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Metric Card" -description: "Metric Card with sizes and variants" +description: "Card surfacing a numeric metric with label and icon" --- import { MetricCard } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/panel-label.mdx b/packages/demo/src/content/components/panel-label.mdx index 624e13b4..fbf730b2 100644 --- a/packages/demo/src/content/components/panel-label.mdx +++ b/packages/demo/src/content/components/panel-label.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Panel Label" -description: "Panel Label with sizes and variants" +description: "Small heading label for a panel section" --- import { PanelLabel } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/popover.mdx b/packages/demo/src/content/components/popover.mdx index c073bf06..51904303 100644 --- a/packages/demo/src/content/components/popover.mdx +++ b/packages/demo/src/content/components/popover.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Popover" -description: "Popover with sizes and variants" +description: "Floating content anchored to a trigger element" --- import { PopoverDemo } from "@demo/components/demo/popover"; diff --git a/packages/demo/src/content/components/progress.mdx b/packages/demo/src/content/components/progress.mdx index fdb70ec3..4ea61d53 100644 --- a/packages/demo/src/content/components/progress.mdx +++ b/packages/demo/src/content/components/progress.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Progress" -description: "Progress with sizes and variants" +description: "Horizontal progress bar with color variants" --- import { Progress } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/radial-graph.mdx b/packages/demo/src/content/components/radial-graph.mdx index 5f751cff..64c7cc9a 100644 --- a/packages/demo/src/content/components/radial-graph.mdx +++ b/packages/demo/src/content/components/radial-graph.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Radial Graph" -description: "Radial Graph with sizes and variants" +description: "Circular graph for progress or percentages" --- import { RadialGraph } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/radio-dropdown.mdx b/packages/demo/src/content/components/radio-dropdown.mdx index c220006f..55ab5fc8 100644 --- a/packages/demo/src/content/components/radio-dropdown.mdx +++ b/packages/demo/src/content/components/radio-dropdown.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Radio Dropdown" -description: "Radio Dropdown with sizes and variants" +description: "Dropdown for single-choice filtering with counts" --- import { RadioDropdownDemo } from "@demo/components/demo/radio-dropdown"; diff --git a/packages/demo/src/content/components/radio-group.mdx b/packages/demo/src/content/components/radio-group.mdx index c6f8d757..bd2a1cd8 100644 --- a/packages/demo/src/content/components/radio-group.mdx +++ b/packages/demo/src/content/components/radio-group.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Radio Group" -description: "Radio Group with sizes and variants" +description: "Group of radio buttons for single selection" --- import { RadioGroupDemo } from "@demo/components/demo/radio-group"; diff --git a/packages/demo/src/content/components/scroll-area.mdx b/packages/demo/src/content/components/scroll-area.mdx index d3123b09..8203bbae 100644 --- a/packages/demo/src/content/components/scroll-area.mdx +++ b/packages/demo/src/content/components/scroll-area.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Scroll Area" -description: "Scroll Area with sizes and variants" +description: "Scrollable container with custom scrollbars" --- import { ScrollArea } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/search-bar.mdx b/packages/demo/src/content/components/search-bar.mdx index 240428c1..d5c7a763 100644 --- a/packages/demo/src/content/components/search-bar.mdx +++ b/packages/demo/src/content/components/search-bar.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Search Bar" -description: "Search Bar with sizes and variants" +description: "Text input for searching or filtering" --- import { SearchBarDemo } from "@demo/components/demo/search-bar"; diff --git a/packages/demo/src/content/components/section-heading.mdx b/packages/demo/src/content/components/section-heading.mdx index c209e696..969d46d6 100644 --- a/packages/demo/src/content/components/section-heading.mdx +++ b/packages/demo/src/content/components/section-heading.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Section Heading" -description: "Section Heading with sizes and variants" +description: "Section title with optional description and actions" --- import { SectionHeading, Button } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/select.mdx b/packages/demo/src/content/components/select.mdx index 98f60214..c7ee22f0 100644 --- a/packages/demo/src/content/components/select.mdx +++ b/packages/demo/src/content/components/select.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Select" -description: "Select with sizes and variants" +description: "Dropdown for choosing one option from a list" --- import { SelectDemo } from "@demo/components/demo/select"; diff --git a/packages/demo/src/content/components/separator.mdx b/packages/demo/src/content/components/separator.mdx index 0326281d..c826441e 100644 --- a/packages/demo/src/content/components/separator.mdx +++ b/packages/demo/src/content/components/separator.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Separator" -description: "Separator with sizes and variants" +description: "Visual divider line, horizontal or vertical" --- import { Separator } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/switch.mdx b/packages/demo/src/content/components/switch.mdx index 28fcb26a..bfead4f3 100644 --- a/packages/demo/src/content/components/switch.mdx +++ b/packages/demo/src/content/components/switch.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Switch" -description: "Switch with sizes and variants" +description: "Toggle switch for on/off states" --- import { SwitchDemo } from "@demo/components/demo/switch"; diff --git a/packages/demo/src/content/components/textarea.mdx b/packages/demo/src/content/components/textarea.mdx index 57c34337..5928feab 100644 --- a/packages/demo/src/content/components/textarea.mdx +++ b/packages/demo/src/content/components/textarea.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Textarea" -description: "Textarea with sizes and variants" +description: "Multi-line text input field" --- import { Textarea } from "@eqtylab/equality"; diff --git a/packages/demo/src/content/components/toast.mdx b/packages/demo/src/content/components/toast.mdx index 615744d0..24b9a915 100644 --- a/packages/demo/src/content/components/toast.mdx +++ b/packages/demo/src/content/components/toast.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Toast" -description: "Toast notifications with variants and actions" +description: "Auto-dismissing notification message with variants" --- import { ToastDemo } from "@demo/components/demo/toast"; diff --git a/packages/demo/src/content/components/tooltip.mdx b/packages/demo/src/content/components/tooltip.mdx index 78b174cd..414dfbc1 100644 --- a/packages/demo/src/content/components/tooltip.mdx +++ b/packages/demo/src/content/components/tooltip.mdx @@ -1,7 +1,7 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Tooltip" -description: "Tooltip with sizes and variants" +description: "Hover hint showing contextual text" --- import { TooltipDemo } from "@demo/components/demo/tooltip"; From 62b217385c0a608f90cc4552eaefde504f86fd09 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 11:59:20 +1200 Subject: [PATCH 04/33] feat: updated card content header docs --- .../components/card-content-header.mdx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/packages/demo/src/content/components/card-content-header.mdx b/packages/demo/src/content/components/card-content-header.mdx index e2950fac..55ef29ab 100644 --- a/packages/demo/src/content/components/card-content-header.mdx +++ b/packages/demo/src/content/components/card-content-header.mdx @@ -11,6 +11,28 @@ import { CardDescription, } from "@eqtylab/equality"; +## Overview + +Card Content Header is a header row for the top of a card's content, pairing a circular icon with a heading and an optional "See All" action button. It is designed to sit inside [CardContent](card), giving grouped content a consistent title treatment. + +The component renders nothing unless a `heading` or an `onButtonClick` handler is provided. When `onButtonClick` is set, a tertiary "See All" button is shown and the layout adjusts to accommodate it. + +## Usage + +Import the component: + +```tsx +import { CardContentHeader } from "@eqtylab/equality"; +``` + +Basic usage with the required `icon` and a heading: + +```tsx + +``` + +The `icon` prop accepts either a [Lucide](https://lucide.dev/icons/) icon name or a React element, and is rendered inside a circular, elevated background. + ## Variants ### Default @@ -35,3 +57,28 @@ import { Card with CardContentHeader + +### Usage + +```tsx + + + handleSeeAll()} + /> + Card with CardContentHeader + + +``` + +## Props + +| Name | Description | Type | Default | Required | +| --------------- | ----------------------------------------------------------------------------------------- | ------------------------ | ------- | -------- | +| `icon` | Icon shown in the circular background. A Lucide icon name or a React element. | `string`, `ReactElement` | — | ✅ | +| `heading` | Heading text rendered as an `h3`. | `string` | — | ❌ | +| `onButtonClick` | Handler for the "See All" button. Providing it renders the button and adjusts the layout. | `() => void` | — | ❌ | + +> **Note:** The component renders `null` when neither `heading` nor `onButtonClick` is provided, since there would be nothing meaningful to show. From ebaf51412491ed2e0082331f895aa5c40c7a8ce1 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 12:19:02 +1200 Subject: [PATCH 05/33] feat: updated checkbox docs --- .../demo/src/components/demo/checkbox.tsx | 6 ++ .../demo/src/content/components/checkbox.mdx | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 packages/demo/src/components/demo/checkbox.tsx diff --git a/packages/demo/src/components/demo/checkbox.tsx b/packages/demo/src/components/demo/checkbox.tsx new file mode 100644 index 00000000..f5c7d918 --- /dev/null +++ b/packages/demo/src/components/demo/checkbox.tsx @@ -0,0 +1,6 @@ +import { Checkbox } from "@eqtylab/equality"; +import { Minus } from "lucide-react"; + +export const CheckboxCustomIconDemo = () => { + return ; +}; diff --git a/packages/demo/src/content/components/checkbox.mdx b/packages/demo/src/content/components/checkbox.mdx index 72b8201e..50464cb9 100644 --- a/packages/demo/src/content/components/checkbox.mdx +++ b/packages/demo/src/content/components/checkbox.mdx @@ -5,6 +5,35 @@ description: "Toggle control for boolean or multi-select choices" --- import { Checkbox } from "@eqtylab/equality"; +import { CheckboxCustomIconDemo } from "@demo/components/demo/checkbox"; + +## Overview + +Checkbox is a toggle control for boolean or multi-select choices, such as accepting terms or selecting rows in a table. It is built on [Radix UI Checkbox](https://www.radix-ui.com/primitives/docs/components/checkbox), so it is keyboard accessible and works with assistive technology out of the box. + +The checkbox can be controlled or uncontrolled, comes in two sizes, and supports a custom indicator icon. Pair it with a [Label](label) (using a shared `id`/`htmlFor`) to give it an accessible, clickable caption. + +## Usage + +Import the component: + +```tsx +import { Checkbox } from "@eqtylab/equality"; +``` + +Uncontrolled, with a default state: + +```tsx + +``` + +Controlled, driving state yourself: + +```tsx +const [checked, setChecked] = useState(false); + +; +``` ## States @@ -26,6 +55,8 @@ import { Checkbox } from "@eqtylab/equality"; ## Size Variants +The checkbox comes in two sizes. `md` is the default; use `sm` in denser layouts. + ### Medium (default) @@ -33,3 +64,37 @@ import { Checkbox } from "@eqtylab/equality"; ### Small + +### Usage + +```tsx + + +``` + +## Custom Icon + +Use the `icon` prop to replace the default check mark with any icon component, for example to represent an indeterminate state. + + + +### Usage + +```tsx +import { Minus } from "lucide-react"; + +; +``` + +## Props + +Checkbox extends the [Radix Checkbox Root](https://www.radix-ui.com/primitives/docs/components/checkbox#root) props (including `onCheckedChange`, `defaultChecked`, `required`, `name`, and `value`). The most commonly used are listed below. + +| Name | Description | Type | Default | Required | +| ----------------- | ----------------------------------------------------- | ----------------------------------------------- | ------- | -------- | +| `checked` | The controlled checked state. | `boolean`, `"indeterminate"` | — | ❌ | +| `onCheckedChange` | Callback fired when the checked state changes. | `(checked: boolean \| "indeterminate") => void` | — | ❌ | +| `defaultChecked` | The initial checked state when uncontrolled. | `boolean` | — | ❌ | +| `disabled` | Prevents interaction and visually mutes the checkbox. | `boolean` | `false` | ❌ | +| `size` | The size of the checkbox. | `sm`, `md` | `md` | ❌ | +| `icon` | Custom indicator icon component shown when checked. | `React.ElementType` | — | ❌ | From c91234894d16739df745a8d682b1e8398eec8b0c Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 12:42:50 +1200 Subject: [PATCH 06/33] feat: updated command docs --- packages/demo/src/components/demo/command.tsx | 30 +++--- .../demo/src/content/components/command.mdx | 97 +++++++++++++++++++ 2 files changed, 114 insertions(+), 13 deletions(-) diff --git a/packages/demo/src/components/demo/command.tsx b/packages/demo/src/components/demo/command.tsx index 6a25a4fe..dd278d3e 100644 --- a/packages/demo/src/components/demo/command.tsx +++ b/packages/demo/src/components/demo/command.tsx @@ -1,29 +1,33 @@ import { Command, CommandInput, + CommandList, CommandEmpty, CommandGroup, CommandItem, } from "@eqtylab/equality"; import { Check } from "lucide-react"; +import { useState } from "react"; + +const options = ["Option 1", "Option 2", "Option 3"]; export const CommandDemo = () => { + const [selected, setSelected] = useState("Option 1"); + return ( - No repositories found. - - {}}> - Option 1 - - - {}}> - Option 2 - - {}}> - Option 3 - - + + No repositories found. + + {options.map((option) => ( + + {option} + {selected === option && } + + ))} + + ); }; diff --git a/packages/demo/src/content/components/command.mdx b/packages/demo/src/content/components/command.mdx index 34f74862..cdb3cc8c 100644 --- a/packages/demo/src/content/components/command.mdx +++ b/packages/demo/src/content/components/command.mdx @@ -6,6 +6,103 @@ description: "Searchable command palette for running commands" import { CommandDemo } from "@demo/components/demo/command"; +## Overview + +Command is a searchable, keyboard-navigable list for filtering and running commands or selecting from a set of options. It is built on [cmdk](https://cmdk.paco.me/), so typing in the input filters the list in real time, and the arrow keys plus Enter move through and select items. + +It is a compound component: compose a `Command` from an input, a list, groups, and items. Use it inline (as an embedded searchable list) or wrap it in `CommandDialog` to present it as a modal command palette. + +## Usage + +Import the parts you need: + +```tsx +import { + Command, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, +} from "@eqtylab/equality"; +``` + +A basic inline command list: + +```tsx + + + No repositories found. + + handleSelect("option-1")}> + Option 1 + + handleSelect("option-2")}> + Option 2 + + + +``` + ## Default + +## As a Dialog + +Wrap the command list in `CommandDialog` to present it as a modal command palette — commonly opened with a keyboard shortcut such as ⌘K. `CommandDialog` accepts the same `open`/`onOpenChange` props as [Dialog](dialog), plus an optional `title` and `description` (visually part of the dialog header and read by screen readers). + +```tsx +import { + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, +} from "@eqtylab/equality"; + +const [open, setOpen] = useState(false); + + + + + No results found. + + runAction()}>Run action + + +; +``` + +## Slots + +Compose a command interface from the following parts: + +| Name | Description | +| ------------------ | ------------------------------------------------------------------------------- | +| `Command` | The root container that owns filtering and keyboard navigation. | +| `CommandDialog` | Wraps `Command` in a modal dialog for a command-palette experience. | +| `CommandInput` | The search input; typing filters the list. Renders a leading search icon. | +| `CommandList` | Scrollable container for the items. | +| `CommandEmpty` | Content shown when no items match the current search. | +| `CommandGroup` | Groups related items under an optional `heading`. | +| `CommandItem` | A selectable row. Use `value` for filtering and `onSelect` to handle selection. | +| `CommandSeparator` | A divider line between groups or items. | +| `CommandShortcut` | Right-aligned text for showing an item's keyboard shortcut. | + +## Props + +Each part forwards its underlying `cmdk` props (and `className`). The most commonly used are listed below. + +| Name | Applies to | Description | Type | Default | +| -------------- | --------------- | ------------------------------------------------------- | ------------------------- | ---------------------------------- | +| `value` | `CommandItem` | The value used for filtering and passed to `onSelect`. | `string` | — | +| `onSelect` | `CommandItem` | Called when the item is selected via click or keyboard. | `(value: string) => void` | — | +| `disabled` | `CommandItem` | Prevents the item from being selected. | `boolean` | `false` | +| `heading` | `CommandGroup` | Optional label rendered above the group's items. | `string` | — | +| `placeholder` | `CommandInput` | Placeholder text for the search input. | `string` | — | +| `open` | `CommandDialog` | Controls whether the dialog is open. | `boolean` | — | +| `onOpenChange` | `CommandDialog` | Called when the dialog requests to open or close. | `(open: boolean) => void` | — | +| `title` | `CommandDialog` | Accessible dialog title shown in the header. | `string` | `"Command Palette"` | +| `description` | `CommandDialog` | Accessible dialog description shown in the header. | `string` | `"Search for a command to run..."` | From a2cb5fe3c513df0e12f4eebc71ea963808989994 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 14:16:42 +1200 Subject: [PATCH 07/33] feat: update copy button docs --- .../src/content/components/copy-button.mdx | 60 +++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/demo/src/content/components/copy-button.mdx b/packages/demo/src/content/components/copy-button.mdx index a694dda5..a204a02e 100644 --- a/packages/demo/src/content/components/copy-button.mdx +++ b/packages/demo/src/content/components/copy-button.mdx @@ -7,9 +7,29 @@ description: "Button that copies a value to the clipboard" import { CopyButton } from "@eqtylab/equality"; import { CopyButtonDemo } from "@demo/components/demo/copy-button"; +## Overview + +Copy Button is an [IconButton](icon-button) that copies a string to the clipboard when clicked. On success it briefly swaps to a check icon for two seconds before reverting, giving users clear confirmation. It uses the modern Clipboard API where available and falls back to a legacy method for non-secure contexts. + +Use it wherever a user might want to copy a value — API keys, hashes, IDs, code snippets, or share links. + +## Usage + +Import the component: + +```tsx +import { CopyButton } from "@eqtylab/equality"; +``` + +Basic usage with the required `value`: + +```tsx + +``` + ## Size Variants -The `CopyButton` component supports three size variants: small (`"sm"`), medium (`"md"`), and large (`"lg"`). By adjusting the `size` prop, you can easily change the button's dimensions to fit a variety of interfaces and design needs. The default size is `"sm"`, making it compact, while `"md"` and `"lg"` provide progressively larger clickable areas. +The `CopyButton` supports three sizes: `sm` (default), `md`, and `lg`. Adjust the `size` prop to fit a variety of interfaces — `sm` is compact, while `md` and `lg` provide progressively larger clickable areas. ### Small (default) @@ -34,22 +54,42 @@ The `CopyButton` component supports three size variants: small (`"sm"`), medium client:only="react" /> -## Props +### Usage -### `onClick` handler +```tsx + + + +``` + +## Custom Label + +By default the button's accessible label (and tooltip) is "Copy to clipboard". Use the `label` prop to describe what is being copied, which is announced to screen readers. On a successful copy the label temporarily becomes "Copied!". -The `CopyButton` component exposes an `onClick` prop, which allows you to provide a custom function that will be called whenever the button is clicked. This makes the component highly composable, enabling you to trigger additional logic—such as showing a toast notification, logging analytics, or updating application state—alongside the built-in copy-to-clipboard behavior. +```tsx + +``` + +## onClick Handler -For example, you can use the `onClick` handler to display a custom message: +The `onClick` prop runs a custom function **after** the value has been copied, letting you trigger additional logic such as a toast, analytics event, or state update. -```jsx + + +### Usage + +```tsx alert("Button clicked! Text copied!")} - client:only="react" + onClick={() => showToast("Copied to clipboard")} /> ``` -The `onClick` function is called after text has been copied to the clipboard. +## Props - +| Name | Description | Type | Default | Required | +| --------- | -------------------------------------------------------------------------- | ---------------- | --------------------- | -------- | +| `value` | The string copied to the clipboard when the button is clicked. | `string` | — | ✅ | +| `label` | Accessible label and tooltip text. Becomes "Copied!" briefly after a copy. | `string` | `"Copy to clipboard"` | ❌ | +| `size` | The size of the button. | `sm`, `md`, `lg` | `sm` | ❌ | +| `onClick` | Callback invoked after the value has been copied. | `() => void` | — | ❌ | From 6a8f5647e84e611e9c3e0aefd00b54610640dca6 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 14:47:03 +1200 Subject: [PATCH 08/33] feat: updated display field and date range picker docs --- .../content/components/date-range-picker.mdx | 36 +++++ .../src/content/components/display-field.mdx | 131 +++++++++++++++--- 2 files changed, 148 insertions(+), 19 deletions(-) diff --git a/packages/demo/src/content/components/date-range-picker.mdx b/packages/demo/src/content/components/date-range-picker.mdx index 0ba41433..515b12d8 100644 --- a/packages/demo/src/content/components/date-range-picker.mdx +++ b/packages/demo/src/content/components/date-range-picker.mdx @@ -6,6 +6,42 @@ description: "Input for selecting a start and end date" import { DateRangePickerDemo } from "@demo/components/demo/date-range-picker"; +## Overview + +Date Range Picker lets users choose a start and end date from a calendar. It renders as a [Button](button) showing the current range, which opens a [Popover](popover) containing a month calendar with navigation. + +Selection is two-step: the first click sets the start date, the second sets the end date. If the second date falls before the first, the two are swapped automatically so the range always reads chronologically. Once a range is set, a clear (✕) button appears in the trigger to reset it. + +The component is fully controlled — you own the `dateRange` state and update it from the `onSelect` callback. + +## Usage + +Import the component: + +```tsx +import { DateRangePicker } from "@eqtylab/equality"; +``` + +Hold the range in state and pass it back through `onSelect`: + +```tsx +import { useState } from "react"; + +const [dateRange, setDateRange] = useState<{ from?: Date; to?: Date }>({}); + +; +``` + +Both `from` and `to` are optional `Date` objects. `from` is normalized to the start of the day (`00:00:00`) and `to` to the end of the day (`23:59:59`), so a completed range covers both selected days in full. + ## Default + +## Props + +| Name | Description | Type | Default | Required | +| ----------- | ------------------------------------------------------------------------------------- | --------------------------------------------- | ------- | -------- | +| `dateRange` | The currently selected range. `{ from, to }` — both optional `Date` values. | `{ from?: Date; to?: Date }` | — | ✅ | +| `onSelect` | Called with the updated range whenever the user picks a date or clears the selection. | `(range: { from?: Date; to?: Date }) => void` | — | ✅ | +| `className` | Additional CSS classes applied to the trigger button. | `string` | — | ❌ | diff --git a/packages/demo/src/content/components/display-field.mdx b/packages/demo/src/content/components/display-field.mdx index 175e4ee8..2096b415 100644 --- a/packages/demo/src/content/components/display-field.mdx +++ b/packages/demo/src/content/components/display-field.mdx @@ -11,52 +11,127 @@ import { } from "@demo/components/demo/display-field"; import { ELEVATION } from "@eqtylab/equality"; -## Neutral +## Overview + +Display Field presents a read-only value — such as an ID, hash, key, or DID — in a bordered, surfaced container. By default it includes a [CopyButton](copy-button) so users can copy the value in one click. It supports an optional labelled prefix, status variants with matching icons, truncation strategies for long values, custom action buttons, and an expandable slot for supplementary content. + +It sits on the elevation scale via the `elevation` prop (defaulting to `base`), so it can be nested inside cards and other surfaces without clashing. + +## Usage + +Import the component: + +```tsx +import { DisplayField } from "@eqtylab/equality"; +``` + +The value is passed as `children`: + +```tsx +zQ3shrGxRrYyWixJGrr45jJ1MEY76YQZ4KVbt9CYRsTWZ5MWV +``` + +The copy button uses the string children as its value, so copy only works when `children` is a plain string. + +## Variants + +### Neutral -## Neutral Truncated +### Neutral with Prefix - + -## Neutral Middle Truncated +### Neutral Check with Prefix - +`neutralCheck` shows a check icon like `success`, but keeps the neutral colouring. -## Success with Prefix + + +### Success with Prefix + +The `success` and `failure` variants show a status icon alongside the `prefix` (a check and a warning triangle respectively). -## Failure with Prefix +### Failure with Prefix -## Neutral with Prefix +## Truncation - +Long values can be shortened with the `truncate` prop. `true` truncates at the end with an ellipsis, while `"middle"` keeps the start and end visible (useful for hashes and keys where both ends matter). Left as `false`, the value scrolls horizontally. -## Without Copy Button +### End Truncated + +
+ +
+ +### Middle Truncated + +
+ +
+ +### Horizontall Scroll + +
+ +
+ +## Actions + +The copy button is shown by default. Set `copy={false}` to hide it, and pass `actions` to render your own buttons before the copy button. + +### Without Copy Button -## With Additional Action +### With Additional Action -## Copy Disabled with Custom Actions +### Copy Disabled with Custom Actions -## With Slot Content - - +### Usage + +```tsx + + + + + } +> + zQ3shrGxRrYyWixJGrr45jJ1MEY76YQZ4KVbt9CYRsTWZ5MWV + +``` + +## Slot + +Use the `slot` prop to render supplementary content in a separate section beneath the value — for example related metadata or an empty-state message. + + ## Elevations +Use the `elevation` prop with the `ELEVATION` constant to place the field on the elevation scale. `base` is the default. These examples are nested in a [Card](card) to show the effect. + ### Sunken + +## Slots + +| Name | Description | +| ---------- | ------------------------------------------------------------------ | +| `children` | The value displayed in the field. Use a string for copy support. | +| `actions` | Custom action nodes rendered before the copy button. | +| `slot` | Supplementary content shown in a separate section below the value. | + +## Props + +| Name | Description | Type | Default | Required | +| ----------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------- | --------- | -------- | +| `prefix` | Label shown before the value, alongside the variant status icon. | `string` | — | ❌ | +| `variant` | Status style. `success`/`failure` add an icon and colour; `neutralCheck` adds a plain check. | `neutral`, `neutralCheck`, `success`, `failure` | `neutral` | ❌ | +| `truncate` | How to shorten long values. `true` truncates the end; `middle` keeps both ends; `false` scrolls. | `true`, `false`, `"middle"` | `false` | ❌ | +| `copy` | Whether to show the built-in copy button. | `boolean` | `true` | ❌ | +| `elevation` | Position on the elevation scale. Use the `ELEVATION` constant. | `sunken`, `base`, `raised`, `overlay` | `base` | ❌ | From b3497d5a3055bef1bedc00c5096b27dc283359a7 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 15:14:13 +1200 Subject: [PATCH 09/33] feat: updated docs for form and heading components --- packages/demo/src/content/components/form.mdx | 124 +++++++++++++++++- .../demo/src/content/components/heading.mdx | 53 +++++++- 2 files changed, 174 insertions(+), 3 deletions(-) diff --git a/packages/demo/src/content/components/form.mdx b/packages/demo/src/content/components/form.mdx index f3786188..ff896f5f 100644 --- a/packages/demo/src/content/components/form.mdx +++ b/packages/demo/src/content/components/form.mdx @@ -1,11 +1,66 @@ --- layout: "@demo/layouts/mdx-layout.astro" heading: "Form" -description: "Form components built on top of react-hook-form" +description: "Accessible form primitives built on react-hook-form" --- import { FormDemo } from "@demo/components/demo/form"; +## Overview + +Form is a set of composable primitives that connect your fields to [react-hook-form](https://react-hook-form.com/) while wiring up the accessibility relationships between labels, controls, descriptions, and error messages for you. + +Each field is wrapped in a `FormField` (a typed `Controller`) and a `FormItem`, which generates the `id`s that link a [Label](label), the control, its description, and its validation message via `htmlFor` and `aria-describedby`. When a field has an error, the label takes on an error style and the control receives `aria-invalid`, so validation state is conveyed to assistive technology automatically. + +The primitives are unstyled containers around your own inputs — pair them with [Input](input), [Textarea](textarea), [Select](select), [Checkbox](checkbox), and other controls. + +## Usage + +Import the primitives you need: + +```tsx +import { + Form, + FormField, + FormItem, + FormLabel, + FormControl, + FormDescription, + FormMessage, +} from "@eqtylab/equality"; +``` + +Create a form with `useForm`, spread it into `Form`, and compose each field: + +```tsx +import { useForm } from "react-hook-form"; + +const form = useForm({ defaultValues: { username: "" } }); + +
+ + ( + + Username + + + + Your public display name. + + + )} + /> + + +; +``` + +`FormControl` wraps a single form control and forwards the accessibility attributes to it via a [Radix Slot](https://www.radix-ui.com/primitives/docs/utilities/slot), so the child must accept a `ref` and standard input props. `FormMessage` renders the field's validation error automatically — you can also pass custom children, and it renders nothing when there is no message. + ## Examples ### Default Form @@ -14,8 +69,75 @@ import { FormDemo } from "@demo/components/demo/form"; ### Form with Validation Errors +Validation rules are declared on `FormField` via `rules`. When validation fails, `FormMessage` displays the error and the label switches to its error style. + ### Form with Description +`FormDescription` renders helper text that is linked to the control through `aria-describedby`. + + +## Custom Field Parts + +The built-in parts cover most needs, but you can build your own with the exported `useFormField()` hook. Called inside a `FormField`, it returns the current field's linking `id`s and its react-hook-form state (`error`, `isDirty`, `isTouched`, and so on), so a custom part can react to validation without prop-drilling. + +For example, a status icon that appears once the field has been edited: + +```tsx +import { useFormField } from "@eqtylab/equality"; +import { Check, TriangleAlert } from "lucide-react"; + +function FieldStatus() { + const { error, isDirty } = useFormField(); + + if (!isDirty) return null; + + return error ? ( + + ) : ( + + ); +} +``` + +Drop it inside a `FormItem`, alongside the other parts: + +```tsx + + Email + + + + + + +``` + +`useFormField()` only works inside a `FormField` (it reads the field via context) and throws otherwise. + +## Slots + +Compose a form from the following parts: + +| Name | Description | +| ----------------- | ----------------------------------------------------------------------------------------------------- | +| `Form` | Provider that shares the `useForm` instance with the fields. Spread your `form` object onto it. | +| `FormField` | Connects a named field to react-hook-form. Wraps a `Controller`; use its `render` prop for the field. | +| `FormItem` | Groups a single field's parts and generates the linking `id`s. | +| `FormLabel` | Label for the control. Automatically targets the control and reflects error state. | +| `FormControl` | Wraps the actual input, forwarding `id`, `aria-describedby`, and `aria-invalid`. | +| `FormDescription` | Helper text linked to the control via `aria-describedby`. | +| `FormMessage` | Displays the field's validation error (or custom children); renders nothing when empty. | + +## Props + +`Form` receives the object returned by `useForm`. `FormField` forwards all [react-hook-form `Controller`](https://react-hook-form.com/docs/usecontroller/controller) props; the most commonly used are listed below. The remaining parts accept standard element attributes plus `className`. + +| Name | Applies to | Description | Type | Required | +| --------- | ----------- | ------------------------------------------------------------------------- | ----------------------------------------- | -------- | +| `control` | `FormField` | The `control` object from `useForm`. | `Control` | ✅ | +| `name` | `FormField` | The field name; must match a key in your form values. | `string` | ✅ | +| `render` | `FormField` | Render function receiving `field` (and `fieldState`) to render the input. | `({ field, fieldState }) => ReactElement` | ✅ | +| `rules` | `FormField` | Validation rules applied to the field. | `RegisterOptions` | ❌ | diff --git a/packages/demo/src/content/components/heading.mdx b/packages/demo/src/content/components/heading.mdx index 25ef40c0..007885be 100644 --- a/packages/demo/src/content/components/heading.mdx +++ b/packages/demo/src/content/components/heading.mdx @@ -6,12 +6,61 @@ description: "Semantic heading with configurable visual level" import { HeadingDemo } from "@demo/components/demo/heading"; -## HTML headings +## Overview + +Heading renders a semantic HTML heading (`h1`–`h6`) with the design system's typographic styling. It separates _meaning_ from _appearance_: the `as` prop sets the actual heading tag (for document structure and accessibility), while the optional `displayAs` prop lets you borrow the visual style of a different level without changing the underlying element. + +## Usage + +Import the component: + +```tsx +import { Heading } from "@eqtylab/equality"; +``` + +Basic usage — `as` is required and determines both the tag and its style: + +```tsx +Page title +``` + +## HTML Headings + +Each level has its own type styling. Set `as` to the appropriate level for its place in the document outline. +### Usage + +```tsx +This is an h1 heading +This is an h2 heading +This is an h3 heading +This is an h4 heading +This is an h5 heading +This is an h6 heading +``` + ## Display As -Use `displayAs` to render a different semantic level while maintaining visual styling: +Use `displayAs` to render one semantic level while applying the visual style of another. Here an `h3` is rendered with `h1` styling — the element stays an `

` in the DOM, so the heading hierarchy is preserved while the text looks larger. + +### Usage + +```tsx + + This is an h3 styled as h1 heading + +``` + +## Props + +The component also accepts standard heading attributes (`id`, `className`, etc.). + +| Name | Description | Type | Default | Required | +| ----------- | ----------------------------------------------------------------------------------------- | ---------------------------------- | ------------- | -------- | +| `as` | The semantic HTML heading element to render. Drives both the tag and its default styling. | `h1`, `h2`, `h3`, `h4`, `h5`, `h6` | — | ✅ | +| `displayAs` | Visual style to apply instead of `as`'s. Does not change the rendered element. | `h1`, `h2`, `h3`, `h4`, `h5`, `h6` | value of `as` | ❌ | +| `children` | The heading content. | `ReactNode` | — | ✅ | From 881b8618597436c8e1cf2ef46f21cafc426081ba Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 15:34:41 +1200 Subject: [PATCH 10/33] feat: updated docs for icon and icon button --- packages/demo/src/components/demo/icon.tsx | 2 +- .../src/content/components/icon-button.mdx | 123 ++++++++++++++---- packages/demo/src/content/components/icon.mdx | 80 +++++++++++- 3 files changed, 176 insertions(+), 29 deletions(-) diff --git a/packages/demo/src/components/demo/icon.tsx b/packages/demo/src/components/demo/icon.tsx index ed091c9b..6245bed3 100644 --- a/packages/demo/src/components/demo/icon.tsx +++ b/packages/demo/src/components/demo/icon.tsx @@ -21,7 +21,7 @@ const CustomIcon = ({ className, ...props }: React.SVGProps) => { export const IconDemo = () => { return ( -
+
} background="circle" />
); diff --git a/packages/demo/src/content/components/icon-button.mdx b/packages/demo/src/content/components/icon-button.mdx index b7e55231..ca462628 100644 --- a/packages/demo/src/content/components/icon-button.mdx +++ b/packages/demo/src/content/components/icon-button.mdx @@ -6,7 +6,33 @@ description: "Icon-only button with an accessible label" import { IconButton } from "@eqtylab/equality"; -## Small (default) +## Overview + +Icon Button is a compact, icon-only button for actions where a label would be redundant or space is tight — toolbars, table rows, and card headers. The icon is a [Lucide](https://lucide.dev/icons/) icon referenced by name. + +Because there is no visible text, the `label` prop is important: it sets the button's `aria-label` so screen reader users know what the action does. Always provide a `label` that describes the action (e.g. "Delete", not "Trash icon"). When an `href` is supplied, Icon Button renders as an anchor (``) instead of a `
); })()} -## With Suffix Icon +### With Suffix Icon {(() => { const eyeIcon = React.createElement(Eye); @@ -101,7 +149,26 @@ return ( type="text" placeholder="Verified input" suffix={React.createElement(Check)} - value="john@example.com" + defaultValue="john@example.com" /> ); })()} + +### Usage + +```tsx +import { Search, Eye } from "lucide-react"; + +} /> +} /> +``` + +## Props + +Input accepts all standard `` attributes (`type`, `placeholder`, `value`, `defaultValue`, `onChange`, `disabled`, `min`, `max`, etc.) in addition to the props below. + +| Name | Description | Type | Default | Required | +| -------- | --------------------------------------------------- | ----------- | ------- | -------- | +| `prefix` | Content rendered inside the field, before the text. | `ReactNode` | — | ❌ | +| `suffix` | Content rendered inside the field, after the text. | `ReactNode` | — | ❌ | +| `type` | The native input type. | `string` | `text` | ❌ | From 6f912fc463437618c0a5acfe8146ec8709ec23d1 Mon Sep 17 00:00:00 2001 From: giuliana-gladeye Date: Mon, 6 Jul 2026 16:10:24 +1200 Subject: [PATCH 12/33] feat: updated label and loading overlay docs --- .../demo/src/content/components/label.mdx | 34 ++++++++++++++ .../content/components/loading-overlay.mdx | 45 +++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/packages/demo/src/content/components/label.mdx b/packages/demo/src/content/components/label.mdx index 55a449f5..3cab8f46 100644 --- a/packages/demo/src/content/components/label.mdx +++ b/packages/demo/src/content/components/label.mdx @@ -6,6 +6,40 @@ description: "Text label for a form control" import { LabelDemo } from "@demo/components/demo/label"; +## Overview + +Label provides an accessible caption for a form control. It is built on [Radix UI Label](https://www.radix-ui.com/primitives/docs/components/label), which associates the label with its control so that clicking the label focuses the input and screen readers announce the caption when the control is focused. + +Associate a label with a control in one of two ways: give the label an `htmlFor` prop matching the control's `id`, or nest the control inside the label. For fields built with [Form](form), use `FormLabel` instead — it wires up this association automatically. + +## Usage + +Import the component: + +```tsx +import { Label } from "@eqtylab/equality"; +``` + +Link the label to a control via `htmlFor` and a matching `id`: + +```tsx +import { Label, Input } from "@eqtylab/equality"; + +
+ + +
; +``` + ## Default + +## Props + +Label accepts all standard `