Skip to content
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

Merged
merged 18 commits into from
Jun 8, 2023
Merged

WIP - Storybook UI Library #3087

merged 18 commits into from
Jun 8, 2023

Conversation

codemist
Copy link
Collaborator

@codemist codemist commented May 30, 2023

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)

image

How to test

Run npm run storybook to preview.

Checklist (Definition of Done)

  • Localization strings (if needed) have been added.
  • Commits in this PR are minimal and have descriptive commit messages.
  • I've added or updated the relevant sections in readme and/or code comments
  • I've added a unit test to test for potential regressions of this bug.
  • Product Owner accepted the User Story (demo of functionality completed) or waived the privilege.
  • All acceptance criteria are met.
  • Jira ticket has been updated (if needed) to match changes made during the development process.
  • Jira ticket has been updated (if needed) with suggestions for QA when this PR is deployed to stage.

@codemist codemist changed the base branch from main to nextjs May 30, 2023 19:50
src/app/package.json Outdated Show resolved Hide resolved
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
Copy link
Collaborator

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.

src/app/tokens.scss Outdated Show resolved Hide resolved
.storybook/main.ts Show resolved Hide resolved
.storybook/preview.ts Show resolved Hide resolved
import React from "react";
import styles from "./button.module.scss";

export type Props = {
Copy link
Collaborator

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.

Copy link
Collaborator

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.

Comment on lines 19 to 26
const classes = [
styles.button,
styles[type],
destructive && styles.destructive,
large && styles.large,
]
.filter(Boolean)
.join(" ");
Copy link
Collaborator

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.

Copy link
Collaborator Author

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 = {
Copy link
Collaborator

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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
background: black;
background: $color-black;

line-height: 1;

&.primary {
color: white;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
color: white;
color: $color-white;


&.large {
font: $text-body-lg;
color: white;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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;

src/app/.storybook/preview.js Outdated Show resolved Hide resolved
OrahNbur

This comment was marked as spam.

Comment on lines 81 to 95
<dt>{headline}</dt>
<dl>{description}</dl>
Copy link
Collaborator

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>
      </>

/* Arial font-size matching for minimal CLS */

@font-face {
font-family: Inter-fallback;
Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

@maxxcrawford maxxcrawford force-pushed the storybook-ui branch 3 times, most recently from d6c6942 to 27c12b1 Compare June 6, 2023 20:26
},
},
status: {
type: "beta", // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate'
Copy link
Contributor

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.

Copy link
Collaborator

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.

@maxxcrawford
Copy link
Contributor

I think we can review this as is. I added a "status" label add-on so that we can caveat which components are completed/etc.

@pdehaan @codemist @Vinnl

@maxxcrawford maxxcrawford marked this pull request as ready for review June 6, 2023 20:39
@maxxcrawford maxxcrawford requested a review from Vinnl June 6, 2023 20:39
import type { StorybookConfig } from "@storybook/nextjs";

const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
Copy link
Collaborator

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

Copy link
Collaborator

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";
Copy link
Collaborator

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 = {
Copy link
Collaborator

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;
Copy link
Collaborator

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";
Copy link
Collaborator

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>
Copy link
Collaborator

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}>
Copy link
Collaborator

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>
Copy link
Collaborator

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?

const config = {
stories: [
// "../components/client/stories/**/*.mdx",
"../components/client/stories/**/*.stories.@(js|jsx|ts|tsx)",
Copy link
Collaborator

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?

@mozilla mozilla deleted a comment from netlify bot Jun 7, 2023
@Vinnl
Copy link
Collaborator

Vinnl commented Jun 7, 2023

Copy link
Collaborator

@Vinnl Vinnl left a 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)"],
Copy link
Collaborator

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.

},
},
status: {
type: "beta", // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate'
Copy link
Collaborator

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 = {
Copy link
Collaborator

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
Copy link
Collaborator

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) 😁

Suggested change
type: string; // primary | secondary | tertiary
type: "primary" | "secondary" | "tertiary";

Same for a couple of props in ExposureCard.

src/app/(nextjs_migration)/components/client/Button.tsx Outdated Show resolved Hide resolved
src/app/(nextjs_migration)/components/client/Icons.tsx Outdated Show resolved Hide resolved
src/app/.storybook/main.js Outdated Show resolved Hide resolved
/* Arial font-size matching for minimal CLS */

@font-face {
font-family: Inter-fallback;
Copy link
Collaborator

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.

@codemist codemist merged commit 85c5c8a into nextjs Jun 8, 2023
@codemist codemist deleted the storybook-ui branch June 8, 2023 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants