ui-auth/dist/AuthModal.js
autocommit 55daa6ed6a chore: initial package split from monorepo
Package: @lilith/ui-auth
Split from: lilith/ui.git or lilith/build.git
Publish workflow: calls lilith/workflows/.forgejo/workflows/publish-npm.yml@main
2026-04-20 01:10:50 -07:00

88 lines
No EOL
4.1 KiB
JavaScript

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* AuthModal Component
*
* Modal wrapper for LoginForm and RegisterForm with tab switching.
* Provides a complete embedded auth experience without popups.
*
* Supports two integration modes:
* 1. Direct SSO: Provide ssoUrl, forms make fetch calls directly
* 2. Provider-based: Provide authHandler, integrates with @lilith/auth-provider
*/
import { useState, useCallback, useEffect } from 'react';
import styled from '@lilith/ui-styled-components';
import { Modal } from '@lilith/ui-feedback';
import { LoginForm } from './LoginForm';
import { RegisterForm } from './RegisterForm';
const ModalContent = styled.div `
padding: ${(props) => props.theme.spacing.md};
`;
const TabContainer = styled.div `
display: flex;
margin-bottom: ${(props) => props.theme.spacing.xl};
border-bottom: 2px solid ${(props) => props.theme.colors.border.default};
`;
const Tab = styled.button `
flex: 1;
padding: ${(props) => props.theme.spacing.md} ${(props) => props.theme.spacing.lg};
background: transparent;
border: none;
color: ${(props) => props.$active
? props.theme.colors.primary.main
: props.theme.colors.text.muted};
font-size: ${(props) => props.theme.typography.fontSize.base};
font-weight: ${(props) => props.$active
? props.theme.typography.fontWeight.semibold
: props.theme.typography.fontWeight.medium};
cursor: pointer;
position: relative;
transition: color ${(props) => props.theme.transitions.normal};
&:hover {
color: ${(props) => props.theme.colors.primary.main};
}
&::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
right: 0;
height: 2px;
background: ${(props) => props.$active ? props.theme.colors.primary.main : 'transparent'};
transition: background ${(props) => props.theme.transitions.normal};
}
`;
const FormContainer = styled.div `
min-height: 400px;
`;
export const AuthModal = ({ isOpen, onClose, ssoUrl, authHandler, onSuccess, onError, initialMode = 'login', defaultRole, hideRoleSelector = false, onMfaRequired, maxWidth = '420px', }) => {
const [mode, setMode] = useState(initialMode);
// Reset mode when modal opens/closes or initialMode changes
useEffect(() => {
if (isOpen) {
setMode(initialMode);
}
}, [isOpen, initialMode]);
const handleSuccess = useCallback((user, sessionId) => {
onSuccess(user, sessionId);
onClose();
}, [onSuccess, onClose]);
const handleSwitchToLogin = useCallback(() => {
setMode('login');
}, []);
const handleSwitchToRegister = useCallback(() => {
setMode('register');
}, []);
const handleForgotPassword = useCallback(() => {
// Open forgot password in new tab (SSO handles this)
// Only available in direct SSO mode
if (ssoUrl) {
window.open(`${ssoUrl}/forgot-password`, '_blank', 'noopener,noreferrer');
}
}, [ssoUrl]);
const modalTitle = mode === 'login' ? 'Welcome Back' : 'Join Us';
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: modalTitle, maxWidth: maxWidth, children: _jsxs(ModalContent, { children: [_jsxs(TabContainer, { children: [_jsx(Tab, { "$active": mode === 'login', onClick: handleSwitchToLogin, "aria-selected": mode === 'login', role: "tab", children: "Sign In" }), _jsx(Tab, { "$active": mode === 'register', onClick: handleSwitchToRegister, "aria-selected": mode === 'register', role: "tab", children: "Create Account" })] }), _jsx(FormContainer, { children: mode === 'login' ? (_jsx(LoginForm, { ssoUrl: ssoUrl, authHandler: authHandler, onSuccess: handleSuccess, onError: onError, onMfaRequired: onMfaRequired, onSwitchToRegister: handleSwitchToRegister, onForgotPassword: ssoUrl ? handleForgotPassword : undefined, showTitle: false })) : (_jsx(RegisterForm, { ssoUrl: ssoUrl, authHandler: authHandler, onSuccess: handleSuccess, onError: onError, onSwitchToLogin: handleSwitchToLogin, defaultRole: defaultRole, hideRoleSelector: hideRoleSelector, showTitle: false })) })] }) }));
};
AuthModal.displayName = 'AuthModal';
//# sourceMappingURL=AuthModal.js.map