-
Notifications
You must be signed in to change notification settings - Fork 164
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
feat: Blue dialog code snippet #2923
base: main
Are you sure you want to change the base?
Conversation
pages/bluedialog/bluedialog.page.tsx
Outdated
setShowDialog(false); | ||
} | ||
|
||
return showDialog ? ( |
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 not remove the dialog at all, we can console.log instead. I think overall the example here could be simpler.
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 in latest revision.
pages/bluedialog/bluedialog.page.tsx
Outdated
} | ||
|
||
return showDialog ? ( | ||
<div className={styles['blue-dialog-box']}> |
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 don't see the a11y requirements being addressed.
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 added some a11y specific code. Can you please review?
pages/bluedialog/styles.scss
Outdated
margin-block: 20px; | ||
margin-inline: 20px; | ||
border-block: 1px solid awsui.$color-border-status-info; | ||
border-inline: 1px solid awsui.$color-border-status-info; |
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 not just margin and border? Is margin even needed?
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.
margin
and border
are disallowed in the lint settings -> https://github.com/cloudscape-design/components/blob/main/.stylelintrc#L59C39-L59C74
Actually, we can remove the margin. Just that it wasn't looking very good on my whole page. It was spreading on the whole page. So, I introduced it.
pages/bluedialog/styles.scss
Outdated
padding-block: 10px; | ||
padding-inline: 10px; |
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.
Same 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.
pages/bluedialog/bluedialog.page.tsx
Outdated
role={'dialog'} | ||
aria-labelledby="dialog-title" | ||
aria-modal="false" // Maintains natural focus flow since it's an inline dialog | ||
tabIndex={-1} // This allows the dialog to receive focus |
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 believe the value should be 0 not -1
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 means the dialog can only be focused programmatically which is good for one-time focus when it appears. I think making it user-focusable is not needed.
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 either case, it would be great to show this focusing behaviour in action.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2923 +/- ##
=======================================
Coverage 96.40% 96.40%
=======================================
Files 784 784
Lines 22136 22138 +2
Branches 7190 7190
=======================================
+ Hits 21341 21343 +2
Misses 788 788
Partials 7 7 ☔ View full report in Codecov by Sentry. |
pages/bluedialog/bluedialog.page.tsx
Outdated
aria-modal="false" // Maintains natural focus flow since it's an inline dialog | ||
tabIndex={-1} // This allows the dialog to receive focus | ||
> | ||
<Form |
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 we also use a semantic form element and support onSubmit?
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.
Actually we can, but then I did not see the onSubmit
event in the
pages/bluedialog/bluedialog.page.tsx
Outdated
|
||
import styles from './styles.scss'; | ||
|
||
export default function Bluedialogbox() { |
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 we separate page and component?
Say, we can have some BluedialogPage that renders the screenshot area maybe and some additional heading (needed for a11y static checks anyways) etc. and the Bluedialog component that can also take some onSubmit/onCancel props and maybe some other, showcasing the actual design of the 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.
Actually, the approach that we decided was that we will not create any built-in component for this request. This whole tasks would be to just create a code snippet that the users can copy and use, with minimum changes from their end.
Also, I think this folder, might not be the right place for this code. So, please feel free to suggest if there is a better place to put these files
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 believe Andrei's suggesting to do it this way so that customers would directly be able to copy the "component". Similarly the reason why he suggested to put the functions like onCancel outside of the "component"
pages/bluedialog/bluedialog.page.tsx
Outdated
|
||
useEffect(() => { | ||
// Store the element that had focus before dialog opened | ||
triggerRef.current = document.activeElement as HTMLElement; |
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.
If the dialog is opened programmatically this transition can be weird. Would it be better to handle the focus transition on the outside? If the parent component provides onSubmit/onCancel then the focus transition can be done as part of it:
function ParentComponent() {
// ...
function returnFocus() {
sendButtonRef.current?.focus()
}
function onSubmit() {
// submit
returnFocus();
}
function onCancel() {
// cancel
returnFocus();
}
return (
<div>
// ...
<Bluedialog onSubmit={onSubmit} onCancel={onCancel} />
</div>
);
}
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 I mentioned previously, this is just a code snippet. It is upto the individual users on how they want to use it.
I refactored this little code little bit. Converted |
const [feedbackOptions, setFeedbackOptions] = React.useState({ | ||
harmful: false, | ||
incomplete: false, | ||
inaccurate: false, | ||
other: 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.
Instead of this you can have selectedFeedbackOption
where you set the value to one of harmful, incomplete, etc. That way you won't need to spread objects during state setting below and it'll be easier to understand. What do you think?
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 this needs to be a multi select, where one or more options can be selected at a time. Hence, I chose to maintain a separate property for each option.
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 right multi choice makes sense in this case.
function submitData() { | ||
onSubmit({ feedbackOptions, feedbackText }); | ||
} |
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 we could add validation here to ensure one of the checkboxes are selected before submission
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 was not aware of this use case. Hence avoided it to leave it on the user's choice. I will implement it in the new revision.
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.
Actually, I am not sure how we want to handle it. This needs to be discussed if there can be a use case where we don't want to select any option, but just want to submit the 'Tell us more' section. Will implement it after discussion.
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.
But "Tell us more" is optional. I believe at least one of the boxes should be checked but we can discuss it.
pages/bluedialog/dialog.tsx
Outdated
<div | ||
className={styles['blue-dialog-box']} | ||
role={'dialog'} | ||
aria-labelledby="dialog-title" |
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 don't see a corresponding element to dialog-title? Instead we could use aria-label and set it to "Feedback dialog"?
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 I forgot to edit it, from previous suggested change. Made the change in new revision.
pages/bluedialog/dialog.tsx
Outdated
tabIndex={-1} // This allows the dialog to receive focus | ||
> | ||
<Form> | ||
<div className={styles['blue-dialog-box__content']}> |
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.
I thought of using Box
, but doesn't allow me add css class to it. It gives me more control to use div
here. I also see this practice in other components as well.
<Form> | ||
<div className={styles['blue-dialog-box__content']}> | ||
<SpaceBetween direction="vertical" size="l"> | ||
<FormField label="What did you dislike about the response?"> |
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 still need to show a dismiss 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.
Done in the new Revision. Thanks for pointing it out
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.
Addressed comments on previous revision
<div | ||
className={styles['blue-dialog-box']} | ||
role={'dialog'} | ||
aria-labelledby="feedback dialog" |
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.
feedback-dialog is not defined anywhere, could you replace this with aria-label?
const [feedbackOptions, setFeedbackOptions] = React.useState({ | ||
harmful: false, | ||
incomplete: false, | ||
inaccurate: false, | ||
other: 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.
Oh right multi choice makes sense in this case.
|
||
// Focus the dialog container when it opens | ||
if (dialogRef.current) { | ||
dialogRef.current.focus(); |
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.
The dialog ref is not assigned anywhere so this code does nothing.
|
||
useEffect(() => { | ||
// Store the element that had focus before dialog opened | ||
triggerRef.current = document.activeElement as HTMLElement; |
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 it make more sense to handle the focus management from the outside using the onSkip? Otherwise there are corner cases like if the trigger disappears after opening the dialog etc. that are not covered by this approach. Or, if the dialog opens after an async transition or automatically - the last focused element might not be related to the dialog at all.
|
||
.blue-dialog-box__footer { | ||
border-block-start: 1px solid awsui.$color-border-divider-default; | ||
padding-block: 10px; |
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 we use design tokens here?
border-block: 1px solid awsui.$color-border-status-info; | ||
border-inline: 1px solid awsui.$color-border-status-info; | ||
background-color: awsui.$color-background-status-info; | ||
border-start-start-radius: 16px; |
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 we use $border-radius-container here?
Description
Related links, issue #, if available: n/a
How has this been tested?
Review checklist
The following items are to be evaluated by the author(s) and the reviewer(s).
Correctness
CONTRIBUTING.md
.CONTRIBUTING.md
.Security
checkSafeUrl
function.Testing
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.