1+ 'use client' ;
2+
3+ import { Tooltip } from '@base-ui-components/react/tooltip' ;
14import { CheckIcon , ExclamationMarkIcon } from '@phosphor-icons/react' ;
25
36import { classnames } from '@/utils/classnames.ts' ;
7+ import { Arrow } from '../Arrow.tsx' ;
48import { Loading } from '../Loading.tsx' ;
59import { useFormContext } from './form.ts' ;
610
711export function SubmitButton ( {
812 status,
13+ tooltip,
914 children,
10- } : Readonly < { status : 'idle' | 'error' | 'success' | 'submitting' ; children : React . ReactNode } > ) {
15+ } : Readonly < {
16+ status : 'idle' | 'error' | 'success' | 'submitting' ;
17+ /**
18+ * If provided, then render a rooltip around the button with additional details
19+ */
20+ tooltip ?:
21+ | {
22+ disabled ?: boolean | undefined ;
23+ content : React . ReactNode ;
24+ }
25+ | null
26+ | undefined ;
27+ children : React . ReactNode ;
28+ } > ) {
1129 const form = useFormContext ( ) ;
1230
1331 return (
@@ -19,35 +37,85 @@ export function SubmitButton({
1937 dirty : state . isDirty ,
2038 } ) }
2139 >
22- { ( { canSubmit, isSubmitting, valid, dirty } ) => (
23- < button
24- type = "submit"
25- disabled = { ! canSubmit || ! valid || ! dirty || isSubmitting }
26- data-state = { status }
27- className = { classnames (
28- 'rounded-md bg-indigo-600 dark:bg-indigo-500 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 dark:hover:bg-indigo-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-500 inline-flex items-center gap-x-2 cursor-pointer' ,
29- 'disabled:bg-gray-400 disabled:text-gray-900 disabled:hover:bg-gray-400 disabled:focus-visible:outline-gray-400 disabled:cursor-not-allowed' ,
30- 'data-[state=error]:bg-red-600 data-[state=error]:hover:bg-red-500 data-[state=error]:focus-visible:bg-red-500 data-[state=success]:focus-visible:bg-green-500' ,
31- 'data-[state=success]:bg-green-600 data-[state=success]:hover:bg-green-500' ,
32- ) }
33- >
34- { status === 'submitting' ? (
35- < Loading />
36- ) : status === 'success' ? (
37- < >
38- < CheckIcon className = "size-5 text-white" aria-hidden = "true" />
39- { children }
40- </ >
41- ) : status === 'error' ? (
42- < >
43- < ExclamationMarkIcon className = "size-5 text-white" aria-hidden = "true" />
44- Error
45- </ >
46- ) : (
47- children
48- ) }
49- </ button >
50- ) }
40+ { ( { canSubmit, isSubmitting, valid, dirty } ) => {
41+ if ( tooltip ) {
42+ return (
43+ < Tooltip . Provider delay = { 300 } closeDelay = { 1_000 } >
44+ < Tooltip . Root disabled = { tooltip . disabled || false } >
45+ < Tooltip . Trigger
46+ type = "submit"
47+ disabled = { ! canSubmit || ! valid || ! dirty || isSubmitting }
48+ data-state = { status }
49+ className = { classnames (
50+ 'rounded-md bg-indigo-600 dark:bg-indigo-500 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 dark:hover:bg-indigo-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-500 inline-flex items-center gap-x-2 cursor-pointer' ,
51+ 'disabled:bg-gray-400 disabled:text-gray-900 disabled:hover:bg-gray-400 disabled:focus-visible:outline-gray-400 disabled:cursor-not-allowed' ,
52+ 'data-[state=error]:bg-red-600 data-[state=error]:hover:bg-red-500 data-[state=error]:focus-visible:bg-red-500 data-[state=success]:focus-visible:bg-green-500' ,
53+ 'data-[state=success]:bg-green-600 data-[state=success]:hover:bg-green-500' ,
54+ ) }
55+ >
56+ { status === 'submitting' ? (
57+ < Loading />
58+ ) : status === 'success' ? (
59+ < >
60+ < CheckIcon className = "size-5 text-white" aria-hidden = "true" />
61+ { children }
62+ </ >
63+ ) : status === 'error' ? (
64+ < >
65+ < ExclamationMarkIcon className = "size-5 text-white" aria-hidden = "true" />
66+ Error
67+ </ >
68+ ) : (
69+ children
70+ ) }
71+ </ Tooltip . Trigger >
72+ < Tooltip . Portal >
73+ < Tooltip . Positioner side = "top" sideOffset = { 10 } >
74+ < Tooltip . Popup className = "box-border text-sm flex flex-col px-2 py-3 rounded-lg bg-gray-100 dark:bg-slate-900 transform-content data-[starting-style]:opacity-0 data-[ending-style]:opacity-0 w-fit max-w-xs" >
75+ < Tooltip . Arrow className = "flex data-[side=top]:-bottom-2 data-[side=top]:rotate-180 data-[side=bottom]:-top-2 data-[side=bottom]:rotate-0 data-[side=left]:-right-3 data-[side=left]:rotate-90 data-[side=right]:-left-3 data-[side=right]:-rotate-90" >
76+ < Arrow />
77+ </ Tooltip . Arrow >
78+ < span className = "text-xs text-gray-700 dark:text-white whitespace-break-spaces w-full" >
79+ { tooltip . content }
80+ </ span >
81+ </ Tooltip . Popup >
82+ </ Tooltip . Positioner >
83+ </ Tooltip . Portal >
84+ </ Tooltip . Root >
85+ </ Tooltip . Provider >
86+ ) ;
87+ }
88+
89+ return (
90+ < button
91+ type = "submit"
92+ disabled = { ! canSubmit || ! valid || ! dirty || isSubmitting }
93+ data-state = { status }
94+ className = { classnames (
95+ 'rounded-md bg-indigo-600 dark:bg-indigo-500 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 dark:hover:bg-indigo-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-500 inline-flex items-center gap-x-2 cursor-pointer' ,
96+ 'disabled:bg-gray-400 disabled:text-gray-900 disabled:hover:bg-gray-400 disabled:focus-visible:outline-gray-400 disabled:cursor-not-allowed' ,
97+ 'data-[state=error]:bg-red-600 data-[state=error]:hover:bg-red-500 data-[state=error]:focus-visible:bg-red-500 data-[state=success]:focus-visible:bg-green-500' ,
98+ 'data-[state=success]:bg-green-600 data-[state=success]:hover:bg-green-500' ,
99+ ) }
100+ >
101+ { status === 'submitting' ? (
102+ < Loading />
103+ ) : status === 'success' ? (
104+ < >
105+ < CheckIcon className = "size-5 text-white" aria-hidden = "true" />
106+ { children }
107+ </ >
108+ ) : status === 'error' ? (
109+ < >
110+ < ExclamationMarkIcon className = "size-5 text-white" aria-hidden = "true" />
111+ Error
112+ </ >
113+ ) : (
114+ children
115+ ) }
116+ </ button >
117+ ) ;
118+ } }
51119 </ form . Subscribe >
52120 ) ;
53121}
0 commit comments