8000 feat(nav): animate expandable nav items by srambach · Pull Request #7321 · patternfly/patternfly · GitHub
[go: up one dir, main page]

Skip to content

feat(nav): animate expandable nav items#7321

Merged
mcoker merged 22 commits intopatternfly:mainfrom
srambach:try-grid-animation
Feb 25, 2025
Merged

feat(nav): animate expandable nav items#7321
mcoker merged 22 commits intopatternfly:mainfrom
srambach:try-grid-animation

Conversation

@srambach
Copy link
Member
@srambach srambach commented Feb 3, 2025

Fixes #6597

Implements microanimations on the nav component:

  • Hover on nav items transitions the background color
  • Selected nav items transitions text color
  • Expand/collapse slides the sub menu open/shut. In reduced motion, the menu fades but no slide.
  • Expansion caret rotates when expanded
  • Works cross browser

Figma reference: https://www.figma.com/design/VMEX8Xg2nzhBX8rfBx53jp/branch/UR1JfYwpZI6MP3rLj18iJ3/PatternFly-6%3A-Components?m=auto&node-id=3-35&t=PQCNAH226TGUdUfd-1

TIP - the site navigation will reflect the changes, rather than having to go to the examples and manually manipulate them.

@patternfly-build
Copy link
Collaborator
patternfly-build commented Feb 3, 2025

@andrew-ronaldson
Copy link
Collaborator

The opening animation looks great but closing feels a bit clunky. It feels like there is a pause between the sub items collapsing and the nav repositioning.

Copy link
Contributor
@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

As discussed in standup, this is just a general review of the code, not yet a review of the animation work specifically 👍

line-height: var(--pf-t--global--font--line-height--body);
color: var(--pf-t--global--text--color--regular);
// stylelint-disable property-no-unknown
interpolate-size: allow-keywords;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is something we'll need to keep a close eye on as it's only supported in chromium browsers at the moment - https://caniuse.com/mdn-css_properties_interpolate-size_allow-keywords

It has the potential to make us and users believe keyword animations are working fine everywhere if the animation is not tested in FF/Safari.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll remove this as I don't think it's necessary now.

// * Nav toggle icon
// * Nav item
--#{$nav}__item--RowGap: var(--#{$nav}__list--RowGap);
--#{$nav}__item--TransitionDuration: 0; // var(--pf-t--global--motion--duration--slide-in--default);
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a nit, but did you mean to leave the comment? I'd probably take it out - one less thing to track/update if we changed the token used.

Comment on lines +72 to +77
--#{$nav}__link--background-color--TransitionDuration: var(--pf-t--global--motion--duration--fade--default);
--#{$nav}__link--background-color--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);

// text color transition for current
--#{$nav}__link--m-current--color--TransitionDuration: var(--pf-t--global--motion--duration--fade--short);
--#{$nav}__link--m-current--color--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, looking at a couple of other components, we're adding the property for the transition in the var name after Transition[Duration/Timing/etc]

--#{$menu}--m-drilldown__content--TransitionDuration--height: var(--pf-t--global--motion--duration--slide-in--default);
--#{$menu}--m-drilldown__content--TransitionDuration--transform: var(--pf-t--global--motion--duration--slide-in--default);

--#{$tabs}__scroll-button--TransitionDuration--margin: .125s;
--#{$tabs}__scroll-button--TransitionDuration--transform: .125s;
--#{$tabs}__scroll-button--TransitionDuration--opacity: .125s;

Suggested change
--#{$nav}__link--background-color--TransitionDuration: var(--pf-t--global--motion--duration--fade--default);
--#{$nav}__link--background-color--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
// text color transition for current
--#{$nav}__link--m-current--color--TransitionDuration: var(--pf-t--global--motion--duration--fade--short);
--#{$nav}__link--m-current--color--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
--#{$nav}__link--TransitionDuration--background-color: var(--pf-t--global--motion--duration--fade--default);
--#{$nav}__link--TransitionTimingFunction--background-color: var(--pf-t--global--motion--timing-function--default);
// text color transition for current
--#{$nav}__link--m-current--TransitionDuration--color: var(--pf-t--global--motion--duration--fade--short);
--#{$nav}__link--m-current--TransitionTimingFunction--color: var(--pf-t--global--motion--timing-function--default);

Comment on lines +87 to +88
--#{$nav}__subnav--max-height--TransitionDuration: 0s; // no slide by default
--#{$nav}__subnav--max-height--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
--#{$nav}__subnav--max-height--TransitionDuration: 0s; // no slide by default
--#{$nav}__subnav--max-height--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
--#{$nav}__subnav--TransitionDuration--max-height: 0s; // no slide by default
--#{$nav}__subnav--TransitionTimingFunction--max-height: var(--pf-t--global--motion--timing-function--default);

