Skip to content

Conversation

@ze-flo
Copy link
Contributor

@ze-flo ze-flo commented Jun 1, 2024

Description

Adds light / dark mode support for our Typography components, excluding CodeBlock

Detail

Note

StyledFont defaults to foreground.default color if no hue is provided. The following components extend it and now inherit the default color:
- SM
- MD
- LG
- XL
- XXL
- XXXL
- Blockquote
- OrderedList
- UnorderedList
- Span

Ellipsis and Paragraph's color also defaults to foreground.default.

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

Comment on lines 33 to 38
default:
fgColorArgs.variable = 'foreground.default';
bgColorArgs.hue = 'neutralHue';
bgColorArgs.dark = { shade: 900 };
bgColorArgs.light = { shade: 200 };
break;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unsupported hues default to grey. If a hue isn't recognized, getColor throws.

Copy link
Member

Choose a reason for hiding this comment

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

This move unintentionally breaks the Code hue API. The expectation is that hue can receive any value that getColor's hue argument can receive. So that includes all Garden hue values (lime, fuschia, etc), hex, etc. So a few things need to happen here:

  • continue to give special treatment to Garden's primary colors
  • get feedback from design on what shades to fallback to (perhaps dark:900 & light: 200)
  • allow getColor to do it's thing – including throwing an error if someone provides a bogus value

Please see StyledTag for comparison.

Copy link
Contributor Author

@ze-flo ze-flo Jun 4, 2024

Choose a reason for hiding this comment

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

StyledCode is "loosely" typed with hue?: string

interface IStyledCodeProps extends Omit<IStyledFontProps, 'size'> {
hue?: string;
size?: ICodeProps['size'];

In our case, only Code uses this component and restricts possible hue values to only grey, red, green, and yellow.

export const HUE = ['grey', 'red', 'green', 'yellow'] as const;

export interface ICodeProps extends HTMLAttributes<HTMLElement> {
/** Applies color to the background and the text */
hue?: (typeof HUE)[number];
/** Adjusts the font size. By default font size is inherited from the surrounding text. */
size?: (typeof INHERIT_SIZE)[number];
}

Therefore, I don't think it's a breaking change, but rather a call to improve clarity by redefining the hue type in StyledCode to match its real-life usage. I must emphasize this suggestion only make sense because StyledCode is exclusively used by Code.

interface IStyledCodeProps extends Omit<IStyledFontProps, 'size'> {
  hue?: (typeof HUE)[number];
  size?: ICodeProps['size'];
}

Toughts?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, interesting – I was looking at the wrong (Styled) API and testing on v8 with usage like <Code hue="fuschia">. In this case, restricting the hue color values makes sense. I still think allowing getColor to throw on invalid usage – as it now does in other v9 components – is appropriate and better than protecting the consumer from themselves.

}

if (props.hue) {
const shade = props.hue === 'yellow' ? 700 : 600;
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 the default shade for all hues is now 700 in light mode.

let fontWeight;
let lineHeight;
let color;
let color = getColor({ theme, variable: 'foreground.default' });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sets default color correctly based on mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jzempel To maintain the current behavior, do we need to keep color as undefined? If so, the color would be inherited from the parent container. It will also be the user's responsibility to set the correct color based on the mode they're in.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the current API structure needs to be kept (aka undefined)


expect(container.firstChild).toHaveStyleRule(
'color',
(PALETTE as any)[hue][mode === 'light' ? 700 : 500]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Follows getColor's logic:

_shade = scheme === 'dark' ? 500 : 700;

);
});

it('handles yellow hue with specialized shading', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not needed since every hue's shade is 700 in light mode.


color = getColorV8(props.hue, shade, props.theme);
if (hue) {
color = getColor({ hue, theme });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using default shades:

_shade = scheme === 'dark' ? 500 : 700;

@ze-flo ze-flo requested review from lucijanblagonic and steue June 1, 2024 00:38
@ze-flo ze-flo marked this pull request as ready for review June 1, 2024 00:38
@ze-flo ze-flo requested a review from a team as a code owner June 1, 2024 00:38
expect(container.firstChild).toHaveStyleRule('background-color', PALETTE_V8.yellow[200]);
});
});
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved specs to StyledCode.spec.tsx.

Copy link
Member

Choose a reason for hiding this comment

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

This is fine for now. However, the prevailing recent thinking is to test at the element component level rather than at the view component. This way we're penetrating all points of interest. See the newer Combobox and Menu components in the dropdowns package for comparison.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for clarifying. I wasn't sure about that. I'll move the specs back to this file instead.

@coveralls
Copy link

coveralls commented Jun 4, 2024

Coverage Status

coverage: 96.094% (+0.01%) from 96.084%
when pulling 4b3c78e on ze-flo/typography-recolor
into cffdb06 on next.

