-
Notifications
You must be signed in to change notification settings - Fork 127
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
Refactor SidePanel #2903
base: next
Are you sure you want to change the base?
Refactor SidePanel #2903
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Size Change: +3.66 kB (+0.54%) Total Size: 676 kB
ℹ️ View Unchanged
|
bd6ce6a
to
762ceb9
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## next #2903 +/- ##
==========================================
+ Coverage 87.98% 88.07% +0.09%
==========================================
Files 227 222 -5
Lines 13088 12911 -177
Branches 1795 1777 -18
==========================================
- Hits 11515 11372 -143
+ Misses 1519 1486 -33
+ Partials 54 53 -1
|
762ceb9
to
2843340
Compare
2843340
to
714716c
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.
This is the first half of my review that focuses on the changes in the Dialog component (and issues I had missed in previous reviews 🙈).
I'll review the SidePanel related changes next.
@@ -5,7 +5,7 @@ | |||
display: flex; | |||
align-items: center; | |||
width: 100%; | |||
background-color: var(--cui-bg-normal); | |||
background-color: var(--cui-bg-elevated); |
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.
💖
@@ -140,14 +151,14 @@ export const Dialog = forwardRef<HTMLDialogElement, DialogProps>( | |||
if (open && dialogElement) { | |||
timeoutId = setTimeout(() => { | |||
if (initialFocusRef?.current) { | |||
initialFocusRef?.current?.focus(); | |||
initialFocusRef?.current?.focus({ preventScroll: true }); |
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.
That's a neat improvement!
event.preventDefault(); | ||
} | ||
}, | ||
[preventClose], | ||
[preventOutsideClickClose], | ||
); | ||
|
||
useEffect(() => { |
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 would split this useEffect
into multiple, granular effects to improve performance:
- Registering the dialog with the polyfill. This should only happen once, on mount.
- Setting the animation duration as a custom property. This should re-run whenever the animation duration value changes (i.e. it shouldn't use the
animationDurationRef
) - Adding the
keydown
event listener... - ...and adding the
close
event listener. I'd separate the event listener effects since they are added under different conditions
lastFocusedElementRef.current = null; | ||
handleDialogClose(); | ||
}, [handleDialogClose]); | ||
if (!preventOutsideClickClose) { |
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.
This check is redundant since useClickOutside
is only enabled when preventOutsideClickClose
is truthy on line 285.
useEscapeKey((e: KeyboardEvent) => { | ||
e.preventDefault(); | ||
handleDialogClose(); | ||
}, open && !preventEscapeKeyClose); |
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.
This inline arrow function changes on every render, which means the event listener inside useEscapeKey
will be removed and re-added on every render. Wrap it in useCallback
to avoid that.
@@ -166,42 +166,79 @@ describe('Dialog', () => { | |||
render(<Dialog {...props} open />); | |||
vi.runAllTimers(); | |||
expect(screen.getByText('Dialog content')).toBeVisible(); | |||
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument(); |
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.
.toBeVisible()
is a bit stricter/safer since it also ensures that the button isn't visually hidden.
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument(); | |
expect(screen.getByRole('button', { name: 'Close' })).toBeVisible(); |
/** | ||
* Prevent users from closing the modal by clicking/tapping the overlay or | ||
* pressing the escape key, and hides the close button. | ||
* @default `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.
* @default `false`. | |
* @default false |
@@ -57,6 +66,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>((props, ref) => { | |||
hideCloseButton, | |||
variant = 'contextual', | |||
className, | |||
preventClose, |
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.
Let's be explicit about the default value here in case the underlying default values in Dialog change.
preventClose, | |
preventClose = false, |
| 'preventOutsideClickClose' | ||
| 'preventEscapeKeyClose' | ||
| 'hideCloseButton' |
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.
Suggestion: We could export a PublicDialogProps
type from the Dialog component to avoid having to omit all these private props in every component that builds on top of it (and potentially forgetting to omit one in the future).
Addresses DSYS-878
Purpose
Refactor the SidePanel component to replace react-modal with the Dialog component. Remove the react-modal dependency.
Approach and changes
backButtonLabel
react-modal
packagepreventClose
prop into :preventOutsideClickClose
,preventEscapeKeyClose
andhideCloseButton
.Definition of done