Button

Buttons, or “calls-to-action,” are one of the most common UI elements for users to choose an action. While links are focused on navigation, buttons should be used to submit information or change the state of a page.

Component

Storybook

Storybook - Button Documentation

Figma Demo

Guidelines

Variations

Buttons are offered in three sizes: sm (32px), base (40px), and lg (48px). Note that the icon-only tertiary variation has an xs (20px) size for input fields.

There are three variations of button hierarchy: primary, secondary, and tertiary.

Standard button width will hug the contents inside, while the stretch variant will allow it to fill the width of its parent container.

Buttons may have a leading or trailing icon to help communicate intent and draw attention.

Usage

Hierarchy

Button usage should reflect the importance of the action they represent on the page.

  • Primary buttons should be used for the primary action of a page or component, such as “Submit.” They should not be overused.
  • Secondary buttons should be used for less important CTAs on a page or within a component, such as “Cancel.”
  • Tertiary buttons are used primarily in the header or footer or for close buttons on modals or alerts. Their default state background container is white.

Size

  • The base size should be used in the majority of cases.
  • Reserve the sm size for tight spaces such as drawers or menus.
  • Reserve the lg size for key areas such as buttons in the global navigation area.
  • The xs tertiary style should be used inside search inputs.

Width

  • For button placement in the main content area of the page, use standard-width buttons.
  • When buttons need to be placed inside a smaller container such as a dropdown or a side menu, regardless of breakpoint, use stretch-width buttons.

Best Practices

  • Use like button sizes with like input sizes, e.g., a lg button should pair with a lg form field.
  • Do not pair two different sizes of buttons together.
  • Use clear button labels that set expectations such as “Choose location.”
  • Do not use vague labels that wouldn’t make sense without the surrounding context.

Accessibility

Button labels should be clear and not depend on the surrounding context to be interpreted correctly.

Content

Button titles should be brief, set expectations, and use Title Case.

There is a max width set to the text field on buttons, allowing for approximately 20 characters in the button title. Button copy that exceeds this limit will be truncated.

Component Specs

API

  • action: () => void
    Sets the action of the button.

  • actionOptions: Record<string, any> (default: {})
    Sets the action options of the button.

  • class: string (default: undefined)
    Extra classes provided to the component.

  • disabled: boolean (default: false)
    Sets the button to be disabled.

  • href: string (default: undefined)
    Sets the href of the button.

  • iconOnly: boolean (default: false)
    Sets the button to be icon only.

  • iconAfter: typeof SvelteComponent / icon name (default: undefined)
    Sets the icon to be after the label.

  • iconBefore: typeof SvelteComponent / icon name (default: undefined)
    Sets the icon to be before the label.

  • iconName: typeof SvelteComponent / icon name (default: undefined)
    Sets the icon of the button.

  • indicator: string, undefined (default: undefined)
    Sets the button to have an indicator.

  • indicatorClass: string, undefined (default: undefined)
    Sets the class of the indicator.

  • label: string (default: 'Button')
    Sets the label of the button or the title for an icon-only button.

  • showLoader: boolean (default: false)
    Sets the button to have a loader.

  • place: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' (default: 'top-right')
    Sets the placement of the indicator.

  • size: 'xs' (tertiary only) | 'sm' | 'default' | 'lg' (default: 'default')
    Sets the size of the button.

  • stretch: boolean (default: false)
    Sets the button to be stretch or space between.

  • testId: string (default: undefined)
    Sets the test id of the button.

  • type: HTMLButtonAttributes[‘type’] (default: 'button')
    Sets the type of the button.

  • variant: 'primary' | 'secondary' | 'tertiary' | 'search' (default: 'primary')
    Sets the variant of the button.

Example

<script>
	import { Button } from '@getprovi/craft-svelte';
</script>

<Button label="Button name" size="sm" />
<Button variant="secondary" label="Secondary" />
<Button variant="tertiary" label="Tertiary" size="lg" />
<Button size="sm" iconOnly iconName={Notification} label="Notifications" />
<Button size="lg" iconAfter={ChevronDown} label="Order" />
<Button label="Location" size="sm" iconBefore={LocationPinSolid} />
<Button showLoader label="Button with showLoader" />

Types

interface Props extends Omit<ComponentProps<Frame>, 'role'> {
	iconOnly?: boolean;
	iconName?: typeof SvelteComponent;
	iconBefore?: typeof SvelteComponent | undefined;
	iconAfter?: typeof SvelteComponent | undefined;
	indicator?: ComponentProps<Indicator>['label'];
	indicatorClass?: string | undefined;
	label?: string | undefined;
	showLoader?: boolean;
	place?: IndicatorPlacementType;
	size?: 'xs' | 'sm' | 'default' | 'lg';
	stretch?: boolean;
	variant?: 'primary' | 'secondary' | 'tertiary' | 'search';
}

interface AProps extends Props, HTMLAnchorAttributes {
	type?: never;
	disabled?: never;
	showLoader?: never;
}
interface BProps extends Props, HTMLButtonAttributes {
	href?: never;
	type?: 'button' | 'submit' | 'reset';
	disabled?: HTMLButtonAttributes['disabled'];
}