Submit Button

Specifically designed for form submission with built-in loading states, making it perfect for forms that need to show submission progress and prevent double submissions.

npx shadcn@latest add https://shuip.plvo.dev/r/submit-button.json
pnpm dlx shadcn@latest add https://shuip.plvo.dev/r/submit-button.json
bun x shadcn@latest add https://shuip.plvo.dev/r/submit-button.json
import { ReloadIcon } from '@radix-ui/react-icons';
import type { VariantProps } from 'class-variance-authority';
import type * as React from 'react';
import { Button, type buttonVariants } from '@/components/ui/button';
type ButtonProps = React.ComponentProps<'button'> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
};
export interface SubmitButtonProps extends ButtonProps {
children?: React.ReactNode;
disabled?: boolean;
loading?: boolean;
icon?: React.JSX.Element;
}
export function SubmitButton({
children,
disabled,
loading,
icon = <ReloadIcon className='mr-2 size-4 animate-spin' aria-label='Loading' />,
...props
}: SubmitButtonProps) {
return (
<Button type='submit' aria-label='Submit' disabled={disabled || loading} {...props}>
{loading && icon}
{children || 'Submit'}
</Button>
);
}
Loading...

Built-in features

  • Automatic loading state: Shows spinner icon when loading prop is true
  • Full-width by default: Optimized for form layouts
  • Customizable icon: Can override the default loading spinner
  • Form integration: Native type="submit" behavior

Common use cases

Basic form submission

<SubmitButton children="Save Changes" loading={isSaving} />

<SubmitButton loading={isSaving}>
  <span className="flex items-center">
    <Send className="mr-2 h-4 w-4" />
    Send Message
  </span>
</SubmitButton>

With custom icon

<SubmitButton 
  children="Processing Payment"
  loading={isProcessing}
  icon={<CreditCard className="mr-2 h-4 w-4 animate-pulse" />}
/>

With JSX label

<SubmitButton 
  children={
    <span className="flex items-center">
      <Send className="mr-2 h-4 w-4" />
      Send Message
    </span>
  }
  loading={isSending}
/>

Custom styling

<SubmitButton 
  children="Delete Account"
  loading={isDeleting}
  className="bg-destructive hover:bg-destructive/90"
  disabled={!confirmed}
/>

Examples

Default

Loading...
import { SubmitButton } from '@/components/ui/shuip/submit-button';
export default function SubmitButtonExample() {
return <SubmitButton>Submit</SubmitButton>;
}

Loading

Loading...
import { SubmitButton } from '@/components/ui/shuip/submit-button';
export default function SubmitButtonLoadingExample() {
return <SubmitButton loading={true}>Submit</SubmitButton>;
}

Props

Prop

Type

On this page