Skip to content

Commit

Permalink
Index table sticky header fixes (#9616)
Browse files Browse the repository at this point in the history
### WHY are these changes introduced?

Fixes Shopify/archive-polaris-backlog-2024#769

### WHAT is this pull request doing?

- Updates drop shadow on sticky header
- Fixes background color on sticky header
- Fixes heading baseline alignment for header

### How to 🎩

Review in Storybook


<details>
<summary>Copy-paste this code in
<code>playground/Playground.tsx</code>:</summary>

```jsx
import React, {useState} from 'react';

import {
  IndexTable,
  LegacyCard,
  Page,
  useIndexResourceState,
  Text,
} from '../src';

export function Playground() {
  const [sortIndex, setSortIndex] = useState(0);
  const [sortDirection, setSortDirection] = useState('descending');

  const sortToggleLabels = {
    0: {ascending: 'A-Z', descending: 'Z-A'},
    1: {ascending: 'Ascending', descending: 'Descending'},
    2: {ascending: 'Newest', descending: 'Oldest'},
    3: {ascending: 'Ascending', descending: 'Ascending'},
    4: {ascending: 'A-Z', descending: 'Z-A'},
    5: {ascending: 'A-Z', descending: 'Z-A'},
    6: {ascending: 'A-Z', descending: 'Z-A'},
    7: {ascending: 'A-Z', descending: 'Z-A'},
  };

  const initialRows = [
    {
      id: '3411',
      url: '#',
      name: 'Mae Jemison',
      date: '2022-02-04',
      location: 'Decatur, USA',
      orders: 20,
      amountSpent: '$2,400',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '2561',
      url: '#',
      date: '2022-01-19',
      name: 'Ellen Ochoa',
      location: 'Los Angeles, USA',
      orders: 30,
      amountSpent: '$140',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Not paid',
      notes: 'This customer lives on the 3rd floor',
    },
    {
      id: '1245',
      url: '#',
      date: '2021-12-12',
      name: 'Anne-Marie Johnson',
      location: 'Portland, USA',
      orders: 10,
      amountSpent: '$250',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Not paid',
      notes: '',
    },
    {
      id: '8741',
      url: '#',
      date: '2022-05-11',
      name: 'Bradley Stevens',
      location: 'Hialeah, USA',
      orders: 5,
      amountSpent: '$26',
      fulfillmentStatus: 'Unfulfilled',
      paymentStatus: 'Not paid',
      notes: 'This customer has requested fragile delivery',
    },
    {
      id: '3411',
      url: '#',
      name: 'Mae Jemison',
      date: '2022-02-04',
      location: 'Decatur, USA',
      orders: 20,
      amountSpent: '$2,400',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '1234',
      url: 'https://example.com',
      name: 'John Doe',
      date: '2022-03-15',
      location: 'New York, USA',
      orders: 10,
      amountSpent: '$1,000',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: 'Waiting for confirmation',
    },
    {
      id: '5678',
      url: 'https://example.org',
      name: 'Jane Smith',
      date: '2022-01-10',
      location: 'Los Angeles, USA',
      orders: 15,
      amountSpent: '$1,800',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: 'Delivered on time',
    },
    {
      id: '9123',
      url: 'https://example.net',
      name: 'Robert Johnson',
      date: '2022-02-20',
      location: 'Chicago, USA',
      orders: 5,
      amountSpent: '$500',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '4567',
      url: '#',
      name: 'Emily Davis',
      date: '2022-03-01',
      location: 'San Francisco, USA',
      orders: 12,
      amountSpent: '$1,200',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '8901',
      url: 'https://example.com',
      name: 'Michael Johnson',
      date: '2022-04-05',
      location: 'Houston, USA',
      orders: 8,
      amountSpent: '$800',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: 'Awaiting payment',
    },
    {
      id: '2345',
      url: 'https://example.org',
      name: 'Sarah Thompson',
      date: '2022-02-15',
      location: 'Seattle, USA',
      orders: 18,
      amountSpent: '$2,000',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '6789',
      url: 'https://example.net',
      name: 'David Wilson',
      date: '2022-03-25',
      location: 'Miami, USA',
      orders: 3,
      amountSpent: '$300',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '3456',
      url: '#',
      name: 'Olivia Martinez',
      date: '2022-01-05',
      location: 'Denver, USA',
      orders: 7,
      amountSpent: '$700',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '7890',
      url: 'https://example.com',
      name: 'James Anderson',
      date: '2022-04-10',
      location: 'Boston, USA',
      orders: 14,
      amountSpent: '$1,400',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: '',
    },
    {
      id: '3411',
      url: '#',
      name: 'Mae Jemison',
      date: '2022-02-04',
      location: 'Decatur, USA',
      orders: 20,
      amountSpent: '$2,400',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '2561',
      url: '#',
      date: '2022-01-19',
      name: 'Ellen Ochoa',
      location: 'Los Angeles, USA',
      orders: 30,
      amountSpent: '$140',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Not paid',
      notes: 'This customer lives on the 3rd floor',
    },
    {
      id: '1245',
      url: '#',
      date: '2021-12-12',
      name: 'Anne-Marie Johnson',
      location: 'Portland, USA',
      orders: 10,
      amountSpent: '$250',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Not paid',
      notes: '',
    },
    {
      id: '8741',
      url: '#',
      date: '2022-05-11',
      name: 'Bradley Stevens',
      location: 'Hialeah, USA',
      orders: 5,
      amountSpent: '$26',
      fulfillmentStatus: 'Unfulfilled',
      paymentStatus: 'Not paid',
      notes: 'This customer has requested fragile delivery',
    },
    {
      id: '3411',
      url: '#',
      name: 'Mae Jemison',
      date: '2022-02-04',
      location: 'Decatur, USA',
      orders: 20,
      amountSpent: '$2,400',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '1234',
      url: 'https://example.com',
      name: 'John Doe',
      date: '2022-03-15',
      location: 'New York, USA',
      orders: 10,
      amountSpent: '$1,000',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: 'Waiting for confirmation',
    },
    {
      id: '5678',
      url: 'https://example.org',
      name: 'Jane Smith',
      date: '2022-01-10',
      location: 'Los Angeles, USA',
      orders: 15,
      amountSpent: '$1,800',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: 'Delivered on time',
    },
    {
      id: '9123',
      url: 'https://example.net',
      name: 'Robert Johnson',
      date: '2022-02-20',
      location: 'Chicago, USA',
      orders: 5,
      amountSpent: '$500',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '4567',
      url: '#',
      name: 'Emily Davis',
      date: '2022-03-01',
      location: 'San Francisco, USA',
      orders: 12,
      amountSpent: '$1,200',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '8901',
      url: 'https://example.com',
      name: 'Michael Johnson',
      date: '2022-04-05',
      location: 'Houston, USA',
      orders: 8,
      amountSpent: '$800',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: 'Awaiting payment',
    },
    {
      id: '2345',
      url: 'https://example.org',
      name: 'Sarah Thompson',
      date: '2022-02-15',
      location: 'Seattle, USA',
      orders: 18,
      amountSpent: '$2,000',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '6789',
      url: 'https://example.net',
      name: 'David Wilson',
      date: '2022-03-25',
      location: 'Miami, USA',
      orders: 3,
      amountSpent: '$300',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '3456',
      url: '#',
      name: 'Olivia Martinez',
      date: '2022-01-05',
      location: 'Denver, USA',
      orders: 7,
      amountSpent: '$700',
      fulfillmentStatus: 'Fulfilled',
      paymentStatus: 'Paid',
      notes: '',
    },
    {
      id: '7890',
      url: 'https://example.com',
      name: 'James Anderson',
      date: '2022-04-10',
      location: 'Boston, USA',
      orders: 14,
      amountSpent: '$1,400',
      fulfillmentStatus: 'Pending',
      paymentStatus: 'Unpaid',
      notes: '',
    },
  ];
  const [sortedRows, setSortedRows] = useState(
    sortRows(initialRows, sortIndex, sortDirection),
  );

  const resourceName = {
    singular: 'customer',
    plural: 'customers',
  };

  const rows = sortedRows ?? initialRows;

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

  function handleClickSortHeading(index, direction) {
    setSortIndex(index);
    setSortDirection(direction);
    const newSortedRows = sortRows(rows, index, direction);
    setSortedRows(newSortedRows);
  }

  function sortRows(localRows, index, direction) {
    return [...localRows].sort((rowA, rowB) => {
      const key = index === 0 ? 'name' : 'location';
      if (rowA[key] < rowB[key]) {
        return direction === 'descending' ? -1 : 1;
      }
      if (rowA[key] > rowB[key]) {
        return direction === 'descending' ? 1 : -1;
      }
      return 0;
    });
  }

  const rowMarkup = rows.map(
    (
      {
        id,
        name,
        date,
        location,
        orders,
        amountSpent,
        fulfillmentStatus,
        paymentStatus,
        notes,
      },
      index,
    ) => (
      <IndexTable.Row
        id={id}
        key={id}
        selected={selectedResources.includes(id)}
        position={index}
      >
        <IndexTable.Cell>
          <Text fontWeight="bold" as="span">
            {name}
          </Text>
        </IndexTable.Cell>
        <IndexTable.Cell>{date}</IndexTable.Cell>
        <IndexTable.Cell>
          <Text as="span" alignment="end" numeric>
            {orders}
          </Text>
        </IndexTable.Cell>
        <IndexTable.Cell>
          <Text as="span" alignment="end" numeric>
            {amountSpent}
          </Text>
        </IndexTable.Cell>
        <IndexTable.Cell>{location}</IndexTable.Cell>
        <IndexTable.Cell>{fulfillmentStatus}</IndexTable.Cell>
        <IndexTable.Cell>{paymentStatus}</IndexTable.Cell>
        <IndexTable.Cell>{notes}</IndexTable.Cell>
      </IndexTable.Row>
    ),
  );
  return (
    <Page title="Playground">
      {/* Add the code you want to test in here */}

      <LegacyCard>
        <IndexTable
          resourceName={resourceName}
          itemCount={rows.length}
          selectedItemsCount={
            allResourcesSelected ? 'All' : selectedResources.length
          }
          onSelectionChange={handleSelectionChange}
          headings={[
            {title: 'Name'},
            {title: 'Date', defaultSortDirection: 'ascending'},
            {
              alignment: 'end',
              id: 'order-count',
              title: 'Order count',
            },
            {
              alignment: 'end',
              id: 'amount-spent',
              title: 'Amount spent',
            },

            {title: 'Location'},
            {title: 'Fulfillment status'},
            {title: 'Payment status'},
            {title: 'Notes'},
          ]}
          sortable={[true, true, false, true, true, false, false]}
          sortDirection={sortDirection}
          sortColumnIndex={sortIndex}
          onSort={handleClickSortHeading}
          sortToggleLabels={sortToggleLabels}
          lastColumnSticky
        >
          {rowMarkup}
        </IndexTable>
      </LegacyCard>
    </Page>
  );
}
```

</details>
  • Loading branch information
aveline authored Jul 6, 2023
1 parent 0044647 commit bee00d4
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion polaris-react/src/components/IndexTable/IndexTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ $loading-panel-height: 53px;
--pc-index-table-checkbox-offset-left: var(--p-space-3);
--pc-index-table-checkbox-offset-right: var(--p-space-2);
// stylelint-enable
line-height: var(--p-font-line-height-1);

&:first-child:not(.TableHeading-flush) {
padding-left: var(--p-space-3);
Expand Down Expand Up @@ -846,6 +845,11 @@ $loading-panel-height: 53px;
visibility: visible;
background-color: var(--p-color-bg);
box-shadow: var(--p-shadow-md);

#{$se23} & {
box-shadow: var(--p-shadow-xs);
background-color: var(--p-color-bg-secondary-experimental);
}
}

.IndexTable:hover {
Expand Down

0 comments on commit bee00d4

Please sign in to comment.