mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
## Description Adds the ability to align text to the left, center or right for relevant fields. Previously text was always centered which can be less desirable. See attached debug document which has left, center and right text alignments set for fields. <img width="614" alt="image" src="https://github.com/user-attachments/assets/361a030e-813d-458b-9c7a-ff4c9fa5e33c" /> ## Related Issue N/A ## Changes Made - Added text align option - Update the insert in pdf method to support different alignments - Added a debug mode to field insertion ## Testing Performed - Ran manual tests using the debug mode
168 lines
4.9 KiB
TypeScript
168 lines
4.9 KiB
TypeScript
import { Trans, msg } from '@lingui/macro';
|
|
import { useLingui } from '@lingui/react';
|
|
|
|
import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text';
|
|
import { type TTextFieldMeta as TextFieldMeta } from '@documenso/lib/types/field-meta';
|
|
import { Input } from '@documenso/ui/primitives/input';
|
|
import { Label } from '@documenso/ui/primitives/label';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@documenso/ui/primitives/select';
|
|
import { Switch } from '@documenso/ui/primitives/switch';
|
|
import { Textarea } from '@documenso/ui/primitives/textarea';
|
|
|
|
type TextFieldAdvancedSettingsProps = {
|
|
fieldState: TextFieldMeta;
|
|
handleFieldChange: (key: keyof TextFieldMeta, value: string | boolean) => void;
|
|
handleErrors: (errors: string[]) => void;
|
|
};
|
|
|
|
export const TextFieldAdvancedSettings = ({
|
|
fieldState,
|
|
handleFieldChange,
|
|
handleErrors,
|
|
}: TextFieldAdvancedSettingsProps) => {
|
|
const { _ } = useLingui();
|
|
|
|
const handleInput = (field: keyof TextFieldMeta, value: string | boolean) => {
|
|
const text = field === 'text' ? String(value) : (fieldState.text ?? '');
|
|
const limit =
|
|
field === 'characterLimit' ? Number(value) : Number(fieldState.characterLimit ?? 0);
|
|
const fontSize = field === 'fontSize' ? Number(value) : Number(fieldState.fontSize ?? 14);
|
|
const readOnly = field === 'readOnly' ? Boolean(value) : Boolean(fieldState.readOnly);
|
|
const required = field === 'required' ? Boolean(value) : Boolean(fieldState.required);
|
|
|
|
const textErrors = validateTextField(text, {
|
|
characterLimit: Number(limit),
|
|
readOnly,
|
|
required,
|
|
fontSize,
|
|
type: 'text',
|
|
});
|
|
|
|
handleErrors(textErrors);
|
|
handleFieldChange(field, value);
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col gap-4">
|
|
<div>
|
|
<Label>
|
|
<Trans>Label</Trans>
|
|
</Label>
|
|
<Input
|
|
id="label"
|
|
className="bg-background mt-2"
|
|
placeholder={_(msg`Field label`)}
|
|
value={fieldState.label}
|
|
onChange={(e) => handleFieldChange('label', e.target.value)}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Label className="mt-4">
|
|
<Trans>Placeholder</Trans>
|
|
</Label>
|
|
<Input
|
|
id="placeholder"
|
|
className="bg-background mt-2"
|
|
placeholder={_(msg`Field placeholder`)}
|
|
value={fieldState.placeholder}
|
|
onChange={(e) => handleFieldChange('placeholder', e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label className="mt-4">
|
|
<Trans>Add text</Trans>
|
|
</Label>
|
|
<Textarea
|
|
id="text"
|
|
className="bg-background mt-2"
|
|
placeholder={_(msg`Add text to the field`)}
|
|
value={fieldState.text}
|
|
onChange={(e) => handleInput('text', e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>
|
|
<Trans>Character Limit</Trans>
|
|
</Label>
|
|
<Input
|
|
id="characterLimit"
|
|
type="number"
|
|
min={0}
|
|
className="bg-background mt-2"
|
|
placeholder={_(msg`Field character limit`)}
|
|
value={fieldState.characterLimit}
|
|
onChange={(e) => handleInput('characterLimit', e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>
|
|
<Trans>Font Size</Trans>
|
|
</Label>
|
|
<Input
|
|
id="fontSize"
|
|
type="number"
|
|
className="bg-background mt-2"
|
|
placeholder={_(msg`Field font size`)}
|
|
value={fieldState.fontSize}
|
|
onChange={(e) => handleInput('fontSize', e.target.value)}
|
|
min={8}
|
|
max={96}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>
|
|
<Trans>Text Align</Trans>
|
|
</Label>
|
|
|
|
<Select
|
|
value={fieldState.textAlign}
|
|
onValueChange={(value) => handleInput('textAlign', value)}
|
|
>
|
|
<SelectTrigger className="bg-background mt-2">
|
|
<SelectValue placeholder="Select text align" />
|
|
</SelectTrigger>
|
|
|
|
<SelectContent>
|
|
<SelectItem value="left">Left</SelectItem>
|
|
<SelectItem value="center">Center</SelectItem>
|
|
<SelectItem value="right">Right</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="mt-4 flex flex-col gap-4">
|
|
<div className="flex flex-row items-center gap-2">
|
|
<Switch
|
|
className="bg-background"
|
|
checked={fieldState.required}
|
|
onCheckedChange={(checked) => handleInput('required', checked)}
|
|
/>
|
|
<Label>
|
|
<Trans>Required field</Trans>
|
|
</Label>
|
|
</div>
|
|
<div className="flex flex-row items-center gap-2">
|
|
<Switch
|
|
className="bg-background"
|
|
checked={fieldState.readOnly}
|
|
onCheckedChange={(checked) => handleInput('readOnly', checked)}
|
|
/>
|
|
<Label>
|
|
<Trans>Read only</Trans>
|
|
</Label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|