-
Notifications
You must be signed in to change notification settings - Fork 370
feat(AnimationsProvider): Add Support for AnimationsProvider #11990
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
base: main
Are you sure you want to change the base?
Conversation
Preview: https://pf-react-pr-11990.surge.sh A11y report: https://pf-react-pr-11990-a11y.surge.sh |
…ons, add AnimationsProvider to helpers, add md files for documentation fix(components): update hasAnimations to fall back to context fix(md): remove cssPrefix fix(alertgroup): fix tests
855d346
to
49bcb04
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this! I have a handful of comments/change requests but they're mostly fairly small things.
This review didn't include looking at changing AlertGroup and DualListSelector from class based to function components that was needed as unfortunately I ran out of time. I wouldn't say to redo anything, but just for the sake of the future if a similar situation arises I would advocate for splitting that work into a distinct PR just to make review/testing easier, but that's just my $0.02.
); | ||
|
||
const closeButton = screen.getByLabelText('Close'); | ||
fireEvent.click(closeButton); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's a particular reason to need fireEvent we should default to userEvent per the suggestions of the RTL team.
If there is a particular reason fireEvent is needed please add a comment explaining why.
|
||
// Should call callback on transition end when animations are enabled via context | ||
fireEvent.transitionEnd(screen.getByText('Test Alert').closest('.pf-v6-c-alert-group__item') as HTMLElement); | ||
expect(mockCallback).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of checking for the onClose callback to be called/not called would it make more sense to test for animation related classes on the element?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, really good call here - updated
children, | ||
id, | ||
isTree = false, | ||
hasAnimations: localHasAnimations, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I feel like hasAnimationsProp
or something would maybe be a little clearer of a deconstructed name? I don't have strong feelings on that though and it might just be a matter of preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may not be consistent with it, but we do have instances where in this context we've used somethingProp
, while for variables inside the component we use localSomething
. Again we may not be consistent on this, but I'd probably lean towards using hasAnimationsProp instead here, and reserving localHasAnimations for a variable/state name inside the component code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wise-king-sullyman @thatblindgeye thank you, great points, I like hasAnimationsProp
here too, it's clearer and follows our existing conventions better - updated it.
export interface AnimationsConfig { | ||
/** Whether animations are enabled globally */ | ||
hasAnimations?: boolean; | ||
} | ||
|
||
/** Props for the AnimationsProvider component */ | ||
export interface AnimationsProviderProps { | ||
/** Animation configuration settings */ | ||
config?: AnimationsConfig; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be required? I'm not sure what use case there would be for someone to use the provider without setting a config with a hasAnimations value.
|
||
// Local prop takes precedence when explicitly set (including false) | ||
// If local prop is undefined, fall back to context | ||
return localHasAnimations !== undefined ? localHasAnimations : (contextHasAnimations ?? false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be simplified to just localHasAnimations ?? contextHasAnimations ?? false
instead of a ternary with a nullish coalescing operator nested inside it?
return <div data-testid="has-animations">{hasAnimations ? 'animations-enabled' : 'animations-disabled'}</div>; | ||
}; | ||
|
||
describe('AnimationsProvider', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can you remove this nesting describe block? We default to not using them around whole suites.
Also if you're not aware of our testing styles/guidelines you might want to give that article in our wiki a look 🙂
packages/react-core/src/helpers/AnimationsProvider/__tests__/AnimationsProvider.test.tsx
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,161 @@ | |||
--- | |||
id: Animations provider | |||
section: helpers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we going to be adding a helpers section to the site?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a topic to bring up in a platform topics meeting @jenny-s51 . I don't believe we really document helpers anywhere on Org currently, and I would have thought communication about this new context would be housed in something like release highlights/notes. A decision on this could mean having to remove the new examples that you added here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wise-king-sullyman @thatblindgeye yep great callout, I think it makes sense to delete it here and include this md file as part of patternfly/patternfly-org#4783 - removed it from this PR and will add it there as a follow-up.
@@ -0,0 +1,69 @@ | |||
import { TreeView } from '@patternfly/react-core'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file being used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, deleted it
}); | ||
|
||
// Animation context tests | ||
test('respects AnimationsProvider context when no local hasAnimations prop', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of the opposite of Austin's comment about regarding a describe block, I personally might wrap these tests in a describe block specifically for the context tests. Not a blocker and depending how quickly we want to get this merged in, would like to hear @wise-king-sullyman opinion here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so too @thatblindgeye - based on the RTL guide this seems like a good use case for a grouped describe()
block, I've updated the tests to include it, but will also defer to @wise-king-sullyman here for the final word on whether or not we'd like to keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not against grouping associated things like the animation tests together in a describe block in an otherwise broader test suite, just wrapping full test suites in a describe block 🙂
target.removeChild(this.state.container); | ||
} | ||
} | ||
appendTo, // do not pass down to ul |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: it's pre-existing but I think we could remove this comment now that it's a functional component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, removed
children, | ||
id, | ||
isTree = false, | ||
hasAnimations: localHasAnimations, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may not be consistent with it, but we do have instances where in this context we've used somethingProp
, while for variables inside the component we use localSomething
. Again we may not be consistent on this, but I'd probably lean towards using hasAnimationsProp instead here, and reserving localHasAnimations for a variable/state name inside the component code.
const [focusAfterExpandChange, setFocusAfterExpandChange] = useState(false); | ||
|
||
const { isExpanded, onToggleExpand, toggleAriaLabel, hasAnimations } = expandableInput || {}; | ||
const { isExpanded, onToggleExpand, toggleAriaLabel, hasAnimations: localHasAnimations } = expandableInput || {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a followup to my above reply to Austin about the prop name, I think this makes sense to call it localHasAnimations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just following up here to confirm based on the discussion in the thread here, I renamed it to hasAnimations for both the destructed and internal variable for consistency with our existing conventions for destructured props, for example JumpLinks uses activeIndex: activeIndexProp
and isExpanded: isExpandedProp
. What are your thoughts on using hasAnimationsProp
here?
…e prop to hasAnimationsProp to match existing conventions
What: Closes #11962
This PR enables support for
AnimationsProvider
.PatternFly consumers will now be able to set animations for opt-in components once at the app level (instead of on every component via
hasAnimations
) while maintaining full backward compatibility.Testing Instructions
To test the new context provider functionality:
Run
yarn start
and navigate to http://localhost:8002/components/alert#toast-alert-groupCopy and paste the code below into the demo TSX code:
Click to expand
hasAnimations
prop.Additional Changes & Fixes
Converted class components to functional components to enable React Hooks usage
useHasAnimations
hook integration:AlertGroup.tsx
- Required foruseHasAnimations
hook integrationDualListSelector.tsx
- Required foruseHasAnimations
hook integrationQuick Verification
hasAnimations
prop.<AnimationsProvider config={{ hasAnimations: true }}>
hasAnimations
prop from the child component.Testing Note: Since PatternFly example files don't typically import from
/helpers
, the ESLint configs require aReact
import with the// eslint-disable-next-line no-restricted-imports
comment at the top of the file for local testing. Real consumers won't have this issue.Success Criteria
hasAnimations
prop overrides provider when set