@hubspot/ui-extensions
TypeScript icon, indicating that this package has built-in type declarations

0.8.16 • Public • Published

UI Extensions

React components and utilities for extending HubSpot's UI.

TOC

Components

Accordion

Import
import { Accordion } from '@hubspot/ui-extensions';
Props

The Accordion component accepts the following props:

export interface AccordionProps {
  title: string;
  children: ReactNode;
  defaultOpen?: boolean;
  disabled?: boolean;
  open?: boolean;
  onClick?: () => void;
  size?:
    | 'small'
    | 'extra-small'
    | 'medium'
    | 'xs'
    | 'sm'
    | 'md';
}
Prop Type Default Description
title string N/A The title text for the accordion.
children ReactNode(optional) N/A The main content of the accordion when it opens.
defaultOpen boolean(optional) false If true, the accordion will be open by default.
disabled boolean(optional) false If true, users cannot change the open state of the accordion.
open boolean(optional) N/A Use it when you want to control the open state programatically. If true, the accordion will open.
onClick () => void (optional) N/A A function that will be invoked when the title is clicked. It receives no arguments and it's return value is ignored.
size 'extra-small' | 'small' | 'medium' | 'xs' | 'sm' | 'md' 'small' The size of the accordion title.
Usage
function Extension() {
  return (
    <>
      <Accordion title="Item One">
        <Text>first inner text</Text>
      </Accordion>
      <Accordion title="Item Two">
        <Text>second inner text</Text>
      </Accordion>
    </>
  );
}

Alert

Import
import { Alert } from '@hubspot/ui-extensions';
Props

The Alert component accepts the following props:

export interface AlertProps {
  title: string;
  children?: ReactNode;
  variant?: 'info' | 'warning' | 'success' | 'error' | 'danger';
}
Prop Type Default Description
title string N/A The title text for the alert message.
children ReactNode(optional) N/A The main content of the alert message when the body prop is not provided.
variant 'info' | 'warning' | 'success' |'error' | 'danger' (optional) 'info' Sets the color variation of the alert
Usage
const Extension = () => {
  return (
    <>
      <Alert title="Important Info" variant="info">
        This is an informative message.
      </Alert>
      <Alert title="Success"variant="success">
        Operation completed successfully.
      </Alert>
      <Alert title="Warning" variant="warning" >
        Proceed with caution.
      </Alert>
      <Alert title="Error" variant="error" >
        Something went wrong. Please try again.
      </Alert>
      <Alert title="Danger" variant="danger" >
        This action cannot be undone. Be careful.
      </Alert>
    </>
  );
};

Box

Import
import { Box } from '@hubspot/ui-extensions';
Props
export interface BoxProps {
  children: ReactNode;
  alignSelf?: 'start' | 'center' | 'baseline' | 'end' | 'stretch' | 'auto';
  flex?: 'initial' | 'auto' | 'none' | number;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
alignSelf 'start' | 'center' | 'baseline' | 'end' | 'stretch' | 'auto' (optional) 'auto' Overrides flex's align item value for this element.
flex 'initial' | 'auto' | 'none' | number (optional) 'initial' Sets how the item will grow or shrink when it's a direct ancestor of the Flex component.

flex prop Options

