Disclosure
A single expand/collapse section built on the native <details> and <summary> elements.
Advanced build settings
Overrides apply to this project only. Leave them alone to keep the detected defaults.
View code
let settings = { ...BUILD_DEFAULTS };
function editSetting(field: keyof typeof BUILD_DEFAULTS) {
return on<HTMLInputElement, "input">("input", (event) => {
settings[field] = event.currentTarget.value;
void handle.update();
});
}
function resetDefaults() {
settings = { ...BUILD_DEFAULTS };
void handle.update();
}
<Disclosure open>
<Disclosure.Trigger>
<Disclosure.Header mix={[grow()]}>Advanced build settings</Disclosure.Header>
<ChevronDownIcon data-slot="icon" aria-hidden="true" />
</Disclosure.Trigger>
<Disclosure.Panel>
<Description>
Overrides apply to this project only. Leave them alone to keep the detected defaults.
</Description>
<Label htmlFor="buildCommand">Build command</Label>
<Input id="buildCommand" name="buildCommand" value={settings.command} mix={[editSetting("command")]} />
<Label htmlFor="outputDirectory">Output directory</Label>
<Input id="outputDirectory" name="outputDirectory" value={settings.output} mix={[editSetting("output")]} />
<Label htmlFor="installCommand">Install command</Label>
<Input id="installCommand" name="installCommand" value={settings.install} mix={[editSetting("install")]} />
<Switch name="buildCache" defaultChecked>Reuse the build cache between deploys</Switch>
<Button
variant="outline"
color="neutral"
size="sm"
mix={[on<HTMLButtonElement, "click">("click", resetDefaults)]}
>
Reset to defaults
</Button>
</Disclosure.Panel>
</Disclosure>Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/uiimport "@sdxc/ui/theme.css";Usage
import { Disclosure } from "@sdxc/ui";Renders the section's <details> host, revealing
Disclosure.Panel's content while open. The ::details-content
block-size transition is a progressive enhancement over the native toggle.
Composition
The parts the component publishes, each a static property of the host.
DisclosureDisclosure.HeaderRenders Disclosure.HeaderProps.children as an accessible heading at the ambient level, nested directly inside Disclosure.Trigger, since<summary>must stay<details>'s direct child.Disclosure.TriggerRenders Disclosure.TriggerProps.children inside a native<summary>with its marker suppressed, so the indicator is a glyph the consumer passes as a child carryingdata-slot="icon"— which the section turns over while it is open.Disclosure.PanelRenders Disclosure.PanelProps.children in a<div>positioned after Disclosure.Trigger, all<details>needs to treat it as the collapsible body.Disclosure.GroupRenders Disclosure.GroupProps.children as a bordered, rounded list of Disclosure sections sharing one divider between them.
Examples
<Disclosure open>
<Disclosure.Trigger>{t("faq.shipping.question")}</Disclosure.Trigger>
<Disclosure.Panel>
<p>{t("faq.shipping.answer")}</p>
</Disclosure.Panel>
</Disclosure>Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The section's compound parts: Disclosure.Trigger followed by Disclosure.Panel. |
Also accepts everything in TagProps<"details">.
Disclosure.Header
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The trigger's label text, exposed as a heading for assistive technology. |
Also accepts everything in TagProps<"h1">.
Disclosure.Trigger
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The always-visible label, typically plain text or Disclosure.Header. |
Also accepts everything in TagProps<"summary">.
Disclosure.Panel
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The content revealed while the section is open. |
Also accepts everything in TagProps<"div">.
Disclosure.Group
| Prop | Type | Description |
|---|---|---|
children | RemixNode | One or more Disclosure sections to stack into a single bordered list. |
Also accepts everything in TagProps<"div">.