Comment on lines +90 to +92
@media ( prefers-reduced-motion: no-preference ) {
--#{$nav}__subnav--max-height--TransitionDuration: var(--pf-t--global--motion--duration--slide-in--default);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
@media ( prefers-reduced-motion: no-preference ) {
--#{$nav}__subnav--max-height--TransitionDuration: var(--pf-t--global--motion--duration--slide-in--default);
}
@media (prefers-reduced-motion: no-preference) {
--#{$nav}__subnav--TransitionDuration--max-height: var(--pf-t--global--motion--duration--slide-in--default);
}

}

&.pf-m-expanded {
row-gap: var(--#{$nav}__item--RowGap); // no fallback here as this value is used to calc clickable offsets
Copy link
Contributor

Choose a reason for hiding this comment

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

nit but you can remove that comment. It's leftover from the PR that made nav items clickable outside of the visible area

Suggested change
row-gap: var(--#{$nav}__item--RowGap); // no fallback here as this value is used to calc clickable offsets
row-gap: var(--#{$nav}__item--RowGap);

Copy link
Member Author

Choose a reason for hiding this comment

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

I wondered about that.

grid-template-rows: 0fr;
}

[hidden] {
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll ideally scope this to an element, otherwise it could target something we don't intend. Also just to confirm, the element it's supposed to target gets hidden in react, versus being removed or something else? A lot of things in core are hidden when they're just removed or something else in react.

Copy link
Member Author

Choose a reason for hiding this comment

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

This compiles out to this snippet - did you mean scoped further than a subnav? And yes, it seems to just be [hidden] - but maybe I'm missing something?
.pf-v6-c-nav__subnav [hidden] { --pf-v6-c-nav__list--RowGap: 0; grid-template-rows: 0fr; }
image

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it should be as such so that it's associated with .pf-v6-c-nav__subnav

Suggested change
[hidden] {
&[hidden] {

I tried it locally and the subnav collapse is much smoother.

border-radius: var(--#{$nav}__link--BorderRadius);
transition-timing-function: var(--#{$nav}__link--background-color--TransitionTimingFunction), var(--#{$nav}__link--m-current--color--TransitionTimingFunction);
transition-duration: var(--#{$nav}__link--background-color--TransitionDuration), var(--#{$nav}__link--m-current--color--TransitionDuration);
transition-property: background-color color;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
transition-property: background-color color;
transition-property: background-color, color;

Comment on lines +307 to +308
transition-timing-function: var(--#{$nav}__link--background-color--TransitionTimingFunction), var(--#{$nav}__link--m-current--color--TransitionTimingFunction);
transition-duration: var(--#{$nav}__link--background-color--TransitionDuration), var(--#{$nav}__link--m-current--color--TransitionDuration);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
transition-timing-function: var(--#{$nav}__link--background-color--TransitionTimingFunction), var(--#{$nav}__link--m-current--color--TransitionTimingFunction);
transition-duration: var(--#{$nav}__link--background-color--TransitionDuration), var(--#{$nav}__link--m-current--color--TransitionDuration);
transition-timing-function: var(--#{$nav}__link--TransitionTimingFunction--background-color), var(--#{$nav}__link--m-current--TransitionTimingFunction--color);
transition-duration: var(--#{$nav}__link--TransitionDuration--background-color), var(--#{$nav}__link--m-current--TransitionDuration--color);

--#{$nav}__item--TransitionDuration: 0; // var(--pf-t--global--motion--duration--slide-in--default);
--#{$nav}__item--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);

@media ( prefers-reduced-motion: no-preference ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🥸

Suggested change
@media ( prefers-reduced-motion: no-preference ) {
@media (prefers-reduced-motion: no-preference) {

@srambach
Copy link
Member Author
srambach commented Feb 4, 2025

The opening animation looks great but closing feels a bit clunky. It feels like there is a pause between the sub items collapsing and the nav repositioning.

@andrew-ronaldson That's actually a question I had. If you look at the timeline, opacity happens in about half the time of the slide. WDYT about making them the same?
image

Here's what was spec'd, and I realized I also need to add in close timing function (accelerate - but the difference in duration remains)
image

@srambach
Copy link
Member Author
srambach commented Feb 4, 2025

@andrew-ronaldson Also, here's a video with the opacity duration of the list set to the same value as the slide duration

2025-02-04_14-16-20.mp4

@kaylachumley
Copy link

referencing the video above: I like the the opacity duration of the list set to the same value as the slide duration

@srambach
Copy link
Member Author
srambach commented Feb 6, 2025

Fixed the incorrect selector for a hidden subnav. Based on discussion at 2/6/25 animation meeting, we'll leave the duration of the opacity transition the same as the others --pf-t--global--motion--duration--slide-in--default. We'll try decreasing the duration of the collapse transition so that it's --pf-t--global--motion--duration--slide-in--short.

Copy link
Collaborator
@andrew-ronaldson andrew-ronaldson left a comment

Choose a reason for hiding this comment

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

Beauty in motion. 📽️

Copy link
@kaylachumley kaylachumley left a comment

Choose a reason for hiding this comment

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

perfect! thank youuu

@srambach srambach requested a review from mcoker February 19, 2025 15:37
@mcoker mcoker requested a review from kaylachumley February 19, 2025 21:43
@mcoker
Copy link
Contributor
mcoker commented Feb 19, 2025

@andrew-ronaldson @kaylachumley - @srambach changed the item spacing a bit to accommodate the change to the focus ring. Would you mind reviewing again?

Copy link
Collaborator
@andrew-ronaldson andrew-ronaldson left a comment

Choose a reason for hiding this comment

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

Let's move and groove!

Copy link
Contributor
@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

NICE! Left some comments, some we talked about. Looks like you don't need to write animations to remove the @starting-style blocks? Left some comments 👍

display: none;
visibility: hidden;

& .#{$nav}__list {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit - the & is redundant here

Suggested change
& .#{$nav}__list {
.#{$nav}__list {

Comment on lines +233 to +234
padding-block-start: 0;
padding-block-end: 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

If you add --#{$nav}__subnav--PaddingBlock[Start/End]: --#{$nav}__item--RowGap as base vars and use them here, you can modify the vars under &.pf-m-expanded instead of having to add a block for & > .#{$nav}__subnav and declare the padding properties here

&.pf-m-expanded {
// duration for collapsing needs to set the property rather than the variable because of nested items
transition-duration: var(--#{$nav}__item--m-expanded--TransitionDuration--row-gap);
& > .#{$nav}__subnav {
padding-block-start: var(--#{$nav}__item--RowGap);
padding-block-end: var(--#{$nav}__item--RowGap);
}

transition-timing-function: var(--#{$nav}__list--TransitionTimingFunction--opacity);
transition-duration: var(--#{$nav}__list--TransitionDuration--opacity);
transition-property: opacity;
transition-behavior: allow-discrete;
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't look like you need this now

transition-timing-function: var(--#{$nav}__subnav--TransitionTimingFunction--grid-template-rows);
transition-duration: var(--#{$nav}__subnav--TransitionDuration--grid-template-rows);
transition-property: grid-template-rows, padding-block-start;
transition-behavior: allow-discrete;
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you can remove this now

.#{$nav}__toggle-icon {
display: inline-block;
transition-duration: var(--#{$nav}__item__toggle-icon--TransitionDuration--transform);
transition-property: transform;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need a timing function?

Comment on lines +242 to +244
@starting-style {
grid-template-rows: 0fr;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need this actually? It starts out as 0fr already

&[hidden] {
--#{$nav}__subnav--TransitionDuration--grid-template-rows: var(--#{$nav}__subnav--hidden--TransitionDuration--grid-template-rows);
grid-template-rows: 0fr;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you saying we don't need the @starting-style block? That allows the animation to run on page load (same with the next comment, if that's what you meant.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah! I didn't know those were for firing on page load. I'll re-review 👍

Comment on lines +222 to +224
@starting-style {
opacity: 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You shouldn't need this, either. It's already 0 when the subnav is hidden

[class^="#{$nav}"][hidden] {
visibility: hidden;
& .#{$nav}__list {
--#{$nav}__list--TransitionDuration--opacity: var(--#{$nav}__list--hidden--TransitionDuration--opacity);
opacity: 0;
}
}

Copy link
@kaylachumley kaylachumley left a comment

Choose a reason for hiding this comment

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

ty! looks good

@mcoker mcoker changed the title feat(Nav): microanimation feat(nav): animate expandable nav items Feb 24, 2025
Copy link
Contributor
@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

Discussed offline but the subnav base vars seemed like they might be able to be a little simpler? I proposed a couple of changes in a PR to this PR - srambach#4. It also moves the opacity animation to the subnav instead of list, so the expand/fade is all on the one containing element now, which will work better if we add other stuff to subnav (groups with titles, for example)

Copy link
Collaborator
@andrew-ronaldson andrew-ronaldson left a comment

Choose a reason for hiding this comment

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

Let's move this into the Done column!

Copy link
Contributor
@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

FANTASTIC! 🥳

@mcoker mcoker merged commit 3fdd0c3 into patternfly:main Feb 25, 2025
4 checks passed
@patternfly-build
Copy link
Collaborator

🎉 This PR is included in version 6.2.0-prerelease.10 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Navigation - Animate transitions and expandable sections

6 participants

0