-
Notifications
You must be signed in to change notification settings - Fork 14
Conversation
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.
Looking good! Excited to see this coming along. ✨
Spotted just one small change...
Also, I'm not sure how this should be implemented (whether via the SpaceKit component or on a per view basis), but the width of these cards should constrained to a max-width. The Alert inline banners should flow with the content they are in, but toast cards will sit above the UI and slide in from off screen (sorry, that probably wasn't very clear from the design principles doc! 🙈) and generally should be constrained to a max-width in real use 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.
Hey @Jephuff, please hold on merging this until I review it this afternoon!
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.
Hey @Jephuff, please hold on merging this until I review it this afternoon!
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.
For all who are checking out this PR; I had a sync conversation about this with @Jephuff yesterday. My asks were to not extend from Card
and to offer a color: PaletteColor
prop that would be used to set all the necessary colors in favor of offering contexts for the colors that might not be consistent across all Apollo properties.
@AlexanderMann if you're cool working on this, definitely give it a shot. I'd start with a fresh PR and not extend from As for the colors, please accept a I'd say give the component a interface AlertProps {
/**
* Color to apply to the (you choose, icon or text). We will programmatically
* pick a darker/lighter shade for the other one (and that will presumably
* change for a light and dark theme!)
*/
accentColor: PaletteColor;
title: React.ReactNode;
} I'm going to be off for the long weekend tomorrow but I'm happy to pop on and look at this if it's blocking. |
I have on occasion wished for a styled-component that looked like Card but didn't come with all the dressings that Card does, possibly a |
Updated the alert to not extend card, accept color as prop and accept icon as prop. @cheapsteak I looked at making a common CardBase component, not a while lot is actually common between the 2
I'm going to copy-paste for now :D |
I was hoping we'd be able to pull a border radius as well, but other than that that's pretty much what I was after I wonder if you've caught this thread https://meteor.slack.com/archives/CJM405HJB/p1588779273039400 ? I would have just inlined the shadows myself, but my understanding is that we are heavily encouraging if not mandating that space kit be used whenever possible. That behooves us to try to provide a pleasant developer experience, and in my experience it's more pleasant to use something that gets me 80% of the way there even if I have to add the rest myself, than to have something that gets me 120% of the way there then I have to fight the framework to dispel the unwanted extras. Although, I guess this might be subjective? Anyway, feel free to punt that from this PR as we can fairly say this is out of scope :) |
My goal with this was to provide the UI to be used in different places like a Toast component (or modal, or inline). so I think max-width and if the card flows with the rest of the document would be determined by the usage 👍 |
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 are coming along nicely, but still noticing a few discrepancies between the implementation and the designs:
- the border below the heading should only be used on cards with the expanded content version (also please note the content left margin differs slightly between these variants)
- the heading bottom border on the dark mode cards should be
grey-dark
(differs from the light mode cards - the button the dark mode cards should use the dark theme buttons (I think they have a darker border color for dark contexts)
Let me know if you have any questions about the specifics of the designs. I'd be happy to go over them with you to clarify anything that may be confusing.
Just to clarify, this design is only intended for use as a toast message. By definition (Bootstrap example, Primer example, Android example) a toast is a temporary message that doesn't belong in the normal flow of UI and generally is triggered by an action the user has taken during their workflow, generally appearing from off-screen or floated into the view from an hidden state. This component should never be used as a modal or inline alert. Alert banners vs Alert toasts The use case for inline alert banners differs from the toast message (which is why the design is styled explicitly different from toasts). Those should be displayed when something in the app, data, or user's account is in a state that requires an alert (vs being triggered by an immediate action). For example:
Point being that inline alert banners will stay in the layout permanently until the issue is resolved, verses a toast message which appears momentarily until you dismiss it or reload the page. Apologies if all of this wasn't very clear in the quip doc. 🙏 All that to say, keeping toast cards with a consistent width (and displaying them in the same place) will be an important part of their usage in the app. If the best thing to do is to implement that on a case by case basis (rather than in the component), that's cool. I just want to make sure the context for how these will be used is clear. 😄 |
Glad we did a one-off for studio first so we can take the time to get this 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.
@Jephuff this is great work. You've got test cases and explanations in the story and the API is solid. I asked for one API change, let me know how you feel about that.
Keep up the good work!
@Jephuff I also updated the title of this PR because that's what will show up in the change log 😃 |
@cheapsteak I agree with you on coming up with something to prevent us from having to re-invent the wheel for the rounded, bordered, shadowed edge of these components. I thought it was fine to keep outside the scope of this; you're right we'll totally need to do that at some point. I hadn't actually considered that it's something we'd want outside of Space Kit. If that's the case, I'd name it something like |
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 making these changes. This is great. A few things:
- I left a few comments labeled as
minor
. When I say minor (I really need to add either a contribution guide or a @justinanastos user manual) it means it's a change that I want you to make but I don't need to review it after so you can self-resolve the comment. If you disagree, which is totally fine, please continue the conversation! - Left a comment about the
"inner"
logic for our SVGs, I want that to merge here and I want to add something special to our svg → tsx conversion process so we don't need to use&.inner
anywhere.
src/Alert/Alert.tsx
Outdated
icon: PropTypes.element.isRequired, | ||
headingAs: PropTypes.oneOfType([ | ||
PropTypes.element.isRequired, | ||
PropTypes.string.isRequired as any, // Using PropTypes.string to match keyof JSX.IntrinsicElements |
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 didn't know we could bypass the TS check here with as any
! Awesome.
src/Alert/Alert.story.mdx
Outdated
@@ -42,7 +42,7 @@ Informational alerts present general info about something you are doing or worki | |||
<Alert | |||
onClose={() => undefined} | |||
color={colors.blue.base} | |||
icon={<IconInfoSolid />} | |||
icon={<IconInfoSolid css={{ "& .inner": { fill: colors.white } }} />} |
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 seems like a failing of our icon components that we should address soon.
// @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#exhaustiveness-checking | ||
/* istanbul ignore next */ | ||
export function assertUnreachable(value: never): never { | ||
throw new TypeError(`Unreachable value reached ${value}`); | ||
} |
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 glad you separated this out. I was going to ask you to add this to the excluded files in rollup so we don't export an assertUnreachable
file, but our config already handles this 😃
Lines 32 to 46 in b3fa01c
input: recursiveReaddirSync(path.resolve("src")) | |
// Don't build tests or storybook stories | |
.filter((filename) => !/\.(?:spec|story|stories)/.test(filename)) | |
// Exclude specific directories | |
.filter( | |
(filename) => | |
![ | |
path.join("src", "icons", "scripts"), | |
path.join("src", "illustrations", "scripts"), | |
path.join("src", "shared"), | |
path.join("src", "AbstractTooltip"), | |
path.join("src", "MenuItemClickListener"), | |
path.join("src", "MenuConfig"), | |
].some((excludedPathname) => filename.includes(excludedPathname)) | |
), |
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.
@Jephuff these are coming along really nicely!! ✨👌✨
The components themselves all look as expected in Storybook, so I'm going to approve the PR to keep from blocking you any further. However, there are a few things I noticed that I'd like to point out and I'll leave it to you to decide whether they are worth changing in this PR or later.
So the first thing is that the Extended Alert variant looks just like the basic version because it doesn't use long text in it's example as is the intent for the card, and also it doesn't have any clarifying instructions below the heading as to it's purpose.
To avoid confusion around it's usage intentions, could we add a paragraph or two of text to the body of the example to display it's intended usage, and add a line below the heading to clarify? (Something like "The extended card variant is for rare use cases where a toast alert is the most appropriate format for explaining longer instructions."
The other thing I noticed is that in SpaceKit this component is listed as an Alert, but technically it's a specific type of alert (alert toast card) out of two currently designed for types (alert banner and alert toast cards). Is your intention to rename these to Alert Toast Cards or a similar designation after we add the alert banners?
Again, feel free to merge and keep rolling along and address these other two points later/elsewhere if you'd prefer. Just wanted to make sure these things are on your radar.
@jglovier Updated the text with some more explanation 👍 |
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.
Sorry to go from a 👍 to asking for a change. The storybook story needs it's context of "success" and "info" removed. If we want to keep this documentation, it belongs in new components inside of Studio (formerly known as AGM/engine).
Also, a question on naming 😃
src/AlertCard/AlertCard.story.mdx
Outdated
<br /> | ||
If a toast card’s content requires more than one paragraph, use the | ||
expanded content toast variant. | ||
</AlertCard> | ||
</Story> | ||
</Preview> | ||
|
||
## Warning Alert | ||
|
||
Warning alerts present information about the action that is about to be taken that alerts the user to consequences of the action and asks for confirmation that the action still be taken in light of the consequences. | ||
|
||
<Preview> | ||
<Story name="warning light"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.orange.base} | ||
icon={<IconWarningSolid />} | ||
heading="Warning alert" | ||
actions={<Button size="small">Confirm</Button>} | ||
> | ||
exceededSubLimitAt is a deprecated field. You can use it but it may not | ||
work as expected. | ||
</AlertCard> | ||
</Story> | ||
<Story name="warning dark"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.orange.base} | ||
icon={<IconWarningSolid />} | ||
heading="Warning alert" | ||
theme="dark" | ||
actions={ | ||
<Button theme="dark" size="small"> | ||
Confirm | ||
</Button> | ||
} | ||
> | ||
exceededSubLimitAt is a deprecated field. You can use it but it may not | ||
work as expected. | ||
</AlertCard> | ||
</Story> | ||
</Preview> | ||
|
||
## Error Alert | ||
|
||
Error alerts let the user know that something has gone wrong or is blocked in the given workflow they are trying to complete. When possible, error alerts should contain helpful information about what has happened to help unblock the user (such as steps to resolve or a link to a docs article). | ||
|
||
<Preview> | ||
<Story name="error light"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.red.base} | ||
icon={<IconErrorSolid />} | ||
heading="Error alert" | ||
style={{ marginBottom: 20 }} | ||
> | ||
Something is broken. You cannot perform this action at this time. | ||
</AlertCard> | ||
</Story> | ||
<Story name="error dark"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.red.base} | ||
icon={<IconErrorSolid css={{ "& .inner": { fill: colors.white } }} />} | ||
heading="Error alert" | ||
theme="dark" | ||
style={{ marginBottom: 20 }} | ||
> | ||
Something is broken. You cannot perform this action at this time. | ||
</AlertCard> | ||
</Story> | ||
</Preview> | ||
|
||
## Success Alert | ||
|
||
Success alerts are confirmation that the action the user was trying to take has succeeded. | ||
|
||
<Preview> | ||
<Story name="success light"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.green.base} | ||
icon={<IconSuccessSolid />} | ||
heading="Success alert" | ||
> | ||
A new schema registry has been created by timbotnik. | ||
</AlertCard> | ||
</Story> | ||
<Story name="success dark"> | ||
<AlertCard | ||
onClose={() => undefined} | ||
color={colors.green.base} | ||
icon={<IconSuccessSolid css={{ "& .inner": { fill: colors.white } }} />} | ||
theme="dark" | ||
heading="Success alert" | ||
> | ||
A new schema registry has been created by timbotnik. | ||
</AlertCard> | ||
</Story> | ||
</Preview> |
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 missed this in my review, so I'm sorry. We're not going to share contextual components as Space Kit ideas, just components that can be configured. Instead of demonstrating like this, demonstrate how the component can be configured.
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 can definitely remove the concepts of error/warning/success/error.
before I do that, @jglovier I think you might have had thoughts on this?
@@ -0,0 +1,234 @@ | |||
/** @jsx jsx */ |
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 commenting here just so the conversation can be threaded. I'm confused as to why this is named AlertCard
. Which item in the design principals docs is this implementing and what naming conflict was there?
https://apollographql.quip.com/AgFcAwybcEWN/Alerts-design-principles
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 are to be used in the Alert toast cards.
Joel pointed out the conflict
The other thing I noticed is that in SpaceKit this component is listed as an Alert, but technically it's a specific type of alert (alert toast card) out of two currently designed for types (alert banner and alert toast cards). Is your intention to rename these to Alert Toast Cards or a similar designation after we add the alert banners?
We will need an AlertBanner soon so AlertCard
and AlertBanner
seemed preferable to Alert
and AlertBanner
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.
LGTM! Great work @Jephuff !
🚀 PR was released in |
https://apollographql.atlassian.net/browse/AP-572
Create an
Alert