Skip to content

Commit

Permalink
Add example for accordions with additional labels (#3437)
Browse files Browse the repository at this point in the history
Co-authored-by: Josh Wooding <[email protected]>
Co-authored-by: Fernanda Castillo <[email protected]>
  • Loading branch information
3 people authored May 30, 2024
1 parent f44fe1e commit f8de151
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 43 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-items-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@salt-ds/core": patch
---

Fixed the chevron alignment for multi-line accordions.
10 changes: 9 additions & 1 deletion packages/core/src/accordion/AccordionHeader.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
display: flex;
gap: var(--salt-spacing-100);
padding: var(--salt-spacing-50) var(--salt-spacing-100);
align-items: center;
border: 0;
width: 100%;
min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));
Expand All @@ -14,6 +13,7 @@
font-weight: var(--salt-text-fontWeight-strong);
text-align: left;
cursor: var(--salt-actionable-cursor-hover);
box-sizing: border-box;
}

.saltAccordionHeader:focus-visible {
Expand All @@ -27,7 +27,14 @@
cursor: var(--salt-actionable-cursor-disabled);
}

.saltAccordionHeader-content {
padding: var(--salt-spacing-75) 0;
width: 100%;
box-sizing: border-box;
}

.saltAccordionHeader-icon {
height: var(--salt-size-base);
transition: transform var(--salt-duration-perceptible) ease-in-out;
}

Expand Down Expand Up @@ -60,5 +67,6 @@
}

.saltAccordionHeader .saltAccordionHeader-statusIndicator {
height: var(--salt-size-base);
margin-left: auto;
}
2 changes: 1 addition & 1 deletion packages/core/src/accordion/AccordionHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const AccordionHeader = forwardRef<
{...rest}
>
<ChevronRightIcon aria-hidden="true" className={withBaseName("icon")} />
{children}
<div className={withBaseName("content")}>{children}</div>
{status && (
<StatusIndicator
className={withBaseName("statusIndicator")}
Expand Down
95 changes: 94 additions & 1 deletion packages/core/stories/accordion/accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, SyntheticEvent } from "react";
import { useState, SyntheticEvent, ChangeEvent } from "react";
import {
AccordionGroup,
AccordionPanel,
Expand All @@ -10,6 +10,13 @@ import {
FormFieldLabel as FormLabel,
Input,
AccordionGroupProps,
StackLayout,
Text,
SplitLayout,
Label,
FormFieldLabel,
CheckboxGroup,
Checkbox,
} from "@salt-ds/core";
import { Meta, StoryFn } from "@storybook/react";
import "./accordion.stories.css";
Expand Down Expand Up @@ -186,3 +193,89 @@ export const Status: StoryFn<AccordionGroupProps> = (props) => (
))}
</AccordionGroup>
);

const accounts = [
{ name: "Account 1", number: "8736" },
{ name: "Account 2", number: "2564" },
];

const features = [
{
name: "Domestic wires",
id: "domestic_wires",
description: "Initiate wire transfers to another bank",
},
{
name: "Account transfers",
id: "account_transfers",
description: "Move money within your accounts",
},
];

export const AdditionalLabels: StoryFn = () => {
const [state, setState] = useState<Record<string, string[]>>({
domestic_wires: [],
account_transfers: [],
});

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
const name = event.target.name;

setState((prev) => ({
...prev,
[name]: prev[name].includes(value)
? prev[name].filter((account) => account !== value)
: [...prev[name], value],
}));
};

return (
<div style={{ width: "80%", height: "100%" }}>
<AccordionGroup>
{Object.values(features).map(({ name, description, id }) => (
<Accordion value={id}>
<AccordionHeader>
<StackLayout gap={0.5}>
<SplitLayout
align="baseline"
startItem={
<Text>
<strong>{name}</strong>
</Text>
}
endItem={
<Text styleAs="label" color="secondary">
{state[id].length} of {accounts.length} accounts
</Text>
}
/>
<Text styleAs="label" color="secondary">
{description}
</Text>
</StackLayout>
</AccordionHeader>
<AccordionPanel>
<FormField>
<FormFieldLabel>Accounts for this service</FormFieldLabel>
<CheckboxGroup
checkedValues={state[id]}
onChange={handleChange}
direction="horizontal"
>
{accounts.map(({ name, number }) => (
<Checkbox
label={`${name} (...${number})`}
name={id}
value={number}
/>
))}
</CheckboxGroup>
</FormField>
</AccordionPanel>
</Accordion>
))}
</AccordionGroup>
</div>
);
};
18 changes: 16 additions & 2 deletions site/docs/components/accordion/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@ data:
By default, `Accordion` is a single element the user can expand or collapse to show or hide content within a panel.

</LivePreview>
<LivePreview componentName="accordion" exampleName="AccordionGroup" >
<LivePreview componentName="accordion" exampleName="Group" displayName="Accordion Group">

## Accordion groups
## Accordion group

You can place accordions in an accordion group, which allows multiple accordions to be open at the same time.

</LivePreview>
<LivePreview componentName="accordion" exampleName="ExclusiveGroup">

## Exclusive group

You can use `Accordion`'s controlled API to allow only one accordion to be expanded at a time.

</LivePreview>
<LivePreview componentName="accordion" exampleName="Disabled" >

Expand All @@ -43,5 +50,12 @@ You can set a status of "error", "warning" or "success" for an accordion to indi

