Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 4 additions & 20 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,19 @@ export default defineConfig({
],
framework: '@storybook/nextjs-vite',
staticDirs: ['../src/assets'],
// Inject base tag for manager (navigation/toolbar) when deploying to /_storybook/
managerHead:
process.env.CHROMATIC !== 'true'
? (head) => `
${head}
<base href="/_storybook/" />
`
: undefined,
// Inject base tag for preview (iframe where components render) when deploying to /_storybook/
previewHead:
process.env.CHROMATIC !== 'true'
? (head) => `
${head}
<base href="/_storybook/" />
`
: undefined,
viteFinal: async (c, { configType }) => {
// Dynamically import the plugin to avoid build issues
if (!createMockResolverPlugin) {
const mockPlugin = await import('./mockResolverPlugin.js')
createMockResolverPlugin = mockPlugin.createMockResolverPlugin
}

const isProduction = configType === 'PRODUCTION'
const isChromatic = process.env.CHROMATIC === 'true'

return mergeConfig(c, {
// Only set custom base path for production builds (not for Chromatic)
base:
configType === 'PRODUCTION' && process.env.CHROMATIC !== 'true'
? '/_storybook/'
: c.base,
base: isProduction && !isChromatic ? '/_storybook/' : c.base,
server: {
allowedHosts: true,
hmr: { clientPort: 443 },
Expand Down
91 changes: 91 additions & 0 deletions components/AuthUI/AuthUI.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Meta, StoryObj } from '@storybook/nextjs-vite'
import { HttpResponse, http } from 'msw'
import AuthUI from '@/components/AuthUI/AuthUI'
import { User } from '@/src/api/generated'
import {
mockFirebaseUser,
useFirebaseUser,
} from '@/src/hooks/useFirebaseUser.mock'
import { CAPI } from '@/src/mocks/apibase'
import { handlers } from '@/src/mocks/handlers'

const meta = {
title: 'Components/AuthUI/SignIn',
component: AuthUI,
parameters: {
layout: 'fullscreen',
backgrounds: { default: 'dark' },
msw: {
handlers: handlers,
},
},
decorators: [
(Story) => (
<div className="bg-gray-900 min-h-screen">
<Story />
</div>
),
],
} satisfies Meta<typeof AuthUI>

export default meta

type Story = StoryObj<typeof meta>

// Mock user data
const mockUser: User = {
id: 'user-123',
name: 'John Doe',
email: '[email protected]',
isAdmin: false,
isApproved: true,
}

export const Default: Story = {
parameters: {
msw: {
handlers: [
http.get(CAPI('/users'), () =>
HttpResponse.json(null, { status: 401 })
),
...handlers,
],
},
},
async beforeEach() {
// Mock Firebase user as logged out
useFirebaseUser.mockReturnValue([null, false, undefined])
},
}

export const Loading: Story = {
parameters: {
msw: {
handlers: [
http.get(CAPI('/users'), () =>
HttpResponse.json(null, { status: 401 })
),
...handlers,
],
},
},
async beforeEach() {
// Mock Firebase user as loading
useFirebaseUser.mockReturnValue([null, true, undefined])
},
}

export const AlreadyLoggedIn: Story = {
parameters: {
msw: {
handlers: [
http.get(CAPI('/users'), () => HttpResponse.json(mockUser)),
...handlers,
],
},
},
async beforeEach() {
// Mock Firebase user as logged in
useFirebaseUser.mockReturnValue([mockFirebaseUser, false, undefined])
},
}
74 changes: 74 additions & 0 deletions components/AuthUI/Logout.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Meta, StoryObj } from '@storybook/nextjs-vite'
import { HttpResponse, http } from 'msw'
import Logout from '@/components/AuthUI/Logout'
import { User } from '@/src/api/generated'
import {
mockFirebaseUser,
useFirebaseUser,
} from '@/src/hooks/useFirebaseUser.mock'
import { CAPI } from '@/src/mocks/apibase'
import { handlers } from '@/src/mocks/handlers'

const meta = {
title: 'Components/AuthUI/Logout',
component: Logout,
parameters: {
layout: 'fullscreen',
backgrounds: { default: 'dark' },
msw: {
handlers: handlers,
},
},
decorators: [
(Story) => (
<div className="bg-gray-900 min-h-screen">
<Story />
</div>
),
],
} satisfies Meta<typeof Logout>

export default meta

type Story = StoryObj<typeof meta>

// Mock user data
const mockUser: User = {
id: 'user-123',
name: 'John Doe',
email: '[email protected]',
isAdmin: false,
isApproved: true,
}

export const Default: Story = {
parameters: {
msw: {
handlers: [
http.get(CAPI('/users'), () => HttpResponse.json(mockUser)),
...handlers,
],
},
},
async beforeEach() {
// Mock Firebase user as logged in
useFirebaseUser.mockReturnValue([mockFirebaseUser, false, undefined])
},
}

export const LoggedOut: Story = {
parameters: {
msw: {
handlers: [
http.get(CAPI('/users'), () =>
HttpResponse.json(null, { status: 401 })
),
...handlers,
],
},
},
async beforeEach() {
// Mock Firebase user as logged out
useFirebaseUser.mockReturnValue([null, false, undefined])
},
}
20 changes: 20 additions & 0 deletions react-firebase-hooks/auth.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { vi } from 'vitest'

// Mock the Firebase auth hooks for Storybook
export const useSignInWithGoogle = vi.fn().mockName('useSignInWithGoogle')
export const useSignInWithGithub = vi.fn().mockName('useSignInWithGithub')
export const useSignOut = vi.fn().mockName('useSignOut')
export const useAuthState = vi.fn().mockName('useAuthState')

// Set default return values
useSignInWithGoogle.mockReturnValue([vi.fn(), undefined, false, undefined])
useSignInWithGithub.mockReturnValue([vi.fn(), undefined, false, undefined])
useSignOut.mockReturnValue([vi.fn(), false, undefined])
useAuthState.mockReturnValue([null, false, undefined])

console.log('mocking react-firebase-hooks/auth', {
useSignInWithGoogle,
useSignInWithGithub,
useSignOut,
useAuthState,
})
8 changes: 4 additions & 4 deletions src/hooks/useFirebaseUser.mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fn } from '@storybook/test'
import { User as FirebaseUser } from 'firebase/auth'
import { vi } from 'vitest'
import * as actual from './useFirebaseUser'

export * from './useFirebaseUser'
Expand All @@ -24,8 +25,7 @@ export const mockFirebaseUser = {
providerId: 'google',
} satisfies FirebaseUser // Using 'as any' to avoid having to mock the entire Firebase User interface

export const useFirebaseUser = fn(actual.useFirebaseUser)
export const useFirebaseUser = vi
.fn(actual.useFirebaseUser)
.mockName('useFirebaseUser')
.mockReturnValue([mockFirebaseUser, false, undefined])

import { User as FirebaseUser } from 'firebase/auth'
30 changes: 15 additions & 15 deletions src/stories/Configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Accessibility from './assets/accessibility.png'
import Theming from './assets/theming.png'
import AddonLibrary from './assets/addon-library.png'

export const RightArrow = () => (
export const RightArrow = (
<svg
viewBox="0 0 14 14"
width="8px"
Expand Down Expand Up @@ -57,7 +57,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/configure/styling-and-css/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-section-item">
<Image
Expand All @@ -72,7 +72,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/writing-stories/decorators/?renderer=react#context-for-mocking"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-section-item">
<Image
Expand All @@ -90,7 +90,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/configure/images-and-assets/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
</div>
</div>
Expand Down Expand Up @@ -119,7 +119,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/writing-docs/autodocs/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-grid-item">
<Image
Expand All @@ -134,7 +134,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/sharing/publish-storybook/?renderer=react#publish-storybook-with-chromatic"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-grid-item">
<Image
Expand All @@ -150,7 +150,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/sharing/design-integrations/?renderer=react#embed-storybook-in-figma-with-the-plugin"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-grid-item">
<Image
Expand All @@ -166,7 +166,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/writing-tests/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-grid-item">
<Image
Expand All @@ -181,7 +181,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/writing-tests/accessibility-testing/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
<div className="sb-grid-item">
<Image
Expand All @@ -196,7 +196,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/docs/configure/theming/?renderer=react"
target="_blank"
>Learn more<RightArrow /></a>
>Learn more{RightArrow}</a>
</div>
</div>
</div>
Expand All @@ -208,7 +208,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/addons/"
target="_blank"
>Discover all addons<RightArrow /></a>
>Discover all addons{RightArrow}</a>
</div>
<div className='sb-addon-img'>
<Image
Expand All @@ -235,7 +235,7 @@ export const RightArrow = () => (
<a
href="https://github.com/storybookjs/storybook"
target="_blank"
>Star on GitHub<RightArrow /></a>
>Star on GitHub{RightArrow}</a>
</div>
<div className="sb-section-item">
<Image
Expand All @@ -252,7 +252,7 @@ export const RightArrow = () => (
<a
href="https://discord.gg/storybook"
target="_blank"
>Join Discord server<RightArrow /></a>
>Join Discord server{RightArrow}</a>
</div>
</div>
<div className="sb-section-item">
Expand All @@ -270,7 +270,7 @@ export const RightArrow = () => (
<a
href="https://www.youtube.com/@chromaticui"
target="_blank"
>Watch on YouTube<RightArrow /></a>
>Watch on YouTube{RightArrow}</a>
</div>
</div>
<div className="sb-section-item">
Expand All @@ -287,7 +287,7 @@ export const RightArrow = () => (
<a
href="https://storybook.js.org/tutorials/"
target="_blank"
>Discover tutorials<RightArrow /></a>
>Discover tutorials{RightArrow}</a>
</div>

</div>
Expand Down