@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 14.9 kB
Source Map (JSON)
{"version":3,"file":"button.cjs","sources":["../../../../../src/components/ui/button/button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useTheme } from \"@/theme/context\";\nimport { type StyledProps, getColorVariant } from \"@/theme/styled\";\nimport { css } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport React from \"react\";\n\nexport interface ButtonProps\n\textends React.ButtonHTMLAttributes<HTMLButtonElement> {\n\t/** Button variant */\n\tvariant?: \"solid\" | \"outlined\" | \"light\" | \"flat\" | \"ghost\";\n\t/** Button color theme */\n\tcolor?: \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"danger\";\n\t/** Button size */\n\tsize?: \"sm\" | \"md\" | \"lg\";\n\t/** Button radius */\n\tradius?: \"none\" | \"sm\" | \"md\" | \"lg\" | \"full\";\n\t/** Loading state */\n\tisLoading?: boolean;\n\t/** Disabled state */\n\tisDisabled?: boolean;\n\t/** Full width button */\n\tfullWidth?: boolean;\n\t/** Icon only button */\n\tisIconOnly?: boolean;\n\t/** Start content (icon) */\n\tstartContent?: React.ReactNode;\n\t/** End content (icon) */\n\tendContent?: React.ReactNode;\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Custom styles */\n\tcss?: any;\n\tonPress?: (e: MouseEvent) => void;\n}\n\ntype StyledButtonProps = StyledProps<ButtonProps>;\n\nconst getButtonVariantStyles = (props: StyledButtonProps) => {\n\tconst { theme, variant = \"solid\", color = \"primary\", isDisabled } = props;\n\tconst baseColor = getColorVariant(theme, color, 500);\n\tconst hoverColor = getColorVariant(theme, color, 600);\n\tconst lightColor = getColorVariant(theme, color, 50);\n\tconst darkColor = getColorVariant(theme, color, 700);\n\n\tconst disabledStyles = css`\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n `;\n\n\tswitch (variant) {\n\t\tcase \"solid\":\n\t\t\treturn css`\n background-color: ${baseColor};\n color: ${theme.colors.text.inverse};\n border: 2px solid ${baseColor};\n\n &:hover:not(:disabled) {\n background-color: ${hoverColor};\n border-color: ${hoverColor};\n }\n\n &:active:not(:disabled) {\n background-color: ${darkColor};\n border-color: ${darkColor};\n }\n\n ${isDisabled && disabledStyles}\n `;\n\n\t\tcase \"outlined\":\n\t\t\treturn css`\n background-color: transparent;\n color: ${baseColor};\n border: 2px solid ${baseColor};\n\n &:hover:not(:disabled) {\n background-color: ${lightColor};\n }\n\n &:active:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n\n ${isDisabled && disabledStyles}\n `;\n\n\t\tcase \"light\":\n\t\t\treturn css`\n background-color: ${lightColor};\n color: ${darkColor};\n border: 2px solid transparent;\n\n &:hover:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n\n &:active:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 200)};\n }\n\n ${isDisabled && disabledStyles}\n `;\n\n\t\tcase \"flat\":\n\t\t\treturn css`\n background-color: ${getColorVariant(theme, color, 100)};\n color: ${baseColor};\n border: 2px solid transparent;\n\n &:hover:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 200)};\n }\n\n &:active:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 300)};\n }\n\n ${isDisabled && disabledStyles}\n `;\n\n\t\tcase \"ghost\":\n\t\t\treturn css`\n background-color: transparent;\n color: ${baseColor};\n border: 2px solid transparent;\n\n &:hover:not(:disabled) {\n background-color: ${lightColor};\n }\n\n &:active:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n\n ${isDisabled && disabledStyles}\n `;\n\n\t\tdefault:\n\t\t\treturn css`\n background-color: transparent;\n color: ${baseColor};\n border: 2px solid ${baseColor};\n\n &:hover:not(:disabled) {\n background-color: ${lightColor};\n }\n\n &:active:not(:disabled) {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n\n ${isDisabled && disabledStyles}\n\t\t\t`;\n\t}\n};\n\n// Fixed: Add !important to size-related properties to ensure they take precedence\nconst getButtonSizeStyles = (props: StyledButtonProps) => {\n\tconst { theme, size = \"md\", isIconOnly } = props;\n\n\tif (isIconOnly) {\n\t\tswitch (size) {\n\t\t\tcase \"sm\":\n\t\t\t\treturn css`\n min-width: ${theme.spacing[8]} !important;\n height: ${theme.spacing[8]} !important;\n padding: 0 !important;\n `;\n\t\t\tcase \"md\":\n\t\t\t\treturn css`\n min-width: ${theme.spacing[10]} !important;\n height: ${theme.spacing[10]} !important;\n padding: 0 !important;\n `;\n\t\t\tcase \"lg\":\n\t\t\t\treturn css`\n min-width: ${theme.spacing[12]} !important;\n height: ${theme.spacing[12]} !important;\n padding: 0 !important;\n `;\n\t\t\tdefault:\n\t\t\t\treturn css``;\n\t\t}\n\t}\n\n\tswitch (size) {\n\t\tcase \"sm\":\n\t\t\treturn css`\n height: ${theme.spacing[8]} !important;\n padding: 0 ${theme.spacing[3]} !important;\n font-size: ${theme.fontSizes.sm} !important;\n min-width: ${theme.spacing[16]} !important;\n `;\n\t\tcase \"md\":\n\t\t\treturn css`\n height: ${theme.spacing[10]} !important;\n padding: 0 ${theme.spacing[4]} !important;\n font-size: ${theme.fontSizes.base} !important;\n min-width: ${theme.spacing[20]} !important;\n `;\n\t\tcase \"lg\":\n\t\t\treturn css`\n height: ${theme.spacing[12]} !important;\n padding: 0 ${theme.spacing[6]} !important;\n font-size: ${theme.fontSizes.lg} !important;\n min-width: ${theme.spacing[24]} !important;\n `;\n\t\tdefault:\n\t\t\treturn css``;\n\t}\n};\n\n// Fixed: Ensure border-radius is applied with !important to override any conflicting styles\nconst getButtonRadiusStyles = (props: StyledButtonProps) => {\n\tconst { theme, radius = \"md\" } = props;\n\n\tswitch (radius) {\n\t\tcase \"none\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.none} !important;`;\n\t\tcase \"sm\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.sm} !important;`;\n\t\tcase \"md\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.md} !important;`;\n\t\tcase \"lg\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.lg} !important;`;\n\t\tcase \"full\":\n\t\t\treturn css`border-radius: ${theme.borderRadius.full} !important;`;\n\t\tdefault:\n\t\t\treturn css`border-radius: ${theme.borderRadius.md} !important;`;\n\t}\n};\n\nconst StyledButton = styled.button<StyledButtonProps>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: ${(props) => props.theme.spacing[2]};\n font-family: inherit;\n font-weight: ${(props) => props.theme.fontWeights.medium};\n line-height: ${(props) => props.theme.lineHeights.tight};\n text-decoration: none;\n cursor: pointer;\n transition: all ${(props) => props.theme.transitions.normal};\n position: relative;\n overflow: hidden;\n white-space: nowrap;\n user-select: none;\n outline: none;\n\n /* Apply base styles first */\n ${getButtonVariantStyles}\n ${getButtonSizeStyles}\n\n /* Apply radius styles last to ensure they take precedence */\n ${getButtonRadiusStyles}\n\n ${(props) =>\n\t\tprops.fullWidth &&\n\t\tcss`\n width: 100%;\n `}\n\n &:focus-visible {\n outline: 2px solid ${(props) => props.theme.colors.border.focus};\n outline-offset: 2px;\n }\n\n /* Custom CSS prop - applied last */\n ${(props) => props.css}\n`;\n\nconst LoadingSpinner = styled.div<{ size?: \"sm\" | \"md\" | \"lg\" }>`\n width: ${(props) => {\n\t\tswitch (props.size) {\n\t\t\tcase \"sm\":\n\t\t\t\treturn \"12px\";\n\t\t\tcase \"lg\":\n\t\t\t\treturn \"20px\";\n\t\t\tdefault:\n\t\t\t\treturn \"16px\";\n\t\t}\n\t}};\n height: ${(props) => {\n\t\tswitch (props.size) {\n\t\t\tcase \"sm\":\n\t\t\t\treturn \"12px\";\n\t\t\tcase \"lg\":\n\t\t\t\treturn \"20px\";\n\t\t\tdefault:\n\t\t\t\treturn \"16px\";\n\t\t}\n\t}};\n border: 2px solid currentColor;\n border-radius: 50%;\n border-top-color: transparent;\n animation: spin 1s linear infinite;\n\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }\n`;\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tvariant = \"solid\",\n\t\t\tcolor = \"primary\",\n\t\t\tsize = \"md\",\n\t\t\tradius = \"md\",\n\t\t\tisLoading = false,\n\t\t\tisDisabled = false,\n\t\t\tfullWidth = false,\n\t\t\tisIconOnly = false,\n\t\t\tstartContent,\n\t\t\tendContent,\n\t\t\tclassName,\n\t\t\tcss,\n\t\t\tonPress,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst { theme } = useTheme();\n\t\tconst optionalProps = {} as Record<string, any>;\n\t\tif (onPress) {\n\t\t\toptionalProps.onClick = onPress;\n\t\t}\n\n\t\t// Fixed: Ensure all props including radius are passed correctly\n\t\tconst buttonProps = {\n\t\t\t...optionalProps,\n\t\t\t...props,\n\t\t\tvariant,\n\t\t\tcolor,\n\t\t\tsize,\n\t\t\tradius, // Make sure radius is explicitly passed\n\t\t\tisDisabled: isDisabled || isLoading,\n\t\t\tfullWidth,\n\t\t\tisIconOnly,\n\t\t\tclassName,\n\t\t\tdisabled: isDisabled || isLoading,\n\t\t\tcss,\n\t\t};\n\n\t\treturn (\n\t\t\t<StyledButton theme={theme} ref={ref} {...buttonProps}>\n\t\t\t\t{isLoading && <LoadingSpinner size={size} />}\n\t\t\t\t{!isLoading && startContent && startContent}\n\t\t\t\t{children}\n\t\t\t\t{!isLoading && endContent && endContent}\n\t\t\t</StyledButton>\n\t\t);\n\t},\n);\n\nButton.displayName = \"Button\";\n"],"names":["getButtonVariantStyles","props","theme","variant","color","isDisabled","baseColor","getColorVariant","hoverColor","lightColor","darkColor","disabledStyles","css","getButtonSizeStyles","size","isIconOnly","getButtonRadiusStyles","radius","StyledButton","styled","LoadingSpinner","Button","React","children","isLoading","fullWidth","startContent","endContent","className","onPress","ref","useTheme","optionalProps","buttonProps","jsxs","jsx"],"mappings":"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"}