Skip to Content
Hashti Design System
Components

Disclosure

Standalone collapsible section or multi-panel group for revealing and hiding secondary details.

Disclosure

A Disclosure is an expandable container component that allows users to toggle the visibility of auxiliary content. <Disclosure> is designed for both standalone folding sections and grouped disclosures across settings, filters, card interiors, and code inspectors.

Built upon React Aria Components’ Disclosure and DisclosureGroup, Hashti’s implementation provides animated chevron indicators, accessible <Heading> level integration, smooth layout collapse, and complete keyboard control.

The geometry of the Hashti functions as an acoustic baffle and thermal buffer, providing spatial gradation between the harsh exterior bazaar and the private domestic courtyard.

The entrance portal welcoming guests with monumental tilework and niche vaulted geometries.


Import

import { Disclosure, DisclosureGroup } from "@hashti/react";
// Or via compound subcomponents:
// Disclosure.Root, Disclosure.Trigger, Disclosure.Indicator, Disclosure.Panel, Disclosure.Group

Anatomy

<Disclosure>
  <Disclosure.Trigger headingLevel={3}>
    <span>Advanced Network Settings</span>
    <Disclosure.Indicator />
  </Disclosure.Trigger>
  <Disclosure.Panel>
    <p>Configure custom DNS and proxy rules here.</p>
  </Disclosure.Panel>
</Disclosure>

Examples

Standalone Disclosure

A single disclosure section is ideal for secondary settings or detailed descriptions on a product card:

import { Disclosure, TextField } from "@hashti/react";

export function StandaloneDisclosureExample() {
  return (
    <div className="max-w-md p-4 border border-[var(--divider)] rounded-lg">
      <h3 className="font-semibold text-base mb-2">Project Settings</h3>
      <TextField label="Project Name" defaultValue="Hashti Design System" />

      <Disclosure className="mt-4" defaultExpanded={false}>
        <Disclosure.Trigger headingLevel={4} variant="ghost" className="w-full justify-between">
          <span>Advanced Configuration</span>
          <Disclosure.Indicator />
        </Disclosure.Trigger>
        <Disclosure.Panel>
          <div className="pt-3 space-y-3">
            <TextField label="API Endpoint" defaultValue="https://api.hashti.raminrez.dev" />
            <TextField label="Webhook Secret" type="password" defaultValue="secret_key" />
          </div>
        </Disclosure.Panel>
      </Disclosure>
    </div>
  );
}

Visual Variants

Hashti supports three distinct disclosure visual variants:

  • default: Clean divider rule below trigger with gentle padding.
  • card: Contained surface box (--surface-raised) with subtle border, ideal for dashboard widgets.
  • flush: Borderless minimal trigger suited for dense sidebars or inline trees.
import { Disclosure } from "@hashti/react";

export function CardDisclosureExample() {
  return (
    <Disclosure variant="card" className="max-w-lg">
      <Disclosure.Trigger headingLevel={3} className="w-full justify-between">
        <span>Payment Gateway Credentials</span>
        <Disclosure.Indicator />
      </Disclosure.Trigger>
      <Disclosure.Panel>
        <p className="text-sm text-[var(--text-muted)]">
          Manage your production and sandbox Stripe and PayPal API keys.
        </p>
      </Disclosure.Panel>
    </Disclosure>
  );
}

Grouped Disclosures (DisclosureGroup)

Wrap multiple disclosures in <DisclosureGroup> to coordinate multi-panel layouts. Configure allowsMultipleExpanded={false} (default) for single-open accordion behavior, or allowsMultipleExpanded={true} to permit opening multiple sections simultaneously:

import { Disclosure, DisclosureGroup } from "@hashti/react";

export function FAQGroupExample() {
  return (
    <DisclosureGroup allowsMultipleExpanded variant="card" className="space-y-3 max-w-xl">
      <Disclosure id="panel-1">
        <Disclosure.Trigger headingLevel={3} className="w-full justify-between">
          <span>What design tokens are available in Hashti?</span>
          <Disclosure.Indicator />
        </Disclosure.Trigger>
        <Disclosure.Panel>
          <p className="text-sm text-[var(--text-muted)]">
            Hashti ships with 8 full semantic themes (Core 4, Relay 2, and Frame 2) with 191
            foundational tokens for color, typography, elevation, and density.
          </p>
        </Disclosure.Panel>
      </Disclosure>

      <Disclosure id="panel-2">
        <Disclosure.Trigger headingLevel={3} className="w-full justify-between">
          <span>Is right-to-left (RTL) supported?</span>
          <Disclosure.Indicator />
        </Disclosure.Trigger>
        <Disclosure.Panel>
          <p className="text-sm text-[var(--text-muted)]">
            Yes! Hashti has first-class Persian (Vazirmatn) and Arabic dual-engine support with
            automatic chevron rotation and directional margin mirroring.
          </p>
        </Disclosure.Panel>
      </Disclosure>
    </DisclosureGroup>
  );
}

Props Reference

Disclosure (Disclosure.Root)

PropTypeDefaultDescription
isExpandedboolean—Controlled expansion state.
defaultExpandedbooleanfalseUncontrolled default initial expanded state.
onExpandedChange(isExpanded: boolean) => void—Callback fired when the disclosure toggles.
size'sm' | 'md' | 'lg''md'Density and padding sizing tier.
variant'default' | 'card' | 'flush''default'Surface rendering style.
isDisabledbooleanfalseWhether the disclosure trigger is disabled.
childrenReactNode—Trigger and Panel components.

Disclosure.Trigger (DisclosureTrigger)

PropTypeDefaultDescription
headingLevel1 | 2 | 3 | 4 | 5 | 6—Automatically wraps the trigger button in a semantic <Heading level={N}> for document landmark compliance.
variant'ghost' | 'tertiary' | ...'ghost'Button style for the trigger header.
childrenReactNode—Trigger label and optional indicator.

Disclosure.Indicator (DisclosureIndicator)

PropTypeDefaultDescription
childrenReactNode<Icon name="chevronRight" />Custom rotation icon. Defaults to Hashti chevron which rotates 90° when expanded.

Disclosure.Panel (DisclosurePanel)

PropTypeDefaultDescription
childrenReactNode—Collapsible contents revealed when expanded.

Keyboard Interactions

KeyAction
Enter / SpaceWhen focus is on <Disclosure.Trigger>, toggles panel expansion.
TabNavigates focus between disclosure triggers and any interactive elements within open panels.

Hashti Token Bindings

TokenCSS VariableApplied Element
Surface Raised--surface-raisedCard variant background
Divider Border--dividerDefault bottom rule and card border
Focus Ring--focus2px focus outline on trigger
Chevron Fill--text-mutedIndicator icon color
Transition Duration--motion-duration-moderate-01150ms cubic-bezier panel collapse

Keyboard Interactions

KeyAction
Space / EnterToggles disclosure panel visibility.
TabMoves focus through trigger button and panel contents.

WAI-ARIA & Data Attributes

AttributeTargetDescription
[data-hovered]TriggerPresent on pointer hover.
[data-expanded]Trigger, PanelSet when panel is open.
[data-focused]TriggerActive on keyboard focus.
[data-disabled]TriggerPresent when disclosure is disabled.