Skip to content

Conversation

@philschoefer
Copy link
Contributor

@philschoefer philschoefer commented Aug 29, 2022

WHY are these changes introduced?

@brianshen1990 was integrating the new DataTable in the BulkAccountInviter app and noticed that regular cells were never wrapping in multiple lines, pushing the table width beyond the available space. This triggered the condensed nav. This PR fixes this by defaulting to cells wrapping unless the truncate prop is specifically set.

This was caused by this PR which wrapped all cells in a TruncatedText component which would automatically add tooltips in case content doesn't have enough space. This was a bit too heavy handed. After this PR TruncatedText is only applied if the truncate prop is specifically set.

I also ensured the fixed first column feature will work properly no matter whether truncated is set or not. This means you can now have fixed first columns with text wrapping and with text being truncated depending on what the consumer prefers.

Lastly, there seemed to be a bug in the calculation of headers when fixedFirstColums is set to a value larger than 1. This was because currently we're only calculating columnVisibilityData when condensed was true. This means no heading widths are available to properly calculate the absolute positioning of fixed headings in the sticky header unless the viewport width was reduced to trigger condensed to be true. After this PR columnVisibilityData will be calculated when either stickyHeading is true or the table is condensed.

Screenshot of wrapping issue

Condensed navigation due to text in first column not wrapping

Video of heading with calculation issue

Sticky heading calculated ionco

WHAT is this pull request doing?

GIF of sticky heading width calculated correctly

GIF of correct heading calculation

GIF of truncation with and without fixed first column

Truncation in combination with fixed first column and without

How to 🎩

🖥 Local development instructions
🗒 General tophatting guidelines
📄 Changelog guidelines

Spin-URL: (shopify/web) https://shop1.shopify.data-table-enhancements.philipp-schofer.us.spin.dev/admin/

  1. Try combinations of the following props:
    • truncate on/off
    • fixedFirstColumns - 1,2,3 or 0
    • stickyHeader on/off
  2. Open the Playground in Safari and ensure everything renders correctly when the above props are combined.
Copy-paste this code in playground/Playground.tsx:
import {Page, Card, DataTable} from '@shopify/polaris';
import React from 'react';

export function Playground() {
  const rows = [
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merino Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
  ];

  return (
    <>
      <Page title="Sales by product">
        <Card>
          <DataTable
            columnContentTypes={[
              'text',
              'numeric',
              'numeric',
              'numeric',
              'numeric',
            ]}
            headings={[
              'Product',
              'Price',
              'SKU Number',
              'Net quantity',
              'Net sales',
            ]}
            rows={rows}
            // increasedTableDensity
            // truncate
            stickyHeader
            showTotalsInFooter
            // fixedFirstColumns={2}
            totals={['', '', '', 255, '$155,830.00']}
          />
        </Card>
      </Page>
      <br />
    </>
  );
}

🎩 checklist

@github-actions
Copy link
Contributor

github-actions bot commented Aug 29, 2022

size-limit report 📦

Path Size
polaris-react-cjs 201.15 KB (+0.02% 🔺)
polaris-react-esm 128.97 KB (+0.03% 🔺)
polaris-react-esnext 183.1 KB (+0.03% 🔺)
polaris-react-css 40.62 KB (+0.03% 🔺)

@philschoefer philschoefer marked this pull request as ready for review August 29, 2022 14:45
.FixedFirstColumn {
position: absolute;
background: var(--p-surface);
background: inherit;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to assume that the table is --p-surface. However that might not be the case. This ensures it always is whatever the defined DataTable background is set to.

&:last-of-type {
border-right: var(--p-border-divider);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer needed since now any cell that needs to be separated simply has the Cell-Seperate class.

if (table && scrollContainer) {
condensed = table.scrollWidth > scrollContainer.clientWidth;
// safari sometimes incorrectly sets the scrollwidth too large by 1px
condensed = table.scrollWidth > scrollContainer.clientWidth + 1;
Copy link
Contributor Author

@philschoefer philschoefer Aug 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevents this weirdness

29-36-cpa3t-1u38c

maxWidth: `${
columnVisibilityData[fixedFirstColumns - 1]?.rightEdge
}px`,
width: `${columnVisibilityData[fixedFirstColumns - 1]?.rightEdge}px`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused issues with things lining up correctly. We always want the fixed first columns table to match the correct width of the underlying table. maxWidth gives no benefit but instead leaves room for error.

} else {
this.tableHeadings[index] = ref;
this.tableHeadingWidths[index] = ref.getBoundingClientRect().width;
this.tableHeadingWidths[index] = ref.clientWidth;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically getBoundingClientRect().width gives a more accurate number, but the rounding ends up being inconsistent between the headings and the headings in the sticky header table. Overall clientWidth gives more consistent results as it provides a integer vs a float.

const {stickyHeader} = this.props;

if (condensed && table && scrollContainer && dataTable) {
if ((stickyHeader || condensed) && table && scrollContainer && dataTable) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stickyHeader also needs the measurements to correctly apply the widths to it's headings.

borderRight:
headingIndex === fixedFirstColumns - 1 && fixedCellVisible
? 'var(--p-border-divider)'
: undefined,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was impossible to get the borders to be in the exact same position in the different contexts this way. I had to introduce lastFixedFirstColumn to be able to use CSS ::after pseudo-element which gave more reliable results.

setRef(ref);
}}
style={{...minWidthStyles}}
>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just re-ordered the above props to match the order.

</TruncatedText>
) : (
content
)}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we only truncate if we actually have the truncate prop. @brianshen1990, this is what fixes the issue you were encountering.

@philschoefer philschoefer self-assigned this Aug 29, 2022
Copy link

@brianshen1990 brianshen1990 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From bulk-account-inviter's prospective, this PR looks great!

@nickpresta
Copy link
Member

/snapit

@github-actions
Copy link
Contributor

🫰✨ Thanks @nickpresta! Your snapshots have been published to npm.

Test the snapshots by updating your package.json with the newly published versions:

yarn add @shopify/polaris-icons@0.0.0-snapshot-release-20220829184636
yarn add @shopify/polaris@0.0.0-snapshot-release-20220829184636

@philschoefer
Copy link
Contributor Author

Thanks @nickpresta for creating the snapshot. I should have done this. Here is the spin instance for other reviewers which contains the snapshot: https://shop1.shopify.data-table-enhancements.philipp-schofer.us.spin.dev/admin/

Copy link
Member

@nickpresta nickpresta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this in our Cohort Analysis branch and things look good. Thanks!

Copy link
Member

@chloerice chloerice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌🏽 :shipit:

@philschoefer philschoefer merged commit 60086a6 into main Aug 30, 2022
@philschoefer philschoefer deleted the data-table-enhancements branch August 30, 2022 17:37
@github-actions github-actions bot mentioned this pull request Aug 30, 2022
nickpresta pushed a commit that referenced this pull request Aug 31, 2022
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.


# Releases
## @shopify/polaris-icons@6.0.0

### Major Changes

-   [#7012](#7012) [`bd00ef4ed`](bd00ef4) Thanks [@leileu](https://github.com/leileu)! - Adding Metafields icon to polaris

### Minor Changes

-   [#7013](#7013) [`1e0645f33`](1e0645f) Thanks [@jpmarra](https://github.com/jpmarra)! - Added IdentityCard icon


-   [#7028](#7028) [`635bcfeb7`](635bcfe) Thanks [@joelzwarrington](https://github.com/joelzwarrington)! - add vertical viewport icon variations

## @shopify/polaris@10.1.0

### Minor Changes

-   [#6976](#6976) [`ae7345f0c`](ae7345f) Thanks [@tylernoseworthy](https://github.com/tylernoseworthy)! - - Added a `fixedFirstColumns` prop to `DataTable` so that multiple columns can be fixed
    -   Deprecated the `DataTable` `fixedFirstColumn` prop


-   [#7043](#7043) [`60086a61f`](60086a6) Thanks [@philschoefer](https://github.com/philschoefer)! - Updates to `DataTable`

    -   Fixed `DataTable` cell content not wrapping when the `truncate` prop is `false`
    -   Added support for setting the `DataTable` `truncate` prop without having to set the `fixedFirstColumns` prop

### Patch Changes

-   [#7022](#7022) [`716956df6`](716956d) Thanks [@QuintonC](https://github.com/QuintonC)! - Fixed visual bug for avatar shape prop


-   [#7038](#7038) [`d1a33d8b0`](d1a33d8) Thanks [@kyledurand](https://github.com/kyledurand)! - Applied default background color to image avatar


-   [#6993](#6993) [`fa840e4a9`](fa840e4) Thanks [@kyledurand](https://github.com/kyledurand)! - Removed deprecation from Layout.AnnotatedSection


-   [#7003](#7003) [`2b5f7d0fc`](2b5f7d0) Thanks [@mrcthms](https://github.com/mrcthms)! - Fix visual bug for sortable, selectable index table headings

-   Updated dependencies \[[`bd00ef4ed`](bd00ef4), [`1e0645f33`](1e0645f), [`635bcfeb7`](635bcfe)]:
    -   @shopify/polaris-icons@6.0.0

## polaris.shopify.com@0.14.0

### Minor Changes

-   [#7018](#7018) [`a8087a358`](a8087a3) Thanks [@alex-page](https://github.com/alex-page)! - Generate assets once with a seperate script


-   [#6934](#6934) [`793e26f4d`](793e26f) Thanks [@alex-page](https://github.com/alex-page)! - Use @shopify/polaris-icons instead of /icons and copy-icons


-   [#7049](#7049) [`7a548a00a`](7a548a0) Thanks [@alex-page](https://github.com/alex-page)! - Move search to the server side

### Patch Changes

-   [#7015](#7015) [`e612cbccb`](e612cbc) Thanks [@lgriffee](https://github.com/lgriffee)! - Update navigation column in breakpoints table for MD breakpoint


-   [#7027](#7027) [`a805116a6`](a805116) Thanks [@sarahill](https://github.com/sarahill)! - Updated design guidance for typography

-   Updated dependencies \[[`716956df6`](716956d), [`ae7345f0c`](ae7345f), [`60086a61f`](60086a6), [`bd00ef4ed`](bd00ef4), [`d1a33d8b0`](d1a33d8), [`fa840e4a9`](fa840e4), [`2b5f7d0fc`](2b5f7d0), [`1e0645f33`](1e0645f), [`635bcfeb7`](635bcfe)]:
    -   @shopify/polaris@10.1.0
    -   @shopify/polaris-icons@6.0.0

## polaris-for-figma@0.0.11

### Patch Changes

-   Updated dependencies \[[`716956df6`](716956d), [`ae7345f0c`](ae7345f), [`60086a61f`](60086a6), [`d1a33d8b0`](d1a33d8), [`fa840e4a9`](fa840e4), [`2b5f7d0fc`](2b5f7d0)]:
    -   @shopify/polaris@10.1.0

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants