@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 19.5 kB
Source Map (JSON)
{"version":3,"file":"modal.cjs","sources":["../../../../../src/components/ui/modal/modal.tsx"],"sourcesContent":["import { useTheme } from \"@/theme/context\";\nimport type { StyledProps } from \"@/theme/styled\";\nimport type { Theme } from \"@/theme/theme\";\nimport { css, keyframes } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport React, { useEffect, useRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport interface ModalProps extends React.HTMLAttributes<HTMLDivElement> {\n\t/** Modal open state */\n\tisOpen?: boolean;\n\t/** Close modal callback */\n\tonClose?: () => void;\n\t/** Modal size */\n\tsize?:\n\t\t| \"xs\"\n\t\t| \"sm\"\n\t\t| \"md\"\n\t\t| \"lg\"\n\t\t| \"xl\"\n\t\t| \"2xl\"\n\t\t| \"3xl\"\n\t\t| \"4xl\"\n\t\t| \"5xl\"\n\t\t| \"full\";\n\t/** Modal radius */\n\tradius?: \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\t/** Modal placement */\n\tplacement?:\n\t\t| \"auto\"\n\t\t| \"top\"\n\t\t| \"top-center\"\n\t\t| \"center\"\n\t\t| \"bottom\"\n\t\t| \"bottom-center\";\n\t/** Hide close button */\n\thideCloseButton?: boolean;\n\t/** Close on backdrop click */\n\tisDismissable?: boolean;\n\t/** Close on escape key */\n\tisKeyboardDismissDisabled?: boolean;\n\t/** Disable scroll lock */\n\tscrollBehavior?: \"inside\" | \"outside\" | \"normal\";\n\t/** Modal backdrop blur */\n\tbackdrop?: \"transparent\" | \"opaque\" | \"blur\";\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Custom styles */\n\tcss?: any;\n\t/** Portal container */\n\tportalContainer?: Element;\n}\n\ntype StyledModalProps = StyledProps<ModalProps>;\n\n// Animation keyframes\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n`;\n\nconst fadeOut = keyframes`\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n`;\n\nconst scaleIn = keyframes`\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n`;\n\nconst scaleOut = keyframes`\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n`;\n\nconst getModalSizeStyles = (props: StyledModalProps) => {\n\tconst { theme, size = \"md\" } = props;\n\n\tswitch (size) {\n\t\tcase \"xs\":\n\t\t\treturn css`\n max-width: 320px;\n width: 90vw;\n `;\n\t\tcase \"sm\":\n\t\t\treturn css`\n max-width: 400px;\n width: 90vw;\n `;\n\t\tcase \"md\":\n\t\t\treturn css`\n max-width: 512px;\n width: 90vw;\n `;\n\t\tcase \"lg\":\n\t\t\treturn css`\n max-width: 640px;\n width: 90vw;\n `;\n\t\tcase \"xl\":\n\t\t\treturn css`\n max-width: 768px;\n width: 90vw;\n `;\n\t\tcase \"2xl\":\n\t\t\treturn css`\n max-width: 896px;\n width: 90vw;\n `;\n\t\tcase \"3xl\":\n\t\t\treturn css`\n max-width: 1024px;\n width: 90vw;\n `;\n\t\tcase \"4xl\":\n\t\t\treturn css`\n max-width: 1152px;\n width: 90vw;\n `;\n\t\tcase \"5xl\":\n\t\t\treturn css`\n max-width: 1280px;\n width: 90vw;\n `;\n\t\tcase \"full\":\n\t\t\treturn css`\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n border-radius: 0;\n margin: 0;\n `;\n\t\tdefault:\n\t\t\treturn css`\n max-width: 512px;\n width: 90vw;\n `;\n\t}\n};\n\nconst getModalRadiusStyles = (props: StyledModalProps) => {\n\tconst { theme, radius = \"lg\", size } = props;\n\n\tif (size === \"full\") return css``;\n\n\tswitch (radius) {\n\t\tcase \"none\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.none};`;\n\t\tcase \"sm\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.sm};`;\n\t\tcase \"md\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.md};`;\n\t\tcase \"lg\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.lg};`;\n\t\tcase \"xl\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.xl};`;\n\t\tdefault:\n\t\t\treturn css`border-radius: ${theme.borderRadius.lg};`;\n\t}\n};\n\nconst getModalPlacementStyles = (props: StyledModalProps) => {\n\tconst { placement = \"center\", size } = props;\n\n\tif (size === \"full\") {\n\t\treturn css`\n justify-content: center;\n align-items: center;\n `;\n\t}\n\n\tswitch (placement) {\n\t\tcase \"top\":\n\t\t\treturn css`\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 3rem;\n `;\n\t\tcase \"top-center\":\n\t\t\treturn css`\n justify-content: center;\n align-items: flex-start;\n padding-top: 3rem;\n `;\n\t\tcase \"center\":\n\t\t\treturn css`\n justify-content: center;\n align-items: center;\n `;\n\t\tcase \"bottom\":\n\t\t\treturn css`\n justify-content: flex-start;\n align-items: flex-end;\n padding-bottom: 3rem;\n `;\n\t\tcase \"bottom-center\":\n\t\t\treturn css`\n justify-content: center;\n align-items: flex-end;\n padding-bottom: 3rem;\n `;\n\t\tdefault:\n\t\t\treturn css`\n justify-content: center;\n align-items: center;\n \n @media (max-height: 640px) {\n align-items: flex-start;\n padding-top: 2rem;\n padding-bottom: 2rem;\n }\n `;\n\t}\n};\n\nconst getBackdropStyles = (props: StyledModalProps) => {\n\tconst { theme, backdrop = \"opaque\" } = props;\n\n\tswitch (backdrop) {\n\t\tcase \"transparent\":\n\t\t\treturn css`\n background-color: transparent;\n `;\n\t\tcase \"opaque\":\n\t\t\treturn css`\n background-color: rgba(0, 0, 0, 0.5);\n `;\n\t\tcase \"blur\":\n\t\t\treturn css`\n background-color: rgba(0, 0, 0, 0.3);\n backdrop-filter: blur(4px);\n `;\n\t\tdefault:\n\t\t\treturn css`\n background-color: rgba(0, 0, 0, 0.5);\n `;\n\t}\n};\n\nconst ModalOverlay = styled.div<StyledModalProps & { isClosing?: boolean }>`\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: ${(props) => props.theme.zIndex.modal};\n display: flex;\n padding: ${(props) => props.theme.spacing[4]};\n animation: ${(props) => (props.isClosing ? fadeOut : fadeIn)} \n ${(props) => props.theme.transitions.normal};\n\n ${getBackdropStyles}\n ${getModalPlacementStyles}\n\n /* Custom CSS prop */\n ${(props) => props.css}\n`;\n\nconst ModalContent = styled.div<\n\tStyledModalProps & {\n\t\tisClosing?: boolean;\n\t\tscrollBehavior?: \"inside\" | \"outside\" | \"normal\";\n\t}\n>`\n position: relative;\n background-color: ${(props) => props.theme.colors.background.primary};\n box-shadow: ${(props) => props.theme.shadows.xl};\n display: flex;\n flex-direction: column;\n outline: none;\n animation: ${(props) => (props.isClosing ? scaleOut : scaleIn)} \n ${(props) => props.theme.transitions.normal};\n \n ${getModalSizeStyles}\n ${getModalRadiusStyles}\n\n ${(props) =>\n\t\tprops.scrollBehavior === \"inside\" &&\n\t\tcss`\n max-height: calc(100vh - 2 * ${props.theme.spacing[4]});\n overflow: hidden;\n `}\n\n ${(props) =>\n\t\tprops.scrollBehavior === \"outside\" &&\n\t\tcss`\n max-height: none;\n overflow: visible;\n `}\n`;\n\nconst CloseButton = styled.button<{ theme: Theme }>`\n position: absolute;\n top: ${(props) => props.theme.spacing[4]};\n right: ${(props) => props.theme.spacing[4]};\n background: none;\n border: none;\n cursor: pointer;\n padding: ${(props) => props.theme.spacing[2]};\n border-radius: ${(props) => props.theme.borderRadius.sm};\n color: ${(props) => props.theme.colors.text.secondary};\n transition: all ${(props) => props.theme.transitions.fast};\n z-index: 10;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n &:hover {\n background-color: ${(props) => props.theme.colors.neutral[100]};\n color: ${(props) => props.theme.colors.text.primary};\n }\n\n &:focus {\n outline: 2px solid ${(props) => props.theme.colors.border.focus};\n outline-offset: 2px;\n }\n`;\n\nconst CloseIcon = () => (\n\t// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>\n\t<svg\n\t\twidth=\"16\"\n\t\theight=\"16\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t>\n\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t</svg>\n);\n\nexport const Modal = React.forwardRef<HTMLDivElement, ModalProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tisOpen = false,\n\t\t\tonClose,\n\t\t\tsize = \"md\",\n\t\t\tradius = \"lg\",\n\t\t\tplacement = \"auto\",\n\t\t\thideCloseButton = false,\n\t\t\tisDismissable = true,\n\t\t\tisKeyboardDismissDisabled = false,\n\t\t\tscrollBehavior = \"normal\",\n\t\t\tbackdrop = \"opaque\",\n\t\t\tclassName,\n\t\t\tcss,\n\t\t\tportalContainer,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst { theme } = useTheme();\n\t\tconst modalRef = useRef<HTMLDivElement>(null);\n\t\tconst overlayRef = useRef<HTMLDivElement>(null);\n\n\t\t// Handle escape key\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(event: KeyboardEvent) => {\n\t\t\t\tif (!isKeyboardDismissDisabled && event.key === \"Escape\" && isOpen) {\n\t\t\t\t\tonClose?.();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[isOpen, onClose, isKeyboardDismissDisabled],\n\t\t);\n\n\t\t// Handle backdrop click\n\t\tconst handleOverlayClick = useCallback(\n\t\t\t(event: React.MouseEvent) => {\n\t\t\t\tif (isDismissable && event.target === overlayRef.current) {\n\t\t\t\t\tonClose?.();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[isDismissable, onClose],\n\t\t);\n\n\t\t// Focus management\n\t\tuseEffect(() => {\n\t\t\tif (isOpen && modalRef.current) {\n\t\t\t\tmodalRef.current.focus();\n\t\t\t}\n\t\t}, [isOpen]);\n\n\t\t// Scroll lock\n\t\tuseEffect(() => {\n\t\t\tif (isOpen && scrollBehavior !== \"normal\") {\n\t\t\t\tconst originalStyle = window.getComputedStyle(document.body).overflow;\n\t\t\t\tdocument.body.style.overflow = \"hidden\";\n\n\t\t\t\treturn () => {\n\t\t\t\t\tdocument.body.style.overflow = originalStyle;\n\t\t\t\t};\n\t\t\t}\n\t\t}, [isOpen, scrollBehavior]);\n\n\t\t// Keyboard event listener\n\t\tuseEffect(() => {\n\t\t\tif (isOpen) {\n\t\t\t\tdocument.addEventListener(\"keydown\", handleKeyDown);\n\t\t\t\treturn () => document.removeEventListener(\"keydown\", handleKeyDown);\n\t\t\t}\n\t\t}, [isOpen, handleKeyDown]);\n\n\t\tconst modalProps = {\n\t\t\t...props,\n\t\t\tsize,\n\t\t\tradius,\n\t\t\tplacement,\n\t\t\tbackdrop,\n\t\t\tscrollBehavior,\n\t\t\tclassName,\n\t\t\ttheme,\n\t\t\tcss,\n\t\t};\n\n\t\tif (!isOpen) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst modalContent = (\n\t\t\t<ModalOverlay\n\t\t\t\tref={overlayRef}\n\t\t\t\tonClick={handleOverlayClick}\n\t\t\t\t{...modalProps}\n\t\t\t>\n\t\t\t\t<ModalContent\n\t\t\t\t\tref={modalRef}\n\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-modal=\"true\"\n\t\t\t\t\t{...modalProps}\n\t\t\t\t>\n\t\t\t\t\t{!hideCloseButton && (\n\t\t\t\t\t\t<CloseButton\n\t\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\t\taria-label=\"Close modal\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CloseIcon />\n\t\t\t\t\t\t</CloseButton>\n\t\t\t\t\t)}\n\t\t\t\t\t{children}\n\t\t\t\t</ModalContent>\n\t\t\t</ModalOverlay>\n\t\t);\n\n\t\t// Use portal if container provided, otherwise render directly\n\t\tconst container = portalContainer || document.body;\n\t\treturn createPortal(modalContent, container);\n\t},\n);\n\nModal.displayName = \"Modal\";\n\n// Modal subcomponents\nexport interface ModalHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n\tclassName?: string;\n\tcss?: any;\n}\n\nexport const ModalHeader = styled.div<StyledProps<ModalHeaderProps>>`\n display: flex;\n flex-direction: column;\n gap: ${(props) => props.theme.spacing[2]};\n padding: ${(props) => props.theme.spacing[6]} ${(props) => props.theme.spacing[6]} 0;\n padding-right: ${(props) => props.theme.spacing[12]}; /* Space for close button */\n\n ${(props) => props.css}\n`;\n\nexport interface ModalBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n\tclassName?: string;\n\tcss?: any;\n}\n\nexport const ModalBody = styled.div<\n\tStyledProps<ModalBodyProps> & {\n\t\tscrollBehavior?: \"inside\" | \"outside\" | \"normal\";\n\t}\n>`\n display: flex;\n flex-direction: column;\n gap: ${(props) => props.theme.spacing[4]};\n padding: ${(props) => props.theme.spacing[6]};\n flex: 1;\n \n ${(props) =>\n\t\tprops.scrollBehavior === \"inside\" &&\n\t\tcss`\n overflow-y: auto;\n max-height: none;\n `}\n\n ${(props) => props.css}\n`;\n\nexport interface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n\tclassName?: string;\n\tcss?: any;\n}\n\nexport const ModalFooter = styled.div<StyledProps<ModalFooterProps>>`\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n align-items: center;\n gap: ${(props) => props.theme.spacing[3]};\n padding: 0 ${(props) => props.theme.spacing[6]} ${(props) => props.theme.spacing[6]};\n\n ${(props) => props.css}\n`;\n"],"names":["fadeIn","keyframes","fadeOut","scaleIn","scaleOut","getModalSizeStyles","props","theme","size","css","getModalRadiusStyles","radius","getModalPlacementStyles","placement","getBackdropStyles","backdrop","ModalOverlay","styled","ModalContent","CloseButton","CloseIcon","jsxs","jsx","Modal","React","children","isOpen","onClose","hideCloseButton","isDismissable","isKeyboardDismissDisabled","scrollBehavior","className","portalContainer","ref","useTheme","modalRef","useRef","overlayRef","handleKeyDown","useCallback","event","handleOverlayClick","useEffect","originalStyle","modalProps","modalContent","container","createPortal","ModalHeader","ModalBody","ModalFooter"],"mappings":"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"}