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

[CSS-in-JS] Convert EuiAvatar #5670

Merged
merged 21 commits into from
Apr 5, 2022
Merged

Conversation

thompsongl
Copy link
Contributor

@thompsongl thompsongl commented Mar 1, 2022

Summary

  • Converts EuiAvatar styles from Sass to Emotion
  • Establishes a pattern for using array syntax inside of css prop values for better class name output ([CSS-in-JS] Convert EuiAvatar #5670 (comment))
  • Establishes a pattern for components with variant, stateful, and subcomopnent styles

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in Chrome, Safari, Edge, and Firefox
  • Checked Code Sandbox works for any docs examples
  • Added or updated jest and cypress tests
  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately
  • Performance testing

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@thompsongl thompsongl mentioned this pull request Mar 1, 2022
12 tasks
Comment on lines 100 to 103
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doesn't seem like we should need all this vendor prefixing. Investigating.
https://caniuse.com/flexbox

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Stylis is tracking; not sure it's worth doing something non-standard when it comes to prefixing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just noting, also, that updating .browserslistrc to eliminate Safari 7 does not change the generated vendor prefixes.

Comment on lines 190 to 195
css={[
styles.euiAvatar,
styles[size],
styles[type],
isDisabled && styles.isDisabled,
color === 'plain' && styles.plain,
]}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interestingly, using an array inside the css prop will result in the component name getting used in the resulting class name. Definitely not documented anywhere I can see.
So just using "labelFormat": "[local]" config, we get a class name like css-{hash}-EuiAvatar. Or css-{hash}-s-space-EuiAvatar if other variants are in play. This seems good!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, it's not important for this component, but order matters when composing styles in a css prop array: https://emotion.sh/docs/composition

For instance, if we were setting background-color in the isDisabled styles, the plain styles would "win" the specificity battle. This is largely helpful for our purposes but different from how the CSS specificity rules.

@thompsongl thompsongl mentioned this pull request Mar 1, 2022
7 tasks
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@thompsongl thompsongl marked this pull request as ready for review March 2, 2022 20:04
@thompsongl thompsongl changed the base branch from css-in-js/conversions to main March 3, 2022 19:58
@thompsongl thompsongl added this to In progress in CSS in JS via automation Mar 3, 2022
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@cee-chen
Copy link
Member

cee-chen commented Mar 3, 2022

Not sure if it matters, but should the CSS name still be mangled/uglified on the PR staging link? Here's what I'm seeing on https://eui.elastic.co/pr_5670/#/display/avatar:

Mostly asking because from my understanding on the other PR, we were not mangling strings on prod? Or am I getting confused and that setting was on the EuiMark PR only?

@thompsongl
Copy link
Contributor Author

Or am I getting confused and that setting was on the EuiMark PR only?

Whoops, sorry for the confusion. This PR is missing the "autoLabel": "always" config that is present in the EuiMark PR.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

A whole lotta comments/questions, but in general I love it. We can go over some of the more discussion-y questions in the sync.

src-docs/src/views/theme/_json/eui_legacy_dark.json Outdated Show resolved Hide resolved
src/components/avatar/__snapshots__/avatar.test.tsx.snap Outdated Show resolved Hide resolved
src/global_styling/mixins/_size.ts Outdated Show resolved Hide resolved
src/components/avatar/avatar.tsx Show resolved Hide resolved
src/components/avatar/avatar.styles.ts Outdated Show resolved Hide resolved
src/components/avatar/avatar.styles.ts Outdated Show resolved Hide resolved
src/components/avatar/avatar.tsx Outdated Show resolved Hide resolved
src/components/avatar/avatar.styles.ts Outdated Show resolved Hide resolved
src/components/avatar/avatar.styles.ts Outdated Show resolved Hide resolved
src/components/avatar/avatar.styles.ts Outdated Show resolved Hide resolved
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

1 similar comment
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@thompsongl
Copy link
Contributor Author

[From the last sync]
Can we generate multiple classes per component to eliminate duplication?

No. Unfortunately that just isn't how emotion (or styled-components) works. The whole point is to eliminate naming collisions and specificity overrides. They solved it by creating a unique class per style instance. Even if we used a workaround to pass classes to className the emotion serializer still process and combines the style rules. Luckily, it's fast, and keeps track of composition so that all small space avatars on the page will reuse the same class.

Can we now move the style into css directly so we start eliminating inline styles?

We'll want to keep some inline styles for dynamic styles like generating a color based on content. This will dramatically reduce the number of generated classes.

This does kind of mess with our BEM naming convention though. Do we care?

Perhaps we have a separate function for subcomponents. EuiAvatarIcon doesn't actually have styles, so this PR isn't the appropriate place to explore.

But either Emotion or something else is actually doing the calculation so it renders as:
font-size: calc(14.4px);
Have we actually tested trying to do math on px values to see how Emotion specifically handles it? This could be a huge game-changer if we don't need calc().

Math on px values does not work (we expected this). After the refactor to dedupe the sizing styles, the output is font-size: calc(16px * .9);. I haven't been able to find why we go 14.4px previously.

@thompsongl thompsongl requested a review from cchaos March 23, 2022 22:49
@cchaos
Copy link
Contributor

cchaos commented Mar 30, 2022

@thompsongl I'm ready to do a final review on this but can you pull in main and update the snapshots?

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

cchaos added 3 commits March 30, 2022 17:48
It removed the size `-m` from the class ☹️
Fixes class name output but is it worth it?
Adds a typically unecessary extra css`` wrapper but keeps the keys
Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

I pushed 3 commits which are 3 attempts to DRY out the sizing styles. The first was the most intuitive to me, but resulted in the size value (-m) no longer being output to the class name. So the next two were other attempts. I finalized on the third but the con is that it results in multiple css wrappers. I don't know what that might do to performance (if any) but it kind of hurts readability just slightly.

src/components/avatar/avatar.tsx Outdated Show resolved Hide resolved
src/components/avatar/avatar.tsx Show resolved Hide resolved
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@cchaos cchaos mentioned this pull request Mar 31, 2022
11 tasks
@thompsongl
Copy link
Contributor Author

thompsongl commented Apr 5, 2022

Sorry for the delayed responses; I completely missed the notification!

I finalized on the third but the con is that it results in multiple css wrappers. I don't know what that might do to performance (if any) but it kind of hurts readability just slightly.

I think we can remove one layer of css, but I'm looking now. (See #5670 (comment))

Comment on lines +58 to +63
s: css(
_avatarSize({
size: euiTheme.size.l,
fontSize: euiTheme.size.m,
})
),
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 css method can be called as just a normal function for cases like this. And _avatarSize can just return a normal string that will be accepted.
🎉

Copy link
Contributor

Choose a reason for hiding this comment

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

Lets get some docs written down about this before we forget 🤔

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

🙌 Thank you for that wiki addition!

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5670/

@thompsongl thompsongl merged commit e85c6e7 into elastic:main Apr 5, 2022
CSS in JS automation moved this from In progress to Done Apr 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

5 participants