Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tables): new light/dark mode colors #1833

Merged
merged 17 commits into from
Jun 18, 2024
Merged

feat(tables): new light/dark mode colors #1833

merged 17 commits into from
Jun 18, 2024

Conversation

geotrev
Copy link
Contributor

@geotrev geotrev commented Jun 5, 2024

Description

Adds light / dark mode support for Table components.

Detail

In addition to updating to light/dark compatibility, this PR also:

  • Uses base styling from IconButton for OverflowButton (with height/width overrides)
  • Removes isHovered, isFocused, and isActive props from OverflowButton

Checklist

  • 👌 design updates will be Garden Designer approved (add the designer as a reviewer)
  • 🌐 demo is up-to-date (npm start)
  • ⬅️ renders as expected with reversed (RTL) direction
  • 🤘 renders as expected with Bedrock CSS (?bedrock)
  • 💂‍♂️ includes new unit tests. Maintain existing coverage (always >= 96%)
  • ♿ tested for WCAG 2.1 AA accessibility compliance
  • 📝 tested in Chrome, Firefox, Safari, and Edge

@geotrev geotrev self-assigned this Jun 5, 2024
@geotrev geotrev requested a review from a team as a code owner June 5, 2024 23:52
@coveralls
Copy link

Coverage Status

coverage: 96.083% (+0.04%) from 96.04%
when pulling 575381f on george/table-recolor
into 142286c on next.

@coveralls
Copy link

Coverage Status

coverage: 96.083% (+0.04%) from 96.04%
when pulling 06aa20f on george/table-recolor
into 142286c on next.

Comment on lines 30 to 35
getColor({
variable: 'background.emphasis',
transparency: theme.opacity[100],
light: { offset: -300 },
theme
})};
Copy link
Contributor

Choose a reason for hiding this comment

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

Given the context and how background.subtle is used in other components, wouldn't background.subtle fit better semantically?

Suggested change
getColor({
variable: 'background.emphasis',
transparency: theme.opacity[100],
light: { offset: -300 },
theme
})};
getColor({
variable: 'background.subtle',
transparency: theme.opacity[100],
light: { offset: 300 },
dark: { offset: -600 },
theme
})};

Copy link
Contributor

@ze-flo ze-flo Jun 6, 2024

Choose a reason for hiding this comment

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

I would be good to understand Design's intent for using a custom color / opacity combo.

With Chrome's color-picker tool, I got the "flattened" HEX value for the stripped row background color. That value corresponds to the color a visual user perceives when the row color (neutral (400:600)/0.08%) is applied over our default light / dark background.

Using this tool, I compared their DeltaE:

Light

custom: #f9f9fa
background.subtle: #f8f9f9

Screenshot 2024-06-06 at 10 18 22 AM

Dark

custom: #1e2328
background.subtle: #1c2227

Screenshot 2024-06-06 at 10 19 19 AM

As you can see, the colors are nearly identical.

Typically, a Delta E of less than 1 is not perceptible to the human eye.

If Table is always rendered on top of a backdrop with a background.default, would it make more sense to reuse background.subtle?

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 agree, subtle makes more sense 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And thank you for the detailed breakdown / comparison with other components in this use case. TIL!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Something I'm thinking about is what it means for the color and its semantics when we need to do a 6 level offset (plus/minus 600). Does the color respect its design intent by the time its shade is offset by this much? @lucijanblagonic perhaps a question for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The backgrounds of both GroupRow and Row (when striped) are set to the below value, per Flo's suggestion, which is the reason for my inquiry/curiosity around color intent with major offsets:

 getColor({
      variable: 'background.subtle',
      transparency: theme.opacity[100],
      light: { offset: 300 },
      dark: { offset: -600 },
      theme
})

Copy link

Choose a reason for hiding this comment

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

That value corresponds to the color a visual user perceives when the row color (neutral (400:600)/0.08%) is applied over our default light / dark background.

that is exactly the intent! we wanted a value that visually matches the v8 group/striped bg treatment. i've attached an image to visually describe the points below:

image

  1. at first glance, background.subtle was the first logical replacement, but that is intentionally a solid fill, and a solid fill would not respect the bg subtle, raised, and recessed treatments in both light and dark modes.
  2. with that considered we opted for the existing neutral opacity, which targets 700 and 500 @ .8, but in light mode it was too dark of a bg (albeit dark mode bg was just fine)
  3. then opted for the grey-400 / grey-600 @ .08 as it was the closest match.

if there's a more efficient way to obtain that visual parity, then i'm all for it!

Comment on lines 117 to 122
getColor({
variable: 'background.emphasis',
transparency: DEFAULT_THEME.opacity[100],
light: { offset: -300 },
theme: DEFAULT_THEME
})
Copy link
Member

Choose a reason for hiding this comment

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

In the context of tests, the preference would be to replace with rgba(PALETTE[color][shade], DEFAULT_THEME.opacity[amount]) rather than repeating getColor code from the component implementation. It just makes the tests slightly more imperative and simpler to maintain.

packages/tables/src/elements/OverflowButton.tsx Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

It might be outside the scope of this PR, but when Table.SortableCell is in use, the header cells do not honor table sizing as expected. This bug exists in v8, but it would be nice if we can clean it up in v9.

Copy link
Contributor Author

@geotrev geotrev Jun 10, 2024

Choose a reason for hiding this comment

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

Is this the bug you're referring to? Where the text/icons aren't vertically centered?

Screenshot 2024-06-10 at 11 16 07 AM

Copy link
Member

Choose a reason for hiding this comment

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

Yes, when you turn Table.SortableCell off, they get placed in their correct positions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it. I'll plan to see if that's addressable in a follow-on PR on main so we can pull it over into next after.

packages/tables/src/styled/StyledHead.ts Show resolved Hide resolved
Comment on lines 52 to 55
${colorStyles}

${sizeStyles}
Copy link
Member

Choose a reason for hiding this comment

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

@@ -23,36 +23,79 @@ export interface IStyledRowProps {
size?: ITableProps['size'];
}

const baseRowColorStyles = ({ theme, isStriped }: IStyledRowProps & ThemeProps<DefaultTheme>) => {
return css`
border-bottom: ${theme.borders.sm} ${getColor({ variable: 'border.subtle', theme })};
Copy link
Member

Choose a reason for hiding this comment

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

[nit] the preference is usually to separate border-bottom from border-bottom-color. And moving these values out to local variables makes the CSS more readable.

})};
`;
};

export const StyledBaseRow = styled.tr<IStyledRowProps>`
Copy link
Member

Choose a reason for hiding this comment

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

Fwiw, this combined Styled... components in one file is a bad code smell. Might be good to clean it up here.

@lucijanblagonic
Copy link

There is an inconsistency with border-bottom-color on Hover. Our designs specify border bottom color to be opacity/primary/200
image

Current implementation
image

Updated example
image

Not sure if there are any other implications to the border-color, @steue please take a look as well.

Copy link
Member

@jzempel jzempel left a comment

Choose a reason for hiding this comment

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

The dependency for @zendeskgarden/react-buttons needs to be added to table's package.json

@geotrev geotrev force-pushed the george/table-recolor branch from 06aa20f to f17a9d5 Compare June 10, 2024 18:34
Copy link
Member

@jzempel jzempel left a comment

Choose a reason for hiding this comment

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

Looks like Table.Row isSelected styling got partially lost. Perhaps due to a $ prop spread? 🤷

Screenshot 2024-06-11 at 10 12 00 AM

@@ -16,7 +16,7 @@ const COMPONENT_ID = 'tables.cell';

export interface IStyledCellProps
extends Pick<ICellProps, 'isMinimum' | 'isTruncated' | 'hasOverflow' | 'width'> {
size?: ITableProps['size'];
$size?: ITableProps['size'];
Copy link
Member

Choose a reason for hiding this comment

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

Please note that the picked props above will continue to leak in styled-components v6.

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 went ahead and converted the remaining props to transient props and I think captured all the remaining spreadable props as explicitly converted. Doing another self review now, as well.

ref={ref}
tabIndex={isReadOnly ? undefined : -1}
Copy link
Member

Choose a reason for hiding this comment

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

I like the element component move, but in order to match previous the tabIndex should follow {...otherProps} so that it wins.

Comment on lines 57 to 59
${colorStyles}

${sizeStyles}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
${colorStyles}
${sizeStyles}
${sizeStyles}
${colorStyles}

[nit] per API docs, these should be switched .. although it shouldn't happen, color should hold the more significant position if there happens to be a cascade.

`;
};

export const StyledRow = styled(StyledBaseRow).attrs<IStyledRowProps>({
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export const StyledRow = styled(StyledBaseRow).attrs<IStyledRowProps>({
export const StyledRow = styled(StyledBaseRow).attrs({

[nit] type should no longer be needed for the attrs.

@geotrev
Copy link
Contributor Author

geotrev commented Jun 11, 2024

@jzempel think you found a limitation with how backgrounds/borders intermingle in cases of truncation re: isSelected. Will wait for design to weigh in (left a comment in the design inventory).

Copy link
Member

@jzempel jzempel left a comment

Choose a reason for hiding this comment

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

🎉

Copy link

@steue steue left a comment

Choose a reason for hiding this comment

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

the accommodations look good in light mode! but the borders look too dark when isSelected is set to true. it looks like it is set to blue-900? we have it set to blue-500 @ 16%. was this the border issue you were speaking of?

image

i was able to target it directly in inspect to get the desired effect.

image

@geotrev
Copy link
Contributor Author

geotrev commented Jun 13, 2024

@steue In order to resolve the issue JZ reported above, we need a solid border as one with opacity will result in truncated rows hiding the border. 😅

@steue
Copy link

steue commented Jun 14, 2024

😓 in light mode isSelected treatment looks good. but it still looks too dark than intended in dark mode. since we can not use opacity, could we use a bespoke value to achieve the same effect? wdyt @lucijanblagonic ?
image

@lucijanblagonic
Copy link

lucijanblagonic commented Jun 17, 2024

It's probably best to use colors that we have available within those 12 steps, and accept the technical limitations. A big change in saturation and lightness in dark mode (like using blue-800/700) doesn't look good, and it's OK to have a subtle border as the background is much more prominent.

  • consistent color for border-bottom-color in both states (selected, selected + hover)
  • use blue-300 for light mode
  • use blue-900 for dark mode

fixed-blue-300-900
With changes applied in inspector

image
Screenshot of 300/900 border color

Copy link

@steue steue left a comment

Choose a reason for hiding this comment

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

i think this is an acceptable workaround for the limitation posed. thanks for the discussion @lucijanblagonic! sorry and thank you @geotrev for explaining the issue and patience with the back and forth!

@geotrev geotrev merged commit 54514f3 into next Jun 18, 2024
5 checks passed
@geotrev geotrev deleted the george/table-recolor branch June 18, 2024 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

7 participants