-
Notifications
You must be signed in to change notification settings - Fork 148
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
docs(Drawer): add API decision #2009
Conversation
|
✅ PR title follows Conventional Commits specification. |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 7831003:
|
* | ||
* Also decides if clicking outside on overlay closes the drawer or not | ||
*/ | ||
showOverlay?: boolean; |
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.
So overlay is optional? Won't that look weird? What is the use case?
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.
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.
when overlay is disabled, does the area outside the drawer remain interactive?
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
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.
does the area outside the drawer remain interactive
We should ideally control this with a new prop like shouldDismissOnClickOutside
|
||
<img width="500px" src="./2024-02-07-20-04-07.png" alt="Drawer Figma Skeleton"> | ||
|
||
## Design |
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.
Will Drawer be absolute positioned always? What if it needs to be used as a left/right navigation drawer?
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.
It will be fixed positioned on top right. It is always positioned like navigation drawer
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.
So we are setting a default position for Drawers on the top-right across all products? Like we set bottom-left
for toasts?
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.
yup
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.
There are use-cases where drawer is used for navigation on left side in a lot of apps. Won't that ever be a use-case for us?
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.
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.
There are use-cases where drawer is used for navigation on left side in a lot of apps. Won't that ever be a use-case for us?
Nope. So for desktop, our navigation bar itself is on left so there won't be anything opening from that side.
On mobile too we have drawers opening from right side only. Plus navigation component is something that we might tackle separately. This navigation component will use our Drawer internally on mobile. So at that time we can relook at this.
Anyway even if usecase comes up, its just addition of new prop so not much effort and no breaking change
/** | ||
* Show or hide overlay. | ||
* | ||
* Also decides if clicking outside on overlay closes the drawer or not |
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.
Wont there ever be a possibility where overlay isn't needed but click outside still needs to close the drawer?
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.
no I did ask this to designers. If someone wants clicking outside to close drawer, they should always have overlay
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.
Also decides if clicking outside on overlay closes the drawer or not
I feel we should have a separate prop for deciding this, it shouldn't be dependant on the presence of overlay.
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.
you mean for a usecase where someone doesn't want to show overlay but still want to close Drawer on clicking outside? I can confirm this once with design if this should be possible. Ideally overlay should be present in most cases except few exceptional cases where outer items have to be interactive
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 also vote for the separation of the logic to dismiss the overlay items on click outside on a different prop. If Modal and BottomSheet have a prop tomorrow to disable dismiss on click outside on the overlay the same prop should be extended over 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.
Agreed. Better to have a separate prop since we might be adding the same to Modal & BottomSheet too
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.
Modal and BottomSheet would anyway have different prop than Drawer in this particular case no?
E.g. in Modal and BottomSheet, we always want to show overlay so there will never be a showOverlay
prop. Whereas in Drawer, we definitely need to have showOverlay
prop.
If we're having that prop and we know interactions outside have to be consistent with display of overlay, wouldn't adding new prop be extra overhead for consumers here?
Because if we add 2 props, it creates impossible states of
<>
<Drawer
showOverlay={true}
shouldDismissOnOutsideClick={false}
/>
<Drawer
showOverlay={false}
shouldDismissOnOutsideClick={true}
/>
</>
These scenarios should throw error in 2 props case because its not correct usage from UX perspective
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.
Oh anyway just discussed this with design - https://razorpay.slack.com/archives/G01B3LQ9H0W/p1707808893726369
Usecase that we have on Modal is something that we would have it here as well. I'll make changes to add 2 props.
- DrawerHeaderBadge | ||
- DrawerHeaderIcon | ||
- DrawerHeaderAsset | ||
- DrawerHeaderLink | ||
- DrawerHeaderButton |
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 keep creating these components for multiple components... Modal, Bottomsheet, Drawer. We might need to look into changing these into just HeaderBadge
, HeaderIcon
, etc. This would keep adding unnecessary repetitive components.
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.
true. HeaderBadge
is a good idea. Lets discuss this with team once in next standup?
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.
How are these components different from normal Badge
/Icon
? For example, I see _CardHeaderBadge
is same as Badge
. Why can't we use theBadge
component directly?
const _CardHeaderBadge = (props: BadgeProps): React.ReactElement => { |
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.
These subcomponents usually have defined defaults that are different from defaults of actual component. E.g.
return <Badge size="medium" marginLeft="spacing.3" {...props} />; |
However in some examples like CardHeaderBadge, the defaults of wrapper are same as defaults of actual component. There it is just for consistency in API otherwise some components will be like Badge
while some be like CardHeaderText
etc
## Accessibility | ||
|
||
- **Aria Attributes:** Drawer will have `aria-modal="true"` and `role="dialog"` and will be treated as modal for voiceover users. | ||
- **Focus Handling:** Ensure Close Icon is focussable |
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.
Like Modal & Bottomsheet, should we also expose initialFocusRef
?
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 I think we should. Drawer will also have similar usecases like Modal and BottomSheet so requirement will anyway come
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.
Add keyboard handling details, e.g, Esc
should close the drawer.
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.
done
|
||
## Design | ||
|
||
- [Drawer - Figma Design](https://www.figma.com/file/jubmQL9Z8V7881ayUD95ps/Blade-DSL?node-id=78667%3A66663&mode=dev) |
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.
Does the drawer have a fixed width? Will the width change based on the content? If it is fixed width, why do we not have size options?
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.
It currently has a fixed max-width of 420px and inside that it takes width based on the content.
Let me check with design once if we want to go with max-width or defined size because in Modal I see its defined size
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 checked with RK. It is fixed width of 420px on desktop always. We will only support one size right now
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.
fixed width of 420px
Max width would be 420px right?
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.
nope. Drawer is always 420px irrespective of the content.
/** | ||
* Controlled state of drawer open or not | ||
*/ | ||
isOpen: boolean; |
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.
What happens if multiple drawers are opened together? I'm guessing same behaviour as Modal?
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 similar but only 2 drawers can be kept open at once from design-side. And the 2nd drawer has a back button instead of close button.
Let me add the stacking behaviour to this API doc I didn't mention it in this
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.
Would we need a separate callback for the back button?
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.
back button is just dismiss of 2nd Drawer. Consumer knows which is their second drawer so they can use that onDismiss
itself.
|
||
<img width="500px" src="./2024-02-07-20-04-07.png" alt="Drawer Figma Skeleton"> | ||
|
||
## Design |
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.
So we are setting a default position for Drawers on the top-right across all products? Like we set bottom-left
for toasts?
/** | ||
* Show or hide overlay. | ||
* | ||
* Also decides if clicking outside on overlay closes the drawer or not |
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.
Also decides if clicking outside on overlay closes the drawer or not
I feel we should have a separate prop for deciding this, it shouldn't be dependant on the presence of overlay.
- DrawerHeaderBadge | ||
- DrawerHeaderIcon | ||
- DrawerHeaderAsset | ||
- DrawerHeaderLink | ||
- DrawerHeaderButton |
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.
How are these components different from normal Badge
/Icon
? For example, I see _CardHeaderBadge
is same as Badge
. Why can't we use theBadge
component directly?
const _CardHeaderBadge = (props: BadgeProps): React.ReactElement => { |
## Accessibility | ||
|
||
- **Aria Attributes:** Drawer will have `aria-modal="true"` and `role="dialog"` and will be treated as modal for voiceover users. | ||
- **Focus Handling:** Ensure Close Icon is focussable |
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.
Add keyboard handling details, e.g, Esc
should close the drawer.
Co-authored-by: Nitin Kumar <snitin315@gmail.com>
…zorpay/blade into drawer/api-decision
/** | ||
* Show or hide overlay. | ||
* | ||
* Also decides if clicking outside on overlay closes the drawer or not |
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 also vote for the separation of the logic to dismiss the overlay items on click outside on a different prop. If Modal and BottomSheet have a prop tomorrow to disable dismiss on click outside on the overlay the same prop should be extended over here.
/** | ||
* Override z-index of Drawer. | ||
* | ||
* @default 1002 |
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.
@saurav12 Can design take up a decision on the alignment of all our default z-indices for our overlay components? Imo it should be Modal < Drawer < BottomSheet < Popover < Tooltip. We have the zIndex
property to override for each component but by default the system should make a recommendation.
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.
Sure, makes sense. We will document these in the Figma itself.
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.
+1
/> | ||
<DrawerBody> | ||
<Slot /> | ||
</DrawerBody> |
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.
No Footer?
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.
nope
## Drawer Stacking | ||
|
||
- Only 2 Drawers can be stacked on top of each other | ||
- 2nd Drawer always has overlay independent of `showOverlay` 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.
So, the showOverlay
prop is redundant for the 2nd drawer? Why so? If I don't want to show overlay in 1st drawer because important information is present on the left then that should hold for the 2nd drawer as well.
So I feel, if we are giving control of showing overlay it should be either on both drawers or none. WDYT?
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.
So, the showOverlay prop is redundant for the 2nd drawer? Why so? If I don't want to show overlay in 1st drawer because important information is present on the left then that should hold for the 2nd drawer as well.
For example in X, 1st Drawer is used for showing information based on the interaction on left side. But 2nd Drawer does not have that usecase.
Plus overlay on 2nd Drawer is also there to denote the stacking. If there's 2 Drawers open without overlay, there is no direct way to tell user that there is another drawer behind this drawer.
Also in most cases, Drawer should always have overlay. There are just few exceptions for 1st Drawer which is why we need to provide overlay prop
- 2nd Drawer always has overlay independent of `showOverlay` prop | ||
- 2nd Drawer always has back button instead of close button. Clicking on back button closes the 2nd drawer. | ||
|
||
<img width="500px" src="./2024-02-12-11-01-32.png" /> |
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.
Can you add a code example for stacked drawers?
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.
Good point. Adding.
## Drawer Stacking | ||
|
||
- Only 2 Drawers can be stacked on top of each other | ||
- 2nd Drawer always has overlay independent of `showOverlay` 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.
Won't this be counterintuitive? How will we communicate this to our devs? I can imagine this coming in as a bug in the future
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.
Won't this be counterintuitive?
True but don't see any other way to implement this. We do want to show overlay on 2nd drawer.
How will we communicate this to our devs?
We can throw error. Also its enforced from design side so its not possible to implement something like this on design as the UI itself is slightly different for 2nd drawer.
|
||
- Only 2 Drawers can be stacked on top of each other | ||
- 2nd Drawer always has overlay independent of `showOverlay` prop | ||
- 2nd Drawer always has back button instead of close button. Clicking on back button closes the 2nd drawer. |
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.
Why though? a back button only makes sense when the navigation is within the drawer and not another drawer on top of it.
If we are doing this, then we should also have a back button on 2nd Modal? Same logic would be applicable there. I think we shouldn't have a back button in either cases.
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.
In case of Modal, the size of the modal would also let people know about modal behind it no? If we put close button on 2nd Drawer, because all Drawers are same size and similarly placed, it feels like clicking close will close everything. But instead we only go back to the first Drawer in the stack.
Basically we would need something to let consumer know that this Drawer is stacked. Back button and overlay was our way to communicate that. But we can discuss this once with RK maybe?
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.
Started discussion here - https://razorpay.slack.com/archives/G01B3LQ9H0W/p1707813910309619?thread_ts=1707803235.144969&cid=G01B3LQ9H0W
Adding it to open questions
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.
* feat(Drawer): add API decisions * feat: add full skeleton * fix: image width * fix: typo * feat: add stacking section to api decision * Update packages/blade/src/components/Drawer/_decisions/decisions.md Co-authored-by: Nitin Kumar <snitin315@gmail.com> * fix: remove DrawerHeaderLink and DrawerHeaderButton * feat: add open questions * feat: add discussion slack thread * feat: update API decision with new API --------- Co-authored-by: Nitin Kumar <snitin315@gmail.com>
✨ Pretty Doc ✨