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
Feature: #41 Alert. #60
Conversation
22718b1
to
2885dd9
Compare
: html``} | ||
${this.size === 'large' | ||
? html` | ||
<div id="header"> |
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 this use the <outline-header>
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.
Thanks for the question. I'm not sure.
In the storybook examples I left it as a slot, so we could pass in an <outline-header>
if desired.
The trade-off there seems to be a little more work on the consumer of the component for the flexibility to define the header level / visual level.
I suppose we could always look to see if the slotted component was an <outline-header>
, text, or something else and then only wrap text in the <outline-header>
. What levels would we use then as defaults?
Anyone have ideas?
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. I saw the this.statusType
and was thinking that was the text that was passed, but realize that is just a placeholder and we should be using content in the slot so that might make more sense. One reason I guess would be to keep all headings the same style.
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 agree with Chris on this one, I think this should be an outline-heading
with the statusType rendered inside of it. I don't think there is much benefit to allowing a consumer to place their own element here. If someone wanted to do that they could extend this element and overwrite the largeTemplate()
method I'd mentioned above.
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.
After a while on a project with the enhanced editor I think the slot is a better idea.
We should also look at adding the ability to close alerts. If these might be used to display an alert dynamically after page load we should look into supporting aria-live polite |
Thanks, Chris! I added this idea and the icon TODO to this story (#67) in case we want to implement the basic version first and then add enhancements. |
Added an automated test. This should be ready for review. :) |
3682ca8
to
532d22c
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.
The component overall looks good, I requested a few changes here that are mainly refactors and clean up.
: html``} | ||
${this.size === 'large' | ||
? html` | ||
<div id="header"> |
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 agree with Chris on this one, I think this should be an outline-heading
with the statusType rendered inside of it. I don't think there is much benefit to allowing a consumer to place their own element here. If someone wanted to do that they could extend this element and overwrite the largeTemplate()
method I'd mentioned above.
isInteractive = false; | ||
|
||
@property({ type: Boolean }) | ||
shouldShowIcon = 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.
This probably needs to be shouldHideIcon
because of the way attributes work in the DOM. The presence of an attribute means true
, so there is no way to set a false value if the default is true
. :(
So, all boolean attributes probably need to default to 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.
Interesting 🤯
render(): TemplateResult { | ||
// The `body` wrapper is used to avoid styles (like border) that are preventing us from styling `:host`. | ||
return html` | ||
<div id="body" role="${this.isInteractive ? 'alertdialog' : 'alert'}"> |
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 is going to require some more 'plumbing'.
Looks like you're going to need for 'alertdialog':
- aria-label/ledby
- focusable control/focused close button.
- trapped/wrapping tab order.
https://developer.mozilla.org/enUS/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_alertdialog_role
I see the SB example, but we can't always be sure that the consumer will pass the requirements.
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.
Thanks for the links! Maybe we can remove this feature for now and add a todo.
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 you could change isInteractive
to something like alertDialogue: string
and if it's there pass that to an aria-label attrib, and then set the role to "alertdialog". Just a thought to keep the functionality. Also we may just need to have a focusable close button here either way.
export type AlertStatusType = typeof alertStatusTypes[number]; | ||
|
||
// This can be useful for testing. | ||
export interface OutlineAlertInterface extends 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.
I like this a lot and think it should become a standard.
@property({ type: Boolean }) | ||
isInteractive = false; | ||
|
||
@property({ type: 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.
Even if they're simple/obvious let's keep the standard of docs for every/state/method.
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.
Yeah I agree, I've been doing this and reflecting that comment in the story controls. I'd like to look into creating a method for using those JSDocs to populate the storybook control info for us. Stencil does something similar.
I think for Storybook, especially, it's important to be explicit with the comments because there are QA, design, clients, etc. who are going to be seeing these pages. Its more user friendly and accessible is my argument.
A Storybook style guide is something I'd love to get nailed down soon, I'm just trying to figure out the best way to write them still too. Would be a good discussion for guild.
`; | ||
}; | ||
|
||
export const Information = Template.bind({}); |
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 think we need a SB example for every possible iteration/variant.
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 it's beneficial to write stories for every visual representation of a component like we do with the button component, especially as we implement VRT. It would be good to detect if something you did broke a layout of a component in a specific state.
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 down to have this discussion in a larger setting, but for me SB serves t purposes. 1: To show what the component can do. 2: To show how to use the component.
I think 1 is taken care of by the controls we take the time to set up. So the number of variants in a story should be dictated by the different ways the component can be used. EX: the alertdialog option 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.
@LeeMellon , I think that's an interesting point.
This is the first time I've used storybook, so the patterns are new to me. I can see the point of view that a smaller number of stories may be easier for an implementer since it focuses their attention.
If it's helpful, this is what I've used Storybook for so far.
I write the storybook page first with examples of the variations that I understand need to be represented. In the alert, this means one of each status type. There is some level of feeling things out here. On a current project, we have an icon that can show 1800 icons and I don't have 1800 stories. So, I think 4 statuses makes sense to me as stories, but 1800 doesn't. I made another component to show all the colors / icons and those have their own component pages. In development, I was settings CSS classes per status type, but there were no CSS changes for those icons. Meaning, it was possible for me to break a single status type, but not a single icon.
If there is JS interaction, I may write the Jest tests at this point too.
Then, I start implementing the component itself. At this time, I'm watching those stories to see the components change and gradually get the features that I expect. Most of the time I'm looking at the docs
pane, or for interaction / screen reader the iframe
example.
If I forgot an example, I'll add more stories to capture those use cases.
... And I don't really use the controls much.
I agree with @mabry1985, that for visual regression testing, some of the additional variations may be helpful since the tools will default to one screenshot of each.
Might be a good team discussion or one for Github discussions.
import componentStyles from './outline-alert.css.lit'; | ||
import { OutlineElement } from '../outline-element/outline-element'; | ||
|
||
export const alertSizes = ['small', 'large'] as const; |
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 is over complicating things. I think you want to replace these two lines with export type AlertSize = 'small' | 'large'
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.
Thanks for the review @LeeMellon. Going to look into all this in more detail when I get a chance.
The attempt here was to provide an array of values used by Storybook to populate the select box and provide the type in this file for TS checking.
Is there a way to do both of those in one place? This pattern I found somewhere, but was new to me. :) The best I could find to avoid copy & paste issues.
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 this is good, he's using const assertion here. I just figured out how to do this myself this week, it allows us to create a type and capture it in a variable in one go.
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.
Thanks for the explanation, @mabry1985! And the link to where it's used.
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.
Thanks both of you. Using this regularly now.
I know this one has been sitting a while, but I'm about ready to start the "mass merge". However, I want to hold on this one and update the |
Description
Adds an alert. See #41.
Testing notes
Example
Notes
Took styling and types mostly from #41.
This doesn't render an icon yet since there are still some open questions around that.