From e7f7eadebb5c643f1fca9c07a2586d12970c628f Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Mon, 18 May 2026 17:55:37 +0800 Subject: [PATCH 1/2] feat: use multi-select for file upload accept attribute --- .../components/edit/field-edit.tsx | 91 ++++++++++++++++--- 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/src/form-builder/components/edit/field-edit.tsx b/src/form-builder/components/edit/field-edit.tsx index 398ad2f..b2cb85f 100644 --- a/src/form-builder/components/edit/field-edit.tsx +++ b/src/form-builder/components/edit/field-edit.tsx @@ -35,8 +35,16 @@ import { DrawerTitle, DrawerTrigger, } from '@/components/ui/drawer' +import { Field, FieldDescription, FieldLabel } from '@/components/ui/field' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' +import { + MultiSelect, + MultiSelectContent, + MultiSelectItem, + MultiSelectTrigger, + MultiSelectValue, +} from '@/components/ui/multi-select' import { ScrollArea } from '@/components/ui/scroll-area' import { Tooltip, @@ -160,6 +168,72 @@ const socialMediaButtonsVariants = Object.entries(socialLogsUrls).map( }), ) +const acceptAttributeOptions = [ + 'image/*', + 'image/png', + 'image/jpeg', + 'image/gif', + '.pdf', + 'application/pdf', + '.doc', + '.docx', + '.xls', + '.xlsx', + 'text/csv', + 'audio/*', + 'video/*', + '.zip', +].map((value) => ({ value, label: value })) + +function getAcceptValues(accept: unknown) { + return typeof accept === 'string' + ? accept + .split(',') + .map((value) => value.trim()) + .filter(Boolean) + : [] +} + +function AcceptAttributeMultiSelect({ + value, + onChange, +}: { + value: unknown + onChange: (values: string[]) => void +}) { + const selectedValues = getAcceptValues(value) + const options = [ + ...acceptAttributeOptions, + ...selectedValues + .filter( + (value) => + !acceptAttributeOptions.some((option) => option.value === value), + ) + .map((value) => ({ value, label: value })), + ] + + return ( + + Accept attribute + + Comma separated list of MIME types or file extensions + + + + + + + {options.map((option) => ( + + {option.label} + + ))} + + + + ) +} + function OptionsList({ options = [], onChange, @@ -679,18 +753,13 @@ function FormElementAttributes({ }} form={form} /> - { + form.setValue('accept', selectedValues.join(', '), { + shouldDirty: true, + }) }} - form={form} /> From 808780d86adf8a715d1b9489a67e0d6f156c2db1 Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Mon, 18 May 2026 19:15:24 +0800 Subject: [PATCH 2/2] chore: update file upload accept description --- src/form-builder/components/edit/field-edit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/form-builder/components/edit/field-edit.tsx b/src/form-builder/components/edit/field-edit.tsx index b2cb85f..0e75c9d 100644 --- a/src/form-builder/components/edit/field-edit.tsx +++ b/src/form-builder/components/edit/field-edit.tsx @@ -216,7 +216,7 @@ function AcceptAttributeMultiSelect({ Accept attribute - Comma separated list of MIME types or file extensions + Select MIME types or file extensions to accept