Skip to content

Commit

Permalink
feat(button): add circle and circle_small sizes (#2573)
Browse files Browse the repository at this point in the history
  • Loading branch information
shleewhite authored Aug 4, 2022
1 parent 86cd95a commit ee2e535
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 18 deletions.
6 changes: 6 additions & 0 deletions .changeset/silly-spoons-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@twilio-paste/button': minor
'@twilio-paste/core': minor
---

[Button] add "circle" and "circle_small" sizes
2 changes: 1 addition & 1 deletion packages/paste-core/components/button/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const handlePropValidation = ({
}

// Icon validation
if ((size === 'icon' || size === 'icon_small') && fullWidth) {
if ((size === 'icon' || size === 'icon_small' || size === 'circle' || size === 'circle_small') && fullWidth) {
throw new Error('[Paste: Button] Icon buttons should not be fullWidth.');
}

Expand Down
8 changes: 8 additions & 0 deletions packages/paste-core/components/button/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,12 @@ export const SizeStyles: {[key in ButtonSizes]: BoxStyleProps} = {
fontSize: 'fontSize30',
lineHeight: 'lineHeight20',
},
circle: {
padding: 'space30',
borderRadius: 'borderRadiusCircle',
},
circle_small: {
padding: 'space20',
borderRadius: 'borderRadiusCircle',
},
};
10 changes: 9 additions & 1 deletion packages/paste-core/components/button/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type {BoxProps} from '@twilio-paste/box';

type ButtonTypes = 'submit' | 'button' | 'reset';
export type ButtonSizes = 'small' | 'default' | 'icon' | 'icon_small' | 'reset' | 'rounded_small';
export type ButtonSizes =
| 'small'
| 'default'
| 'icon'
| 'icon_small'
| 'reset'
| 'rounded_small'
| 'circle'
| 'circle_small';
export type ButtonVariants =
| 'primary'
| 'primary_icon'
Expand Down
51 changes: 36 additions & 15 deletions packages/paste-core/components/button/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,28 @@ import {isRenderingOnServer} from '@twilio-paste/animation-library';
import {Button} from '../src';
import type {ButtonVariants, ButtonSizes} from '../src/types';

const ButtonSizeOptions = ['default', 'small', 'icon', 'icon_small', 'reset', 'rounded_small'];
const ButtonSizeOptions = [
'default',
'small',
'icon',
'icon_small',
'reset',
'rounded_small',
'circle',
'circle_small',
];

const AllSizeOptions: React.FC<{variant: ButtonVariants}> = ({variant}) => {
const allButtons: React.ReactNode[] = [];

ButtonSizeOptions.forEach((size) => {
if (variant === 'reset' && size !== 'reset') return;
const children =
size === 'icon' || size === 'icon_small' ? <PlusIcon title="Add item to cart" decorative={false} /> : variant;
size === 'icon' || size === 'icon_small' || size === 'circle' || size === 'circle_small' ? (
<PlusIcon title="Add item to cart" decorative={false} />
) : (
variant
);

allButtons.push(
<>
Expand All @@ -26,18 +39,26 @@ const AllSizeOptions: React.FC<{variant: ButtonVariants}> = ({variant}) => {
<Button variant={variant as ButtonVariants} size={size as ButtonSizes}>
{children}
</Button>
{size !== 'icon' && size !== 'icon_small' && size !== 'reset' && (
<Button variant={variant as ButtonVariants} size={size as ButtonSizes}>
<PlusIcon title="Add item to cart" decorative={false} />
{children}
</Button>
)}
{size !== 'icon' && size !== 'icon_small' && size !== 'reset' && (
<Button variant={variant as ButtonVariants} size={size as ButtonSizes}>
{children}
<PlusIcon title="Add item to cart" decorative={false} />
</Button>
)}
{size !== 'icon' &&
size !== 'icon_small' &&
size !== 'reset' &&
size !== 'circle' &&
size !== 'circle_small' && (
<Button variant={variant as ButtonVariants} size={size as ButtonSizes}>
<PlusIcon title="Add item to cart" decorative={false} />
{children}
</Button>
)}
{size !== 'icon' &&
size !== 'icon_small' &&
size !== 'reset' &&
size !== 'circle' &&
size !== 'circle_small' && (
<Button variant={variant as ButtonVariants} size={size as ButtonSizes}>
{children}
<PlusIcon title="Add item to cart" decorative={false} />
</Button>
)}

<Button variant={variant as ButtonVariants} size={size as ButtonSizes} loading={!isRenderingOnServer}>
{children}
Expand All @@ -47,7 +68,7 @@ const AllSizeOptions: React.FC<{variant: ButtonVariants}> = ({variant}) => {
</Button>
</Stack>
</Box>
{size !== 'icon' && size !== 'icon_small' && size !== 'reset' && (
{size !== 'icon' && size !== 'icon_small' && size !== 'reset' && size !== 'circle' && size !== 'circle_small' && (
<Box key={`variant-${variant}-${size}`} marginBottom="space40" padding="space30">
<Stack orientation="vertical" spacing="space40">
<Button variant={variant as ButtonVariants} size={size as ButtonSizes} fullWidth>
Expand Down
45 changes: 44 additions & 1 deletion packages/paste-website/src/pages/components/button/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ Use primary icon, secondary icon, and destructive icon Button variants for butto
that, for a specific reason and purpose, can only have an icon in them, such as in
compact UI situations. These variants do not have any border nor background color.
When using these variants, use `size="reset"` in the Button component to remove
any unnecessary padding. To change the size of an icon button, change the size of the Icon component itself.
any unnecessary padding. To change the size of an icon button, [change the size of the Icon component](<(/components/icons/usage-guidelines#resizing-icons)>) itself.

Use an icon that can only convey a single action.

Expand Down Expand Up @@ -389,6 +389,49 @@ Use icon-only Buttons sparingly. If there is any text in a button, do not use th
</Stack>`}
</LivePreview>

#### Circle Buttons

You can create circle Buttons from variants that have background colors and borders,
like primary and secondary, by using that variant and changing the size of the Button
component to `size="circle"` or `size="circle_small"`.

Like icon buttons, circle buttons can only have an icon in them.
To change the size of the Button, change [the size of the Icon component](/components/icons/usage-guidelines#resizing-icons) itself.

Use an icon that can only convey a single action.

Use circular icon-only Buttons sparingly. If there is any text in a button, do not use a circle button.

<LivePreview scope={{Button, Stack, PlusIcon, MinusIcon, CloseIcon}} language="jsx">
{`
<Stack orientation="horizontal" spacing="space60">
<Button variant="primary" size="circle">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="secondary" size="circle">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive" size="circle">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive_secondary" size="circle">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="primary" size="circle_small">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="secondary" size="circle_small">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive" size="circle_small">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive_secondary" size="circle_small">
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</Stack>`}
</LivePreview>

#### Internationalization

To internationalize a Button, simply pass different text as the children. If the Button is an anchor with an external link, you need to also pass the `i18nExternalLinkLabel` prop, with the value wrapped in parentheses. The value should be a translation of the phrase "link takes you to an external page", to indicate that the `showExternal` link will open the link in a new URL.
Expand Down

0 comments on commit ee2e535

Please sign in to comment.