reactjsshopifyshopify-apppolaris

How to reset the selection in Shopify Polaris IndexTable


How do I reset the selection in Shopify Polaris IndexTable with a function? https://polaris.shopify.com/components/tables/index-table

import {
  IndexTable,
  LegacyCard,
  useIndexResourceState,
  Text,
  Button,
} from '@shopify/polaris';
import React from 'react';

function SimpleIndexTableExample() {
  const orders = [
    {
      id: '1020',
      order: '#1020',
    },
    {
      id: '1019',
      order: '#1019',
    },
    {
      id: '1018',
      order: '#1018',
    },
  ];
  const resourceName = {
    singular: 'order',
    plural: 'orders',
  };

  const {selectedResources, allResourcesSelected, handleSelectionChange} =
    useIndexResourceState(orders);

    const resetSelection = () => {
      console.log('Reset selection. No items selected anymore.')
    }

  const rowMarkup = orders.map(
    (
      {id, order},
      index,
    ) => (
      <IndexTable.Row
        id={id}
        key={id}
        selected={selectedResources.includes(id)}
        position={index}
      >
        <IndexTable.Cell>
          <Text variant="bodyMd" fontWeight="bold" as="span">
            {order}
          </Text>
        </IndexTable.Cell>
      </IndexTable.Row>
    ),
  );

  return (
    <LegacyCard>
      <IndexTable
        resourceName={resourceName}
        itemCount={orders.length}
        selectedItemsCount={
          allResourcesSelected ? 'All' : selectedResources.length
        }
        onSelectionChange={handleSelectionChange}
        headings={[
          {title: 'Order'},
        ]}
      >
        {rowMarkup}
      </IndexTable>
      <Button onClick={resetSelection}>Reset selection</Button>
    </LegacyCard>

  );
}


export default SimpleIndexTableExample;

I have tried to re-render the IndexTable and child components to reset it, change selectedItemsCount and itemCount values, but the results are very inconsistent and feels like I'm hacking away a part that should be very simple.

Shopify Polaris seemingly uses this hook to control the selection, but there is no documentation really on how to use it:

const { selectedResources, allResourcesSelected, handleSelectionChange } =
    useIndexResourceState(productList);

Here is a simple example in Codesandbox


Solution

  • In order to clear the whole selection you must update your hook and add the clearSelection helper. The new hook will look like this:

    const { selectedResources, allResourcesSelected, handleSelectionChange, clearSelection } = useIndexResourceState(productList)
    

    Now, you can use this button in the React component: <Button onClick={clearSelection}>Reset selection</Button>.

    You can also remove only specific items from the selection. To do that, update the hook like this:

    const { selectedResources, allResourcesSelected, handleSelectionChange, clearSelection, removeSelectedResources } = useIndexResourceState(productsList)
    

    and define a function to remove the items:

    const removeFromSelection = () => {
            removeSelectedResources(selectedResources); // this will clear the selection, it's a workaround to the straightforward solution described above
            removeSelectedResources(['1020']); //this will remove only the row with id 1020
    };