'use client'; import { ark } from '@ark-ui/react/factory'; import { createContext, mergeProps } from '@ark-ui/react/utils'; import type React from 'react'; import { type ComponentProps, forwardRef, useMemo } from 'react'; import { styled } from 'styled-system/jsx'; import { type ButtonVariantProps, button } from 'styled-system/recipes'; import { Group, type GroupProps } from './Group'; import { Loader } from './Loader'; interface ButtonLoadingProps { /** * If `true`, the button will show a loading spinner. * @default false */ loading?: boolean | undefined; /** * The text to show while loading. */ loadingText?: React.ReactNode | undefined; /** * The spinner to show while loading. */ spinner?: React.ReactNode | undefined; /** * The placement of the spinner * @default "start" */ spinnerPlacement?: 'start' | 'end' | undefined; } type BaseButtonProps = ComponentProps; const BaseButton = styled(ark.button, button); export interface ButtonProps extends BaseButtonProps, ButtonLoadingProps {} export const Button = forwardRef( function Button(props, ref) { const propsContext = useButtonPropsContext(); const buttonProps = useMemo( () => mergeProps(propsContext, props), [propsContext, props], ); const { loading, loadingText, children, spinner, spinnerPlacement, ...rest } = buttonProps; return ( {!props.asChild && loading ? ( {children} ) : ( children )} ); }, ); export interface ButtonGroupProps extends GroupProps, ButtonVariantProps {} export const ButtonGroup = forwardRef( function ButtonGroup(props, ref) { const [variantProps, otherProps] = useMemo( () => button.splitVariantProps(props), [props], ); return ( ); }, ); const [ButtonPropsProvider, useButtonPropsContext] = createContext({ name: 'ButtonPropsContext', hookName: 'useButtonPropsContext', providerName: '', strict: false, });