  • initial: The item is sized according to its width and height properties. It shrinks to its minimum size to fit the container, but does not grow to absorb any extra free space in the flex container.
  • auto: The item is sized according to its width and height properties, but grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container.
  • none: The item is sized according to its width and height properties. It is fully inflexible: it neither shrinks nor grows in relation to the flex container.
  • number: Tells a component to fill all available space, shared evenly amongst other components with the same parent. The larger the flex given, the higher the ratio of space a component will take compared to its siblings.
Usage
const Extension = () => {
  return (
    <Box>
      <Text>Hello</Text>
    </Box>
  );
};

Button

Import
import { Button } from '@hubspot/ui-extensions';
Props
interface ButtonProps {
  children: string;
  onClick?: () => void;
  href?: string;
  disabled?: boolean;
  variant?: 'primary' | 'secondary' | 'destructive';
  type?: 'button' | 'reset' | 'submit';
}
Prop Type Default Description
children string N/A The displayable text for the Button
onClick () => void (optional) N/A A function that will be invoked when the button is clicked. It receives no arguments and it's return value is ignored
href string(optional) N/A A URL that will be opened when the button is clicked. If the value is a URL external to HubSpot it will be opened in a new tab.
disabled boolean(optional) N/A Determines if the button should be disabled or not.
variant 'primary' | 'secondary' | 'destructive' (optional) 'secondary' Sets the color variation of the button
type 'button' | 'reset' | 'submit' (optional) 'button' Sets the HTML attribute "role" of the button
Usage
const Extension = () => {
  return (
    <Button
      onClick={() => {
        console.log('Someone clicked on the button!');
      }}
      href="https://hubspot.com"
      variant="destructive"
      type="button"
    >
      Click me!
    </Button>
  );
};

ButtonRow

Import
import { ButtonRow } from '@hubspot/ui-extensions';
Props
interface ButtonRowProps {
  children: ReactNode;
  disableDropdown?: boolean;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
disableDropdown boolean(optional) false Disables the dropdown list of buttons that appears the the children expand beyond the horizontal space
Usage
const Extension = () => {
  return (
    <ButtonRow disableDropdown={false}>
      <Button
        onClick={() => {
          console.log('Regular button clicked');
        }}
      >
        Regular Button
      </Button>
      <Button
        onClick={() => {
          console.log('Reset button clicked');
        }}
        variant="destructive"
        type="reset"
      >
        Reset
      </Button>
      <Button
        onClick={() => {
          console.log('Submit button clicked');
        }}
        variant="primary"
        type="submit"
      >
        Submit
      </Button>
    </ButtonRow>
  );
};

Card

Import
import { Card } from '@hubspot/ui-extensions';
Props
interface CardProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
Usage
const Extension = () => {
  return (
    <Card>
      <Button
        onClick={() => {
          console.log('Regular button clicked');
        }}
      >
        Regular Button
      </Button>
    </Card>
  );
};

DateInput

Import
import { DateInput } from '@hubspot/ui-extensions';
Props
interface DateInputProps {
  label: string;
  name: string;
  value?: { year: number; month: number; date: number };
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  error?: boolean;
  defaultValue?: { year: number; month: number; date: number };
  validationMessage?: string;
  onChange?: (value: {
    year: number;
    month: number;
    date: number;
    formattedDate?: string;
  }) => void;
  onBlur?: (value: {
    year: number;
    month: number;
    date: number;
    formattedDate?: string;
  }) => void;
  onFocus?: (value: {
    year: number;
    month: number;
    date: number;
    formattedDate?: string;
  }) => void;
  min?: { year: number; month: number; date: number };
  max?: { year: number; month: number; date: number };
  minValidationMessage?: string;
  maxValidationMessage?: string;
  format?:
    | 'YYYY-MM-DD'
    | 'L'
    | 'LL'
    | 'll'
    | 'short'
    | 'long'
    | 'medium'
    | 'standard';
  timezone?: 'userTz' | 'portalTz';
  clearButtonLabel?: string;
  todayButtonLabel?: string;
}
Prop Type Default Description
label string N/A The label text to display for the form input element.
name string N/A The unique identifier for the input element, this could be thought of as the HTML5 Input element's name attribute
value { year: number; month: number; date: number }(optional) N/A The value of the input
required boolean(optional) false Determines if the required indicator should be displayed
readOnly boolean(optional) false Determines if the field is editable or not.
description string(optional) N/A Instructional message to display to the user to help understand the purpose of the input.
tooltip string(optional) N/A Text that will appear in a tooltip next to the input label.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the input has an error.
onChange (value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional) N/A A callback function that is invoked when the user selects or types a valid date. It won't get called on invalid inputs.
onBlur (value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional) N/A A function that is called and passed the value every time the field loses focus.
onFocus (value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional) N/A A function that is called and passed the value every time the field gets focused.
min { year: number; month: number; date: number }(optional) N/A Sets the earliest date that will be valid.
max { year: number; month: number; date: number }(optional) N/A Sets the latest date that will be valid
minValidationMessage string "You must choose an older date" Sets the message that users will see when the hover over dates that are older than the min date.
maxValidationMessage string "You must choose a newer date" Sets the message that users will see when the hover over dates that are newer than the max date.
format 'short' | 'long' | 'medium' | 'standard' | 'YYYY-MM-DD' | 'L' | 'LL' | 'll' short Sets the date format that input will display to users.
timezone 'userTz' | 'portalTz' userTz Sets the timezone that the component will user to calculate valid dates.
clearButtonLabel string Clear Sets the label of the clear button.
todayButtonLabel string Today Sets the label of the today button.

Format Options

  • short: 09/04/1986
  • long: September 4, 1986
  • medium : Sep 4, 1986
  • standard: 1986-09-04
  • L: 09/04/1986
  • LL: September 4, 1986
  • ll : Sep 4, 1986
  • YYYY-MM-DD: 1986-09-04
Usage
const Extension = () => {
  return (
      <DateInput
        label="Appointment Date"
        name="appointment-date"
        format="LL"
      />
  );
};

DescriptionList

Import
import { DescriptionList } from '@hubspot/ui-extensions';
Props
interface DescriptionListProps {
  children: ReactNode;
  direction?: 'row' | 'column';
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. The children should be DescriptionListItem
direction 'row' | 'column' (optional) 'column' The direction the label/value pairs are placed in the description list container.
Usage
const Extension = () => {
  return (
    <DescriptionList direction="row">
      <DescriptionListItem label={'First Name'}>
        <Text>Alan</Text>
      </DescriptionListItem>
      <DescriptionListItem label={'Last Name'}>
        <Text>Turing</Text>
      </DescriptionListItem>
    </DescriptionList>
  );
};

DescriptionListItem

Import
import { DescriptionListItem } from '@hubspot/ui-extensions';
Props
interface DescriptionListItemProps {
  children: ReactNode;
  label: string;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
label string N/A Text to be displayed as the label
Usage
const Extension = () => {
  return (
    <DescriptionList direction="row">
      <DescriptionListItem label={'First Name'}>
        <Text>Alan</Text>
      </DescriptionListItem>
      <DescriptionListItem label={'Last Name'}>
        <Text>Turing</Text>
      </DescriptionListItem>
    </DescriptionList>
  );
};

Divider

Import
import { Divider } from '@hubspot/ui-extensions';
Props
interface DividerProps {
  distance?:
    | 'flush'
    | 'extra-small'
    | 'small'
    | 'medium'
    | 'large'
    | 'extra-large';
}
Prop Type Default Description
distance 'flush'| 'extra-small' | 'small' | 'medium' | 'large'| 'extra-large' (optional) 'small' The size of the padding above and below the divider.
Usage
const Extension = () => {
  return <Divider distance="extra-large" />;
};

Flex

Import
import { Flex } from '@hubspot/ui-extensions';
Props
export interface FlexProps {
  children?: React.ReactNode;
  direction?: 'row' | 'column';
  justify?: 'center' | 'end' | 'start' | 'around' | 'between';
  align?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
  alignSelf?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
  wrap?: 'wrap' | 'nowrap';
  gap?:
  | 'flush'
  | 'small'
  | 'extra-small'
  | 'medium'
  | 'large'
  | 'extra-large'
  | 'xs'
  | 'sm'
  | 'md'
  | 'lg'
  | 'xl';
}
Prop Type Default Description
direction 'row' | 'column' 'column' Sets the direction in which elements are placed.
justify 'start' | 'center' |'end' |'around' | 'between' 'start' Defines how to distribute space between and around children on main axis.
align 'start' | 'center' |'baseline' | 'end' | 'stretch' |'between' 'start' Controls the aligment of children in the cross axis.
alignSelf 'start' | 'center' | 'baseline' | 'end' | 'stretch' | 'auto' (optional) 'auto' Overrides flex's align item value for this element. Useful when Flex is the child of another Flex component.
wrap 'wrap' | 'nowrap' 'nowrap' If set to nowrap, children are forced onto one line. If set to wrap, they can wrap into multiple lines.
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
gap 'flush' | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' 'small' Amount of space between each child component passed as children.
Usage
const Extension = () => {
  return (
    <Flex direction="column" distance="large">
      <Tile>Tile 1</Tile>
      <Tile>Tile 2</Tile>
      <Tile>Tile 3</Tile>
    </Flex>
  );
};

Form

Import
import { Form } from '@hubspot/ui-extensions';
Props
interface FormProps {
  children: ReactNode;
  onSubmit?: (event: RemoteEvent<FormInputValues>) => void;
  preventDefault?: boolean;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
onSubmit function(optional) N/A A function that will be called when the form is submitted. It will receive a RemoteEvent as argument and it's return value will be ignored.
preventDefault boolean(optional) false If set to true event.preventDefault() will be invoked before your onSubmit function is called, preventing the default html form behavior.
Usage
const Extension = () => {
  return (
    <Form onSubmit={() => { console.log('Form submitted!')}} preventDefault={true}>
      <Input {...} />
      <Select {...} />
      <Button
        onClick={() => {
          console.log('Submit button clicked');
        }}
        variant="primary"
        type="submit"
      >
        Submit
      </Button>
    </Form>
  );
}

EmptyState

Import
import { EmptyState } from '@hubspot/ui-extensions';
Props
interface EmptyStateProps {
  children: ReactNode;
  flush?: boolean;
  imageWidth?: number;
  layout?: 'horizontal' | 'vertical';
  reverseOrder?: boolean;
  title?: string;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
flush boolean(optional) false Removes the default vertical margins for the component.
imageWidth number(optional) 250 The max-width for the image container.
layout 'horizontal' | 'vertical' (optional) 'horizontal' Sets the layout direction for the content.
reverseOrder boolean(optional) false Swaps the visual order of the text (primary) and image (secondary) content. This ensures the primary content is still presented first to assistive technology.
title string(optional) Intl('All is not lost.') The text for the title header rendered above the children.
Usage
const Extension = ({ data }) => {
  if (!data || !data.length) {
    return (
      <EmptyState title="Nothing here yet" layout="vertical" reverseOrder={true}>
        <Text>Go out there and get some leads!</Text>
      </EmptyState>
    )
  }

  return (
    <Stack>
      {data.map(...)}
    </Stack>
  );
}

ErrorState

Import
import { ErrorState } from '@hubspot/ui-extensions';
Props
interface ErrorStateProps {
  children: ReactNode;
  title?: string;
  type?: 'error' | 'support' | 'lock';
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
title string(optional) Intl('All is not lost.') The text for the title header rendered above the children.
type 'error' | 'support' | 'lock' (optional) 'error' Sets the type of error image that will be shown.
Usage
const Extension = ({ data, error, fetchData }) => {
  if (error) {
    return (
      <ErrorState title="Trouble fetching properties." layout="vertical" reverseOrder={true}>
        <Stack>
          <Text>
            Please try again in a few moments.
          </Text>
          <Button onClick={fetchData}>
            Try again
          </Button>
        </Stack>
      </ErrorState>
    )
  }

  return (
    <Stack>
      {data.map(...)}
    </Stack>
  );
}

Heading

Import
import { Heading } from '@hubspot/ui-extensions';
Props
interface HeadingProps {
  children: ReactNode;
  inline?: boolean;
}
Prop Type Default Description
children string N/A Text to be displayed as heading text.
inline boolean(optional) false Determines if the text will break line or share the space.
Usage
const Extension = () => {
  return <Heading>Plain text, nothing special here</Heading>;
};

Image

Import
import { Image } from '@hubspot/ui-extensions';
Props
interface ImageProps {
  alt?: string;
  href?: string;
  onClick?: () => void;
  src: string;
  width?: number;
  height?: number;
}
Prop Type Description
alt string(optional) The alt text for the image, similar to the alt attribute for the html img tag
href string(optional) If provided, it will be used as a href that will be opened in a new tag when the image is clicked
onClick function(optional) A function that will be called when the image is clicked on. This function will receive no arguments any returned values will be ignored.
src string The url to the image to display, similar to img tag
width number(optional) The pixel width of the image
height number(optional) The pixel height of the image
Usage
const Extension = () => {
  return (
    <Image
      alt="A picture of an adorable black lab puppy, click on me to see in a new tab"
      src="https://picsum.photos/id/237/200/300"
      href="https://picsum.photos/id/237"
      onClick={() => {
        console.log('Someone clicked on the image!');
      }}
      width={200}
    />
  );
};

Input

Import
import { Input } from '@hubspot/ui-extensions';
Props
interface InputProps {
  label: string;
  name: string;
  value?: string;
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  placeholder?: string;
  error?: boolean;
  validationMessage?: string;
  onChange?: (value: string) => void;
  onInput?: (value: string) => void;
  onBlur?: (value: string) => void;
  onFocus?: (value: string) => void;
}
Prop Type Default Description
label string N/A The label text to display for the form input element
name string N/A The unique identifier for the input element, this could be thought of as the HTML5 Input element's name attribute
value string(optional) '' The value of the input
required boolean(optional) false Determines if the required indicator should be displayed
readOnly boolean(optional) false Determines if the field is editable or not.
description string(optional) N/A Instructional message to display to the user to help understand the purpose of the input.
tooltip string(optional) N/A Text that will appear in a tooltip next to the input label.
placeholder string(optional) N/A Text that appears in the input when it has no value set.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the input has an error.
onChange (value: string) => void(optional) N/A A callback function that is invoked when the value is committed. Currently these times are onBlur of the input and when the user submits the form.
onInput (value: string) => void(optional) N/A A function that is called and passed the value every time the field is edited by the user. It is recommended that you do not use this value to update state, that is what onChange should be used for. Instead this should be used for validation.
onBlur (value: string) => void(optional) N/A A function that is called and passed the value every time the field loses focus.
onFocus (value: string) => void(optional) N/A A function that is called and passed the value every time the field gets focused.
Usage
import { useState } from 'react';

const Extension = () => {
  const [name, setName] = useState('');
  const [validationMessage, setValidationMessage] = useState('');
  const [isValid, setIsValid] = useState(true);

  return (
    <Form>
      <Input
        label="First Name"
        name="first-name"
        tooltip="Please enter your first name"
        description="Please enter your first name"
        placeholder="First name"
        required={true}
        error={!isValid}
        validationMessage={validationMessage}
        onChange={value => {
          setName(value);
        }}
        onInput={value => {
          if (value !== 'Bill') {
            setValidationMessage('This form only works for people named Bill');
            setIsValid(false);
          } else if (value === '') {
            setValidationMessage('First name is required');
            setIsValid(false);
          } else {
            setValidationMessage('Valid first name!');
            setIsValid(true);
          }
        }}
      />
    </Form>
  );
};

Link

Import
import { Link } from '@hubspot/ui-extensions';
Props
export interface LinkProps {
  href: string;
  variant?: 'primary' | 'destructive' | 'light' | 'dark';
  children: ReactNode;
  onClick?: () => void;
  preventDefault?: boolean;
}
Prop Type Default Description
href string N/A A URL that will be opened when the link is clicked. If the value is a URL external to HubSpot it will be opened in a new tab.
variant 'primary' | 'light' | 'dark' | 'destructive' (optional) 'primary' Sets the color variation of the link
children ReactNode N/A Sets the content that will render inside the component.
onClick () => void (optional) N/A A function that will be invoked when the link is clicked. It receives no arguments and it's return value is ignored
preventDefault boolean(optional) false If set to true event.preventDefault() will be invoked before your onClick function is called, preventing automatic navigation to the anchor's href url.
Usage
const Extension = () => {
  return <Link href="https://app.hubspot.com/">HubSpot</Link>;
};

LoadingSpinner

Import
import { LoadingSpinner } from '@hubspot/ui-extensions';
Props
export interface LoadingSpinnerProps {
  label: string;
  showLabel?: boolean;
  size?: 'xs' | 'extra-small' | 'sm' | 'small' | 'md' | 'medium';
  layout?: 'inline' | 'centered';
}
Prop Type Default Description
label string N/A The companion text for the loading spinner.
showLabel boolean(optional) false if true, the label will be visible alongside the loading spinner.
size 'xs' | 'sm' | 'md' | 'extra-small' | 'small' | 'medium' (optional) 'sm' The size of the loading spinner icon.
layout 'inline'| 'centered' (optional) N/A Use the centered option for layout as a convenience for the common pattern of filling the space of its parent.
Usage
const Extension = () => {
  return <LoadingSpinner label="Loading..." />;
};

MultiSelect

import { MultiSelect } from '@hubspot/ui-extensions';

Props

interface MultiSelectProps {
  label: string;
  name: string;
  value?: (string | number)[];
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  placeholder?: string;
  error?: boolean;
  errorMessage?: string;
  onChange: (value: (string | number)[]) => void;
  options: {
    label: string;
    value: string | number;
  }[];
  variant?: 'transparent' | 'input';
}
Prop Type Default Description
label string(optional) N/A The label text to display for the select element.
name string(optional) N/A The unique identifier for the select element.
value Array<string | number> N/A The value of the select input.
required boolean false Determines if the required indicator should be displayed.
readOnly boolean false Determines if the field is editable or not.
description string N/A Instructional message to display to the user to help understand the purpose of the input.
tooltip string N/A Text that will appear in a tooltip next to the input label.
placeholder string N/A Text that appears in the input when it has no value set.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the input has an error.
onChange (value: Array<string | number>) => void N/A Function that is called with the new value when it is updated.
options Array<{label: string; value: string | number}> N/A Array of options to be displayed in the select. label will be used as the display text in the dropdown list and value should be a unique identifier. value is the data that will be submitted with the form.
variant 'transparent' | 'input' input Sets the visual styles of the button used for the anchor of the component.
Usage
const Extension = () => {
  const options = [
    { label: 'Ice cream', value: 'ice-cream' },
    { label: 'Pizza', value: 'pizza' },
    { label: 'Burger', value: 'burger' },
    { label: 'Soda', value: 'soda' },
  ];

  return (
    <MultiSelect
      name="favorite-food"
      label="Favorite Food"
      options={options}
    />
  );
};

NumberInput

Import
import { NumberInput } from '@hubspot/ui-extensions';
Props
export interface NumberInputProps {
  label: string;
  name: string;
  value?: number;
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  placeholder?: string;
  error?: boolean;
  defaultValue?: number;
  validationMessage?: string;
  onChange?: (value: number) => void;
  onBlur?: (value: number) => void;
  onFocus?: (value: number) => void;
  min?: number;
  max?: number;
  precision?: number;
  formatStyle?: 'decimal' | 'percentage';
}
Prop Type Default Description
label string N/A The label text to display for the form input element
name string N/A The unique identifier for the input element, this could be thought of as the HTML5 Input element's name attribute
value number(optional) '' The value of the input
required boolean(optional) false Determines if the required indicator should be displayed
readOnly boolean(optional) false Determines if the field is editable or not.
description string(optional) N/A Instructional message to display to the user to help understand the purpose of the input.
tooltip string(optional) N/A Text that will appear in a tooltip next to the input label.
placeholder string(optional) N/A Text that appears in the input when it has no value set.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the input has an error.
onChange (value: number) => void(optional) N/A A callback function that is invoked when the user types a valid number. It won't get called on invalid inputs.
onBlur (value: number) => void(optional) N/A A function that is called and passed the value every time the field loses focus.
onFocus (value: number) => void(optional) N/A A function that is called and passed the value every time the field gets focused.
min number(optional) N/A Sets the lower bound of your input.
max number(optional) N/A Sets the upper bound of your input.
precision number(optional) N/A Represents the number of digits to the right of the decimal point.
precision number(optional) N/A Represents the number of digits to the right of the decimal point.
formatStyle 'decimal' | 'percentage' 'decimal' Formats the input as a decimal point number or a percentage.
Usage
const Extension = () => {
  const [portalCount, setPortalCount] = useState(0);
  return (
    <NumberInput
      label={'HubSpot Portal Count'}
      name="portalsNumber"
      description={'Number of active portals'}
      placeholder={'number of portals'}
      value={portalCount}
      onChange={value => setPortalCount(value)}
    />
  );
};

ProgressBar

Import
import { ProgressBar } from '@hubspot/ui-extensions';
Props
export interface ProgressBarProps {
  title?: string;
  aria-label?: string;
  showPercentage?: boolean;
  value?: number;
  maxValue?: number;
  valueDescription?: string;
  variant?: 'success' | 'danger' | 'warning';
}
Prop Type Default Description
title string(optional) N/A Text to be displayed in the progressbar title.
showPercentage boolean(optional) false Toggles the display of the completion percentage.
value number(optional) 0 The value of the progress indicator.
maxValue number(optional) 100 The maximum value of the progress bar.
valueDescription string(optional) N/A Text that explains the current state of the value prop. Renders to the right of title. Example: "10,000 of 7,500"
variant 'success' | 'danger' | 'warning' 'success' The type of progressbar to display. Defaults to success.
aria-label string(optional) N/A Indicates the content of the ProgressBar to screen readers. Should be used if there's no title.
Usage
const Extension = () => {
  return (
    <ProgressBar
      variant="warning"
      value={50}
      maxValue={200}
      showPercentage={true}
    />
  );
};

Select

Import
import { Select } from '@hubspot/ui-extensions';
Props
interface SelectProps {
  label?: string;
  name?: string;
  value?: string | number | boolean;
  variant?: 'transparent' | 'input'
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  placeholder?: string;
  error?: boolean;
  errorMessage?: string;
  onChange: (value: string) => void;
  options: {
    label: string;
    value: string | number | boolean;
  }[];
}
Prop Type Default Description
label string(optional) N/A The label text to display for the select element.
name string(optional) N/A The unique identifier for the select element.
value string | number | boolean '' The value of the select input.
required boolean false Determines if the required indicator should be displayed
readOnly boolean false Determines if the field is editable or not.
description string N/A Instructional message to display to the user to help understand the purpose of the input.
tooltip string N/A Text that will appear in a tooltip next to the input label.
placeholder string N/A Text that appears in the input when it has no value set.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the input has an error.
onChange (value: string) => void N/A Function that is called with the new value when it is updated.
options Array<{label: string; value: string | number | boolean}> N/A Array of options to be displayed in the select. label will be used as the display text in the dropdown list and value should be a unique identifier. value is the data that will be submitted with the form.
variant 'transparent' | 'input' input Sets the visual styles of the button used for the anchor of the component.
Usage
const Extension = () => {
  const [name, setName] = useState(null);
  const [validationMessage, setValidationMessage] = useState('');
  const [isValid, setIsValid] = useState(true);

  const options = [
    { label: 'Bill', value: 42 },
    { label: 'Ted', value: 43 },
  ];

  return (
    <Form>
      <Select
        label="Best Bill & Ted Character?"
        name="best-char"
        tooltip="Please choose"
        description="Please choose"
        placeholder="Bill or Ted?"
        required={true}
        error={!isValid}
        validationMessage={validationMessage}
        onChange={value => {
          setName(value);
          if (!value) {
            setValidationMessage('This is required');
            setIsValid(false);
          } else {
            setValidationMessage('Excellent!');
            setIsValid(true);
          }
        }}
        options={options}
      />
    </Form>
  );
};

Stack

Import
import { Stack } from '@hubspot/ui-extensions';
Props
interface StackProps {
  distance?:
    | 'flush'
    | 'small'
    | 'extra-small'
    | 'medium'
    | 'large'
    | 'extra-large'
    | 'xs'
    | 'sm'
    | 'md'
    | 'lg'
    | 'xl';
  direction?: 'row' | 'column';
  children?: ReactNode;
}
Prop Type Default Description
distance 'flush' | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' 'small' Amount of space between each child component passed as children
direction 'row' | 'column' 'column' Stacks elements in the vertical or horizontal direction.
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
Usage
const Extension = () => {
  return (
    <Stack>
      <Image {...} />
      <Text {...} />
    </Stack>
    );
}

Statistics

Import
import { Statistics } from '@hubspot/ui-extensions';
Props
interface StatisticsProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be StatisticsItem or StatisticsTrend
Usage
const Extension = () => {
  return (
    <Statistics>
      <StatisticsItem {...} />
      <StatisticsTrend {...} />
    </Statistics>
  );
}

StatisticsItem

Import
import { StatisticsItem } from '@hubspot/ui-extensions';
Props
interface StatisticsItemProps {
  id?: string;
  label: string;
  number: string;
  children: ReactNode;
}
Prop Type Default Description
id string(optional) N/A The unique identifier
label string N/A The text to be used as a label
number string N/A Fully formatted string to be displayed as the item's primary number
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be Text or StatisticsTrend
Usage
const Extension = () => {
  return (
    <Statistics>
      <StatisticsItem label="Sales" number={'30000'}>
        <Text>Big Numbers</Text>
      </StatisticsItem>
    </Statistics>
  );
};

StatisticsTrend

Import
import { StatisticsTrend } from '@hubspot/ui-extensions';
Props
interface StatisticsTrendProps {
  value: string;
  direction: 'increase' | 'decrease';
}
Prop Type Default Description
value string N/A Formatted string to be displayed as trend value
direction 'increase' | 'decrease' N/A Direction in which the trend arrow should be displayed
Usage
const Extension = () => {
  return (
    <Statistics>
      <StatisticsItem label="Item A Sales" number="10000">
        <StatisticsTrend direction="decrease" value="200%" />
      </StatisticsItem>
      <StatisticsItem label="Item B Sales" number="100000">
        <StatisticsTrend direction="increase" value="100%" />
      </StatisticsItem>
    </Statistics>
  );
};

StepIndicator

Import
import { StepIndicator } from '@hubspot/ui-extensions';
Props
export interface StepIndicatorProps {
  stepNames: string[];
  direction?: 'horizontal' | 'vertical';
  onClick?: (stepIndex: number) => void;
  circleSize?: AllSizes;
  currentStep?: number;
  variant?: 'default' | 'compact' | 'flush';
}
Prop Type Default Description
stepNames Array<string> N/A Sets the name of the available steps.
direction 'horizontal' | 'vertical' (optional) N/A Determines whether the step indicator is laid out on a horizontal or vertical axis.
onClick () => void (optional) N/A A function that will be invoked when a step is clicked. It receives the current step index as an argument(zero based). Use this to update the active step.
circleSize 'extra-small' | 'small' | 'medium' | 'large'| 'extra-large' (optional) 'small' Determines the size of the circle of an individual step.
currentStep number(optional) N/A Determines which step is visually active in the step indicator.
variant 'default' | 'compact' | 'flush' (optional) 'default' Changes the visual styling of the component. compact only shows the title of the active step. flush does the same thing, but also removes the left and right margins.
Usage
    function Extension() {
      const [currentStep, setCurrentStep] = useState(0);

      return (
        <Stack>
          <StepIndicator
            currentStep={currentStep}
            stepNames={['First', 'Second', 'Third']}
          />
          <Stack>
            <Button onClick={() => setCurrentStep(currentStep - 1)}>
              Previous
            </Button>
            <Button onClick={() => setCurrentStep(currentStep + 1)}>
              Next
            </Button>
          </Stack>
        </Stack>
      );
    }

Table

Import
import { Table } from '@hubspot/ui-extensions';
Props
interface TableProps {
  children: ReactNode;
  flush?: boolean;
  bordered?: boolean;
  paginated?: boolean;
  // if paginated=true
  pageCount: number;
  onPageChange: (pageNumber: number) => void;
  showButtonLabels?: boolean;
  showFirstLastButtons?: boolean;
  maxVisiblePageButtons?: number;
  page?: number;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be TableHead, TableFooter, or TableBody
flush boolean(optional) false If true the table will not have bottom margin.
bordered boolean(optional) true If false the table will not haver borders around its content.
paginated boolean(optional) false If true, the table will display the paginator component and consumer will have to provide extra pagination props.

Props for paginated=true

Prop Type Default Description
pageCount number N/A The total number of pages available
onPageChange onPageChange: (pageNumber: number) => void N/A A function that will be invoked when the pagination button is clicked. It receives the new page number as argument.
showButtonLabels boolean(optional) true if false, it hides the text labels for the First/Prev/Next/Last buttons. The button labels will still be accessible for screen readers.
showFirstLastButtons boolean(optional) false if true, it displays the First page and Last page buttons.
maxVisiblePageButtons number(optional) 5 Changes how many page buttons are shown.
page number(optional) N/A Denotes the current page.
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Phone</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell>555-555-7866</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

// Paginated example

function generateData(count = 15) {
  const result = [];

  for (let index = 0; index < count; index++) {
    result.push({
      name: `Jane Doe ${index}`,
      email: `janedoemail${index}@hubspot.com`,
    });
  }

  return result;
}

function PaginatedTable() {
  const ITEMS_PER_PAGE = 10;
  const data = generateData(30);

  const [currentPage, setCurrentPage] = useState(1);
  const pageCount = data.length / ITEMS_PER_PAGE;

  const dataToDisplay = data.slice(
    (currentPage - 1) * ITEMS_PER_PAGE,
    currentPage * ITEMS_PER_PAGE
  );

  return (
    <Table
      paginated={true}
      pageCount={pageCount}
      page={currentPage}
      onPageChange={(nextPageNumber: number) => {
        setCurrentPage(nextPageNumber);
      }}
    >
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Email</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        {dataToDisplay.map(({ name, email }) => {
          console.log(name, email);
          return (
            <TableRow key={email}>
              <TableCell>{name}</TableCell>
              <TableCell>{email}</TableCell>
            </TableRow>
          );
        })}
      </TableBody>
    </Table>
  );
}

TableBody

Import
import { TableBody } from '@hubspot/ui-extensions';
Props
interface TableBodyProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be TableRow.
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Phone</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell>555-555-7866</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

TableCell

Import
import { TableCell } from '@hubspot/ui-extensions';
Props
interface TableCellProps {
  children: ReactNode;
  width?: 'min' | 'max' | 'auto' | number;
  align?: 'left' | 'center' | 'right';
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
width 'min' | 'max' | 'auto' | number 'auto' Sets the width of a table cell
align 'left' | 'center' | 'right' 'left' Sets the alignment of a table cell
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Phone</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell>555-555-7866</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

TableFooter

Import
import { TableFooter } from '@hubspot/ui-extensions';
Props
interface TableFooterProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be TableRow.
Usage
const Extension = () => {
  return (
    <Table>
      <TableHead>
        <TableRow>
          <TableHeader>Series</TableHeader>
          <TableHeader>Years on air</TableHeader>
          <TableHeader>Emmys</TableHeader>
        </TableRow>
      </TableHead>
      <TableFooter>
        <TableRow>
          <TableHeader>Totals</TableHeader>
          <TableHeader>43</TableHeader>
          <TableHeader>50</TableHeader>
        </TableRow>
      </TableFooter>
      <TableBody>
        <TableRow>
          <TableCell>The Simpsons</TableCell>
          <TableCell>28</TableCell>
          <TableCell>31</TableCell>
        </TableRow>
        <TableRow>
          <TableCell>M*A*S*H</TableCell>
          <TableCell>11</TableCell>
          <TableCell>14</TableCell>
        </TableRow>
        <TableRow>
          <TableCell>Arrested Development</TableCell>
          <TableCell>4</TableCell>
          <TableCell>5</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

TableHead

Import
import { TableHead } from '@hubspot/ui-extensions';
Props
interface TableHeadProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be TableHeader.
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Phone</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell>555-555-7866</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

TableHeader

Import
import { TableHeader } from '@hubspot/ui-extensions';
Props
interface TableHeaderProps {
  children: ReactNode;
  width?: 'min' | 'max' | 'auto' | number;
  align?: 'left' | 'center' | 'right';
  sortDirection?: 'ascending' | 'descending' | 'none';
  onSortChange?: (value: 'ascending' | 'descending') => void;
  disabled?: boolean;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
width 'min' | 'max' | 'auto' | 'large' 'auto' Sets the width of a table header.
align 'left' | 'center' | 'right' 'left' Sets the alignment of a table header
sortDirection 'ascending' | 'descending' | 'none' 'N/A' Sets the current direction in which the column is sorted (if any). It's a visual indicator, it doesn't modify the data.
disabled boolean(optional) false If true, users cannot change the sort ordering. It has no effect if sort=never or undefined.
onSortChange `(value: 'ascending' 'descending') => void(optional)` N/A
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader width={150} align="left">Name</TableHeader>
          <TableHeader>Price</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell align="right">$1.50</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

TableRow

Import
import { TableRow } from '@hubspot/ui-extensions';
Props
interface TableRowProps {
  children: ReactNode;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
Usage
const Extension = () => {
  return (
    <Table bordered={true}>
      <TableHead>
        <TableRow>
          <TableHeader>Name</TableHeader>
          <TableHeader>Phone</TableHeader>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>Roger Federer</TableCell>
          <TableCell>555-555-7866</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
};

Tag

Import
import { Tag } from '@hubspot/ui-extensions';
Props
interface TagProps {
  children: ReactNode;
  onClick?: () => void;
  variant?: 'default' | 'warning' | 'success' | 'error';
}
Prop Type Default Description
children string N/A Text to be displayed in the tag.
onClick () => void (optional) N/A A function that will be invoked when the Tag is clicked. It receives no arguments and it's return value is ignored.
variant 'default' | 'warning' | 'success' | 'error' (optional) 'default' The color variation of the tag to display
Usage
const Extension = () => {
  return (
    <Tag
      variant="success"
      onClick={() => {
        console.log('Tag clicked!');
      }}
    >
      Success
    </Tag>
  );
};

Text

Import
import { Text } from '@hubspot/ui-extensions';
Props
export interface TextFormatOptions {
  fontWeight?: 'regular' | 'bold' | 'demibold';
  italic?: boolean;
  lineDecoration?: 'none' | 'underline' | 'strikethrough';
}

export type TextProps = {
  variant?: 'bodytext' | 'microcopy';
  inline?: boolean;
  children: ReactNode;
  format?: TextFormatOptions;
};
Prop Type Default Description
format 'TextFormatOptions' (optional) N/A Type of formatting options for the text.
children string N/A Text to be displayed as body text.
variant 'bodytext' | 'microcopy' 'bodytext' Type of text to display
inline boolean(optional) false If false the text component will not insert a line break.

Format Options

  • bold text: { fontWeight: 'bold' }
  • semibold text: { fontWeight: 'demibold' }
  • italicized text: { italic: true }
  • strikethrough text: { lineDecoration: 'strikethrough' }
  • underlined text: { lineDecoration: 'underline' }
  • inline text: <Text inline={true}/>
Usage
const Extension = () => {
  return (
    <>
      <Text>Plain text</Text>
      <Text format={{ fontWeight: 'bold' }}>Bold</Text>
      <Text format={{ italic: true }}>Italics</Text>
      <Text format={{ fontWeight: 'bold', italic: true }}>
        Bold and Italic text
      </Text>
      <Text format={{ lineDecoration: 'strikethrough' }}>
        Strikethrough Text
      </Text>
      <Text variant="microcopy">
        Microcopy text
        <Text inline={true} format={{ fontWeight: 'bold' }}>
          with inner bold
        </Text>
      </Text>
    </>
  );
};

TextArea

Import
import { TextArea } from '@hubspot/ui-extensions';
Props
interface TextareaProps {
  label: string;
  name: string;
  value?: string;
  required?: boolean;
  readOnly?: boolean;
  description?: string;
  tooltip?: string;
  placeholder?: string;
  error?: boolean;
  validationMessage?: string;
  onChange?: (value: string) => void;
  onInput?: (value: string) => void;
  onBlur?: (value: string) => void;
  onFocus?: (value: string) => void;
  cols?: number;
  maxLength?: number;
  rows?: number;
  resize?: 'vertical' | 'horizontal' | 'both' | 'none';
}
Prop Type Default Description
label string N/A The label text to display for the textarea element
name string N/A The unique identifier for the textarea element, this could be thought of as the HTML5 textarea element's name attribute
value string(optional) '' The value of the textarea
required boolean(optional) false Determines if the required indicator should be displayed
readOnly boolean(optional) false Determines if the field is editable or not.
description string(optional) N/A Instructional message to display to the user to help understand the purpose of the textarea.
tooltip string(optional) N/A Text that will appear in a tooltip next to the textarea label.
placeholder string(optional) N/A Text that appears in the textarea when it has no value set.
error boolean(optional) false If set to true, validationMessage is displayed as an error message, if it was provided. The textarea will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message.
validationMessage string(optional) '' The text to show if the textarea has an error.
onChange (value: string) => void(optional) N/A A callback function that is invoked when the value is committed. Currently these times are onBlur of the textarea and when the user submits the form.
onInput (value: string) => void(optional) N/A A function that is called and passed the value every time the field is edited by the user. It is recommended that you do not use this value to update state, that is what onChange should be used for. Instead this should be used for validation.
onBlur (value: string) => void(optional) N/A A function that is called and passed the value every time the field loses focus.
onFocus (value: string) => void(optional) N/A A function that is called and passed the value every time the field gets focused.
cols number(optional) N/A The visible width of the text control, in average character widths.
rows number(optional) N/A The number of visible text lines for the control.
maxLength number(optional) N/A The maximum number of characters (UTF-16 code units) that the user can enter. If this value isn't specified, the user can enter an unlimited number of characters.
resize 'vertical' | 'horizontal' | 'both' | 'none' (optional) 'vertical' Sets whether an element is resizable, and if so, in which directions.
Usage
import { useState } from 'react';

const Extension = () => {
  const [desciptiption, setDescription] = useState('');
  const [validationMessage, setValidationMessage] = useState('');
  const [isValid, setIsValid] = useState(true);

  return (
    <Form>
      <TextArea
        label="Description"
        name="description"
        tooltip="Provide as much detail as possible"
        description="Please include a link"
        placeholder="My desription"
        required={true}
        error={!isValid}
        validationMessage={validationMessage}
        onChange={value => {
          setDescription(value);
        }}
        onInput={value => {
          if (!value.includes('http')) {
            setValidationMessage('A link must be included.');
            setIsValid(false);
          } else {
            setValidationMessage('Valid description!');
            setIsValid(true);
          }
        }}
      />
    </Form>
  );
};

Tile

Import
import { Tile } from '@hubspot/ui-extensions';
Props
interface TileProps {
  children: ReactNode;
  flush?: boolean;
}
Prop Type Default Description
children ReactNode N/A Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.
flush boolean(optional) false If true the content of the Tile will have no left or right padding.
Usage
const Extension = () => {
  return (
    <>
      <Tile flush={true}>
        <Text>No left padding</Text>
      </Tile>
      <Tile>
        <Text>Small amount of left padding</Text>
      </Tile>
    </>
  );
};

ToggleGroup

Import
import { ToggleGroup } from '@hubspot/ui-extensions';
Props
type ToggleGroupProps = {
  toggleType: 'checkboxList' | 'radioButtonList';
  name: string;
  label: string;
  value?: string | string[];
  onChange?: (value: string) => void | (value: string[]) => void;
  validationMessage?: string;
  required?: boolean;
  tooltip?: string;
  error?: boolean;
  options: {
    label: string;
    value: string;
    initialIsChecked?: boolean;
    readonly?: boolean;
    description?: string;
  }[];
  inline?: boolean;
  variant?: 'default' | 'small';
};

| Prop | Type | Default | Description | | --- | --- | --- | --- | --- | | toggleType | 'radioButtonList' \| 'checkboxList' | N/A | The type of toggles that will be shown. 'checkboxList' is a multi-select and 'radioButtonList' is a single select | ; | | name | string | N/A | The unique identifier for the toggle group element. | | label | string | N/A | The label text to display for the toggle group element. | | options | Array<{ label: string; value: string; initialIsChecked?: boolean; readonly?: boolean; description?: string }> | N/A | | | value | string \| string[] (optional) | N/A | The value of the toggle group. If toggleType is 'radioButtonList', this should be a string. If toggleType is 'checkboxList' this should be an array of strings. | | onChange | (value: string) => void \| (value: string[]) => void (optional) | N/A | A function that is called with the new value or values when it is updated. If toggleType is 'radioButtonList', the function will be called with the value that is a string. If toggleType is 'checkboxList' the function will be called with the value that is an array of strings. | | required | boolean(optional) | false | Determines if the required indicator should be displayed | | tooltip | string | N/A | Text that will appear in a tooltip next to the toggle group label. | | error | boolean(optional) | false | If set to true, validationMessage is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, validationMessage is displayed as a success message. | | validationMessage | string(optional) | '' | The text to show if the input has an error. | | inline | boolean(optional) | false | Determines of the options are stacked vertically or share a line horizontally. | | variant | 'default' \| 'small' (optional) | default | The size variation of the individual options. |

Usage
const options = [1, 2, 3, 4].map(n => ({
  label: `Option ${n}`,
  value: `${n}`,
  initialIsChecked: n === 2,
  readonly: false,
  description: `This is option ${n}`,
}));

const Extension = () => {
  return (
    <ToggleGroup
      name="toggle-checkboxes"
      label="Toggle these things"
      error={false}
      options={options}
      tooltip="Here's a secret tip."
      validationMessage="Make sure you do the thing correctly."
      required={false}
      inline={false}
      toggleType="checkboxList"
      variant="default"
    />
  );
};

Readme

Keywords

none

Package Sidebar

Install

npm i @hubspot/ui-extensions

Weekly Downloads

11,508

Version

0.8.16

License

MIT

Unpacked Size

165 kB

Total Files

22

Last publish

Collaborators

  • tscales
  • rsegura
  • hemangthakkar
  • tamarayu
  • jyeager_hubspot
  • camdenphalen
  • bmatto_hs
  • elingyr
  • alonso-cadenas
  • jsines
  • tfinley_hs
  • mshannon_hs
  • arota-hubspot
  • bbarbosa-hubspot
  • service-ccs
  • kemmerle
  • banderson
  • also
  • rberdeen-hubspot
  • harminder01
  • bkrainer-hs
  • friss
  • jhilker
  • atanasiuk
  • ksvirkou-hubspot
  • kbreeman-hubspot
  • brodgers16