@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 8.29 kB
Source Map (JSON)
{"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/base-ui/Button/Button.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { isValidElement, type MouseEvent, type ReactNode, type Ref } from 'react';\n\nimport Icon, { type IconProps } from '@/Icon';\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { styles } from './style';\nimport type { ButtonProps } from './type';\n\nconst resolveIconNode = (node: ReactNode | IconProps['icon'] | undefined | null) => {\n if (node === undefined || node === null) return null;\n if (isValidElement(node) || typeof node === 'string' || typeof node === 'number') {\n return node;\n }\n return <Icon icon={node as any} size={'small'} />;\n};\n\nconst resolveSizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.sizeSmall;\n if (size === 'large') return styles.sizeLarge;\n return styles.sizeMiddle;\n};\n\nconst resolveIconOnlySizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.iconOnlySmall;\n if (size === 'large') return styles.iconOnlyLarge;\n return styles.iconOnlyMiddle;\n};\n\nconst resolveVariantCls = ({\n danger,\n ghost,\n type,\n}: {\n danger: boolean;\n ghost: boolean;\n type: NonNullable<ButtonProps['type']>;\n}): string => {\n if (ghost) {\n if (danger) return styles.ghostDanger;\n if (type === 'primary') return styles.ghostPrimary;\n if (type === 'dashed') return cx(styles.ghostDefault, styles.ghostDashed);\n return styles.ghostDefault;\n }\n\n switch (type) {\n case 'primary': {\n return danger ? styles.dangerSolid : styles.variantPrimary;\n }\n case 'dashed': {\n return danger ? cx(styles.variantDashed, styles.dangerOutlined) : styles.variantDashed;\n }\n case 'fill': {\n return danger ? styles.dangerFill : styles.variantFill;\n }\n case 'text': {\n return danger ? cx(styles.variantText, styles.dangerInline) : styles.variantText;\n }\n case 'link': {\n return danger ? cx(styles.variantLink, styles.dangerInline) : styles.variantLink;\n }\n default: {\n return danger ? cx(styles.variantDefault, styles.dangerOutlined) : styles.variantDefault;\n }\n }\n};\n\nconst tapAnim = { scale: 0.98 };\nconst motionTransition = {\n damping: 26,\n mass: 0.6,\n stiffness: 600,\n type: 'spring' as const,\n};\n\nconst Button = ({\n block,\n children,\n className,\n classNames,\n danger = false,\n disabled,\n ghost = false,\n href,\n htmlType = 'button',\n icon,\n iconPosition = 'start',\n loading,\n onClick,\n ref,\n shape = 'default',\n size = 'middle',\n styles: userStyles,\n target,\n type = 'default',\n ...rest\n}: ButtonProps) => {\n const Motion = useMotionComponent();\n const isInteractionDisabled = disabled || loading;\n const sizeCls = resolveSizeCls(size);\n const variantCls = resolveVariantCls({ danger, ghost, type });\n const shapeCls =\n shape === 'circle' ? styles.shapeCircle : shape === 'round' ? styles.shapeRound : undefined;\n\n const hasChildren =\n children !== undefined && children !== null && children !== false && children !== '';\n const renderIcon = loading || icon;\n const iconOnly = !hasChildren && !!renderIcon;\n const iconOnlySizeCls = iconOnly ? resolveIconOnlySizeCls(size) : undefined;\n\n const composedClassName = cx(\n styles.base,\n sizeCls,\n variantCls,\n shapeCls,\n block && styles.block,\n iconPosition === 'end' && styles.iconEnd,\n iconOnlySizeCls,\n className,\n );\n\n const spinnerNode = (\n <span\n aria-hidden={!loading}\n style={userStyles?.icon}\n className={cx(\n styles.iconBox,\n styles.spinnerSlot,\n loading && styles.spinnerSlotShow,\n iconPosition === 'end' && styles.spinnerSlotEnd,\n classNames?.icon,\n )}\n >\n <span className={styles.spinner} />\n </span>\n );\n\n const iconNode =\n icon && !loading ? (\n <span className={cx(styles.iconBox, classNames?.icon)} style={userStyles?.icon}>\n {resolveIconNode(icon)}\n </span>\n ) : null;\n\n const inner = (\n <>\n {spinnerNode}\n {iconNode}\n {children}\n </>\n );\n\n const motionGestures = isInteractionDisabled\n ? {}\n : { transition: motionTransition, whileTap: tapAnim };\n\n if (href !== undefined) {\n const handleAnchorClick = (e: MouseEvent<HTMLAnchorElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e as unknown as MouseEvent<HTMLButtonElement>);\n };\n\n return (\n <Motion.a\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n href={disabled ? undefined : href}\n target={target}\n {...(rest as any)}\n className={composedClassName}\n ref={ref as Ref<HTMLAnchorElement>}\n onClick={handleAnchorClick}\n {...motionGestures}\n >\n {inner}\n </Motion.a>\n );\n }\n\n const handleButtonClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e);\n };\n\n return (\n <Motion.button\n type={htmlType}\n {...(rest as any)}\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n className={composedClassName}\n disabled={disabled}\n ref={ref as Ref<HTMLButtonElement>}\n onClick={handleButtonClick}\n {...motionGestures}\n >\n {inner}\n </Motion.button>\n );\n};\n\nButton.displayName = 'BaseButton';\n\nexport default Button;\n"],"mappings":"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"}