ui-auth/dist/AuthSplitPanel.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

198 lines
No EOL
6.8 KiB
JavaScript

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* AuthSplitPanel Component
*
* Split layout with info panel on left and auth form on right.
* Ideal for landing page CTAs and full-page auth experiences.
*/
import { useState, useCallback, useEffect } from 'react';
import { ZINDEX_LOCAL } from '@lilith/ui-zname';
import styled, { keyframes } from '@lilith/ui-styled-components';
import { getAuthTheme } from './themes';
// GlassCard available for future use if needed
import { InfoPanel } from './panels/InfoPanel';
import { LoginForm } from './LoginForm';
import { RegisterForm } from './RegisterForm';
const fadeIn = keyframes `
from {
opacity: 0;
}
to {
opacity: 1;
}
`;
const slideIn = keyframes `
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
`;
const PanelContainer = styled.div `
display: grid;
grid-template-columns: 1fr 1fr;
min-height: 600px;
max-height: 90vh;
width: 100%;
max-width: 1100px;
border-radius: 24px;
overflow: hidden;
background: ${({ $panelTheme }) => $panelTheme.overlayGradient};
box-shadow: ${({ $panelTheme }) => $panelTheme.neonGlow},
0 25px 50px -12px rgba(0, 0, 0, 0.5);
animation: ${fadeIn} 0.3s ease-out;
@media (max-width: 900px) {
grid-template-columns: 1fr;
max-width: 500px;
}
`;
const InfoSection = styled.div `
position: relative;
display: flex;
animation: ${slideIn} 0.4s ease-out;
@media (max-width: 900px) {
display: none;
}
`;
const FormSection = styled.div `
position: relative;
display: flex;
flex-direction: column;
padding: 40px;
background: rgba(10, 10, 15, 0.95);
animation: ${slideIn} 0.4s ease-out 0.1s backwards;
@media (max-width: 600px) {
padding: 24px;
}
`;
const CloseButton = styled.button `
position: absolute;
top: 16px;
right: 16px;
z-index: ${ZINDEX_LOCAL.sticky};
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.1);
border: 1px solid ${({ $panelTheme }) => $panelTheme.glassBorder};
border-radius: 50%;
color: rgba(255, 255, 255, 0.7);
cursor: pointer;
transition: all 0.2s ease;
&:hover {
background: ${({ $panelTheme }) => $panelTheme.primary}20;
border-color: ${({ $panelTheme }) => $panelTheme.primary};
color: ${({ $panelTheme }) => $panelTheme.primary};
transform: rotate(90deg);
}
svg {
width: 18px;
height: 18px;
}
`;
const FormHeader = styled.div `
margin-bottom: 32px;
`;
const FormTitle = styled.h2 `
font-size: 1.75rem;
font-weight: 700;
margin: 0 0 8px 0;
background: linear-gradient(
135deg,
#ffffff 0%,
${({ $panelTheme }) => $panelTheme.primary} 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
`;
const FormSubtitle = styled.p `
font-size: 0.9rem;
color: rgba(255, 255, 255, 0.6);
margin: 0;
`;
const TabContainer = styled.div.attrs({ role: 'tablist' }) `
display: flex;
margin-bottom: 24px;
border-bottom: 2px solid ${({ $panelTheme }) => $panelTheme.glassBorder};
`;
const Tab = styled.div.attrs({ role: 'tab' }) `
flex: 1;
padding: 12px 16px;
background: transparent;
border: none;
color: ${({ $active, $panelTheme }) => $active ? $panelTheme.primary : 'rgba(255, 255, 255, 0.5)'};
font-size: 0.95rem;
font-weight: ${({ $active }) => ($active ? 600 : 500)};
cursor: pointer;
position: relative;
transition: color 0.2s ease;
text-align: center;
&:hover {
color: ${({ $panelTheme }) => $panelTheme.primary};
}
&::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
right: 0;
height: 2px;
background: ${({ $active, $panelTheme }) => $active ? $panelTheme.primary : 'transparent'};
transition: background 0.2s ease;
}
`;
const FormWrapper = styled.div `
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
`;
const DefaultInfoContent = {
title: 'Welcome to Lilith',
subtitle: 'Join our community',
description: 'Create your account to access all features and connect with our global community.',
stats: [
{ value: '10K+', label: 'Members' },
{ value: '4.9', label: 'Rating', highlight: true },
],
benefits: [
'Instant access to all features',
'Connect with verified members',
'Secure and private',
'No hidden fees',
],
};
export function AuthSplitPanel({ mode: initialMode = 'register', theme = 'default', customTheme, infoPanel = DefaultInfoContent, authHandler, ssoUrl, defaultRole, showRoleSelector = true, onSuccess, onClose, onError, showCloseButton = true, allowModeSwitch = true, className, }) {
const [mode, setMode] = useState(initialMode);
const panelTheme = customTheme || getAuthTheme(theme);
// Sync internal mode with initialMode prop when it changes
useEffect(() => {
setMode(initialMode);
}, [initialMode]);
const handleModeSwitch = useCallback((newMode) => {
setMode(newMode);
}, []);
const handleSuccess = useCallback((user) => {
onSuccess?.(user);
}, [onSuccess]);
const handleError = useCallback((error) => {
onError?.(error);
}, [onError]);
return (_jsxs(PanelContainer, { "$panelTheme": panelTheme, className: className, children: [_jsx(InfoSection, { className: "InfoSection InfoPanel", children: _jsx(InfoPanel, { content: infoPanel, panelTheme: panelTheme }) }), _jsxs(FormSection, { "$panelTheme": panelTheme, children: [showCloseButton && onClose && (_jsx(CloseButton, { onClick: onClose, "$panelTheme": panelTheme, "aria-label": "close", children: '\u00D7' })), _jsxs(FormHeader, { children: [_jsx(FormTitle, { "$panelTheme": panelTheme, children: mode === 'login' ? 'Welcome Back' : 'Create Account' }), _jsx(FormSubtitle, { children: mode === 'login'
? 'Sign in to continue'
: 'Join us in just a few steps' })] }), allowModeSwitch && (_jsxs(TabContainer, { "$panelTheme": panelTheme, children: [_jsx(Tab, { "$active": mode === 'login', "$panelTheme": panelTheme, onClick: () => handleModeSwitch('login'), children: "Sign In" }), _jsx(Tab, { "$active": mode === 'register', "$panelTheme": panelTheme, onClick: () => handleModeSwitch('register'), children: "Create Account" })] })), _jsx(FormWrapper, { children: mode === 'login' ? (_jsx(LoginForm, { authHandler: authHandler, ssoUrl: ssoUrl, onSuccess: handleSuccess, onError: handleError, onSwitchToRegister: allowModeSwitch ? () => handleModeSwitch('register') : undefined })) : (_jsx(RegisterForm, { authHandler: authHandler, ssoUrl: ssoUrl, defaultRole: defaultRole, hideRoleSelector: !showRoleSelector, onSuccess: handleSuccess, onError: handleError, onSwitchToLogin: allowModeSwitch ? () => handleModeSwitch('login') : undefined })) })] })] }));
}
//# sourceMappingURL=AuthSplitPanel.js.map