-
Notifications
You must be signed in to change notification settings - Fork 203
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
WIP - Storybook UI Library #3087
Conversation
src/app/(nextjs_migration)/components/client/button.module.scss
Outdated
Show resolved
Hide resolved
src/app/(nextjs_migration)/components/client/button.module.scss
Outdated
Show resolved
Hide resolved
src/app/storybook.log
Outdated
npm ERR! network 'proxy' config is set properly. See: 'npm help config' | ||
|
||
npm ERR! A complete log of this run can be found in: | ||
npm ERR! /Users/kandres/.npm/_logs/2023-05-30T16_33_34_119Z-debug-0.log |
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 probably didn't mean to commit this file.
import React from "react"; | ||
import styles from "./button.module.scss"; | ||
|
||
export type Props = { |
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.
Q: Does anything import this type? Does it need to be exported?
If so, does it need a less conflicting name, like ButtonProps
, or should the importer just alias it?
Unless these are just temporary placeholder 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.
Usually you won't need to import Prop
types, but when one component passes on props to another, it can be useful. So I also tend to export them by default, but use the generic name Props
to avoid having another thing to rename when copy-pasting an existing file 😅 Potential importers can then indeed just alias them.
const classes = [ | ||
styles.button, | ||
styles[type], | ||
destructive && styles.destructive, | ||
large && styles.large, | ||
] | ||
.filter(Boolean) | ||
.join(" "); |
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.
Not sure if something like https://www.npmjs.com/package/classnames would simplify this.
I see they have some sort of support for CSS-modules 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.
Will look into this for future iterations.
import React from "react"; | ||
import styles from "./StatusPill.module.scss"; | ||
|
||
export type Props = { |
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 Q here, re: export
and or StatusPillProps
.
.pill { | ||
font: $text-body-sm; | ||
font-weight: 600; | ||
background: black; |
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.
background: black; | |
background: $color-black; |
line-height: 1; | ||
|
||
&.primary { | ||
color: 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.
color: white; | |
color: $color-white; |
|
||
&.large { | ||
font: $text-body-lg; | ||
color: 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.
color: white; | |
color: $color-white; |
color: $color-blue-50; | ||
border: solid 2px $color-blue-50; | ||
background-color: transparent; | ||
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; |
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.
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; | |
box-shadow: rgba($color-black, 0.15) 0 0 0 1px inset; |
<dt>{headline}</dt> | ||
<dl>{description}</dl> |
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 dont think this is semantically correct.
IIUC, per https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl, it should be:
<dl>
<dt>Firefox</dt>
<dd>
A free, open source, cross-platform, graphical web browser developed by the
Mozilla Corporation and hundreds of volunteers.
</dd>
<!-- Other terms and descriptions -->
<dt>...</dt>
<dd>...</dd>
</dl>
So not sure if this should be:
<dl>
<dt>{headline}</dt>
<dd>{description}</dd>
</dl>
Although that just always creates a description list with one list item. Or if it just returns this (like you had, but with <dd>
instead of <dl>
) and then the parent container wraps it in a <dl>
somewhere:
<>
<dt>{headline}</dt>
<dd>{description}</dd>
</>
src/app/fonts/inter.scss
Outdated
/* Arial font-size matching for minimal CLS */ | ||
|
||
@font-face { | ||
font-family: Inter-fallback; |
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.
Not relevant to much probably, but I was reading through the Next.js docs the other day and came across this:
https://nextjs.org/docs/pages/building-your-application/optimizing/fonts
import { Inter } from 'next/font/google';
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({ subsets: ['latin'] });
Not sure if that's worth filing a separate ticket/spike for to investigate in the future if we could potentially do font optimizing.
I also didn't see a Metropolis font on Google Fonts, so wasnt sure how to do potential font optimizing for locally hosted fonts.
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, and AFAIK we're already using that - Storybook is useful, but it shouldn't negatively impact what our actual website looks like. So if Storybook has issues loading the fonts, let's see if we can fix that in a way that doesn't require changes to the actual website code - and until we've found such a fix, we'll just have to accept that the fonts don't look quite right there yet.
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 may not be able to take advantage of the Google Font optimization for Inter in Next.js due to our current handling of tokened fonts for Metropolis. Having two different approaches to loading the fonts could lead to confusion.
d6c6942
to
27c12b1
Compare
.storybook/preview.ts
Outdated
}, | ||
}, | ||
status: { | ||
type: "beta", // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate' |
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.
Note: This currently applies to ALL components. We need to figure out how to set individual status levels.
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 should be able to add parameters to individual stories. That said, I'm not sure if we need a heavyweight release process for these components; since we're the only consumer, I'd rather do without the overhead and just consider them evergreen, at least initially.
import type { StorybookConfig } from "@storybook/nextjs"; | ||
|
||
const config: StorybookConfig = { | ||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], |
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.
Tiny nit: do we need all these globs, or can we standardize on using .ts and/or .tsx files?
git ls-files src/**/*.stories.*
src/app/(nextjs_migration)/components/client/stories/Button.stories.ts
src/app/(nextjs_migration)/components/client/stories/ExposureCard.stories.ts
src/app/(nextjs_migration)/components/client/stories/StatusPill.stories.ts
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'll probably at least want the .mdx
as well, for more documentation-style stories (though possibly we want those to be .stories.mdx
as well?). Though I also don't really mind covering our bases and supporting JS stories as well.
OpenInNew, | ||
PhoneIcon, | ||
} from "./Icons"; | ||
import Image from "next/image"; |
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.
Merge w/ L8 above?
import { Button } from "./Button"; | ||
import Email from "next-auth/providers/email"; | ||
|
||
export type Props = { |
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 as above (or below, or somewhere), should this be renamed to "ExposureCardProps" (not sure if anybody is importing these props or not)
export type Props = { | ||
exposureImg: StaticImageData; | ||
exposureName: string; | ||
exposureType: string; |
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.
re: "*Type" suffix should these be generic string;
or enums?
(Same w/ L27 below for the statusPillType
declaration)
const DetailsFoundItem = (props: DetailsFoundProps) => { | ||
let headline, description; | ||
if (props.whichExposed === "family") { | ||
headline = "Family members"; |
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.
Not sure if we want to add TODO
statements to refactor all this for l10n-ing.
<span className={styles.exposureTypeIcon}>{props.icon}</span> | ||
{headline} | ||
</dt> | ||
<dl>{description}</dl> |
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.
IIUC, i think <dl>
is supposed to be a parent of <dt>
and <dd>
tags
const elementCard = ( | ||
<div> | ||
<div className={styles.exposureCard}> | ||
<div className={styles.exposureHeader}> |
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.
nit: should this be <div>
or <header>
?
); | ||
}; | ||
const elementCard = ( | ||
<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.
nit: Do we need this wrapper div
, or can we just use the child <div className={styles.exposureCard}>
as the top level container?
src/app/.storybook/main.js
Outdated
const config = { | ||
stories: [ | ||
// "../components/client/stories/**/*.mdx", | ||
"../components/client/stories/**/*.stories.@(js|jsx|ts|tsx)", |
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.
Do we need all these globs, or can we reduce this to just .ts and/or .tsx?
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.
Really cool that this adds all the Storybook infra, this is going to be massively useful! Needs a bit of cleanup, but let's do that, then merge this in, and then we can work on/refine individual components in followup pull requests as needed. To clean up to merge, I think we should:
- Revert the addition of unoptimised
Inter
- Remove the second
.storybook
folder - Move new components out of
/app/(nextjs_migration)
, e.g. to `/app/components/
Nice work!
import type { StorybookConfig } from "@storybook/nextjs"; | ||
|
||
const config: StorybookConfig = { | ||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], |
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'll probably at least want the .mdx
as well, for more documentation-style stories (though possibly we want those to be .stories.mdx
as well?). Though I also don't really mind covering our bases and supporting JS stories as well.
.storybook/preview.ts
Outdated
}, | ||
}, | ||
status: { | ||
type: "beta", // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate' |
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 should be able to add parameters to individual stories. That said, I'm not sure if we need a heavyweight release process for these components; since we're the only consumer, I'd rather do without the overhead and just consider them evergreen, at least initially.
import React from "react"; | ||
import styles from "./button.module.scss"; | ||
|
||
export type Props = { |
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.
Usually you won't need to import Prop
types, but when one component passes on props to another, it can be useful. So I also tend to export them by default, but use the generic name Props
to avoid having another thing to rename when copy-pasting an existing file 😅 Potential importers can then indeed just alias them.
import styles from "./button.module.scss"; | ||
|
||
export type Props = { | ||
type: string; // primary | secondary | tertiary |
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 can actually encode this using a union (|
) of literal types (e.g. "literalString"
, or 1
, or false
) 😁
type: string; // primary | secondary | tertiary | |
type: "primary" | "secondary" | "tertiary"; |
Same for a couple of props in ExposureCard
.
src/app/(nextjs_migration)/components/client/ExposureCard.module.scss
Outdated
Show resolved
Hide resolved
src/app/fonts/inter.scss
Outdated
/* Arial font-size matching for minimal CLS */ | ||
|
||
@font-face { | ||
font-family: Inter-fallback; |
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, and AFAIK we're already using that - Storybook is useful, but it shouldn't negatively impact what our actual website looks like. So if Storybook has issues loading the fonts, let's see if we can fix that in a way that doesn't require changes to the actual website code - and until we've found such a fix, we'll just have to accept that the fonts don't look quite right there yet.
References:
Jira: [MNTOR-1621]
Description
Add Storybook (https://storybook.js.org/) to project to view components/design system elements. This includes a Button element, Status Pill and the Exposure Card to test.
Screenshot (if applicable)
How to test
Run
npm run storybook
to preview.Checklist (Definition of Done)