mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
feat: add typed signature (#1357)
Add the ability to insert typed signatures. Once the signature field is placed on the document, a checkbox appears in the document editor where the document owner can allow signers to add typed signatures. Typed signatures are disabled by default. 
This commit is contained in:
@ -47,7 +47,9 @@ import { cn } from '../../lib/utils';
|
||||
import { Alert, AlertDescription } from '../alert';
|
||||
import { Button } from '../button';
|
||||
import { Card, CardContent } from '../card';
|
||||
import { Checkbox } from '../checkbox';
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem } from '../command';
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel } from '../form/form';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '../popover';
|
||||
import { useStep } from '../stepper';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';
|
||||
@ -96,6 +98,7 @@ export type AddFieldsFormProps = {
|
||||
onSubmit: (_data: TAddFieldsFormSchema) => void;
|
||||
canGoBack?: boolean;
|
||||
isDocumentPdfLoaded: boolean;
|
||||
typedSignatureEnabled?: boolean;
|
||||
teamId?: number;
|
||||
};
|
||||
|
||||
@ -107,6 +110,7 @@ export const AddFieldsFormPartial = ({
|
||||
onSubmit,
|
||||
canGoBack = false,
|
||||
isDocumentPdfLoaded,
|
||||
typedSignatureEnabled,
|
||||
teamId,
|
||||
}: AddFieldsFormProps) => {
|
||||
const { toast } = useToast();
|
||||
@ -120,13 +124,7 @@ export const AddFieldsFormPartial = ({
|
||||
const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);
|
||||
const [currentField, setCurrentField] = useState<FieldFormType>();
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
setValue,
|
||||
getValues,
|
||||
} = useForm<TAddFieldsFormSchema>({
|
||||
const form = useForm<TAddFieldsFormSchema>({
|
||||
defaultValues: {
|
||||
fields: fields.map((field) => ({
|
||||
nativeId: field.id,
|
||||
@ -141,6 +139,7 @@ export const AddFieldsFormPartial = ({
|
||||
recipients.find((recipient) => recipient.id === field.recipientId)?.email ?? '',
|
||||
fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined,
|
||||
})),
|
||||
typedSignatureEnabled: typedSignatureEnabled ?? false,
|
||||
},
|
||||
});
|
||||
|
||||
@ -148,10 +147,10 @@ export const AddFieldsFormPartial = ({
|
||||
useHotkeys(['ctrl+v', 'meta+v'], (evt) => onFieldPaste(evt));
|
||||
useHotkeys(['ctrl+d', 'meta+d'], (evt) => onFieldCopy(evt, { duplicate: true }));
|
||||
|
||||
const onFormSubmit = handleSubmit(onSubmit);
|
||||
const onFormSubmit = form.handleSubmit(onSubmit);
|
||||
|
||||
const handleSavedFieldSettings = (fieldState: FieldMeta) => {
|
||||
const initialValues = getValues();
|
||||
const initialValues = form.getValues();
|
||||
|
||||
const updatedFields = initialValues.fields.map((field) => {
|
||||
if (field.formId === currentField?.formId) {
|
||||
@ -166,7 +165,7 @@ export const AddFieldsFormPartial = ({
|
||||
return field;
|
||||
});
|
||||
|
||||
setValue('fields', updatedFields);
|
||||
form.setValue('fields', updatedFields);
|
||||
};
|
||||
|
||||
const {
|
||||
@ -175,7 +174,7 @@ export const AddFieldsFormPartial = ({
|
||||
update,
|
||||
fields: localFields,
|
||||
} = useFieldArray({
|
||||
control,
|
||||
control: form.control,
|
||||
name: 'fields',
|
||||
});
|
||||
|
||||
@ -530,6 +529,12 @@ export const AddFieldsFormPartial = ({
|
||||
);
|
||||
}, [recipientsByRole]);
|
||||
|
||||
const isTypedSignatureEnabled = form.watch('typedSignatureEnabled');
|
||||
|
||||
const handleTypedSignatureChange = (value: boolean) => {
|
||||
form.setValue('typedSignatureEnabled', value, { shouldDirty: true });
|
||||
};
|
||||
|
||||
const handleAdvancedSettings = () => {
|
||||
setShowAdvancedSettings((prev) => !prev);
|
||||
};
|
||||
@ -577,6 +582,7 @@ export const AddFieldsFormPartial = ({
|
||||
title={documentFlow.title}
|
||||
description={documentFlow.description}
|
||||
/>
|
||||
|
||||
<DocumentFlowFormContainerContent>
|
||||
<div className="flex flex-col">
|
||||
{selectedField && (
|
||||
@ -760,269 +766,297 @@ export const AddFieldsFormPartial = ({
|
||||
</Popover>
|
||||
)}
|
||||
|
||||
<div className="-mx-2 flex-1 overflow-y-auto px-2">
|
||||
<fieldset disabled={isFieldsDisabled} className="my-2 grid grid-cols-3 gap-4">
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.SIGNATURE)}
|
||||
onMouseDown={() => setSelectedField(FieldType.SIGNATURE)}
|
||||
data-selected={selectedField === FieldType.SIGNATURE ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-lg font-normal',
|
||||
fontCaveat.className,
|
||||
)}
|
||||
>
|
||||
<Trans>Signature</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Form {...form}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="typedSignatureEnabled"
|
||||
render={({ field: { value, ...field } }) => (
|
||||
<FormItem className="mb-6 flex flex-row items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
{...field}
|
||||
id="typedSignatureEnabled"
|
||||
checkClassName="text-white"
|
||||
checked={value}
|
||||
onCheckedChange={(checked) => field.onChange(checked)}
|
||||
disabled={form.formState.isSubmitting}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.INITIALS)}
|
||||
onMouseDown={() => setSelectedField(FieldType.INITIALS)}
|
||||
data-selected={selectedField === FieldType.INITIALS ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Contact className="h-4 w-4" />
|
||||
Initials
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<FormLabel
|
||||
htmlFor="typedSignatureEnabled"
|
||||
className="text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
<Trans>Enable Typed Signatures</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.EMAIL)}
|
||||
onMouseDown={() => setSelectedField(FieldType.EMAIL)}
|
||||
data-selected={selectedField === FieldType.EMAIL ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<div className="-mx-2 flex-1 overflow-y-auto px-2">
|
||||
<fieldset disabled={isFieldsDisabled} className="my-2 grid grid-cols-3 gap-4">
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.SIGNATURE)}
|
||||
onMouseDown={() => setSelectedField(FieldType.SIGNATURE)}
|
||||
data-selected={selectedField === FieldType.SIGNATURE ? true : undefined}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Mail className="h-4 w-4" />
|
||||
<Trans>Email</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-lg font-normal',
|
||||
fontCaveat.className,
|
||||
)}
|
||||
>
|
||||
<Trans>Signature</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.NAME)}
|
||||
onMouseDown={() => setSelectedField(FieldType.NAME)}
|
||||
data-selected={selectedField === FieldType.NAME ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.INITIALS)}
|
||||
onMouseDown={() => setSelectedField(FieldType.INITIALS)}
|
||||
data-selected={selectedField === FieldType.INITIALS ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<User className="h-4 w-4" />
|
||||
<Trans>Name</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Contact className="h-4 w-4" />
|
||||
Initials
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.DATE)}
|
||||
onMouseDown={() => setSelectedField(FieldType.DATE)}
|
||||
data-selected={selectedField === FieldType.DATE ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.EMAIL)}
|
||||
onMouseDown={() => setSelectedField(FieldType.EMAIL)}
|
||||
data-selected={selectedField === FieldType.EMAIL ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<CalendarDays className="h-4 w-4" />
|
||||
<Trans>Date</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Mail className="h-4 w-4" />
|
||||
<Trans>Email</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.TEXT)}
|
||||
onMouseDown={() => setSelectedField(FieldType.TEXT)}
|
||||
data-selected={selectedField === FieldType.TEXT ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.NAME)}
|
||||
onMouseDown={() => setSelectedField(FieldType.NAME)}
|
||||
data-selected={selectedField === FieldType.NAME ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Type className="h-4 w-4" />
|
||||
<Trans>Text</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<User className="h-4 w-4" />
|
||||
<Trans>Name</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.NUMBER)}
|
||||
onMouseDown={() => setSelectedField(FieldType.NUMBER)}
|
||||
data-selected={selectedField === FieldType.NUMBER ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.DATE)}
|
||||
onMouseDown={() => setSelectedField(FieldType.DATE)}
|
||||
data-selected={selectedField === FieldType.DATE ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Hash className="h-4 w-4" />
|
||||
<Trans>Number</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<CalendarDays className="h-4 w-4" />
|
||||
<Trans>Date</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.RADIO)}
|
||||
onMouseDown={() => setSelectedField(FieldType.RADIO)}
|
||||
data-selected={selectedField === FieldType.RADIO ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.TEXT)}
|
||||
onMouseDown={() => setSelectedField(FieldType.TEXT)}
|
||||
data-selected={selectedField === FieldType.TEXT ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Disc className="h-4 w-4" />
|
||||
<Trans>Radio</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Type className="h-4 w-4" />
|
||||
<Trans>Text</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.CHECKBOX)}
|
||||
onMouseDown={() => setSelectedField(FieldType.CHECKBOX)}
|
||||
data-selected={selectedField === FieldType.CHECKBOX ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.NUMBER)}
|
||||
onMouseDown={() => setSelectedField(FieldType.NUMBER)}
|
||||
data-selected={selectedField === FieldType.NUMBER ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<CheckSquare className="h-4 w-4" />
|
||||
<Trans>Checkbox</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Hash className="h-4 w-4" />
|
||||
<Trans>Number</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.DROPDOWN)}
|
||||
onMouseDown={() => setSelectedField(FieldType.DROPDOWN)}
|
||||
data-selected={selectedField === FieldType.DROPDOWN ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.RADIO)}
|
||||
onMouseDown={() => setSelectedField(FieldType.RADIO)}
|
||||
data-selected={selectedField === FieldType.RADIO ? true : undefined}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
<Trans>Dropdown</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<Disc className="h-4 w-4" />
|
||||
<Trans>Radio</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.CHECKBOX)}
|
||||
onMouseDown={() => setSelectedField(FieldType.CHECKBOX)}
|
||||
data-selected={selectedField === FieldType.CHECKBOX ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<CheckSquare className="h-4 w-4" />
|
||||
<Trans>Checkbox</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.DROPDOWN)}
|
||||
onMouseDown={() => setSelectedField(FieldType.DROPDOWN)}
|
||||
data-selected={selectedField === FieldType.DROPDOWN ? true : undefined}
|
||||
>
|
||||
<Card
|
||||
className={cn(
|
||||
'flex h-full w-full cursor-pointer items-center justify-center group-disabled:opacity-50',
|
||||
// selectedSignerStyles.borderClass,
|
||||
)}
|
||||
>
|
||||
<CardContent className="p-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground flex items-center justify-center gap-x-1.5 text-sm font-normal',
|
||||
)}
|
||||
>
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
<Trans>Dropdown</Trans>
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</DocumentFlowFormContainerContent>
|
||||
|
||||
@ -1059,8 +1093,9 @@ export const AddFieldsFormPartial = ({
|
||||
<DocumentFlowFormContainerStep step={currentStep} maxStep={totalSteps} />
|
||||
|
||||
<DocumentFlowFormContainerActions
|
||||
loading={isSubmitting}
|
||||
disabled={isSubmitting}
|
||||
loading={form.formState.isSubmitting}
|
||||
disabled={form.formState.isSubmitting}
|
||||
disableNextStep={hasErrors}
|
||||
onGoBackClick={() => {
|
||||
previousStep();
|
||||
remove();
|
||||
|
||||
@ -18,6 +18,7 @@ export const ZAddFieldsFormSchema = z.object({
|
||||
fieldMeta: ZFieldMetaSchema,
|
||||
}),
|
||||
),
|
||||
typedSignatureEnabled: z.boolean(),
|
||||
});
|
||||
|
||||
export type TAddFieldsFormSchema = z.infer<typeof ZAddFieldsFormSchema>;
|
||||
|
||||
Reference in New Issue
Block a user