You can use an inline [badge](../badge) to indicate a change, or several changes, to the content within the accordion.

</LivePreview>
<LivePreview componentName="accordion" exampleName="AdditionalLabels" >

## Additional labels

You can add additional labels to provide extra context using the [`Text`](../text) and [`Stack Layout`](../stack-layout) components.

</LivePreview>
</LivePreviewControls>
101 changes: 101 additions & 0 deletions site/src/examples/accordion/AdditionalLabels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { ChangeEvent, ReactElement, useState } from "react";
import {
Accordion,
AccordionGroup,
AccordionHeader,
AccordionPanel,
CheckboxGroup,
Checkbox,
Label,
SplitLayout,
StackLayout,
Text,
FormField,
FormFieldLabel,
} from "@salt-ds/core";

const accounts = [
{ name: "Account 1", number: "8736" },
{ name: "Account 2", number: "2564" },
];

const features = [
{
name: "Domestic wires",
id: "domestic_wires",
description: "Initiate wire transfers to another bank",
},
{
name: "Account transfers",
id: "account_transfers",
description: "Move money within your accounts",
},
];

export const AdditionalLabels = (): ReactElement => {
const [state, setState] = useState<Record<string, string[]>>({
domestic_wires: [],
account_transfers: [],
});

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
const name = event.target.name;

setState((prev) => ({
...prev,
[name]: prev[name].includes(value)
? prev[name].filter((account) => account !== value)
: [...prev[name], value],
}));
};

return (
<div style={{ width: "80%", height: "100%" }}>
<AccordionGroup>
{Object.values(features).map(({ name, description, id }) => (
<Accordion value={id}>
<AccordionHeader>
<StackLayout gap={0.5}>
<SplitLayout
align="baseline"
startItem={
<Text>
<strong>{name}</strong>
</Text>
}
endItem={
<Text styleAs="label" color="secondary">
{state[id].length} of {accounts.length} accounts
</Text>
}
/>
<Text styleAs="label" color="secondary">
{description}
</Text>
</StackLayout>
</AccordionHeader>
<AccordionPanel>
<FormField>
<FormFieldLabel>Accounts for this service</FormFieldLabel>
<CheckboxGroup
checkedValues={state[id]}
onChange={handleChange}
direction="horizontal"
>
{accounts.map(({ name, number }) => (
<Checkbox
label={`${name} (...${number})`}
name={id}
value={number}
/>
))}
</CheckboxGroup>
</FormField>
</AccordionPanel>
</Accordion>
))}
</AccordionGroup>
</div>
);
};
15 changes: 7 additions & 8 deletions site/src/examples/accordion/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@ import {
Accordion,
AccordionHeader,
AccordionPanel,
FlexLayout,
FlowLayout,
FormField,
FormFieldLabel as FormLabel,
FormFieldLabel,
Input,
} from "@salt-ds/core";

export const Default = (): ReactElement => (
<FlexLayout style={{ width: "80%" }}>
<Accordion value="accordion-example" style={{ alignSelf: "self-start" }}>
<div style={{ width: "80%", height: "100%" }}>
<Accordion value="accordion-example">
<AccordionHeader>Internal form</AccordionHeader>
<AccordionPanel>
<FlowLayout>
Please fill out the following details.
<FormField labelPlacement="left">
<FormLabel>Disclosure ID</FormLabel>
<FormFieldLabel>Disclosure ID</FormFieldLabel>
<Input />
</FormField>
<FormField labelPlacement="left">
<FormLabel>Email</FormLabel>
<FormFieldLabel>Email</FormFieldLabel>
<Input />
</FormField>
<FormField labelPlacement="left">
<FormLabel>Justification</FormLabel>
<FormFieldLabel>Justification</FormFieldLabel>
<Input />
</FormField>
</FlowLayout>
</AccordionPanel>
</Accordion>
</FlexLayout>
</div>
);
15 changes: 7 additions & 8 deletions site/src/examples/accordion/Disabled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import {
AccordionPanel,
FlowLayout,
FormField,
FormFieldLabel as FormLabel,
FormFieldLabel,
Input,
FlexLayout,
} from "@salt-ds/core";

export const Disabled = (): ReactElement => (
<FlexLayout style={{ width: "80%" }}>
<AccordionGroup style={{ alignSelf: "self-start" }}>
<div style={{ width: "80%", height: "100%" }}>
<AccordionGroup>
{Array.from({ length: 3 }, (_, i) => i + 1).map((i) => (
<Accordion
value={`accordion-${i}`}
Expand All @@ -25,21 +24,21 @@ export const Disabled = (): ReactElement => (
<FlowLayout>
Please fill out the following details.
<FormField labelPlacement="left">
<FormLabel>Disclosure ID</FormLabel>
<FormFieldLabel>Disclosure ID</FormFieldLabel>
<Input />
</FormField>
<FormField labelPlacement="left">
<FormLabel>Email</FormLabel>
<FormFieldLabel>Email</FormFieldLabel>
<Input />
</FormField>
<FormField labelPlacement="left">
<FormLabel>Justification</FormLabel>
<FormFieldLabel>Justification</FormFieldLabel>
<Input />
</FormField>
</FlowLayout>
</AccordionPanel>
</Accordion>
))}
</AccordionGroup>
</FlexLayout>
</div>
);
Loading

0 comments on commit f8de151

Please sign in to comment.