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

[EuiHeader] Update to set a new global --euiFixedHeadersOffset CSS variable #7144

Merged
merged 16 commits into from
Sep 1, 2023

Conversation

cee-chen
Copy link
Member

@cee-chen cee-chen commented Aug 30, 2023

Summary

screencap

This logic allows EuiHeader to afford for any number of fixed headers (although it's likely that consumers will not use more than two). The most important aspect of this refactor that other EUI components can access this CSS variable globally with no extra JS logic or rerendering on their end, which removes a significant amount of duplicated useEffects from components affected by fixed headers (EuiPageTemplate, EuiSideBar, and EuiCollapsibleNavBeta), and for other components (EuiFlyout and EuiOverlayMask), it allows them to correctly and dynamically set their top position and height instead of relying on a static Sass mixin to work as expected.

I strongly recommend reviewing by commit as multiple downstream components/usages were updated separately.

QA

General checklist

@cee-chen cee-chen requested a review from a team August 30, 2023 02:37
@cee-chen cee-chen marked this pull request as ready for review August 30, 2023 02:37
@cee-chen cee-chen requested a review from 1Copenut August 30, 2023 02:38
Comment on lines +155 to +159
const getHeaderOffset = useCallback(
() => mathWithUnits(headerHeight, (x) => x * euiFixedHeadersCount),
[headerHeight]
);
Copy link
Member Author

@cee-chen cee-chen Aug 30, 2023

Choose a reason for hiding this comment

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

I just want to quickly note - I'm aware this approach is fairly naive, and doesn't account for consumers doing something incredibly wacky, e.g.

<EuiHeader position="fixed" />
<EuiThemeProvider modify={{ base: 10 }}>
  {/* The underlying header will now have a height of '30px' instead of '48px' and calculations will be incorrect */}
  <EuiHeader position="fixed" />
</EuiThemeProvider>

I did spike out an approach for this that uses a Map to store individual header heights, but honestly, at the end of it all when I stood there looking at the final code, I couldn't justify adding the extra complexity for something that I can almost guarantee no consumer is going to use. I'd rather wait to get an actual feature request for it first.

I'll probably still open a draft PR with the working spike and then close it to preserve the code in case some absolute madman out there does want it in the future, but I don't intend on initially shipping with support for it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel this is the right first approach. If consumers come back and ask for a way to remember individual header heights, you've got the solution already sketched out and captured in comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

Almost forgot to do this! Link to the archived map code: #7152

@kibanamachine
Copy link

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

Comment on lines +163 to +164
// Get the top position from the offset of previous header(s)
setTopPosition(getHeaderOffset());
Copy link
Member Author

Choose a reason for hiding this comment

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

Also want to note that this is not dynamic and the current Storybook QA relies on First In Last Out render order for positioning and z-index to work as expected.

Basically, if consumers do something like incredibly wacky like this:

<EuiHeader position="fixed" />
{conditionalHeader && <EuiHeader position="fixed" />}
<EuiHeader position={maybeFixed? 'fixed' : 'static' />
<EuiHeader position="fixed" />

The 4th header's position will not update if the 2nd & 3rd header are dynamically removed from the fixed headers count.

Again, I find it infinitesimally unlikely that this is going to be a production use-case for someone, but if we get a feature request for it in the future, the above map spike that I mentioned will also solve dynamic addition/removal.

Copy link
Member Author

Choose a reason for hiding this comment

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

Link to the archived map code that correctly updates position/z-index: #7152

@kibanamachine
Copy link

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

@cee-chen
Copy link
Member Author

buildkite test this

@cee-chen
Copy link
Member Author

Hmmm, not sure what's going on with buildkite/CI... going to do a full rebase here in a min

- logic will soon become complex enough that it should be separated by concern / shouldn't simply live in the main header component
- note: this is not completely dynamic, as removed headers will not affect subsequent headers, but this is probably not super likely right now
+ update to account for EuiDataGrid's full screen mode
- cleans up a lot of now-unnecessary JS logic
- allows us to clean up a ton of now-unnecessary JS (and remove the resulting test)

- add a minor workaround in style file (as opposed to inheriting EuiFlyout's CSS) - nav state rerender is noticeably more jumpy between stories
- thankfully appears to be rerender shenanigans fixed with just a quick async tick type change
- rename old counter var to more closely match new var names + update comment

- DRY out repeated `mathWithUnits()` logic
@kibanamachine
Copy link

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

@cee-chen
Copy link
Member Author

Alrighty, CI is passing and PR is ready for review whenever

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

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

Two small copy suggestions, then I'm 👍

Comment on lines +155 to +159
const getHeaderOffset = useCallback(
() => mathWithUnits(headerHeight, (x) => x * euiFixedHeadersCount),
[headerHeight]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel this is the right first approach. If consumers come back and ask for a way to remember individual header heights, you've got the solution already sketched out and captured in comment.

src-docs/src/views/header/header_example.js Outdated Show resolved Hide resolved
src-docs/src/views/header/header_example.js Outdated Show resolved Hide resolved
Co-authored-by: Trevor Pierce <[email protected]>
@kibanamachine
Copy link

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

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

@cee-chen cee-chen requested a review from 1Copenut August 31, 2023 20:02
Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

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

👍 LGTM!

@cee-chen cee-chen merged commit f047795 into elastic:theme-css-variables Sep 1, 2023
@cee-chen cee-chen deleted the header-css-var branch September 1, 2023 16:25
Ikuni17 pushed a commit to elastic/kibana that referenced this pull request Sep 12, 2023
Major changes in this PR:

## Removal of `.euiAccordionForm` classNames

EUI is moving away from providing global `classNames` styles for
components - where possible, we want to provide props as opposed to
styles. As part of our ongoing Emotion conversion, we have removed the
following `EuiAccordion`-specific classes:
- `.euiAccordionForm` (replaced with `borders="horizontal"`)
- `.euiAccordionForm__button` (replaced with `buttonProps={{
paddingSize: 'm' }}`)
- `.euiAccordionForm__title` styles - this was only removing text
underlines on hover. If still desired, re-add this behavior with custom
CSS.
- `.euiAccordionForm__extraAction` - there was 1 usage of this in Kibana
in Watcher, which was converted to one-off custom inline Emotion CSS
instead.

This change accounts for the first 3-4 commits in the PR. ⚠️ If your
team was one of the 4-5 teams affected by this change, we would greatly
appreciate your help QAing the UI and ensuring it looks as desired/the
same as before.

## Fixed `EuiHeader` affordance

The Sass `euiHeaderAffordForFixed` mixin has been deprecated and
replaced by a global `--euiFixedHeadersOffset` CSS variable. This
variable updates independently and dynamically based on the number of
fixed headers on the page, and is usable by both Sass and Emotion. All
underlying EUI components that need to account for fixed headers (such
as flyouts and page sidebars/templates) have been updated to consume
this new variable.

This change cleans up a great deal of Sass code, and is incidentally
extremely timely with serverless efforts (as serverless has only one
fixed header and the classic Kibana chrome has two).

This change constitutes a majority of the commits in this PR, which
involve removing various fixed Sass header variables and replacing them
with the new CSS variable. I strongly recommend [reviewing changes by
commit if
possible](https://github.com/elastic/kibana/pull/165790/commits) to see
any associated changes that make sense together with any of your touched
file(s). ⚠️ If your team was affected by this change (primarily due to
custom header layouts), your help would be greatly appreciated QAing
your app to ensure no UI regressions in that regard have occurred.

---

`v88.1.0`⏩ `v88.2.0`

## [`88.2.0`](https://github.com/elastic/eui/tree/v88.2.0)

- Added a new `EuiTextTruncate` component, which provides custom
truncation options beyond native CSS
([#7116](elastic/eui#7116))
- Fixed-positioned `EuiHeader`s now set a global CSS
`--euiFixedHeadersOffset` variable, which updates dynamically based on
the number of fixed headers on the page.
([#7144](elastic/eui#7144))
- `EuiFlyout`s now dynamically set their position, height, and mask
based on the number of fixed headers on the page.
([#7144](elastic/eui#7144))
- Sticky-positioned `EuiPageSidebar`s now dynamically set their position
and height based on the number of fixed headers on the page. This can
still be overridden via the `sticky.offset` prop if needed.
([#7144](elastic/eui#7144))
- `EuiPageTemplate` now dynamically offsets content from any fixed
headers on the page. This can still be overridden via the `offset` prop
if needed. ([#7144](elastic/eui#7144))
- Updated `EuiAccordion` with a new `borders` prop
([#7154](elastic/eui#7154))
- Updated `EuiAccordion` with a new `buttonProps.paddingSize` prop
([#7154](elastic/eui#7154))

**Deprecations**

- Deprecated the Sass `euiHeaderAffordForFixed` mixin. Use the new
global CSS `var(--euiFixedHeadersOffset)` variable instead.
([#7144](elastic/eui#7144))

**CSS-in-JS conversions**

- Except for generic CSS utilities, EUI is moving away from providing
global `classNames` that are component-specific. As part of this effort,
we have removed the following `EuiAccordion`-specific classes:
([#7154](elastic/eui#7154))
- Removed `.euiAccordionForm` styles. Use the `borders="horizontal"`
prop instead
- Removed `.euiAccordionForm__button` styles. Use the `buttonProps={{
paddingSize: 'm' }}` prop instead
- Removed `.euiAccordionForm__extraAction` styles. Convert this to your
own custom CSS if necessary.
- Removed `.euiAccordionForm__title` styles. Convert this to your own
custom CSS if necessary.

---------

Co-authored-by: Stratoula Kalafateli <[email protected]>
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.

4 participants