Skip to content

Commit

Permalink
Disclosure: Add size support
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeltaranto committed Oct 18, 2024
1 parent bae97a1 commit 41c82dc
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 19 deletions.
21 changes: 21 additions & 0 deletions .changeset/wet-bananas-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'braid-design-system': minor
---

---
updated:
- Disclosure
---

**Disclosure:** Add `size` support

Introduce the `size` prop to the `Disclosure` component, providing the same options as the `Text` component.

**EXAMPLE USAGE:**
```jsx
<Disclosure
size="small"
>
...
</Disclosure>
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { ComponentDocs } from 'site/types';
import { Disclosure, Text, TextLink, Strong } from '..';
import { Disclosure, Text, TextLink, Strong, Stack, Notice } from '..';
import source from '@braid-design-system/source.macro';

const docs: ComponentDocs = {
Expand Down Expand Up @@ -43,53 +43,123 @@ const docs: ComponentDocs = {
],
additional: [
{
label: 'Custom space',
label: 'Visual weight',
description: (
<Text>
The space between the disclosure label and content can be customised
via the <Strong>space</Strong> prop.
By default, the call to action will have the same affordance as{' '}
<TextLink href="/components/TextLinkButton">TextLinkButton</TextLink>.
Optionally, the visual weight can be decreased by setting{' '}
<Strong>weight</Strong> to <Strong>weak</Strong>.
</Text>
),
Example: ({ id, setDefaultState, getState, setState }) =>
source(
<>
{setDefaultState('expanded', true)}
{setDefaultState('expanded', false)}

<Disclosure
id={id}
weight="weak"
expandLabel="Show content"
collapseLabel="Hide content"
expanded={getState('expanded')}
onToggle={setState('expanded')}
space="small"
>
<Text>Content</Text>
</Disclosure>
</>,
),
},
{
label: 'Visual weight',
label: 'Sizing',
description: (
<>
<Text>
The size can be customised via the <Strong>size</Strong> prop, which
accepts the same sizes as the{' '}
<TextLink href="/components/Text">Text</TextLink> component.
</Text>
<Notice>
<Text>
The provided <Strong>size</Strong> will also be used as the
default size for <TextLink href="/components/Text">Text</TextLink>{' '}
components within the content of the disclosure.
</Text>
</Notice>
</>
),
Example: ({ id, handler }) =>
source(
<Stack space="large">
<Disclosure
id={`${id}_1`}
expandLabel="Large size"
size="large"
expanded={true}
onToggle={handler}
>
<Text>
Defaults to <Strong>large</Strong> text size
</Text>
</Disclosure>
<Disclosure
id={`${id}_2`}
expandLabel="Standard size"
size="standard"
expanded={true}
onToggle={handler}
>
<Text>
Defaults to <Strong>standard</Strong> text size
</Text>
</Disclosure>
<Disclosure
id={`${id}_3`}
expandLabel="Small size"
size="small"
expanded={true}
onToggle={handler}
>
<Text>
Defaults to <Strong>small</Strong> text size
</Text>
</Disclosure>
<Disclosure
id={`${id}_4`}
expandLabel="Xsmall size"
size="xsmall"
expanded={true}
onToggle={handler}
>
<Text>
Defaults to <Strong>xsmall</Strong> text size
</Text>
</Disclosure>
</Stack>,
),
},
{
label: 'Custom space',
description: (
<Text>
By default, the call to action will have the same affordance as{' '}
<TextLink href="/components/TextLinkButton">TextLinkButton</TextLink>.
Optionally, the visual weight can be decreased by setting{' '}
<Strong>weight</Strong> to <Strong>weak</Strong>.
The default space between the disclosure label and content will be
determined by the <TextLink href="#sizing">size</TextLink>.
Alternatively, this can be customised via the <Strong>space</Strong>{' '}
prop.
</Text>
),
Example: ({ id, setDefaultState, getState, setState }) =>
source(
<>
{setDefaultState('expanded', false)}
{setDefaultState('expanded', true)}

<Disclosure
id={id}
weight="weak"
expandLabel="Show content"
collapseLabel="Hide content"
expanded={getState('expanded')}
onToggle={setState('expanded')}
space="large"
>
<Text>Content</Text>
</Disclosure>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React, { type ReactNode } from 'react';
import type { ComponentScreenshot } from 'site/types';
import { Disclosure, Text } from '../';
import { Disclosure, Stack, Text } from '../';
import { Box } from '../Box/Box';
import { textSizeUntrimmed } from '../../css/typography.css';

const Container = ({ children }: { children: ReactNode }) => (
<Box style={{ maxWidth: 250 }}>{children}</Box>
);

const textSizes = Object.keys(textSizeUntrimmed) as Array<
keyof typeof textSizeUntrimmed
>;

export const screenshots: ComponentScreenshot = {
screenshotWidths: [320],
examples: [
Expand Down Expand Up @@ -182,5 +187,46 @@ export const screenshots: ComponentScreenshot = {
</Text>
),
},
{
label: 'Sizes and default spacing',
Example: ({ id, handler }) => (
<Stack space="large">
{textSizes.map((size) => (
<Disclosure
key={size}
id={`${id}_${size}`}
expandLabel={`${size.charAt(0).toUpperCase()}${size.slice(
1,
)} size`}
size={size}
expanded={true}
onToggle={handler}
>
<Text>Defaults to {size} text size</Text>
</Disclosure>
))}
</Stack>
),
},
{
label: 'Inline: Sizes and default spacing',
Example: ({ id, handler }) => (
<Stack space="large">
{textSizes.map((size) => (
<Text size={size} key={size}>
Inline disclosure in{' '}
<Disclosure
id={`${id}_${size}`}
expandLabel={`${size} size`}
expanded={true}
onToggle={handler}
>
Defaults to {size} text size
</Disclosure>
</Text>
))}
</Stack>
),
},
],
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { type ReactNode, useContext } from 'react';
import assert from 'assert';
import { Box } from '../Box/Box';
import type { ResponsiveSpace } from '../../css/atoms/atoms';
import { Text } from '../Text/Text';
import { Text, type TextProps } from '../Text/Text';
import {
type TextLinkButtonProps,
TextLinkButton,
Expand All @@ -15,23 +15,36 @@ import buildDataAttributes, {
} from '../private/buildDataAttributes';
import { TextContext } from '../Text/TextContext';
import HeadingContext from '../Heading/HeadingContext';
import { DefaultTextPropsProvider } from '../private/defaultTextProps';

export interface DisclosureBaseProps {
expandLabel: string;
collapseLabel?: string;
space?: ResponsiveSpace;
size?: TextProps['size'];
weight?: TextLinkButtonProps['weight'];
data?: DataAttributeMap;
children: ReactNode;
}
export type DisclosureProps = DisclosureBaseProps & UseDisclosureProps;
export type { DisclosureStateProps } from './useDisclosure';

const defaultSpaceForSize: Record<
NonNullable<DisclosureProps['size']>,
ResponsiveSpace
> = {
large: 'medium',
standard: 'medium',
xsmall: 'small',
small: 'small',
};

export const Disclosure = ({
id,
expandLabel,
collapseLabel = expandLabel,
space = 'medium',
space,
size: sizeProp,
children,
data,
weight,
Expand All @@ -51,6 +64,13 @@ export const Disclosure = ({
const headingContext = useContext(HeadingContext);
const isInline = Boolean(textContext || headingContext);

assert(
typeof sizeProp === 'undefined' || !isInline,
`Specifying a custom \`size\` for an \`Disclosure\` inside the context of a \`<${
textContext ? 'Text' : 'Heading'
}>\` component is invalid. See the documentation for correct usage: https://seek-oss.github.io/braid-design-system/components/Disclosure`,
);

