Manifest Debugger

Using react-docgen-typescript. Generation took 5.4s.

Components

() => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <HowItWorksView l10n={getL10n()} /> </PublicShell> )

pages-public-how-it-works · ./src/app/[locale]/(redesign)/(public)/how-it-works/HowItWorksView.stories.tsx
Prop type error
No component file found for the "() => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <HowItWorksView l10n={getL10n()} />
  </PublicShell>
)" component.
   9 | import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";
  10 |
> 11 | const meta: Meta<typeof HowItWorksView> = {
     | ^
  12 |   title: "Pages/Public/How It Works",
  13 |   component: () => (
  14 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/how-it-works/HowItWorksView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { HowItWorksView } from "./HowItWorksView";
import { getL10n } from "../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../PublicShell";
import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof HowItWorksView> = {
  title: "Pages/Public/How It Works",
  component: () => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <HowItWorksView l10n={getL10n()} />
    </PublicShell>
  ),
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof HowItWorksView>;

export const HowItWorks: Story = {
  args: {},
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { HowItWorksView, PublicShell } from "@mozilla/monitor";
How It Works story ok
const HowItWorks = () => <() => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <HowItWorksView l10n={getL10n()} />
  </PublicShell>
) l10n={getL10n()} />;

(props: BreachAlertEmailProps) => ( <StorybookEmailRenderer plainTextVersion={null}> <BreachAlertEmail {...props} /> </StorybookEmailRenderer> )

emails-breach-alert · ./src/emails/templates/breachAlert/BreachAlertEmail.stories.tsx
Prop type error
No component file found for the "(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  11 | import { createRandomHibpListing } from "../../../apiMocks/mockData";
  12 |
> 13 | const meta: Meta<FC<BreachAlertEmailProps>> = {
     | ^
  14 |   title: "Emails/Breach alert",
  15 |   component: (props: BreachAlertEmailProps) => (
  16 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/breachAlert/BreachAlertEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import type { SubscriberRow } from "knex/types/tables";
import { BreachAlertEmailProps, BreachAlertEmail } from "./BreachAlertEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
import { createRandomHibpListing } from "../../../apiMocks/mockData";

const meta: Meta<FC<BreachAlertEmailProps>> = {
  title: "Emails/Breach alert",
  component: (props: BreachAlertEmailProps) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <BreachAlertEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utmCampaignId: "breach-alert",
    subscriber: {
      fxa_profile_json: {
        locale: "en-US",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow,
  },
};

export default meta;
type Story = StoryObj<FC<BreachAlertEmailProps>>;

export const BreachAlertEmailNonUsStory: Story = {
  name: "Breach alert/Non-US",
  args: {
    breach: createRandomHibpListing(),
    breachedEmail: "example@example.com",
    subscriber: {
      fxa_profile_json: {
        locale: "en-CA",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow,
  },
};

export const BreachAlertEmailWithUnsubscribeLinkStory: Story = {
  name: "Breach alert/With unsubscribe link",
  args: {
    breach: createRandomHibpListing(),
    breachedEmail: "example@example.com",
    unsubscribeLink:
      "https://example.com/unsubscribe/breach-alerts?token=abc123",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachAlertEmail, StorybookEmailRenderer } from "@mozilla/monitor";
Breach alert/Non-US story ok
const BreachAlertEmailNonUsStory = () => <(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utmCampaignId="breach-alert"
    subscriber={{
      fxa_profile_json: {
        locale: "en-CA",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow}
    breach={createRandomHibpListing()}
    breachedEmail="example@example.com" />;
Breach alert/With unsubscribe link story ok
const BreachAlertEmailWithUnsubscribeLinkStory = () => <(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utmCampaignId="breach-alert"
    subscriber={{
      fxa_profile_json: {
        locale: "en-US",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow}
    breach={createRandomHibpListing()}
    breachedEmail="example@example.com"
    unsubscribeLink="https://example.com/unsubscribe/breach-alerts?token=abc123" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={getUnstyledRedesignedEmailFooter(props)} > <mjml> <mj-body> <RedesignedEmailFooter {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-redesigned-footer · ./src/emails/components/RedesignedEmailFooter.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
  13 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  14 |
> 15 | const meta: Meta<FC<Props>> = {
     | ^
  16 |   title: "Emails/Components/Redesigned footer",
  17 |   component: (props: Props) => (
  18 |     <StorybookEmailRenderer

./src/emails/components/RedesignedEmailFooter.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import {
  RedesignedEmailFooter,
  Props,
  getUnstyledRedesignedEmailFooter,
} from "./EmailFooter";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Redesigned footer",
  component: (props: Props) => (
    <StorybookEmailRenderer
      plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
    >
      <mjml>
        <mj-body>
          <RedesignedEmailFooter {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const RepeatEmail: Story = {
  name: "Without unsubscribe link",
};

export const WithUnsubscribeLink: Story = {
  name: "With unsubscribe link",
  args: {
    unsubscribeLink:
      "https://example.com/unsubscribe/breach-alerts?token=abc123",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { RedesignedEmailFooter, StorybookEmailRenderer } from "@mozilla/monitor";
Without unsubscribe link story ok
const RepeatEmail = () => <(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" />;
With unsubscribe link story ok
const WithUnsubscribeLink = () => <(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utm_campaign="storybook"
    unsubscribeLink="https://example.com/unsubscribe/breach-alerts?token=abc123" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}> <mjml> <mj-body> <EmailHeader {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-header · ./src/emails/components/EmailHeader.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
    <mjml>
      <mj-body>
        <EmailHeader {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Header",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>

./src/emails/components/EmailHeader.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailHeader, getUnstyledEmailHeader, Props } from "./EmailHeader";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Header",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
      <mjml>
        <mj-body>
          <EmailHeader {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const EmailHeaderStory: Story = {
  name: "Header",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailHeader, StorybookEmailRenderer } from "@mozilla/monitor";
Header story ok
const EmailHeaderStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
    <mjml>
      <mj-body>
        <EmailHeader {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <BoilerplateEmail {...props} /> </StorybookEmailRenderer> )

emails-email-boilerplate · ./src/emails/templates/boilerplate/BoilerplateEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BoilerplateEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Email boilerplate",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/boilerplate/BoilerplateEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, BoilerplateEmail } from "./BoilerplateEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { SanitizedSubscriberRow } from "../../../app/functions/server/sanitize";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Email boilerplate",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <BoilerplateEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    subscriber: {
      signup_language: "en",
    } as SanitizedSubscriberRow,
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const BoilerplateEmailStory: Story = {
  name: "Email boilerplate",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BoilerplateEmail, StorybookEmailRenderer } from "@mozilla/monitor";
Email boilerplate story ok
const BoilerplateEmailStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BoilerplateEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    subscriber={{
      signup_language: "en",
    } as SanitizedSubscriberRow} />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <mjml> <mj-body> <EmailFooter {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-footer · ./src/emails/components/EmailFooter.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Footer",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/components/EmailFooter.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailFooter, Props } from "./EmailFooter";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Footer",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <mjml>
        <mj-body>
          <EmailFooter {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const RepeatEmail: Story = {
  name: "Repeat email",
  args: {
    isOneTimeEmail: false,
  },
};

export const OneTimeEmail: Story = {
  name: "One-time email",
  args: {
    isOneTimeEmail: true,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailFooter, StorybookEmailRenderer } from "@mozilla/monitor";
Repeat email story ok
const RepeatEmail = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" isOneTimeEmail={false} />;
One-time email story ok
const OneTimeEmail = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" isOneTimeEmail />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <mjml> <mj-body> <EmailHero {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-hero · ./src/emails/components/EmailHero.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailHero {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Hero",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/components/EmailHero.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailHero, Props } from "./EmailHero";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Hero",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <mjml>
        <mj-body>
          <EmailHero {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const EmailHeroStory: Story = {
  name: "Hero",
  args: {
    heading: "Email heading",
    subheading: "Email subheading",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailHero, StorybookEmailRenderer } from "@mozilla/monitor";
Hero story ok
const EmailHeroStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailHero {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utm_campaign="storybook"
    heading="Email heading"
    subheading="Email subheading" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <SignupReportEmail {...props} /> </StorybookEmailRenderer> )

emails-signup-report · ./src/emails/templates/signupReport/SignupReportEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { createRandomHibpListing } from "../../../apiMocks/mockData";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Signup Report",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/signupReport/SignupReportEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, SignupReportEmail } from "./SignupReportEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
import { createRandomHibpListing } from "../../../apiMocks/mockData";

const meta: Meta<FC<Props>> = {
  title: "Emails/Signup Report",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <SignupReportEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const SignupReportEmailNoBreachesStory: Story = {
  name: "No breaches detected",
  args: {
    breaches: [],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailOneBreachStory: Story = {
  name: "One breach found",
  args: {
    breaches: [createRandomHibpListing()],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailSomeBreachesStory: Story = {
  name: "Multiple breaches found",
  args: {
    breaches: [
      createRandomHibpListing(),
      createRandomHibpListing(),
      createRandomHibpListing(),
    ],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailManyBreachesStory: Story = {
  name: "Lots of breaches found",
  args: {
    breaches: Array.from({ length: 42 }, () => createRandomHibpListing()),
    breachedEmailAddress: "example@example.com",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { SignupReportEmail, StorybookEmailRenderer } from "@mozilla/monitor";
No breaches detected story ok
const SignupReportEmailNoBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[]}
    breachedEmailAddress="example@example.com" />;
One breach found story ok
const SignupReportEmailOneBreachStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[createRandomHibpListing()]}
    breachedEmailAddress="example@example.com" />;
Multiple breaches found story ok
const SignupReportEmailSomeBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[
      createRandomHibpListing(),
      createRandomHibpListing(),
      createRandomHibpListing(),
    ]}
    breachedEmailAddress="example@example.com" />;
Lots of breaches found story ok
const SignupReportEmailManyBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={Array.from({ length: 42 }, () => createRandomHibpListing())}
    breachedEmailAddress="example@example.com" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <VerifyEmailAddressEmail {...props} /> </StorybookEmailRenderer> )

emails-verify-email-address · ./src/emails/templates/verifyEmailAddress/VerifyEmailAddressEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <VerifyEmailAddressEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Verify email address",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/verifyEmailAddress/VerifyEmailAddressEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, VerifyEmailAddressEmail } from "./VerifyEmailAddressEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { SanitizedSubscriberRow } from "../../../app/functions/server/sanitize";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Verify email address",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <VerifyEmailAddressEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    subscriber: {
      signup_language: "en",
    } as SanitizedSubscriberRow,
    verificationUrl: "https://example.com",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const VerifyEmailAddressEmailStory: Story = {
  name: "Verify email address",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { StorybookEmailRenderer, VerifyEmailAddressEmail } from "@mozilla/monitor";
Verify email address story ok
const VerifyEmailAddressEmailStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <VerifyEmailAddressEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    subscriber={{
      signup_language: "en",
    } as SanitizedSubscriberRow}
    verificationUrl="https://example.com" />;

(props: ViewProps) => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <BreachDetailsView {...props} /> </PublicShell> )

pages-public-breach-listing · ./src/app/[locale]/(redesign)/(public)/breach-details/[breachName]/BreachDetailView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachDetailsView {...props} />
  </PublicShell>
)" component.
  10 | import { defaultExperimentData } from "../../../../../../telemetry/generated/nimbus/experiments";
  11 |
> 12 | const meta: Meta<typeof BreachDetailsView> = {
     | ^
  13 |   title: "Pages/Public/Breach listing",
  14 |   component: (props: ViewProps) => (
  15 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/breach-details/[breachName]/BreachDetailView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { BreachDetailsView, Props as ViewProps } from "./BreachDetailView";
import { getL10n } from "../../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../../PublicShell";
import { createRandomHibpListing } from "../../../../../../apiMocks/mockData";
import { defaultExperimentData } from "../../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof BreachDetailsView> = {
  title: "Pages/Public/Breach listing",
  component: (props: ViewProps) => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <BreachDetailsView {...props} />
    </PublicShell>
  ),
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof BreachDetailsView>;

export const BreachDetailViewStory: Story = {
  name: "Breach listing",
  args: {
    breach: createRandomHibpListing(),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachDetailsView, PublicShell } from "@mozilla/monitor";
Breach listing story ok
const BreachDetailViewStory = () => <(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachDetailsView {...props} />
  </PublicShell>
) l10n={getL10n()} breach={createRandomHibpListing()} />;

(props: ViewProps) => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <BreachIndexView {...props} /> </PublicShell> )

pages-public-breach-index · ./src/app/[locale]/(redesign)/(public)/breaches/BreachIndexView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachIndexView {...props} />
  </PublicShell>
)" component.
  11 | import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";
  12 |
> 13 | const meta: Meta<typeof BreachIndexView> = {
     | ^
  14 |   title: "Pages/Public/Breach index",
  15 |   component: (props: ViewProps) => (
  16 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/breaches/BreachIndexView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { faker } from "@faker-js/faker";
import { BreachIndexView, Props as ViewProps } from "./BreachIndexView";
import { getL10n } from "../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../PublicShell";
import { createRandomHibpListing } from "../../../../../apiMocks/mockData";
import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof BreachIndexView> = {
  title: "Pages/Public/Breach index",
  component: (props: ViewProps) => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <BreachIndexView {...props} />
    </PublicShell>
  ),
};

export default meta;
type Story = StoryObj<typeof BreachIndexView>;

export const BreachIndexViewStory: Story = {
  name: "Breach index",
  args: {
    allBreaches: faker.helpers.multiple(() => createRandomHibpListing(), {
      count: { min: 7, max: 200 },
    }),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachIndexView, PublicShell } from "@mozilla/monitor";
Breach index story ok
const BreachIndexViewStory = () => <(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachIndexView {...props} />
  </PublicShell>
)
    allBreaches={faker.helpers.multiple(() => createRandomHibpListing(), {
      count: { min: 7, max: 200 },
    })} />;

(props: ViewProps) => { const experimentData = props.experimentData ?? defaultExperimentData["Features"]; const enabledFeatureFlags = props.enabledFeatureFlags ?? []; return ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <View {...props} experimentData={experimentData} enabledFeatureFlags={enabledFeatureFlags} /> </PublicShell> ); }

pages-public-landing-page · ./src/app/[locale]/(redesign)/(public)/LandingView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
}" component.
   9 | import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments";
  10 |
> 11 | const meta: Meta<typeof View> = {
     | ^
  12 |   title: "Pages/Public/Landing page",
  13 |   component: (props: ViewProps) => {
  14 |     const experimentData =

./src/app/[locale]/(redesign)/(public)/LandingView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { View, Props as ViewProps } from "./LandingView";
import { getL10n } from "../../../functions/l10n/storybookAndTests";
import { PublicShell } from "./PublicShell";
import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof View> = {
  title: "Pages/Public/Landing page",
  component: (props: ViewProps) => {
    const experimentData =
      props.experimentData ?? defaultExperimentData["Features"];
    const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
    return (
      <PublicShell
        l10n={getL10n("en")}
        experimentData={defaultExperimentData["Features"]}
      >
        <View
          {...props}
          experimentData={experimentData}
          enabledFeatureFlags={enabledFeatureFlags}
        />
      </PublicShell>
    );
  },
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof View>;

export const Landing: Story = {
  name: "Default",
};

export const LandingDe: Story = {
  name: "German",
  args: {
    countryCode: "de",
    l10n: getL10n("de"),
  },
};

export const LandingFr: Story = {
  name: "French",
  args: {
    countryCode: "fr",
    l10n: getL10n("fr"),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { PublicShell, View } from "@mozilla/monitor";
Default story ok
const Landing = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n()} />;
German story ok
const LandingDe = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n("de")} countryCode="de" />;
French story ok
const LandingFr = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n("fr")} countryCode="fr" />;

AnnouncementDialog

layout-navigation-announcement · ./src/app/components/client/toolbar/AnnouncementDialog.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 1 prop type
Component: src/app/components/client/toolbar/AnnouncementDialog.tsx::AnnouncementDialog
Props:
announcements: UserAnnouncementWithDetails[]
Imports
import { AnnouncementDialog } from "@mozilla/monitor";
Announcement Dialog Default story ok
const AnnouncementDialogDefault = () => <AnnouncementDialog announcements={mockedAnnouncementsAllUsers} />;
Announcement Dialog Seen Or Cleared story ok
const AnnouncementDialogSeenOrCleared = () => <AnnouncementDialog announcements={mockedAnnouncementsWithSeenOrCleared} />;
Announcements No Announcements story ok
const AnnouncementsNoAnnouncements = () => <AnnouncementDialog announcements={noAnnouncements} />;

AppPicker

layout-navigation-bento-app-picker · ./src/app/components/client/toolbar/AppPicker.stories.ts
Menu that can be opened to see other relevant products Mozilla has available for people.
Imports
import { AppPicker } from "@mozilla/monitor";
App Picker Default story ok
const AppPickerDefault = () => <AppPicker />;

Button

design-systems-atoms-button · ./src/app/components/client/stories/Button.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 10 prop types
Component: src/app/components/client/Button.tsx::Button
Props:
buttonRef?: RefObject<HTMLAnchorElement | HTMLButtonElement | null>

className?: string

destructive?: boolean

disabled?: boolean

/**
 * A URL to link to if elementType="a".
 */
href?: string

isLoading?: boolean

small?: boolean

theme?: "purple" | "blue"

variant: ButtonVariants

wide?: boolean
Imports
import { Button } from "@mozilla/monitor";
Primary story ok
const Primary = () => <Button variant="primary" destructive={false} small={false}>Button</Button>;
Secondary story ok
const Secondary = () => <Button variant="secondary">Button</Button>;
Primary Small story ok
const PrimarySmall = () => <Button variant="primary" small>Button</Button>;
Primary Wide story ok
const PrimaryWide = () => <Button variant="primary" wide>Button</Button>;
Secondary Small story ok
const SecondarySmall = () => <Button variant="secondary" small>Button</Button>;
Primary Link story ok
const PrimaryLink = () => <Button variant="primary" href="/">Button</Button>;
Secondary Link story ok
const SecondaryLink = () => <Button variant="secondary" href="/">Button</Button>;

DashboardWrapper

pages-logged-in-dashboard · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx
Prop type error
No component file found for the "DashboardWrapper" component.
  161 | };
  162 |
> 163 | const meta: Meta<typeof DashboardWrapper> = {
      | ^
  164 |   title: "Pages/Logged in/Dashboard",
  165 |   component: DashboardWrapper,
  166 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { View as DashboardEl, TabType } from "./View";
import { Shell } from "../../../../Shell/Shell";
import { getL10n } from "../../../../../../functions/l10n/storybookAndTests";
import {
  createRandomBreach,
  createRandomAnnouncement,
  createRandomUser,
} from "../../../../../../../apiMocks/mockData";
import { SubscriberBreach } from "../../../../../../../utils/subscriberBreaches";
import { CountryCodeProvider } from "../../../../../../../contextProviders/country-code";
import { SessionProvider } from "../../../../../../../contextProviders/session";
import { FeatureFlagName } from "../../../../../../../db/tables/featureFlags";
import { UserAnnouncementWithDetails } from "../../../../../../../db/tables/user_announcements";

// Exported values should be stories, but this was already there when
// Storybook added this lint rule, so I guess it works?

const breachOptions = {
  empty: "No data breaches",
  unresolved: "With unresolved data breaches",
  resolved: "All data breaches resolved",
  invalid: "Invalid state (error case)",
};

export type DashboardWrapperProps = (
  | {
      countryCode: "us";
      premium: boolean;
    }
  | {
      countryCode: "nl";
    }
) & {
  breaches: keyof typeof breachOptions;
  elapsedTimeInDaysSinceInitialScan?: number;
  activeTab?: TabType;
  enabledFeatureFlags?: FeatureFlagName[];
  signInCount?: number;
};
const DashboardWrapper = (props: DashboardWrapperProps) => {
  const mockedResolvedBreach: SubscriberBreach = createRandomBreach({
    dataClasses: [
      "email-addresses",
      "ip-addresses",
      "phone-numbers",
      "passwords",
      "pins",
      "social-security-numbers",
      "partial-credit-card-data",
      "security-questions-and-answers",
    ],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
      { passwords: 1 },
    ],
    isResolved: true,
  });

  const mockedUnresolvedBreach: SubscriberBreach = createRandomBreach({
    dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      {
        "email-addresses": [
          "email1@gmail.com",
          "email2@gmail.com",
          "email3@gmail.com",
        ],
      },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
    ],
    isResolved: false,
  });

  const mockedUnresolvedBreach2: SubscriberBreach = createRandomBreach({
    dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      {
        "email-addresses": [
          "email1@gmail.com",
          "email2@gmail.com",
          "email3@gmail.com",
        ],
      },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
    ],
    isResolved: false,
  });

  let breaches: SubscriberBreach[] = [];

  if (props.breaches === "resolved") {
    breaches = [mockedResolvedBreach];
  }
  if (props.breaches === "unresolved") {
    breaches = [
      mockedResolvedBreach,
      mockedUnresolvedBreach,
      mockedUnresolvedBreach2,
    ];
  }

  if (props.breaches === "invalid") {
    // Invalid state since it does not have data classes effected
    breaches = [createRandomBreach({ isResolved: false })];
  }

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];

  const user = createRandomUser();

  if ((props.countryCode !== "us" || !props.premium) && user.fxa) {
    user.fxa.subscriptions = [];
  }

  const mockedSession = {
    expires: new Date().toISOString(),
    user: user,
  };

  return (
    <SessionProvider session={mockedSession}>
      <CountryCodeProvider countryCode={props.countryCode}>
        <Shell
          l10n={getL10n()}
          session={mockedSession}
          nonce=""
          countryCode={props.countryCode}
          enabledFeatureFlags={props.enabledFeatureFlags ?? []}
          announcements={mockedAnnouncements}
        >
          <DashboardEl
            user={user}
            userBreaches={breaches}
            fxaSettingsUrl=""
            enabledFeatureFlags={props.enabledFeatureFlags ?? []}
            activeTab={props.activeTab ?? "action-needed"}
            signInCount={props.signInCount ?? null}
            userAnnouncements={mockedAnnouncements}
            countryCode={props.countryCode}
          />
        </Shell>
      </CountryCodeProvider>
    </SessionProvider>
  );
};

const meta: Meta<typeof DashboardWrapper> = {
  title: "Pages/Logged in/Dashboard",
  component: DashboardWrapper,
  argTypes: {
    breaches: {
      options: Object.keys(breachOptions),
      control: {
        type: "radio",
        labels: breachOptions,
      },
    },
    elapsedTimeInDaysSinceInitialScan: {
      name: "Days since initial scan",
      control: {
        type: "number",
      },
    },
    signInCount: {
      name: "Sign-in count",
      control: {
        type: "number",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof DashboardWrapper>;

export const DashboardNonUsNoBreaches: Story = {
  name: "No breaches",
  args: {
    breaches: "empty",
  },
};

export const DashboardNonUsUnresolvedBreaches: Story = {
  name: "Some breaches unresolved",
  args: {
    breaches: "unresolved",
  },
};

export const DashboardNonUsResolvedBreaches: Story = {
  name: "All breaches resolved",
  args: {
    breaches: "resolved",
  },
};

export const DashboardInvalidState: Story = {
  name: "Invalid state",
  args: {
    breaches: "invalid",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
No breaches story error
Could not generate snippet without component name.
Some breaches unresolved story error
Could not generate snippet without component name.
All breaches resolved story error
Could not generate snippet without component name.
Invalid state story error
Could not generate snippet without component name.
Imports
import { CountryCodeProvider, View as DashboardEl, SessionProvider, Shell } from "@mozilla/monitor";

DoughnutChart

dashboard-top-banner-charts · ./src/app/components/client/stories/Chart.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 4 prop types
Component: src/app/components/client/Chart.tsx::DoughnutChart
Props:
data: [string, number][]

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

isShowFixed: boolean

summary: DashboardSummary
Imports
import { DoughnutChart } from "@mozilla/monitor";
Fixed Exposures story ok
const FixedExposures = () => <DoughnutChart data={data} />;

ExposureCard

dashboard-exposures-exposure-card · ./src/app/components/client/exposure_card/ExposureCard.stories.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 7 prop types
Component: src/app/components/client/exposure_card/ExposureCard.tsx::ExposureCard
Props:
enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

exposureData: SubscriberBreach

exposureImg?: StaticImageData

isExpanded: boolean

locale: string

onToggleExpanded: () => void

resolutionCta: ReactNode
Imports
import { ExposureCard } from "@mozilla/monitor";
Data Breach Action Needed story ok
const DataBreachActionNeeded = () => <ExposureCard
    enabledFeatureFlags={[]}
    exposureImg={TwitterImage}
    exposureData={BreachMockItemNew} />;
Data Breach Fixed story ok
const DataBreachFixed = () => <ExposureCard
    enabledFeatureFlags={[]}
    exposureImg={TwitterImage}
    exposureData={BreachMockItemRemoved} />;

ExposuresFilter

dashboard-exposures-filterbar · ./src/app/components/client/stories/ExposuresFilter.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 4 prop types
Component: src/app/components/client/ExposuresFilter.tsx::ExposuresFilter
Props:
enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

filterValues: FilterState

initialFilterValues: FilterState

setFilterValues: Dispatch<SetStateAction<FilterState>>
Imports
import { ExposuresFilter } from "@mozilla/monitor";
Exposures Filter Default story ok
const ExposuresFilterDefault = () => <ExposuresFilter
    initialFilterValues={initialFilterState}
    filterValues={initialFilterState} />;

FixView

pages-logged-in-guided-resolution-fixview · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.stories.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 9 prop types
Component: src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.tsx::FixView
Props:
currentSection: "data-broker-profiles" | "high-risk-data-breach" | "leaked-passwords" | "security-recommendations"

data: StepDeterminationData

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

hideNavClose?: boolean

hideNextNavigationRightArrow?: boolean

hideProgressIndicator?: boolean

nextStep: { readonly href: "/user/dashboard/fix/high-risk-data-breaches/social-security-number"; readonly id: "HighRiskSsn"; } | { readonly href: "/user/dashboard/fix/high-risk-data-breaches/credit-card"; readonly id: "HighRiskCreditCard"; } | { readonly href: "/user/dashboard/fix/high-risk-data-breaches/bank-account"; readonly id: "HighRiskBankAccount"; } | { readonly href: "/user/dashboard/fix/high-risk-data-breaches/pin"; readonly id: "HighRiskPin"; } | { readonly href: "/user/dashboard/fix/leaked-passwords/passwords"; readonly id: "LeakedPasswordsPassword"; } | { readonly href: "/user/dashboard/fix/leaked-passwords/security-questions"; readonly id: "LeakedPasswordsSecurityQuestion"; } | { readonly href: "/user/dashboard/fix/security-recommendations/phone"; readonly id: "SecurityTipsPhone"; } | { readonly href: "/user/dashboard/fix/security-recommendations/email"; readonly id: "SecurityTipsEmail"; } | { readonly href: "/user/dashboard/fix/security-recommendations/ip"; readonly id: "SecurityTipsIp"; } | { readonly href: "/user/dashboard"; readonly id: "Done"; }

showConfetti?: boolean

subscriberEmails: string[]
Imports
import { FixView } from "@mozilla/monitor";
Fix View with Next Arrow story ok
const FixViewStory = () => <FixView
    subscriberEmails={["test@example.com"]}
    data={{
      user: {
        email: "test@example.com",
      },
      countryCode: "us",
      subscriberBreaches: [],
    }}
    nextStep={{
      id: "HighRiskSsn",
      href: "/user/dashboard/fix/high-risk-data-breaches/social-security-number",
    }}
    currentSection="high-risk-data-breach"
    enabledFeatureFlags={[]}><div>Test content</div></FixView>;

HighRiskBreachWrapper

pages-logged-in-guided-resolution-1-high-risk-data-breaches · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx
Prop type error
No component file found for the "HighRiskBreachWrapper" component.
  101 | };
  102 |
> 103 | const meta: Meta<typeof HighRiskBreachWrapper> = {
      | ^
  104 |   title: "Pages/Logged in/Guided resolution/1. High-risk data breaches",
  105 |   component: HighRiskBreachWrapper,
  106 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { HighRiskBreachLayout } from "../HighRiskBreachLayout";
import {
  HighRiskBreachTypes,
  highRiskBreachTypes,
} from "../highRiskBreachData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { StepDeterminationData } from "../../../../../../../../../functions/server/getRelevantGuidedSteps";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const HighRiskBreachWrapper = (props: {
  type: HighRiskBreachTypes;
  nextUnresolvedBreachType?: keyof typeof BreachDataTypes | "None";
}) => {
  const hasNextUnresolvedBreach = props.nextUnresolvedBreachType !== null;
  const mockedBreaches = [...Array(5)].map(() =>
    createRandomBreach({
      isResolved: hasNextUnresolvedBreach,
    }),
  );

  // Ensure all high-risk data breaches are present in at least one breach:
  mockedBreaches.push(
    createRandomBreach({
      dataClassesEffected: [
        {
          [BreachDataTypes.SSN]: 42,
          [BreachDataTypes.CreditCard]: 42,
          [BreachDataTypes.BankAccount]: 42,
          [BreachDataTypes.PIN]: 42,
        },
      ],
      isResolved: false,
    }),
  );

  // Adds a breach with an unresolved breach type
  if (
    props.nextUnresolvedBreachType &&
    props.nextUnresolvedBreachType !== "None"
  ) {
    mockedBreaches.push(
      createRandomBreach({
        dataClassesEffected: [
          {
            [BreachDataTypes[props.nextUnresolvedBreachType]]: 42,
          },
        ],
        isResolved: false,
      }),
    );
  }

  const data: StepDeterminationData = {
    countryCode: "nl",
    subscriberBreaches: mockedBreaches,
    user: mockedSession.user,
  };

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];

  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode={data.countryCode}
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <HighRiskBreachLayout
        subscriberEmails={[]}
        type={props.type}
        data={data}
        enabledFeatureFlags={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof HighRiskBreachWrapper> = {
  title: "Pages/Logged in/Guided resolution/1. High-risk data breaches",
  component: HighRiskBreachWrapper,
  argTypes: {
    type: {
      options: highRiskBreachTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
    nextUnresolvedBreachType: {
      description: "Next unresolved breach type",
      options: [
        "None",
        "Passwords",
        "SecurityQuestions",
        "Phone",
        "Email",
        "IP",
      ],
      control: {
        type: "radio",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof HighRiskBreachWrapper>;

export const SsnStory: Story = {
  name: "1a. Social Security Number",
  args: {
    type: "social-security-number",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/social-security-number",
      },
    },
  },
};

export const CreditCardStory: Story = {
  name: "1b. Credit card",
  args: {
    type: "credit-card",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/credit-card",
      },
    },
  },
};

export const BankAccountStory: Story = {
  name: "1c. Bank account",
  args: {
    type: "bank-account",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/bank-account",
      },
    },
  },
};

export const PinStory: Story = {
  name: "1d. PIN",
  args: {
    type: "pin",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/pin",
      },
    },
  },
};

export const HighRiskBreachDoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "done",
    nextUnresolvedBreachType: "None",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
1a. Social Security Number story error
Could not generate snippet without component name.
1b. Credit card story error
Could not generate snippet without component name.
1c. Bank account story error
Could not generate snippet without component name.
1d. PIN story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { HighRiskBreachLayout, Shell } from "@mozilla/monitor";

InputField

design-systems-molecules-input-field · ./src/app/components/client/stories/InputField.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 2 prop types
Component: src/app/components/client/InputField.tsx::InputField
Props:
hasFloatingLabel?: boolean

iconButton?: ReactNode
Imports
import { InputField } from "@mozilla/monitor";
Text Input Field Empty story ok
const TextInputFieldEmpty = () => <InputField label="Text input label" placeholder="Type here" type="text" />;
Text Input Field Required story ok
const TextInputFieldRequired = () => <InputField label="Text input label" placeholder="Type here" type="text" isRequired />;
Text Input Field Filled story ok
const TextInputFieldFilled = () => <InputField
    label="Text input label"
    placeholder="Type here"
    type="text"
    value="Input is filled" />;
Text Input Field Invalid story ok
const TextInputFieldInvalid = () => <InputField
    label="Text input label"
    placeholder="Type here"
    type="text"
    isInvalid={false} />;
Text Input Field Invalid With Message story ok
const TextInputFieldInvalidWithMessage = () => <InputField
    label="Text input label"
    placeholder="Type here"
    type="text"
    isInvalid={false}
    errorMessage="Type something" />;
Date Input Field Empty story ok
const DateInputFieldEmpty = () => <InputField label="Date label" type="date" />;
Date Input Field Invalid story ok
const DateInputFieldInvalid = () => <InputField label="Date label" type="date" isInvalid={false} />;
Date Input Field Invalid With Message story ok
const DateInputFieldInvalidWithMessage = () => <InputField
    label="Date label"
    type="date"
    isInvalid={false}
    errorMessage="Select a date" />;
Text Input Field Empty Floating Label story ok
const TextInputFieldEmptyFloatingLabel = () => <InputField
    label="Text input floating label"
    placeholder="Type here"
    type="text"
    hasFloatingLabel />;
Text Input Field Filled Floating Label story ok
const TextInputFieldFilledFloatingLabel = () => <InputField
    label="Text input floating label"
    placeholder="Type here"
    type="text"
    value="Input is filled"
    hasFloatingLabel />;

LeakedPasswordsWrapper

pages-logged-in-guided-resolution-2-leaked-passwords · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx
Prop type error
No component file found for the "LeakedPasswordsWrapper" component.
   95 | };
   96 |
>  97 | const meta: Meta<typeof LeakedPasswordsWrapper> = {
      | ^
   98 |   title: "Pages/Logged in/Guided resolution/2. Leaked passwords",
   99 |   component: LeakedPasswordsWrapper,
  100 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { LeakedPasswordsLayout } from "../LeakedPasswordsLayout";
import {
  LeakedPasswordsTypes,
  leakedPasswordTypes,
} from "../leakedPasswordsData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const LeakedPasswordsWrapper = (props: {
  type: LeakedPasswordsTypes;
  nextUnresolvedBreachType?: keyof typeof BreachDataTypes | "None";
}) => {
  const mockedBreaches = [...Array(5)].map(() =>
    createRandomBreach({
      isResolved: props.nextUnresolvedBreachType !== null,
    }),
  );

  // Ensure all leaked passwords data breaches are present in at least one breach:
  mockedBreaches.push(
    createRandomBreach({
      dataClassesEffected: [
        {
          [BreachDataTypes.Passwords]: 42,
          [BreachDataTypes.SecurityQuestions]: 42,
        },
      ],
      isResolved: false,
    }),
  );

  // Adds a breach with an unresolved breach type
  if (
    props.nextUnresolvedBreachType &&
    props.nextUnresolvedBreachType !== "None"
  ) {
    mockedBreaches.push(
      createRandomBreach({
        dataClassesEffected: [
          {
            [BreachDataTypes[props.nextUnresolvedBreachType]]: 42,
          },
        ],
        isResolved: false,
      }),
    );
  }

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];
  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode="nl"
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <LeakedPasswordsLayout
        subscriberEmails={[]}
        type={props.type}
        data={{
          countryCode: "nl",
          subscriberBreaches: mockedBreaches,
          user: mockedSession.user,
        }}
        enabledFeatureFlags={[]}
        blockdHibpBreachDomains={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof LeakedPasswordsWrapper> = {
  title: "Pages/Logged in/Guided resolution/2. Leaked passwords",
  component: LeakedPasswordsWrapper,
  argTypes: {
    type: {
      options: leakedPasswordTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
    nextUnresolvedBreachType: {
      description: "Next unresolved breach type",
      options: ["None", "SecurityQuestions", "Phone", "Email", "IP"],
      control: {
        type: "radio",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof LeakedPasswordsWrapper>;

export const PasswordsStory: Story = {
  name: "2a. Passwords",
  args: {
    type: "passwords",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/passwords",
      },
    },
  },
};

export const SecurityQuestionsStory: Story = {
  name: "2b. Security questions",
  args: {
    type: "security-questions",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/security-questions",
      },
    },
  },
};

export const LeakedPasswordsDoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "passwords-done",
    nextUnresolvedBreachType: "None",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
2a. Passwords story error
Could not generate snippet without component name.
2b. Security questions story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { LeakedPasswordsLayout, Shell } from "@mozilla/monitor";

MobileShell

layout-mobile-shell · ./src/app/[locale]/(redesign)/MobileShell.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 5 prop types
Component: src/app/[locale]/(redesign)/MobileShell.tsx::MobileShell
Props:
announcements?: UserAnnouncementWithDetails[] | null

countryCode: string

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

fxaSettingsUrl: string

session: Session | null
Imports
import { MobileShell } from "@mozilla/monitor";
Mobile Shell Public story ok
const MobileShellPublic = () => <MobileShell enabledFeatureFlags={[]} countryCode="us" session={null} />;
Mobile Shell Authenticated story ok
const MobileShellAuthenticated = () => <MobileShell enabledFeatureFlags={[]} countryCode="us" session={mockedSession} />;

ModalDialog

design-systems-molecules-modal-dialog · ./src/app/components/client/stories/ModalDialog.stories.tsx
Prop type error
No component file found for the "ModalDialog" component.
  78 |
  79 | // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
> 80 | const meta: Meta<typeof ModalDialog> = {
     | ^
  81 |   title: "Design Systems/Molecules/Modal dialog",
  82 |   component: ModalDialog,
  83 |   argTypes: {

./src/app/components/client/stories/ModalDialog.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";

import { useOverlayTriggerState } from "react-stately";
import { useOverlayTrigger } from "react-aria";
import Image from "next/image";
import Illustration from "../assets/modal-default-img.svg";
import { ModalOverlay } from "../dialog/ModalOverlay";
import { Dialog } from "../dialog/Dialog";
import { Button } from "../Button";

export type ModalDialogProps = {
  withDialog?: boolean;
  withTitle?: boolean;
  withIllustration?: boolean;
};

const ModalDialog = (props: ModalDialogProps) => {
  const modalState = useOverlayTriggerState({ defaultOpen: true });
  const modalTrigger = useOverlayTrigger({ type: "dialog" }, modalState);
  return (
    <>
      <Button {...modalTrigger.triggerProps} variant="primary">
        Open modal {props.withDialog && " dialog"}
      </Button>
      {modalState.isOpen && (
        <ModalOverlay
          state={modalState}
          {...modalTrigger.overlayProps}
          isDismissable={true}
        >
          {props.withDialog ? (
            <Dialog
              title={props.withTitle ? "Here's a dialog for you" : undefined}
              illustration={
                props.withIllustration ? (
                  <Image src={Illustration} alt="" />
                ) : undefined
              }
              onDismiss={() => modalState.close()}
            >
              <p>Some dialog content.</p>
            </Dialog>
          ) : (
            <>
              <div
                style={{
                  display: "flex",
                  flexDirection: "column",
                  alignItems: "flex-start",
                  gap: 16,
                }}
              >
                <p>
                  This is modal content; note that it&apos;s not possible to
                  interact with the content behind the modal overlay.
                  Here&apos;s a button to close the modal: &nbsp;
                </p>
                <Button variant="primary" onPress={() => modalState.close()}>
                  Close modal
                </Button>
                <p>
                  Note that modal overlays aren&apos;t usually used on their
                  own. This is merely an example to help clarify the boundaries
                  between the Modal and Dialog components.
                </p>
              </div>
            </>
          )}
        </ModalOverlay>
      )}
    </>
  );
};

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof ModalDialog> = {
  title: "Design Systems/Molecules/Modal dialog",
  component: ModalDialog,
  argTypes: {
    withDialog: {
      control: "boolean",
      name: "With dialog",
    },
    withTitle: {
      control: "boolean",
      name: "With title",
    },
    withIllustration: {
      control: "boolean",
      name: "With illustration",
    },
  },
};
export default meta;
type Story = StoryObj<typeof ModalDialog>;

export const Modal: Story = {
  name: "Modal without a dialog",
  args: {},
};

export const ModalWithDialog: Story = {
  name: "Modal dialog",
  args: {
    withDialog: true,
  },
};

export const ModalDialogWithTitle: Story = {
  name: "With title",
  args: {
    withDialog: true,
    withTitle: true,
  },
};

export const ModalDialogWithIllustration: Story = {
  name: "With title and illustration",
  args: {
    withDialog: true,
    withTitle: true,
    withIllustration: true,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Modal without a dialog story error
Could not generate snippet without component name.
Modal dialog story error
Could not generate snippet without component name.
With title story error
Could not generate snippet without component name.
With title and illustration story error
Could not generate snippet without component name.
Imports
import { Button, Dialog, ModalOverlay } from "@mozilla/monitor";
import Image from "next/image";

MonitorLogo

layout-navigation-monitor-logo · ./src/app/[locale]/(redesign)/Shell/MonitorLogo.stories.ts
Prop type error
No component file found for the "MonitorLogo" component.
   6 | import { MonitorLogo } from "./MonitorLogo";
   7 |
>  8 | const meta: Meta<typeof MonitorLogo> = {
     | ^
   9 |   title: "Layout/Navigation/Monitor Logo",
  10 |   component: MonitorLogo,
  11 | };

./src/app/[locale]/(redesign)/Shell/MonitorLogo.stories.ts:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { MonitorLogo } from "./MonitorLogo";

const meta: Meta<typeof MonitorLogo> = {
  title: "Layout/Navigation/Monitor Logo",
  component: MonitorLogo,
};

export default meta;
type Story = StoryObj<typeof MonitorLogo>;

export const MonitorLogoFixFlow: Story = {
  args: {},
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/en/fix/leaked-passwords/passwords",
      },
    },
  },
};

export const MonitorLogoActionNeeded: Story = {
  args: {},
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fy-NL/action-needed",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { MonitorLogo } from "@mozilla/monitor";
Monitor Logo Fix Flow story ok
const MonitorLogoFixFlow = () => <MonitorLogo />;
Monitor Logo Action Needed story ok
const MonitorLogoActionNeeded = () => <MonitorLogo />;

PopoverStory

design-systems-atoms-popover · ./src/app/components/client/stories/Popover.stories.tsx
Prop type error
No component file found for the "PopoverStory" component.
  38 | };
  39 |
> 40 | const meta: Meta<typeof PopoverStory> = {
     | ^
  41 |   title: "Design Systems/Atoms/Popover",
  42 |   component: PopoverStory,
  43 |   argTypes: {

./src/app/components/client/stories/Popover.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { useRef } from "react";
import { useOverlayTriggerState } from "react-stately";
import { Popover } from "../Popover";

export type PopoverStoryProps = {
  defaultOpen?: boolean;
};

const PopoverStory = ({ defaultOpen = true }: PopoverStoryProps) => {
  const triggerRef = useRef<HTMLButtonElement>(null);
  const popoverRef = useRef<HTMLDivElement>(null);
  const state = useOverlayTriggerState({ defaultOpen });

  return (
    <>
      <button ref={triggerRef} onClick={() => state.toggle()}>
        Toggle popover
      </button>
      {state.isOpen && (
        <Popover
          triggerRef={triggerRef}
          popoverRef={popoverRef}
          state={state}
          offset={8}
        >
          <div ref={popoverRef} style={{ padding: "1rem" }}>
            Popover content
          </div>
        </Popover>
      )}
    </>
  );
};

const meta: Meta<typeof PopoverStory> = {
  title: "Design Systems/Atoms/Popover",
  component: PopoverStory,
  argTypes: {
    defaultOpen: {
      control: "boolean",
      name: "Default open",
    },
  },
};
export default meta;
type Story = StoryObj<typeof PopoverStory>;

export const PopoverDefault: Story = {
  name: "Open popover",
  args: {
    defaultOpen: true,
  },
};

export const PopoverClosed: Story = {
  name: "Closed popover",
  args: {
    defaultOpen: false,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Open popover story error
Could not generate snippet without component name.
Closed popover story error
Could not generate snippet without component name.
Imports
import { Popover } from "@mozilla/monitor";

ProgressCard

dashboard-top-banner-progress-infographic · ./src/app/components/client/stories/ProgressCard.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 1 prop type
Component: src/app/components/client/ProgressCard.tsx::ProgressCard
Props:
resolvedByYou: number
Imports
import { ProgressCard } from "@mozilla/monitor";
Not eligible for Premium story ok
const ProgressCardItemNonUs = () => <ProgressCard resolvedByYou={3} />;

PublicShell

layout-public-shell · ./src/app/[locale]/(redesign)/(public)/PublicShell.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 2 prop types
Component: src/app/[locale]/(redesign)/(public)/PublicShell.tsx::PublicShell
Props:
experimentData: { "example-feature": { enabled: boolean; something: string | null; }; "last-scan-date": { enabled: boolean; }; "welcome-scan-optional-info": { enabled: boolean; variant: OptionalBrokerScanInfoFields; }; "landing-page-free-scan-cta": { enabled: boolean; variant: FreeScanCtaType; }; "data-broker-removal-time-estimates": { enabled: boolean; }; }

l10n: ExtendedReactLocalization
Imports
import { PublicShell } from "@mozilla/monitor";
Public Shell Story story ok
const PublicShellStory = () => <PublicShell l10n={getL10n("en")} />;

SecurityRecommendationsWrapper

pages-logged-in-guided-resolution-3-security-recommendations · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/[type]/SecurityRecommendations.stories.tsx
Prop type error
No component file found for the "SecurityRecommendationsWrapper" component.
  73 | };
  74 |
> 75 | const meta: Meta<typeof SecurityRecommendationsWrapper> = {
     | ^
  76 |   title: "Pages/Logged in/Guided resolution/3. Security recommendations",
  77 |   component: SecurityRecommendationsWrapper,
  78 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/[type]/SecurityRecommendations.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { SecurityRecommendationsLayout } from "../SecurityRecommendationsLayout";
import {
  SecurityRecommendationTypes,
  securityRecommendationTypes,
} from "../securityRecommendationsData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const mockedBreaches = [...Array(5)].map(() => createRandomBreach());
// Ensure all security recommendation data breaches are present in at least one breach:
mockedBreaches.push(
  createRandomBreach({
    dataClassesEffected: [
      {
        [BreachDataTypes.Phone]: 42,
        [BreachDataTypes.Email]: 42,
        [BreachDataTypes.IP]: 42,
      },
    ],
    isResolved: false,
  }),
);

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const mockedAnnouncements: UserAnnouncementWithDetails[] = [
  createRandomAnnouncement(),
  createRandomAnnouncement(),
  createRandomAnnouncement(),
];

const SecurityRecommendationsWrapper = (props: {
  type: SecurityRecommendationTypes;
}) => {
  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode="nl"
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <SecurityRecommendationsLayout
        subscriberEmails={[]}
        type={props.type}
        data={{
          countryCode: "nl",
          subscriberBreaches: mockedBreaches,
          user: mockedSession.user,
        }}
        enabledFeatureFlags={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof SecurityRecommendationsWrapper> = {
  title: "Pages/Logged in/Guided resolution/3. Security recommendations",
  component: SecurityRecommendationsWrapper,
  argTypes: {
    type: {
      options: securityRecommendationTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof SecurityRecommendationsWrapper>;

export const PhoneStory: Story = {
  name: "3a. Phone number",
  args: {
    type: "phone",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/phone",
      },
    },
  },
};

export const EmailStory: Story = {
  name: "3b. Email address",
  args: {
    type: "email",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/email",
      },
    },
  },
};

export const IpStory: Story = {
  name: "3c. IP address",
  args: {
    type: "ip",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/ip",
      },
    },
  },
};

export const DoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "done",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
3a. Phone number story error
Could not generate snippet without component name.
3b. Email address story error
Could not generate snippet without component name.
3c. IP address story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { SecurityRecommendationsLayout, Shell } from "@mozilla/monitor";

SettingsWrapper

pages-logged-in-settings · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/settings/stories/Settings.stories.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 7 prop types
Component: src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/settings/stories/SettingsStoryWrapper.tsx::SettingsWrapper
Props:
activeTab: "edit-info" | "notifications" | "manage-account" | "edit-profile"

breaches: unknown

countryCode: string

data?: SubscriberEmailPreferencesOutput

emailAddresses?: EmailAddressRow[]

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

subscriber: SubscriberRow
Imports
import { SettingsWrapper } from "@mozilla/monitor";
Settings default no tab story ok
const SettingsNoDefaultTab = () => <SettingsWrapper
    countryCode="us"
    activeTab={undefined}
    enabledFeatureFlags={["SidebarNavigationRedesign"]} />;
Manage account story ok
const SettingsEditManageAccount = () => <SettingsWrapper
    countryCode="us"
    activeTab="manage-account"
    enabledFeatureFlags={["SidebarNavigationRedesign"]} />;
Notifications story ok
const SettingsEditNotifications = () => <SettingsWrapper
    countryCode="us"
    activeTab="notifications"
    enabledFeatureFlags={["SidebarNavigationRedesign"]} />;

SettingsWrapper

pages-logged-in-settings-edit-info · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/settings/stories/SettingsEditInfoNonUsUsers.stories.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 7 prop types
Component: src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/settings/stories/SettingsStoryWrapper.tsx::SettingsWrapper
Props:
activeTab: "edit-info" | "notifications" | "manage-account" | "edit-profile"

breaches: unknown

countryCode: string

data?: SubscriberEmailPreferencesOutput

emailAddresses?: EmailAddressRow[]

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

subscriber: SubscriberRow
Imports
import { SettingsWrapper } from "@mozilla/monitor";
No additional monitored emails story ok
const SettingsEditYourInfo = () => <SettingsWrapper
    countryCode="nl"
    activeTab="edit-info"
    enabledFeatureFlags={["SidebarNavigationRedesign"]} />;
Additional monitored emails story ok
const SettingsEditYourInfoAdditionalMonitoredEmails = () => <SettingsWrapper
    countryCode="nl"
    activeTab="edit-info"
    enabledFeatureFlags={["SidebarNavigationRedesign"]}
    emailAddresses={[mockedVerifiedEmailSecond, mockedVerifiedEmailFourth]} />;
Max monitored emails story ok
const SettingsEditYourInfoMaxMonitoredEmails = () => <SettingsWrapper
    countryCode="nl"
    activeTab="edit-info"
    enabledFeatureFlags={["SidebarNavigationRedesign"]}
    emailAddresses={maxEmails()} />;

Shell

layout-shell · ./src/app/[locale]/(redesign)/Shell/Shell.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 7 prop types
Component: src/app/[locale]/(redesign)/Shell/Shell.tsx::Shell
Props:
announcements: UserAnnouncementWithDetails[] | null

countryCode: string

enabledFeatureFlags: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

hideSidebar?: boolean

l10n: ExtendedReactLocalization

nonce: string

session: Session
Imports
import { Shell } from "@mozilla/monitor";
Shell Authenticated Redesign story ok
const ShellAuthenticatedRedesign = () => <Shell
    countryCode="us"
    l10n={getL10n("en")}
    enabledFeatureFlags={[]}
    session={mockedSession} />;

StatusPill

design-systems-atoms-pill · ./src/app/components/server/StatusPill.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 4 prop types
Component: src/app/components/server/StatusPill.tsx::StatusPill
Props:
enabledFeatureFlags?: ("SidebarNavigationRedesign" | "DisableLandingToDashboardRedirect")[]

exposure: SubscriberBreach

note?: string

type: StatusPillType
Imports
import { StatusPill } from "@mozilla/monitor";
Action Needed story ok
const ActionNeeded = () => <StatusPill type="actionNeeded" />;
Fixed story ok
const Fixed = () => <StatusPill type="fixed" />;

TabList

design-systems-molecules-tablist · ./src/app/components/client/stories/TabList.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 2 prop types
Component: src/app/components/client/TabList.tsx::TabList
Props:
tabs: { key: Key; name: ReactNode; content?: ReactNode; }[]

variant?: "primary" | "secondary"
Imports
import { TabList } from "@mozilla/monitor";
Tab List Item Default story ok
const TabListItemDefault = () => <TabList
    tabs={tabsData}
    onSelectionChange={(selectedKey) => console.log(selectedKey)} />;
Tab List Item Default Selection story ok
const TabListItemDefaultSelection = () => <TabList
    tabs={tabsData}
    defaultSelectedKey="second"
    onSelectionChange={(selectedKey) => console.log(selectedKey)} />;

UnsubscribeBreachAlertsView

pages-public-unsubscribe-from-breach-alerts · ./src/app/[locale]/unsubscribe/breach-alerts/UnsubscribeBreachAlertsView.stories.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 1 prop type
Component: src/app/[locale]/unsubscribe/breach-alerts/UnsubscribeBreachAlertsView.tsx::UnsubscribeBreachAlertsView
Props:
token: string
Imports
import { UnsubscribeBreachAlertsView } from "@mozilla/monitor";
Unsubscribe from breach alerts story ok
const ConfirmationState = () => <UnsubscribeBreachAlertsView token="test-token-abc123" />;

UserMenu

layout-navigation-toolbar · ./src/app/components/client/toolbar/UserMenu.stories.ts
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types (react-docgen-typescript) 2 prop types
Component: src/app/components/client/toolbar/UserMenu.tsx::UserMenu
Props:
fxaSettingsUrl: string

user: { fxa?: { locale: string; twoFactorAuthentication: boolean; metricsEnabled: boolean; avatar: string; avatarDefault: boolean; subscriptions: string[]; } | undefined; subscriber?: SerializedSubscriber | undefined; } & { name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; } & { email: string; }
Imports
import { UserMenu } from "@mozilla/monitor";
User Menu Default story ok
const UserMenuDefault = () => <UserMenu user={dummyUserData} fxaSettingsUrl="https://mock-fxa-settings-url.com" />;

() => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <HowItWorksView l10n={getL10n()} /> </PublicShell> )

pages-public-how-it-works · ./src/app/[locale]/(redesign)/(public)/how-it-works/HowItWorksView.stories.tsx
Prop type error
No component file found for the "() => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <HowItWorksView l10n={getL10n()} />
  </PublicShell>
)" component.
   9 | import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";
  10 |
> 11 | const meta: Meta<typeof HowItWorksView> = {
     | ^
  12 |   title: "Pages/Public/How It Works",
  13 |   component: () => (
  14 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/how-it-works/HowItWorksView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { HowItWorksView } from "./HowItWorksView";
import { getL10n } from "../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../PublicShell";
import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof HowItWorksView> = {
  title: "Pages/Public/How It Works",
  component: () => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <HowItWorksView l10n={getL10n()} />
    </PublicShell>
  ),
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof HowItWorksView>;

export const HowItWorks: Story = {
  args: {},
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { HowItWorksView, PublicShell } from "@mozilla/monitor";
How It Works story ok
const HowItWorks = () => <() => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <HowItWorksView l10n={getL10n()} />
  </PublicShell>
) l10n={getL10n()} />;

(props: BreachAlertEmailProps) => ( <StorybookEmailRenderer plainTextVersion={null}> <BreachAlertEmail {...props} /> </StorybookEmailRenderer> )

emails-breach-alert · ./src/emails/templates/breachAlert/BreachAlertEmail.stories.tsx
Prop type error
No component file found for the "(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  11 | import { createRandomHibpListing } from "../../../apiMocks/mockData";
  12 |
> 13 | const meta: Meta<FC<BreachAlertEmailProps>> = {
     | ^
  14 |   title: "Emails/Breach alert",
  15 |   component: (props: BreachAlertEmailProps) => (
  16 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/breachAlert/BreachAlertEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import type { SubscriberRow } from "knex/types/tables";
import { BreachAlertEmailProps, BreachAlertEmail } from "./BreachAlertEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
import { createRandomHibpListing } from "../../../apiMocks/mockData";

const meta: Meta<FC<BreachAlertEmailProps>> = {
  title: "Emails/Breach alert",
  component: (props: BreachAlertEmailProps) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <BreachAlertEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utmCampaignId: "breach-alert",
    subscriber: {
      fxa_profile_json: {
        locale: "en-US",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow,
  },
};

export default meta;
type Story = StoryObj<FC<BreachAlertEmailProps>>;

export const BreachAlertEmailNonUsStory: Story = {
  name: "Breach alert/Non-US",
  args: {
    breach: createRandomHibpListing(),
    breachedEmail: "example@example.com",
    subscriber: {
      fxa_profile_json: {
        locale: "en-CA",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow,
  },
};

export const BreachAlertEmailWithUnsubscribeLinkStory: Story = {
  name: "Breach alert/With unsubscribe link",
  args: {
    breach: createRandomHibpListing(),
    breachedEmail: "example@example.com",
    unsubscribeLink:
      "https://example.com/unsubscribe/breach-alerts?token=abc123",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachAlertEmail, StorybookEmailRenderer } from "@mozilla/monitor";
Breach alert/Non-US story ok
const BreachAlertEmailNonUsStory = () => <(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utmCampaignId="breach-alert"
    subscriber={{
      fxa_profile_json: {
        locale: "en-CA",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow}
    breach={createRandomHibpListing()}
    breachedEmail="example@example.com" />;
Breach alert/With unsubscribe link story ok
const BreachAlertEmailWithUnsubscribeLinkStory = () => <(props: BreachAlertEmailProps) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BreachAlertEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utmCampaignId="breach-alert"
    subscriber={{
      fxa_profile_json: {
        locale: "en-US",
        subscriptions: ["not-monitor-plus"],
      },
    } as SubscriberRow}
    breach={createRandomHibpListing()}
    breachedEmail="example@example.com"
    unsubscribeLink="https://example.com/unsubscribe/breach-alerts?token=abc123" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={getUnstyledRedesignedEmailFooter(props)} > <mjml> <mj-body> <RedesignedEmailFooter {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-redesigned-footer · ./src/emails/components/RedesignedEmailFooter.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
  13 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  14 |
> 15 | const meta: Meta<FC<Props>> = {
     | ^
  16 |   title: "Emails/Components/Redesigned footer",
  17 |   component: (props: Props) => (
  18 |     <StorybookEmailRenderer

./src/emails/components/RedesignedEmailFooter.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import {
  RedesignedEmailFooter,
  Props,
  getUnstyledRedesignedEmailFooter,
} from "./EmailFooter";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Redesigned footer",
  component: (props: Props) => (
    <StorybookEmailRenderer
      plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
    >
      <mjml>
        <mj-body>
          <RedesignedEmailFooter {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const RepeatEmail: Story = {
  name: "Without unsubscribe link",
};

export const WithUnsubscribeLink: Story = {
  name: "With unsubscribe link",
  args: {
    unsubscribeLink:
      "https://example.com/unsubscribe/breach-alerts?token=abc123",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { RedesignedEmailFooter, StorybookEmailRenderer } from "@mozilla/monitor";
Without unsubscribe link story ok
const RepeatEmail = () => <(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" />;
With unsubscribe link story ok
const WithUnsubscribeLink = () => <(props: Props) => (
  <StorybookEmailRenderer
    plainTextVersion={getUnstyledRedesignedEmailFooter(props)}
  >
    <mjml>
      <mj-body>
        <RedesignedEmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utm_campaign="storybook"
    unsubscribeLink="https://example.com/unsubscribe/breach-alerts?token=abc123" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}> <mjml> <mj-body> <EmailHeader {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-header · ./src/emails/components/EmailHeader.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
    <mjml>
      <mj-body>
        <EmailHeader {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Header",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>

./src/emails/components/EmailHeader.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailHeader, getUnstyledEmailHeader, Props } from "./EmailHeader";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Header",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
      <mjml>
        <mj-body>
          <EmailHeader {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const EmailHeaderStory: Story = {
  name: "Header",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailHeader, StorybookEmailRenderer } from "@mozilla/monitor";
Header story ok
const EmailHeaderStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={getUnstyledEmailHeader(props)}>
    <mjml>
      <mj-body>
        <EmailHeader {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <BoilerplateEmail {...props} /> </StorybookEmailRenderer> )

emails-email-boilerplate · ./src/emails/templates/boilerplate/BoilerplateEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BoilerplateEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Email boilerplate",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/boilerplate/BoilerplateEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, BoilerplateEmail } from "./BoilerplateEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { SanitizedSubscriberRow } from "../../../app/functions/server/sanitize";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Email boilerplate",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <BoilerplateEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    subscriber: {
      signup_language: "en",
    } as SanitizedSubscriberRow,
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const BoilerplateEmailStory: Story = {
  name: "Email boilerplate",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BoilerplateEmail, StorybookEmailRenderer } from "@mozilla/monitor";
Email boilerplate story ok
const BoilerplateEmailStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <BoilerplateEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    subscriber={{
      signup_language: "en",
    } as SanitizedSubscriberRow} />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <mjml> <mj-body> <EmailFooter {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-footer · ./src/emails/components/EmailFooter.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Footer",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/components/EmailFooter.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailFooter, Props } from "./EmailFooter";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Footer",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <mjml>
        <mj-body>
          <EmailFooter {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const RepeatEmail: Story = {
  name: "Repeat email",
  args: {
    isOneTimeEmail: false,
  },
};

export const OneTimeEmail: Story = {
  name: "One-time email",
  args: {
    isOneTimeEmail: true,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailFooter, StorybookEmailRenderer } from "@mozilla/monitor";
Repeat email story ok
const RepeatEmail = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" isOneTimeEmail={false} />;
One-time email story ok
const OneTimeEmail = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailFooter {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
) l10n={getL10n("en")} utm_campaign="storybook" isOneTimeEmail />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <mjml> <mj-body> <EmailHero {...props} /> </mj-body> </mjml> </StorybookEmailRenderer> )

emails-components-hero · ./src/emails/components/EmailHero.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailHero {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)" component.
   9 | import { getL10n } from "../../app/functions/l10n/storybookAndTests";
  10 |
> 11 | const meta: Meta<FC<Props>> = {
     | ^
  12 |   title: "Emails/Components/Hero",
  13 |   component: (props: Props) => (
  14 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/components/EmailHero.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { StorybookEmailRenderer } from "../StorybookEmailRenderer";
import { EmailHero, Props } from "./EmailHero";
import { getL10n } from "../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Components/Hero",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <mjml>
        <mj-body>
          <EmailHero {...props} />
        </mj-body>
      </mjml>
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    utm_campaign: "storybook",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const EmailHeroStory: Story = {
  name: "Hero",
  args: {
    heading: "Email heading",
    subheading: "Email subheading",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { EmailHero, StorybookEmailRenderer } from "@mozilla/monitor";
Hero story ok
const EmailHeroStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <mjml>
      <mj-body>
        <EmailHero {...props} />
      </mj-body>
    </mjml>
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    utm_campaign="storybook"
    heading="Email heading"
    subheading="Email subheading" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <SignupReportEmail {...props} /> </StorybookEmailRenderer> )

emails-signup-report · ./src/emails/templates/signupReport/SignupReportEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { createRandomHibpListing } from "../../../apiMocks/mockData";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Signup Report",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/signupReport/SignupReportEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, SignupReportEmail } from "./SignupReportEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
import { createRandomHibpListing } from "../../../apiMocks/mockData";

const meta: Meta<FC<Props>> = {
  title: "Emails/Signup Report",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <SignupReportEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const SignupReportEmailNoBreachesStory: Story = {
  name: "No breaches detected",
  args: {
    breaches: [],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailOneBreachStory: Story = {
  name: "One breach found",
  args: {
    breaches: [createRandomHibpListing()],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailSomeBreachesStory: Story = {
  name: "Multiple breaches found",
  args: {
    breaches: [
      createRandomHibpListing(),
      createRandomHibpListing(),
      createRandomHibpListing(),
    ],
    breachedEmailAddress: "example@example.com",
  },
};

export const SignupReportEmailManyBreachesStory: Story = {
  name: "Lots of breaches found",
  args: {
    breaches: Array.from({ length: 42 }, () => createRandomHibpListing()),
    breachedEmailAddress: "example@example.com",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { SignupReportEmail, StorybookEmailRenderer } from "@mozilla/monitor";
No breaches detected story ok
const SignupReportEmailNoBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[]}
    breachedEmailAddress="example@example.com" />;
One breach found story ok
const SignupReportEmailOneBreachStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[createRandomHibpListing()]}
    breachedEmailAddress="example@example.com" />;
Multiple breaches found story ok
const SignupReportEmailSomeBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={[
      createRandomHibpListing(),
      createRandomHibpListing(),
      createRandomHibpListing(),
    ]}
    breachedEmailAddress="example@example.com" />;
Lots of breaches found story ok
const SignupReportEmailManyBreachesStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <SignupReportEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    breaches={Array.from({ length: 42 }, () => createRandomHibpListing())}
    breachedEmailAddress="example@example.com" />;

(props: Props) => ( <StorybookEmailRenderer plainTextVersion={null}> <VerifyEmailAddressEmail {...props} /> </StorybookEmailRenderer> )

emails-verify-email-address · ./src/emails/templates/verifyEmailAddress/VerifyEmailAddressEmail.stories.tsx
Prop type error
No component file found for the "(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <VerifyEmailAddressEmail {...props} />
  </StorybookEmailRenderer>
)" component.
  10 | import { getL10n } from "../../../app/functions/l10n/storybookAndTests";
  11 |
> 12 | const meta: Meta<FC<Props>> = {
     | ^
  13 |   title: "Emails/Verify email address",
  14 |   component: (props: Props) => (
  15 |     <StorybookEmailRenderer plainTextVersion={null}>

./src/emails/templates/verifyEmailAddress/VerifyEmailAddressEmail.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { FC } from "react";
import { Props, VerifyEmailAddressEmail } from "./VerifyEmailAddressEmail";
import { StorybookEmailRenderer } from "../../StorybookEmailRenderer";
import { SanitizedSubscriberRow } from "../../../app/functions/server/sanitize";
import { getL10n } from "../../../app/functions/l10n/storybookAndTests";

const meta: Meta<FC<Props>> = {
  title: "Emails/Verify email address",
  component: (props: Props) => (
    <StorybookEmailRenderer plainTextVersion={null}>
      <VerifyEmailAddressEmail {...props} />
    </StorybookEmailRenderer>
  ),
  args: {
    l10n: getL10n("en"),
    subscriber: {
      signup_language: "en",
    } as SanitizedSubscriberRow,
    verificationUrl: "https://example.com",
  },
};

export default meta;
type Story = StoryObj<FC<Props>>;

export const VerifyEmailAddressEmailStory: Story = {
  name: "Verify email address",
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { StorybookEmailRenderer, VerifyEmailAddressEmail } from "@mozilla/monitor";
Verify email address story ok
const VerifyEmailAddressEmailStory = () => <(props: Props) => (
  <StorybookEmailRenderer plainTextVersion={null}>
    <VerifyEmailAddressEmail {...props} />
  </StorybookEmailRenderer>
)
    l10n={getL10n("en")}
    subscriber={{
      signup_language: "en",
    } as SanitizedSubscriberRow}
    verificationUrl="https://example.com" />;

(props: ViewProps) => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <BreachDetailsView {...props} /> </PublicShell> )

pages-public-breach-listing · ./src/app/[locale]/(redesign)/(public)/breach-details/[breachName]/BreachDetailView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachDetailsView {...props} />
  </PublicShell>
)" component.
  10 | import { defaultExperimentData } from "../../../../../../telemetry/generated/nimbus/experiments";
  11 |
> 12 | const meta: Meta<typeof BreachDetailsView> = {
     | ^
  13 |   title: "Pages/Public/Breach listing",
  14 |   component: (props: ViewProps) => (
  15 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/breach-details/[breachName]/BreachDetailView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { BreachDetailsView, Props as ViewProps } from "./BreachDetailView";
import { getL10n } from "../../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../../PublicShell";
import { createRandomHibpListing } from "../../../../../../apiMocks/mockData";
import { defaultExperimentData } from "../../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof BreachDetailsView> = {
  title: "Pages/Public/Breach listing",
  component: (props: ViewProps) => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <BreachDetailsView {...props} />
    </PublicShell>
  ),
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof BreachDetailsView>;

export const BreachDetailViewStory: Story = {
  name: "Breach listing",
  args: {
    breach: createRandomHibpListing(),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachDetailsView, PublicShell } from "@mozilla/monitor";
Breach listing story ok
const BreachDetailViewStory = () => <(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachDetailsView {...props} />
  </PublicShell>
) l10n={getL10n()} breach={createRandomHibpListing()} />;

(props: ViewProps) => ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <BreachIndexView {...props} /> </PublicShell> )

pages-public-breach-index · ./src/app/[locale]/(redesign)/(public)/breaches/BreachIndexView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachIndexView {...props} />
  </PublicShell>
)" component.
  11 | import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";
  12 |
> 13 | const meta: Meta<typeof BreachIndexView> = {
     | ^
  14 |   title: "Pages/Public/Breach index",
  15 |   component: (props: ViewProps) => (
  16 |     <PublicShell

./src/app/[locale]/(redesign)/(public)/breaches/BreachIndexView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { faker } from "@faker-js/faker";
import { BreachIndexView, Props as ViewProps } from "./BreachIndexView";
import { getL10n } from "../../../../functions/l10n/storybookAndTests";
import { PublicShell } from "../PublicShell";
import { createRandomHibpListing } from "../../../../../apiMocks/mockData";
import { defaultExperimentData } from "../../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof BreachIndexView> = {
  title: "Pages/Public/Breach index",
  component: (props: ViewProps) => (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <BreachIndexView {...props} />
    </PublicShell>
  ),
};

export default meta;
type Story = StoryObj<typeof BreachIndexView>;

export const BreachIndexViewStory: Story = {
  name: "Breach index",
  args: {
    allBreaches: faker.helpers.multiple(() => createRandomHibpListing(), {
      count: { min: 7, max: 200 },
    }),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BreachIndexView, PublicShell } from "@mozilla/monitor";
Breach index story ok
const BreachIndexViewStory = () => <(props: ViewProps) => (
  <PublicShell
    l10n={getL10n("en")}
    experimentData={defaultExperimentData["Features"]}
  >
    <BreachIndexView {...props} />
  </PublicShell>
)
    allBreaches={faker.helpers.multiple(() => createRandomHibpListing(), {
      count: { min: 7, max: 200 },
    })} />;

(props: ViewProps) => { const experimentData = props.experimentData ?? defaultExperimentData["Features"]; const enabledFeatureFlags = props.enabledFeatureFlags ?? []; return ( <PublicShell l10n={getL10n("en")} experimentData={defaultExperimentData["Features"]} > <View {...props} experimentData={experimentData} enabledFeatureFlags={enabledFeatureFlags} /> </PublicShell> ); }

pages-public-landing-page · ./src/app/[locale]/(redesign)/(public)/LandingView.stories.tsx
Prop type error
No component file found for the "(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
}" component.
   9 | import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments";
  10 |
> 11 | const meta: Meta<typeof View> = {
     | ^
  12 |   title: "Pages/Public/Landing page",
  13 |   component: (props: ViewProps) => {
  14 |     const experimentData =

./src/app/[locale]/(redesign)/(public)/LandingView.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { View, Props as ViewProps } from "./LandingView";
import { getL10n } from "../../../functions/l10n/storybookAndTests";
import { PublicShell } from "./PublicShell";
import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments";

const meta: Meta<typeof View> = {
  title: "Pages/Public/Landing page",
  component: (props: ViewProps) => {
    const experimentData =
      props.experimentData ?? defaultExperimentData["Features"];
    const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
    return (
      <PublicShell
        l10n={getL10n("en")}
        experimentData={defaultExperimentData["Features"]}
      >
        <View
          {...props}
          experimentData={experimentData}
          enabledFeatureFlags={enabledFeatureFlags}
        />
      </PublicShell>
    );
  },
  args: {
    l10n: getL10n(),
  },
};

export default meta;
type Story = StoryObj<typeof View>;

export const Landing: Story = {
  name: "Default",
};

export const LandingDe: Story = {
  name: "German",
  args: {
    countryCode: "de",
    l10n: getL10n("de"),
  },
};

export const LandingFr: Story = {
  name: "French",
  args: {
    countryCode: "fr",
    l10n: getL10n("fr"),
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { PublicShell, View } from "@mozilla/monitor";
Default story ok
const Landing = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n()} />;
German story ok
const LandingDe = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n("de")} countryCode="de" />;
French story ok
const LandingFr = () => <(props: ViewProps) => {
  const experimentData =
    props.experimentData ?? defaultExperimentData["Features"];
  const enabledFeatureFlags = props.enabledFeatureFlags ?? [];
  return (
    <PublicShell
      l10n={getL10n("en")}
      experimentData={defaultExperimentData["Features"]}
    >
      <View
        {...props}
        experimentData={experimentData}
        enabledFeatureFlags={enabledFeatureFlags}
      />
    </PublicShell>
  );
} l10n={getL10n("fr")} countryCode="fr" />;

DashboardWrapper

pages-logged-in-dashboard · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx
Prop type error
No component file found for the "DashboardWrapper" component.
  161 | };
  162 |
> 163 | const meta: Meta<typeof DashboardWrapper> = {
      | ^
  164 |   title: "Pages/Logged in/Dashboard",
  165 |   component: DashboardWrapper,
  166 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { View as DashboardEl, TabType } from "./View";
import { Shell } from "../../../../Shell/Shell";
import { getL10n } from "../../../../../../functions/l10n/storybookAndTests";
import {
  createRandomBreach,
  createRandomAnnouncement,
  createRandomUser,
} from "../../../../../../../apiMocks/mockData";
import { SubscriberBreach } from "../../../../../../../utils/subscriberBreaches";
import { CountryCodeProvider } from "../../../../../../../contextProviders/country-code";
import { SessionProvider } from "../../../../../../../contextProviders/session";
import { FeatureFlagName } from "../../../../../../../db/tables/featureFlags";
import { UserAnnouncementWithDetails } from "../../../../../../../db/tables/user_announcements";

// Exported values should be stories, but this was already there when
// Storybook added this lint rule, so I guess it works?

const breachOptions = {
  empty: "No data breaches",
  unresolved: "With unresolved data breaches",
  resolved: "All data breaches resolved",
  invalid: "Invalid state (error case)",
};

export type DashboardWrapperProps = (
  | {
      countryCode: "us";
      premium: boolean;
    }
  | {
      countryCode: "nl";
    }
) & {
  breaches: keyof typeof breachOptions;
  elapsedTimeInDaysSinceInitialScan?: number;
  activeTab?: TabType;
  enabledFeatureFlags?: FeatureFlagName[];
  signInCount?: number;
};
const DashboardWrapper = (props: DashboardWrapperProps) => {
  const mockedResolvedBreach: SubscriberBreach = createRandomBreach({
    dataClasses: [
      "email-addresses",
      "ip-addresses",
      "phone-numbers",
      "passwords",
      "pins",
      "social-security-numbers",
      "partial-credit-card-data",
      "security-questions-and-answers",
    ],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
      { passwords: 1 },
    ],
    isResolved: true,
  });

  const mockedUnresolvedBreach: SubscriberBreach = createRandomBreach({
    dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      {
        "email-addresses": [
          "email1@gmail.com",
          "email2@gmail.com",
          "email3@gmail.com",
        ],
      },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
    ],
    isResolved: false,
  });

  const mockedUnresolvedBreach2: SubscriberBreach = createRandomBreach({
    dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"],
    addedDate: new Date("2023-06-18T14:48:00.000Z"),
    dataClassesEffected: [
      {
        "email-addresses": [
          "email1@gmail.com",
          "email2@gmail.com",
          "email3@gmail.com",
        ],
      },
      { "ip-addresses": 1 },
      { "phone-numbers": 1 },
    ],
    isResolved: false,
  });

  let breaches: SubscriberBreach[] = [];

  if (props.breaches === "resolved") {
    breaches = [mockedResolvedBreach];
  }
  if (props.breaches === "unresolved") {
    breaches = [
      mockedResolvedBreach,
      mockedUnresolvedBreach,
      mockedUnresolvedBreach2,
    ];
  }

  if (props.breaches === "invalid") {
    // Invalid state since it does not have data classes effected
    breaches = [createRandomBreach({ isResolved: false })];
  }

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];

  const user = createRandomUser();

  if ((props.countryCode !== "us" || !props.premium) && user.fxa) {
    user.fxa.subscriptions = [];
  }

  const mockedSession = {
    expires: new Date().toISOString(),
    user: user,
  };

  return (
    <SessionProvider session={mockedSession}>
      <CountryCodeProvider countryCode={props.countryCode}>
        <Shell
          l10n={getL10n()}
          session={mockedSession}
          nonce=""
          countryCode={props.countryCode}
          enabledFeatureFlags={props.enabledFeatureFlags ?? []}
          announcements={mockedAnnouncements}
        >
          <DashboardEl
            user={user}
            userBreaches={breaches}
            fxaSettingsUrl=""
            enabledFeatureFlags={props.enabledFeatureFlags ?? []}
            activeTab={props.activeTab ?? "action-needed"}
            signInCount={props.signInCount ?? null}
            userAnnouncements={mockedAnnouncements}
            countryCode={props.countryCode}
          />
        </Shell>
      </CountryCodeProvider>
    </SessionProvider>
  );
};

const meta: Meta<typeof DashboardWrapper> = {
  title: "Pages/Logged in/Dashboard",
  component: DashboardWrapper,
  argTypes: {
    breaches: {
      options: Object.keys(breachOptions),
      control: {
        type: "radio",
        labels: breachOptions,
      },
    },
    elapsedTimeInDaysSinceInitialScan: {
      name: "Days since initial scan",
      control: {
        type: "number",
      },
    },
    signInCount: {
      name: "Sign-in count",
      control: {
        type: "number",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof DashboardWrapper>;

export const DashboardNonUsNoBreaches: Story = {
  name: "No breaches",
  args: {
    breaches: "empty",
  },
};

export const DashboardNonUsUnresolvedBreaches: Story = {
  name: "Some breaches unresolved",
  args: {
    breaches: "unresolved",
  },
};

export const DashboardNonUsResolvedBreaches: Story = {
  name: "All breaches resolved",
  args: {
    breaches: "resolved",
  },
};

export const DashboardInvalidState: Story = {
  name: "Invalid state",
  args: {
    breaches: "invalid",
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
No breaches story error
Could not generate snippet without component name.
Some breaches unresolved story error
Could not generate snippet without component name.
All breaches resolved story error
Could not generate snippet without component name.
Invalid state story error
Could not generate snippet without component name.
Imports
import { CountryCodeProvider, View as DashboardEl, SessionProvider, Shell } from "@mozilla/monitor";

HighRiskBreachWrapper

pages-logged-in-guided-resolution-1-high-risk-data-breaches · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx
Prop type error
No component file found for the "HighRiskBreachWrapper" component.
  101 | };
  102 |
> 103 | const meta: Meta<typeof HighRiskBreachWrapper> = {
      | ^
  104 |   title: "Pages/Logged in/Guided resolution/1. High-risk data breaches",
  105 |   component: HighRiskBreachWrapper,
  106 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { HighRiskBreachLayout } from "../HighRiskBreachLayout";
import {
  HighRiskBreachTypes,
  highRiskBreachTypes,
} from "../highRiskBreachData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { StepDeterminationData } from "../../../../../../../../../functions/server/getRelevantGuidedSteps";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const HighRiskBreachWrapper = (props: {
  type: HighRiskBreachTypes;
  nextUnresolvedBreachType?: keyof typeof BreachDataTypes | "None";
}) => {
  const hasNextUnresolvedBreach = props.nextUnresolvedBreachType !== null;
  const mockedBreaches = [...Array(5)].map(() =>
    createRandomBreach({
      isResolved: hasNextUnresolvedBreach,
    }),
  );

  // Ensure all high-risk data breaches are present in at least one breach:
  mockedBreaches.push(
    createRandomBreach({
      dataClassesEffected: [
        {
          [BreachDataTypes.SSN]: 42,
          [BreachDataTypes.CreditCard]: 42,
          [BreachDataTypes.BankAccount]: 42,
          [BreachDataTypes.PIN]: 42,
        },
      ],
      isResolved: false,
    }),
  );

  // Adds a breach with an unresolved breach type
  if (
    props.nextUnresolvedBreachType &&
    props.nextUnresolvedBreachType !== "None"
  ) {
    mockedBreaches.push(
      createRandomBreach({
        dataClassesEffected: [
          {
            [BreachDataTypes[props.nextUnresolvedBreachType]]: 42,
          },
        ],
        isResolved: false,
      }),
    );
  }

  const data: StepDeterminationData = {
    countryCode: "nl",
    subscriberBreaches: mockedBreaches,
    user: mockedSession.user,
  };

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];

  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode={data.countryCode}
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <HighRiskBreachLayout
        subscriberEmails={[]}
        type={props.type}
        data={data}
        enabledFeatureFlags={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof HighRiskBreachWrapper> = {
  title: "Pages/Logged in/Guided resolution/1. High-risk data breaches",
  component: HighRiskBreachWrapper,
  argTypes: {
    type: {
      options: highRiskBreachTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
    nextUnresolvedBreachType: {
      description: "Next unresolved breach type",
      options: [
        "None",
        "Passwords",
        "SecurityQuestions",
        "Phone",
        "Email",
        "IP",
      ],
      control: {
        type: "radio",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof HighRiskBreachWrapper>;

export const SsnStory: Story = {
  name: "1a. Social Security Number",
  args: {
    type: "social-security-number",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/social-security-number",
      },
    },
  },
};

export const CreditCardStory: Story = {
  name: "1b. Credit card",
  args: {
    type: "credit-card",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/credit-card",
      },
    },
  },
};

export const BankAccountStory: Story = {
  name: "1c. Bank account",
  args: {
    type: "bank-account",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/bank-account",
      },
    },
  },
};

export const PinStory: Story = {
  name: "1d. PIN",
  args: {
    type: "pin",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/pin",
      },
    },
  },
};

export const HighRiskBreachDoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "done",
    nextUnresolvedBreachType: "None",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/high-risk-data-breaches/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
1a. Social Security Number story error
Could not generate snippet without component name.
1b. Credit card story error
Could not generate snippet without component name.
1c. Bank account story error
Could not generate snippet without component name.
1d. PIN story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { HighRiskBreachLayout, Shell } from "@mozilla/monitor";

LeakedPasswordsWrapper

pages-logged-in-guided-resolution-2-leaked-passwords · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx
Prop type error
No component file found for the "LeakedPasswordsWrapper" component.
   95 | };
   96 |
>  97 | const meta: Meta<typeof LeakedPasswordsWrapper> = {
      | ^
   98 |   title: "Pages/Logged in/Guided resolution/2. Leaked passwords",
   99 |   component: LeakedPasswordsWrapper,
  100 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { LeakedPasswordsLayout } from "../LeakedPasswordsLayout";
import {
  LeakedPasswordsTypes,
  leakedPasswordTypes,
} from "../leakedPasswordsData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const LeakedPasswordsWrapper = (props: {
  type: LeakedPasswordsTypes;
  nextUnresolvedBreachType?: keyof typeof BreachDataTypes | "None";
}) => {
  const mockedBreaches = [...Array(5)].map(() =>
    createRandomBreach({
      isResolved: props.nextUnresolvedBreachType !== null,
    }),
  );

  // Ensure all leaked passwords data breaches are present in at least one breach:
  mockedBreaches.push(
    createRandomBreach({
      dataClassesEffected: [
        {
          [BreachDataTypes.Passwords]: 42,
          [BreachDataTypes.SecurityQuestions]: 42,
        },
      ],
      isResolved: false,
    }),
  );

  // Adds a breach with an unresolved breach type
  if (
    props.nextUnresolvedBreachType &&
    props.nextUnresolvedBreachType !== "None"
  ) {
    mockedBreaches.push(
      createRandomBreach({
        dataClassesEffected: [
          {
            [BreachDataTypes[props.nextUnresolvedBreachType]]: 42,
          },
        ],
        isResolved: false,
      }),
    );
  }

  const mockedAnnouncements: UserAnnouncementWithDetails[] = [
    createRandomAnnouncement(),
    createRandomAnnouncement(),
    createRandomAnnouncement(),
  ];
  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode="nl"
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <LeakedPasswordsLayout
        subscriberEmails={[]}
        type={props.type}
        data={{
          countryCode: "nl",
          subscriberBreaches: mockedBreaches,
          user: mockedSession.user,
        }}
        enabledFeatureFlags={[]}
        blockdHibpBreachDomains={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof LeakedPasswordsWrapper> = {
  title: "Pages/Logged in/Guided resolution/2. Leaked passwords",
  component: LeakedPasswordsWrapper,
  argTypes: {
    type: {
      options: leakedPasswordTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
    nextUnresolvedBreachType: {
      description: "Next unresolved breach type",
      options: ["None", "SecurityQuestions", "Phone", "Email", "IP"],
      control: {
        type: "radio",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof LeakedPasswordsWrapper>;

export const PasswordsStory: Story = {
  name: "2a. Passwords",
  args: {
    type: "passwords",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/passwords",
      },
    },
  },
};

export const SecurityQuestionsStory: Story = {
  name: "2b. Security questions",
  args: {
    type: "security-questions",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/security-questions",
      },
    },
  },
};

export const LeakedPasswordsDoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "passwords-done",
    nextUnresolvedBreachType: "None",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/leaked-passwords/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
2a. Passwords story error
Could not generate snippet without component name.
2b. Security questions story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { LeakedPasswordsLayout, Shell } from "@mozilla/monitor";

ModalDialog

design-systems-molecules-modal-dialog · ./src/app/components/client/stories/ModalDialog.stories.tsx
Prop type error
No component file found for the "ModalDialog" component.
  78 |
  79 | // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
> 80 | const meta: Meta<typeof ModalDialog> = {
     | ^
  81 |   title: "Design Systems/Molecules/Modal dialog",
  82 |   component: ModalDialog,
  83 |   argTypes: {

./src/app/components/client/stories/ModalDialog.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";

import { useOverlayTriggerState } from "react-stately";
import { useOverlayTrigger } from "react-aria";
import Image from "next/image";
import Illustration from "../assets/modal-default-img.svg";
import { ModalOverlay } from "../dialog/ModalOverlay";
import { Dialog } from "../dialog/Dialog";
import { Button } from "../Button";

export type ModalDialogProps = {
  withDialog?: boolean;
  withTitle?: boolean;
  withIllustration?: boolean;
};

const ModalDialog = (props: ModalDialogProps) => {
  const modalState = useOverlayTriggerState({ defaultOpen: true });
  const modalTrigger = useOverlayTrigger({ type: "dialog" }, modalState);
  return (
    <>
      <Button {...modalTrigger.triggerProps} variant="primary">
        Open modal {props.withDialog && " dialog"}
      </Button>
      {modalState.isOpen && (
        <ModalOverlay
          state={modalState}
          {...modalTrigger.overlayProps}
          isDismissable={true}
        >
          {props.withDialog ? (
            <Dialog
              title={props.withTitle ? "Here's a dialog for you" : undefined}
              illustration={
                props.withIllustration ? (
                  <Image src={Illustration} alt="" />
                ) : undefined
              }
              onDismiss={() => modalState.close()}
            >
              <p>Some dialog content.</p>
            </Dialog>
          ) : (
            <>
              <div
                style={{
                  display: "flex",
                  flexDirection: "column",
                  alignItems: "flex-start",
                  gap: 16,
                }}
              >
                <p>
                  This is modal content; note that it&apos;s not possible to
                  interact with the content behind the modal overlay.
                  Here&apos;s a button to close the modal: &nbsp;
                </p>
                <Button variant="primary" onPress={() => modalState.close()}>
                  Close modal
                </Button>
                <p>
                  Note that modal overlays aren&apos;t usually used on their
                  own. This is merely an example to help clarify the boundaries
                  between the Modal and Dialog components.
                </p>
              </div>
            </>
          )}
        </ModalOverlay>
      )}
    </>
  );
};

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof ModalDialog> = {
  title: "Design Systems/Molecules/Modal dialog",
  component: ModalDialog,
  argTypes: {
    withDialog: {
      control: "boolean",
      name: "With dialog",
    },
    withTitle: {
      control: "boolean",
      name: "With title",
    },
    withIllustration: {
      control: "boolean",
      name: "With illustration",
    },
  },
};
export default meta;
type Story = StoryObj<typeof ModalDialog>;

export const Modal: Story = {
  name: "Modal without a dialog",
  args: {},
};

export const ModalWithDialog: Story = {
  name: "Modal dialog",
  args: {
    withDialog: true,
  },
};

export const ModalDialogWithTitle: Story = {
  name: "With title",
  args: {
    withDialog: true,
    withTitle: true,
  },
};

export const ModalDialogWithIllustration: Story = {
  name: "With title and illustration",
  args: {
    withDialog: true,
    withTitle: true,
    withIllustration: true,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Modal without a dialog story error
Could not generate snippet without component name.
Modal dialog story error
Could not generate snippet without component name.
With title story error
Could not generate snippet without component name.
With title and illustration story error
Could not generate snippet without component name.
Imports
import { Button, Dialog, ModalOverlay } from "@mozilla/monitor";
import Image from "next/image";

MonitorLogo

layout-navigation-monitor-logo · ./src/app/[locale]/(redesign)/Shell/MonitorLogo.stories.ts
Prop type error
No component file found for the "MonitorLogo" component.
   6 | import { MonitorLogo } from "./MonitorLogo";
   7 |
>  8 | const meta: Meta<typeof MonitorLogo> = {
     | ^
   9 |   title: "Layout/Navigation/Monitor Logo",
  10 |   component: MonitorLogo,
  11 | };

./src/app/[locale]/(redesign)/Shell/MonitorLogo.stories.ts:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { MonitorLogo } from "./MonitorLogo";

const meta: Meta<typeof MonitorLogo> = {
  title: "Layout/Navigation/Monitor Logo",
  component: MonitorLogo,
};

export default meta;
type Story = StoryObj<typeof MonitorLogo>;

export const MonitorLogoFixFlow: Story = {
  args: {},
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/en/fix/leaked-passwords/passwords",
      },
    },
  },
};

export const MonitorLogoActionNeeded: Story = {
  args: {},
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fy-NL/action-needed",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { MonitorLogo } from "@mozilla/monitor";
Monitor Logo Fix Flow story ok
const MonitorLogoFixFlow = () => <MonitorLogo />;
Monitor Logo Action Needed story ok
const MonitorLogoActionNeeded = () => <MonitorLogo />;

PopoverStory

design-systems-atoms-popover · ./src/app/components/client/stories/Popover.stories.tsx
Prop type error
No component file found for the "PopoverStory" component.
  38 | };
  39 |
> 40 | const meta: Meta<typeof PopoverStory> = {
     | ^
  41 |   title: "Design Systems/Atoms/Popover",
  42 |   component: PopoverStory,
  43 |   argTypes: {

./src/app/components/client/stories/Popover.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import { useRef } from "react";
import { useOverlayTriggerState } from "react-stately";
import { Popover } from "../Popover";

export type PopoverStoryProps = {
  defaultOpen?: boolean;
};

const PopoverStory = ({ defaultOpen = true }: PopoverStoryProps) => {
  const triggerRef = useRef<HTMLButtonElement>(null);
  const popoverRef = useRef<HTMLDivElement>(null);
  const state = useOverlayTriggerState({ defaultOpen });

  return (
    <>
      <button ref={triggerRef} onClick={() => state.toggle()}>
        Toggle popover
      </button>
      {state.isOpen && (
        <Popover
          triggerRef={triggerRef}
          popoverRef={popoverRef}
          state={state}
          offset={8}
        >
          <div ref={popoverRef} style={{ padding: "1rem" }}>
            Popover content
          </div>
        </Popover>
      )}
    </>
  );
};

const meta: Meta<typeof PopoverStory> = {
  title: "Design Systems/Atoms/Popover",
  component: PopoverStory,
  argTypes: {
    defaultOpen: {
      control: "boolean",
      name: "Default open",
    },
  },
};
export default meta;
type Story = StoryObj<typeof PopoverStory>;

export const PopoverDefault: Story = {
  name: "Open popover",
  args: {
    defaultOpen: true,
  },
};

export const PopoverClosed: Story = {
  name: "Closed popover",
  args: {
    defaultOpen: false,
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
Open popover story error
Could not generate snippet without component name.
Closed popover story error
Could not generate snippet without component name.
Imports
import { Popover } from "@mozilla/monitor";

SecurityRecommendationsWrapper

pages-logged-in-guided-resolution-3-security-recommendations · ./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/[type]/SecurityRecommendations.stories.tsx
Prop type error
No component file found for the "SecurityRecommendationsWrapper" component.
  73 | };
  74 |
> 75 | const meta: Meta<typeof SecurityRecommendationsWrapper> = {
     | ^
  76 |   title: "Pages/Logged in/Guided resolution/3. Security recommendations",
  77 |   component: SecurityRecommendationsWrapper,
  78 |   argTypes: {

./src/app/[locale]/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/[type]/SecurityRecommendations.stories.tsx:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from "@storybook/nextjs";
import {
  createRandomAnnouncement,
  createRandomBreach,
  createRandomUser,
} from "../../../../../../../../../../apiMocks/mockData";
import { Shell } from "../../../../../../../Shell/Shell";
import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndTests";
import { SecurityRecommendationsLayout } from "../SecurityRecommendationsLayout";
import {
  SecurityRecommendationTypes,
  securityRecommendationTypes,
} from "../securityRecommendationsData";
import { BreachDataTypes } from "../../../../../../../../../functions/universal/breach";
import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements";

const mockedBreaches = [...Array(5)].map(() => createRandomBreach());
// Ensure all security recommendation data breaches are present in at least one breach:
mockedBreaches.push(
  createRandomBreach({
    dataClassesEffected: [
      {
        [BreachDataTypes.Phone]: 42,
        [BreachDataTypes.Email]: 42,
        [BreachDataTypes.IP]: 42,
      },
    ],
    isResolved: false,
  }),
);

const user = createRandomUser();

const mockedSession = {
  expires: new Date().toISOString(),
  user: user,
};

const mockedAnnouncements: UserAnnouncementWithDetails[] = [
  createRandomAnnouncement(),
  createRandomAnnouncement(),
  createRandomAnnouncement(),
];

const SecurityRecommendationsWrapper = (props: {
  type: SecurityRecommendationTypes;
}) => {
  return (
    <Shell
      l10n={getL10n()}
      session={mockedSession}
      nonce=""
      countryCode="nl"
      enabledFeatureFlags={[]}
      announcements={mockedAnnouncements}
    >
      <SecurityRecommendationsLayout
        subscriberEmails={[]}
        type={props.type}
        data={{
          countryCode: "nl",
          subscriberBreaches: mockedBreaches,
          user: mockedSession.user,
        }}
        enabledFeatureFlags={[]}
      />
    </Shell>
  );
};

const meta: Meta<typeof SecurityRecommendationsWrapper> = {
  title: "Pages/Logged in/Guided resolution/3. Security recommendations",
  component: SecurityRecommendationsWrapper,
  argTypes: {
    type: {
      options: securityRecommendationTypes,
      description: "Breach category",
      control: {
        type: "select",
      },
    },
  },
};
export default meta;
type Story = StoryObj<typeof SecurityRecommendationsWrapper>;

export const PhoneStory: Story = {
  name: "3a. Phone number",
  args: {
    type: "phone",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/phone",
      },
    },
  },
};

export const EmailStory: Story = {
  name: "3b. Email address",
  args: {
    type: "email",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/email",
      },
    },
  },
};

export const IpStory: Story = {
  name: "3c. IP address",
  args: {
    type: "ip",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/ip",
      },
    },
  },
};

export const DoneStory: Story = {
  name: "Completed Step",
  args: {
    type: "done",
  },
  parameters: {
    nextjs: {
      navigation: {
        pathname: "/fix/security-recommendations/done",
      },
    },
  },
};
Info
No description found. Write a jsdoc comment such as /** Component description */.
3a. Phone number story error
Could not generate snippet without component name.
3b. Email address story error
Could not generate snippet without component name.
3c. IP address story error
Could not generate snippet without component name.
Completed Step story error
Could not generate snippet without component name.
Imports
import { SecurityRecommendationsLayout, Shell } from "@mozilla/monitor";