@lucijanblagonic
Copy link

Everything looks good. Why was the Code and CodeBlock excluded?

expect(container.firstChild).toHaveStyleRule('background-color', PALETTE_V8.yellow[200]);
});
});
});
Copy link
Member

Choose a reason for hiding this comment

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

This is fine for now. However, the prevailing recent thinking is to test at the element component level rather than at the view component. This way we're penetrating all points of interest. See the newer Combobox and Menu components in the dropdowns package for comparison.

Comment on lines 35 to 37
bgColorArgs.hue = 'neutralHue';
bgColorArgs.dark = { shade: 900 };
bgColorArgs.light = { shade: 200 };
Copy link
Member

@jzempel jzempel Jun 4, 2024

Choose a reason for hiding this comment

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

Suggested change
bgColorArgs.hue = 'neutralHue';
bgColorArgs.dark = { shade: 900 };
bgColorArgs.light = { shade: 200 };
bgColorArgs.variable = 'background.subtle';
bgColorArgs.dark = { offset: -100 };
bgColorArgs.light = { offset: 100 };

Always better to tie into a variable whenever possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Design opted for a custom component variable for this one:

WIP_code-bg-default

#E8EAEC

I chose to explicitly build the color to reflect their choice and highlight the lack for variable for this hue / shade combo.

I think modifying an existing variable can lead to side-effects and increased maintenance overhead.

For ex, if Design were to change the shade of background.subtle, ENG would have to review all uses of this variable to ensure the resulting shade from offsets is still the desired one.

Copy link
Member

Choose a reason for hiding this comment

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

We already have guidance from design to use getColor's offset feature when possible. They wouldn't be using WIP variables if Figma provided similar functionality. Let's double check the semantics with them. As far as any variables change goes, we would have to review all uses – so I don't think that's a major issue here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Following our convo, @jzempel and I decided it was best to leave as-is to better handle future themes.

Copy link
Member

Choose a reason for hiding this comment

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

Let's be sure to double-check intent with design.

Comment on lines 33 to 38
default:
fgColorArgs.variable = 'foreground.default';
bgColorArgs.hue = 'neutralHue';
bgColorArgs.dark = { shade: 900 };
bgColorArgs.light = { shade: 200 };
break;
Copy link
Member

Choose a reason for hiding this comment

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

This move unintentionally breaks the Code hue API. The expectation is that hue can receive any value that getColor's hue argument can receive. So that includes all Garden hue values (lime, fuschia, etc), hex, etc. So a few things need to happen here:

  • continue to give special treatment to Garden's primary colors
  • get feedback from design on what shades to fallback to (perhaps dark:900 & light: 200)
  • allow getColor to do it's thing – including throwing an error if someone provides a bogus value

Please see StyledTag for comparison.


interface IStyledCodeProps extends Omit<IStyledFontProps, 'size'> {
hue?: string;
hue?: ICodeProps['hue'];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

hue?: string; was causing confusion. So I refined the type to emphasize that Code, StyledCode's only consumer, strictly supports grey, red, green, yellow, and undefined.

export const HUE = ['grey', 'red', 'green', 'yellow'] as const;

Passing an unsupported hue would trigger a TS error or an invalid PropType error at runtime.

Comment on lines 35 to 37
bgColorArgs.hue = 'neutralHue';
bgColorArgs.dark = { shade: 900 };
bgColorArgs.light = { shade: 200 };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Following our convo, @jzempel and I decided it was best to leave as-is to better handle future themes.

@@ -1,77 +0,0 @@
/**
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Consolidated into Code.spec.tsx.

'data-garden-version': PACKAGE_VERSION,
as: 'code'
as: 'code',
isMonospace: true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

isMonospace: true is required by StyledFont to apply the correct styles.

Defining it as a defaultProp didn't make that obvious.

This pattern aligns with other components. For ex:

export const StyledAnchor = styled(StyledButton).attrs<IAnchorProps>(props => ({
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION,
as: 'a',
dir: props.theme.rtl ? 'rtl' : undefined,
isLink: true,
type: undefined
}))`

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.

this is looking good! have some clarifications on bg treatment for code components. design did some optical adjustments to the BG and shifted the treatments up 1 step. this would only affect success, danger, and warning. default looks good.

image

other than that, other elements LGTM!
cc: @lucijanblagonic

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.

nice – hits API expectations

@sieeeeeenna
Copy link

Looks good to me! These colors are a nice improvement!

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.

looks awesome thank you!

@ze-flo ze-flo merged commit 7a3ba84 into next Jun 7, 2024
@ze-flo ze-flo deleted the ze-flo/typography-recolor branch June 7, 2024 15:56
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.

8 participants