## Feature Examples

### Structure
- description: An empty state has 4 optional elements: - `image` - `title` - `subtitle` - `child container,` which can hold any component but is primarily reserved for CTA buttons.
- example:
```jsx
<EmptyState
  image={<Image width="120px" height="120px" />}
  title="Title"
  subtitle="Subtitle"
>
  <StorybookComponents.Placeholder>
    Child container
  </StorybookComponents.Placeholder>
</EmptyState>;
```

### Align
- description: `align` controls how all `EmptyState` content (title, subtitle, image, and actions) is aligned inside its container. - `align="start"`: aligns content to the start (left in LTR) - `align="center"`: centers content (default) - `align="end"`: aligns content to the end (right in LTR)
- example:
```jsx
() => (
  <Box padding="20px" gap="20px" direction="vertical">
    <EmptyState
      align="start"
      title="No products yet"
      subtitle="Add your first product to get started."
    >
      <Button size="small">Add product</Button>
    </EmptyState>

    <EmptyState
      align="center"
      title="No products yet"
      subtitle="Add your first product to get started."
    >
      <Button size="small">Add product</Button>
    </EmptyState>

    <EmptyState
      align="end"
      title="No products yet"
      subtitle="Add your first product to get started."
    >
      <Button size="small">Add product</Button>
    </EmptyState>
  </Box>
);
```

### Skin
- description: Control an empty state's appearance with the `skin` property. There are 3 types: - `page` is for full-page empty states where data is displayed in a full-width table or a card. - `page-no-border` is for full-page empty states where data is displayed in an unknown layout. - `section` is the default theme for layout elements such as cards, tables or modals.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column" gap="48px">
  <EmptyState
    image={<Image width="120px" height="120px" />}
    skin="page"
    title="Page theme"
    subtitle="A subtitle guides users to their next step."
  />
  <EmptyState
    image={<Image width="120px" height="120px" />}
    skin="page-no-border"
    title="Page-no-border theme"
    subtitle="A subtitle guides users to their next step."
  />
  <EmptyState
    image={<Image width="120px" height="120px" />}
    skin="section"
    title="Section theme"
    subtitle="A subtitle guides users to their next step."
  />
</StorybookComponents.Stack>;
```

### Children
- description: Add 1 or more CTA buttons below the subtitle as child elements of the empty state. Be sure to give the user clear next actions.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <EmptyState
    skin="page-no-border"
    title="Add your first product"
    subtitle="Start adding products so customers can shop your online store."
  >
    <StorybookComponents.Placeholder height="36px">
      Child elements
    </StorybookComponents.Placeholder>
  </EmptyState>
  <EmptyState
    skin="page-no-border"
    title="Add your first product"
    subtitle="Start adding products so customers can shop your online store."
  >
    <TextButton prefixIcon={<Icons.Add />}>Add Product</TextButton>
  </EmptyState>
  <EmptyState
    skin="page-no-border"
    title="Add your first product"
    subtitle="Start adding products so customers can shop your online store."
  >
    <StorybookComponents.Stack gap="16px">
      <TextButton prefixIcon={<Icons.Add />}>Add New Product</TextButton>
      <TextButton prefixIcon={<Icons.DownloadImport />}>
        Import Products
      </TextButton>
    </StorybookComponents.Stack>
  </EmptyState>
</StorybookComponents.Stack>;
```

## Common Use Case Examples

### No data on a page
- description: Use the `page` or `page-no-border` skin to tell users what will appear on the page once there's data to display, and if relevant, what they can do to get started.
- example:
```jsx
<Page>
  <Page.Header
    title="Tasks and Reminders"
    actionsBar={<Button prefixIcon={<Icons.Add />}>Add Task</Button>}
  />
  <Page.Content>
    <EmptyState
      skin="page"
      image={
        <Image
          width="120px"
          height="120px"
          src="no_categories.png"
          transparent
        />
      }
      title="Add your first task"
      subtitle="Manage tasks and reminders for your site to get more done."
    >
      {<TextButton prefixIcon={<Icons.Add />}>Add Task</TextButton>}
    </EmptyState>
  </Page.Content>
</Page>;
```

### No data in a card
- description: Use the `section` skin empty state to tell users what will appear on the card once there's data to display and, if relevant, what they can do to get started. Keep the design minimal and avoid using illustrations.
- example:
```jsx
<Page>
  <Page.Header
    title="New Category"
    actionsBar={
      <Box gap="SP2">
        <Button skin="inverted">Cancel</Button>
        <Button>Save</Button>
      </Box>
    }
    breadcrumbs={
      <Breadcrumbs
        activeId="3"
        items={[
          { id: '1', value: 'Categories' },
          { id: '2', value: 'New Category' },
        ]}
      />
    }
    showBackButton
    onBackClicked={() => {}}
  />
  <Page.Content>
    <Layout>
      <Cell>
        <Card>
          <Card.Header title="Category details" />
          <Card.Divider />
          <Card.Content>
            <Layout>
              <Cell span={4}>
                <FormField label="Category name" required>
                  <Input placeholder="e.g., Fitness Classes" />
                </FormField>
              </Cell>
            </Layout>
          </Card.Content>
        </Card>
      </Cell>
      <Cell>
        <Card>
          <Card.Header title="Services" />
          <Card.Divider />
          <Card.Content>
            <EmptyState
              title="Add services to this category"
              subtitle="Choose the services you want included in this category or create new ones."
            >
              <TextButton prefixIcon={<Icons.Add />}>Add Services</TextButton>
            </EmptyState>
          </Card.Content>
        </Card>
      </Cell>
      <Cell>
        <Page.Footer divider>
          <Page.Footer.End>
            <Box gap="SP2">
              <Button priority="secondary">Cancel</Button>
              <Button>Save</Button>
            </Box>
          </Page.Footer.End>
        </Page.Footer>
      </Cell>
    </Layout>
  </Page.Content>
</Page>;
```

### No search results
- description: Use an empty state when a search doesn't return any results. Explain what happened and what users can do next to adjust their search.
- example:
```jsx
() => {
  const [searchTerm, setSearchTerm] = React.useState('');
  const [display, setDisplay] = React.useState('none');
  const [records, setRecords] = React.useState([
    {
      name: `Ballet shoes`,
      SKU: 'BP063001',
      price: '$78',
      inventory: 16,
    },
    {
      name: `Chelsea boots`,
      SKU: 'BP063001',
      price: '$112',
      inventory: 32,
    },
    {
      name: `Desert boots`,
      SKU: 'BP063001',
      price: '$89',
      inventory: 23,
    },
    {
      name: `Platform shoes`,
      SKU: 'BP063001',
      price: '$45',
      inventory: 102,
    },
    {
      name: `Espadrilles`,
      SKU: 'BP063001',
      price: '$96',
      inventory: 4,
    },
    {
      name: `Moccasins`,
      SKU: 'BP063001',
      price: '$104',
      inventory: 45,
    },
  ]);

  const columns = [
    {
      title: 'Name',
      render: (row) => row.name,
      width: '30%',
    },
    {
      title: 'SKU',
      render: (row) => row.SKU,
      width: '20%',
    },
    {
      title: 'Price',
      render: (row) => row.price,
      width: '20%',
    },
    {
      title: 'Inventory',
      render: (row) => row.inventory,
      width: '20%',
    },
  ];

  const clearSearch = () => {
    setSearchTerm('');
  };

  const renderSearch = (expandable) => {
    return (
      <Search
        size="small"
        expandable={expandable}
        placeholder="Search..."
        onChange={(e) => {
          setSearchTerm(e.target.value);
        }}
        value={searchTerm}
        onClear={clearSearch}
      />
    );
  };

  const getFilteredData = () => {
    let data = records;

    if (searchTerm !== '') {
      data = data.filter((row) =>
        row.name.toUpperCase().includes(searchTerm.toUpperCase()),
      );
    }

    return data;
  };

  const filteredData = getFilteredData();

  const renderEmptyState = () => (
    <Table.EmptyState
      title="No results found"
      subtitle="No items matched your search. Try searching for something else."
      image={
        <Image
          width="120px"
          height="120px"
          transparent={true}
          src="EmptyState_Generic1.svg"
        />
      }
    >
      <TextButton onClick={clearSearch}>Clear Search</TextButton>
    </Table.EmptyState>
  );

  return (
    <Card>
      <Table data={filteredData} columns={columns} rowVerticalPadding="medium">
        <TableToolbar>
          <TableToolbar.ItemGroup position="start">
            <TableToolbar.Item>
              <Text size="small" weight="normal">
                6 products
              </Text>
            </TableToolbar.Item>
          </TableToolbar.ItemGroup>
          <TableToolbar.ItemGroup position="end">
            <TableToolbar.Item>{renderSearch(false)}</TableToolbar.Item>
          </TableToolbar.ItemGroup>
        </TableToolbar>
        {filteredData.length ? <Table.Titlebar /> : renderEmptyState()}
        <Table.Content titleBarVisible={false} />
      </Table>
    </Card>
  );
};
```

### Failed to load
- description: Let users know that their data failed to load. If possible, provide a next action.
- example:
```jsx
<Page>
  <Page.Header
    title="Website Widgets"
    subtitle="Widgets let you add features and functionality to your site."
  />
  <Page.Content>
    <EmptyState
      skin="page-no-border"
      image={
        <Image width="120px" src="EmptyState_ServerError.svg" transparent />
      }
      title="We couldn't load this page"
      subtitle="Looks like there was a technical issue on our end. Wait a few minutes and try again."
    >
      <TextButton prefixIcon={<Icons.Refresh />}>Try Again</TextButton>
    </EmptyState>
  </Page.Content>
</Page>;
```

### App introduction
- description: Use an empty state in the main tab of the app settings panel to give a brief introduction to the app. Place the app icon and a short description at the top, and provide main actions to help users get started using the app.
- example:
```jsx
<SidePanel
  skin="floating"
  width="420px"
  onCloseButtonClick={() => {}}
  onHelpButtonClick={() => {}}
>
  <SidePanel.Header title="Blog" />
  <Box height="480px">
    <VerticalTabs size="small" activeTabId={0} onChange={() => {}}>
      <VerticalTabs.TabItem id={0}>Main</VerticalTabs.TabItem>
      <VerticalTabs.TabItem id={1}>Display</VerticalTabs.TabItem>
      <VerticalTabs.TabItem id={2}>Layout</VerticalTabs.TabItem>
      <VerticalTabs.TabItem id={3}>Design</VerticalTabs.TabItem>
      <VerticalTabs.TabItem id={4}>Support</VerticalTabs.TabItem>
    </VerticalTabs>
    <Divider direction="vertical" />
    <SidePanel.Content>
      <EmptyState
        theme="section"
        image={
          <Image
            width="120px"
            height="120px"
            src="onboarding_community.svg"
            transparent
          />
        }
        title="Blog feed"
        subtitle="Customize the layout and design of your blog feed, or create a post."
      >
        <Box gap="SP2" direction="vertical">
          <Button size="small">Create Post</Button>
          <Button size="small" priority="secondary">
            Manage Posts
          </Button>
        </Box>
      </EmptyState>
    </SidePanel.Content>
  </Box>
</SidePanel>;
```
