Worksheet

Overview

Worksheet displays information about a collection of objects and allow the merchant to manage and edit object data.

When to use:

  • To display and edit information across a large data set (e.x. products, customers, inventory, price lists).
  • To quickly scan and compare information in order to identify patterns, transform data, or augment with additional details.
  • Unlike Tables, a Worksheet component is actionable and interactive and should be used in situations where editing is the primary purpose.

Implementation

Edit the code below to see your changes live!

function Example() {
  const columns: Array<WorksheetColumn<Product>> = [
    {
      hash: 'productName',
      header: 'Product name',
      validation: (value) => !!value,
      notation: (value) => {
        switch (value) {
          case 'Product 1':
            return {
              color: 'danger',
              description: 'Change value to 2',
            };

          case '2':
            return {
              color: 'warning40',
              description: 'To make it green change it to 3',
            };

          case '3':
            return {
              color: 'success',
              description: 'Value is equal 3',
            };
        }
      },
      width: 200,
      tooltip: 'Tooltip text',
    },
    { hash: 'isVisible', header: 'Visible', type: 'checkbox', width: 80 },
    { hash: 'otherField', header: 'Other field' },
    {
      hash: 'otherField2',
      header: 'Other field',
      type: 'select',
      config: {
        options: [
          { value: 'option-1', content: 'Option 1' },
          { value: 'option-2', content: 'Option 2' },
          { value: 'option-3', content: 'Option 3' },
        ],
      },
      validation: (value) => !!value,
      width: 200,
    },
    {
      hash: 'otherField3',
      header: 'Category',
      type: 'modal',
      config: {
        header: 'Choose categories',
        render: CategoryTree,
      },
      formatting: (value: number) => CATEGORIES[value],
    },
    {
      hash: 'numberField',
      header: 'Number field',
      type: 'number',
      formatting: (value: number) => `$${value}.00`,
      validation: (value: number) =>
        typeof value === 'number' && !Number.isNaN(value),
      width: 100,
    },
  ];

  const items: Array<Partial<Product>> = [
    {
      id: 1,
      productName: 'Product 1',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-1',
      otherField3: 2,
      numberField: 50,
    },
    {
      id: 2,
      productName: 'Product 2',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-1',
      otherField3: 6,
      numberField: 50,
    },
    {
      id: 3,
      productName: 'Product 3',
    },
    {
      id: 4,
      productName: 'Variant 1',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-2',
      otherField3: 9,
      numberField: 50,
    },
    {
      id: 5,
      productName: '',
      isVisible: true,
      otherField: 'Text',
      otherField2: '',
      otherField3: 4,
      numberField: 50,
    },
    {
      id: 6,
      productName: 'Variant 3',
      isVisible: true,
      otherField: 'Text',
      otherField2: '',
      otherField3: 3,
      numberField: 50,
    },
    {
      id: 7,
      productName: 'Variant 4',
      isVisible: false,
      otherField: 'Text',
      otherField2: 'option-2',
      otherField3: 4,
      numberField: 50,
    },
    {
      id: 8,
      productName: 'Product 4',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-2',
      otherField3: 7,
      numberField: 50,
    },
    {
      id: 9,
      productName: 'Product 5',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-2',
      otherField3: 3,
      numberField: 50,
    },
    {
      id: 10,
      productName: 'Product 6',
      isVisible: true,
      otherField: 'Text',
      otherField2: 'option-3',
      otherField3: 3,
      numberField: 50,
    },
  ];

  return (
    <Worksheet
      columns={columns}
      items={items}
      minWidth={900}
      onChange={(items) => items}
      onErrors={(items) => items}
    />
  );
}

Props

Prop name
Type
Default
Description
columns *TextColumn | NumberColumn | CheckboxColumn | SelectableColumn | ModalColumn

Columns will be of type TextColumn by default.

expandableRows[key: string]: Array<string | number>;

Accepts an object with parent ids as keys and an array of child ids that will be hidden on render.

defaultExpandedRowsArray<string | number>

Accepts an array with parent ids that will be expanded by default.

disabledRowsArray<string | number>

Accepts an array with ids of rows that will be disabled.

items *any[]

The array of items to display.

onChange *(items: any[]) => void

Returns the items that have been updated.

onErrors(items: WorksheetError[]) => void

Returns an array of Error when an error is present.

minWidthnumber

Sets a min-width.

localization{ toggleRowExpanded: string }

Overrides the label with localized text.

Props ending with * are required

Do's and Don'ts

Do
Always display a Worksheet component with collapsed side navigation.
Column header names should use sentence case, be concise and describe the type of content displayed in that column.
Each row contains information related to a single entity.
Each cell contains either a single data point or groups of data from a multi-select interaction (e.g. categories).
Interactive elements per cell include: text/numerical input, subtle buttons which open a modal, checkboxes and drop downs.
Show the total number of items at the top of the Worksheet.
Use the Worksheet for bulk editing actions.
A Worksheet should always be on it’s own page. Never combine a worksheet with other tables or panels of content.
Don't
Never use the Worksheet component to display a simple list of related content. Instead use a Table.
Editing or actions should always be initiated directly on a cell. Do not use the actions icon/menu.