Skip to content

Accordion

Accordion widgets are Layout Fields that allow users to toggle the visibility of content sections. They are ideal for grouping related fields and saving vertical space in complex forms.

accordion.ts
import { gui } from '@golemui/gui-shared';
export default [
gui.layouts.accordion([
{
label: 'Personal Information',
uid: 'personal',
children: [
gui.inputs.textInput('name', {
label: 'Full Name',
}),
],
},
{
label: 'Account Settings',
uid: 'account',
children: [
gui.inputs.textInput('email', {
label: 'Email Address',
}),
],
},
], {
defaultOpen: {
personal: true,
},
uid: 'accordion_basic',
}),
];
accordion.json
{
"form": [
{
"uid": "accordion_basic",
"kind": "layout",
"type": "accordion",
"props": {
"sections": [
{ "uid": "personal", "label": "Personal Information" },
{ "uid": "account", "label": "Account Settings" }
],
"defaultOpen": { "personal": true }
},
"children": [
{
"uid": "personal",
"kind": "input",
"type": "textinput",
"path": "name",
"label": "Full Name"
},
{
"uid": "account",
"kind": "input",
"type": "textinput",
"path": "email",
"label": "Email Address"
}
]
}
]
}

Use these props to customize your Accordion widget.

proptypedescription
sectionsarrayRequired. Array of section definitions: { label: string, uid: string }. Each uid must match the uid of one of the accordion’s children.
singleOpenbooleanIf true, only one section can be open at a time — opening a section closes the others. Defaults to false
defaultOpenobjectMap of section uid to boolean controlling which sections start expanded (e.g., { "section_1": true }). Defaults to all collapsed
renderModestring'all' keeps every section mounted in the DOM and toggles visibility; 'activeOnly' mounts a section’s children only while it is open. Defaults to 'all'

Use the singleOpen property to ensure that opening one section automatically closes others.

accordion.ts
import { gui } from '@golemui/gui-shared';
export default [
gui.layouts.accordion([
{
label: 'First Section',
uid: 'sec1',
children: [
gui.inputs.textInput('f1', {
label: 'Field 1',
}),
],
},
{
label: 'Second Section',
uid: 'sec2',
children: [
gui.inputs.textInput('f2', {
label: 'Field 2',
}),
],
},
], {
singleOpen: true,
uid: 'accordion_single',
}),
];
accordion.json
{
"form": [
{
"uid": "accordion_single",
"kind": "layout",
"type": "accordion",
"props": {
"sections": [
{ "uid": "sec1", "label": "First Section" },
{ "uid": "sec2", "label": "Second Section" }
],
"singleOpen": true
},
"children": [
{
"uid": "sec1",
"kind": "input",
"type": "textinput",
"path": "f1",
"label": "Field 1"
},
{
"uid": "sec2",
"kind": "input",
"type": "textinput",
"path": "f2",
"label": "Field 2"
}
]
}
]
}

Use defaultOpen to pre-expand sections on initial render. The keys are section uids; sections whose key is true start open.

accordion.ts
import { gui } from '@golemui/gui-shared';
export default [
gui.layouts.accordion([
{
label: 'Personal Information',
uid: 'section1',
children: [
gui.layouts.flex([
gui.inputs.textInput('shoppingCart.firstName'),
]),
],
},
{
label: 'Shipping Address',
uid: 'section2',
children: [
gui.layouts.flex([
gui.inputs.textInput('shoppingCart.shippingAddress'),
]),
],
},
{
label: 'Billing Address',
uid: 'section3',
children: [
gui.layouts.flex([
gui.inputs.textInput('shoppingCart.billingAddress'),
]),
],
},
], {
defaultOpen: {
section1: true,
section2: true,
},
uid: 'tab5',
}),
];
accordion.json
{
"form": [
{
"uid": "tab5",
"kind": "layout",
"type": "accordion",
"props": {
"defaultOpen": {
"section1": true,
"section2": true
},
"sections": [
{ "label": "Personal Information", "uid": "section1" },
{ "label": "Shipping Address", "uid": "section2" },
{ "label": "Billing Address", "uid": "section3" }
]
},
"children": [
{
"uid": "section1",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.firstName"
}
]
},
{
"uid": "section2",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.shippingAddress"
}
]
},
{
"uid": "section3",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.billingAddress"
}
]
}
]
}
]
}

Use renderMode to control when section children are mounted. The default 'all' keeps every section in the DOM and hides closed ones, which preserves child state and form values when collapsing. Use 'activeOnly' to mount a section’s children only while it is open — useful when sections contain expensive widgets, side effects on mount, or media you don’t want loaded up front. Inspect the rendered DOM as you toggle sections to see the difference.

accordion.ts
import { gui } from '@golemui/gui-shared';
export default [
gui.layouts.accordion(
[
{
label: 'Personal Information',
uid: 'section1',
children: [gui.layouts.flex([gui.inputs.textInput('shoppingCart.firstName')])],
},
{
label: 'Shipping Address',
uid: 'section2',
children: [gui.layouts.flex([gui.inputs.textInput('shoppingCart.shippingAddress')])],
},
{
label: 'Billing Address',
uid: 'section3',
children: [gui.layouts.flex([gui.inputs.textInput('shoppingCart.billingAddress')])],
},
],
{
renderMode: 'activeOnly',
defaultOpen: { section1: true },
uid: 'accordion_render_mode',
},
),
];
accordion.json
{
"form": [
{
"uid": "accordion_render_mode",
"kind": "layout",
"type": "accordion",
"props": {
"renderMode": "activeOnly",
"defaultOpen": { "section1": true },
"sections": [
{ "label": "Personal Information", "uid": "section1" },
{ "label": "Shipping Address", "uid": "section2" },
{ "label": "Billing Address", "uid": "section3" }
]
},
"children": [
{
"uid": "section1",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.firstName"
}
]
},
{
"uid": "section2",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.shippingAddress"
}
]
},
{
"uid": "section3",
"kind": "layout",
"type": "flex",
"children": [
{
"uid": "",
"kind": "input",
"type": "textinput",
"path": "shoppingCart.billingAddress"
}
]
}
]
}
]
}

Accordions can be styled as explained in the Styling Guide.

Following you will find a list with the CSS Variables used to style the accordion.

CSS VariableDescription
--gui-bg-defaultBackground color for sections and buttons
--gui-border-defaultBorder color for sections and buttons
--gui-text-defaultText color for labels
--gui-space-3Padding inside sections and buttons

This is the anatomy of the Accordion Widget in case you want to use your CSS styles.

accordion-anatomy.html
<div class="gui-accordion">
<div class="gui-widget" id="accordion_uid">
<div class="gui-accordion__section">
<button type="button" class="active" id="accordion_button_personal" aria-expanded="true">
Personal Information
<span class="gui-accordion__icon"></span>
</button>
<section role="region" id="accordion_section_personal" aria-labelledby="accordion_button_personal">
<!-- Content for Personal Information -->
<div class="gui-widget">
<!-- Child widgets render here -->
</div>
</section>
</div>
<div class="gui-accordion__section">
<button type="button" id="accordion_button_account" aria-expanded="false">
Account Settings
<span class="gui-accordion__icon"></span>
</button>
<section role="region" id="accordion_section_account" aria-labelledby="accordion_button_account" hidden>
<!-- Content for Account Settings -->
</section>
</div>
</div>
</div>