feat: add LoginDialog modal wrapper component
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
54
src/design-system/composites/LoginForm/LoginDialog.test.tsx
Normal file
54
src/design-system/composites/LoginForm/LoginDialog.test.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { describe, it, expect, vi } from 'vitest'
|
||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import userEvent from '@testing-library/user-event'
|
||||||
|
import { LoginDialog } from './LoginDialog'
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
open: true,
|
||||||
|
onClose: vi.fn(),
|
||||||
|
onSubmit: vi.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('LoginDialog', () => {
|
||||||
|
it('renders Modal with LoginForm when open', () => {
|
||||||
|
render(<LoginDialog {...defaultProps} />)
|
||||||
|
expect(screen.getByRole('dialog')).toBeInTheDocument()
|
||||||
|
expect(screen.getByRole('heading', { name: 'Sign in' })).toBeInTheDocument()
|
||||||
|
expect(screen.getByLabelText(/email/i)).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not render when closed', () => {
|
||||||
|
render(<LoginDialog {...defaultProps} open={false} />)
|
||||||
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls onClose on Esc', async () => {
|
||||||
|
const onClose = vi.fn()
|
||||||
|
const user = userEvent.setup()
|
||||||
|
render(<LoginDialog {...defaultProps} onClose={onClose} />)
|
||||||
|
await user.keyboard('{Escape}')
|
||||||
|
expect(onClose).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls onClose on backdrop click', async () => {
|
||||||
|
const onClose = vi.fn()
|
||||||
|
const user = userEvent.setup()
|
||||||
|
render(<LoginDialog {...defaultProps} onClose={onClose} />)
|
||||||
|
await user.click(screen.getByTestId('modal-backdrop'))
|
||||||
|
expect(onClose).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('passes LoginForm props through', () => {
|
||||||
|
render(
|
||||||
|
<LoginDialog
|
||||||
|
{...defaultProps}
|
||||||
|
title="Welcome"
|
||||||
|
socialProviders={[{ label: 'Continue with Google', onClick: vi.fn() }]}
|
||||||
|
error="Bad credentials"
|
||||||
|
/>,
|
||||||
|
)
|
||||||
|
expect(screen.getByText('Welcome')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('Continue with Google')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('Bad credentials')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
15
src/design-system/composites/LoginForm/LoginDialog.tsx
Normal file
15
src/design-system/composites/LoginForm/LoginDialog.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Modal } from '../Modal/Modal'
|
||||||
|
import { LoginForm, type LoginFormProps } from './LoginForm'
|
||||||
|
|
||||||
|
export interface LoginDialogProps extends LoginFormProps {
|
||||||
|
open: boolean
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LoginDialog({ open, onClose, className, ...formProps }: LoginDialogProps) {
|
||||||
|
return (
|
||||||
|
<Modal open={open} onClose={onClose} size="sm" className={className}>
|
||||||
|
<LoginForm {...formProps} />
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user