const { expanded, buttonProps, contentProps } = useDisclosure({
id,
...(restProps.expanded !== undefined
Expand All @@ -63,6 +83,15 @@ export const Disclosure = ({
}),
});

const size = sizeProp ?? textContext?.size ?? 'standard';
const defaultSpace = isInline
? /*
* If inline, only use `xxsmall` as the space between the trigger
* and the content will include the line height of the text
*/
'xxsmall'
: defaultSpaceForSize[size];

const trigger = (
<TextLinkButton hitArea="large" weight={weight} {...buttonProps}>
{expanded ? collapseLabel : expandLabel}
Expand All @@ -84,15 +113,21 @@ export const Disclosure = ({
display={isInline ? 'inline' : undefined}
userSelect="none"
>
{isInline ? <> {trigger}</> : <Text>{trigger}</Text>}
{isInline ? <> {trigger}</> : <Text size={size}>{trigger}</Text>}
</Box>
<Box
component={component}
paddingTop={space}
paddingTop={space ?? defaultSpace}
display={expanded ? 'block' : 'none'}
{...contentProps}
>
{children}
{isInline ? (
children
) : (
<DefaultTextPropsProvider size={size}>
{children}
</DefaultTextPropsProvider>
)}
</Box>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2952,6 +2952,11 @@ exports[`Disclosure 1`] = `
expanded?: boolean
id: string
onToggle?: (expanded: boolean) => void
size?:
| "large"
| "small"
| "standard"
| "xsmall"
space?:
| "gutter"
| "large"
Expand Down

0 comments on commit 41c82dc

Please sign in to comment.