@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
1 lines • 7.91 kB
Source Map (JSON)
{"version":3,"file":"FileInput.cjs","names":["genericFactory","useProps","useResolvedStylesApi","CloseButton","FileButton","InputBase","Input"],"sources":["../../../src/components/FileInput/FileInput.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { useMergedRef, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n ElementProps,\n Factory,\n genericFactory,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n} from '../../core';\nimport { CloseButton } from '../CloseButton';\nimport { FileButton } from '../FileButton';\nimport {\n __BaseInputProps,\n __InputStylesNames,\n ClearSectionMode,\n Input,\n InputVariant,\n} from '../Input';\nimport { InputBase } from '../InputBase/InputBase';\n\nexport interface FileInputProps<Multiple = false>\n extends\n BoxProps,\n __BaseInputProps,\n StylesApiProps<FileInputFactory>,\n ElementProps<'button', 'value' | 'defaultValue' | 'onChange' | 'placeholder'> {\n component?: any;\n\n /** Called when value changes */\n onChange?: (payload: Multiple extends true ? File[] : File | null) => void;\n\n /** Controlled component value */\n value?: Multiple extends true ? File[] : File | null;\n\n /** Uncontrolled component default value */\n defaultValue?: Multiple extends true ? File[] : File | null;\n\n /** If set, user can pick more than one file @default false */\n multiple?: Multiple;\n\n /** File input accept attribute, for example, `\"image/png,image/jpeg\"` */\n accept?: string;\n\n /** Input name attribute */\n name?: string;\n\n /** Input form attribute */\n form?: string;\n\n /** Value renderer. By default, displays file name. */\n valueComponent?: React.FC<{ value: null | File | File[] }>;\n\n /** If set, the clear button is displayed in the right section @default false */\n clearable?: boolean;\n\n /** Determines how the clear button and rightSection are rendered @default 'both' */\n clearSectionMode?: ClearSectionMode;\n\n /** Props passed down to the clear button */\n clearButtonProps?: React.ComponentProps<'button'>;\n\n /** If set, the input value cannot be changed */\n readOnly?: boolean;\n\n /** Specifies that, optionally, a new file should be captured, and which device should be used to capture that new media of a type defined by the accept attribute. */\n capture?: boolean | 'user' | 'environment';\n\n /** Props passed down to the hidden `input[type=\"file\"]` */\n fileInputProps?: React.ComponentProps<'input'>;\n\n /** Input placeholder */\n placeholder?: React.ReactNode;\n\n /** Reference of the function that should be called when value changes to null or empty array */\n resetRef?: React.Ref<() => void>;\n}\n\nexport type FileInputFactory = Factory<{\n props: FileInputProps;\n ref: HTMLButtonElement;\n stylesNames: __InputStylesNames | 'placeholder';\n variant: InputVariant;\n signature: <Multiple extends boolean = false>(\n props: FileInputProps<Multiple>\n ) => React.JSX.Element;\n}>;\n\nconst DefaultValue: FileInputProps['valueComponent'] = ({ value }) => (\n <div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {Array.isArray(value) ? value.map((file) => file.name).join(', ') : value?.name}\n </div>\n);\n\nconst defaultProps = {\n valueComponent: DefaultValue,\n size: 'sm',\n} satisfies Partial<FileInputProps>;\n\nexport const FileInput = genericFactory<FileInputFactory>((_props) => {\n const props = useProps('FileInput', defaultProps, _props);\n const {\n unstyled,\n vars,\n onChange,\n value,\n defaultValue,\n multiple,\n accept,\n name,\n form,\n valueComponent: ValueComponent,\n clearable,\n clearSectionMode,\n clearButtonProps,\n readOnly,\n capture,\n fileInputProps,\n rightSection,\n size,\n placeholder,\n component,\n resetRef: resetRefProp,\n classNames,\n styles,\n attributes,\n ...others\n } = props;\n\n const resetRef = useRef<() => void>(null);\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<FileInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const [_value, setValue] = useUncontrolled<null | File | File[]>({\n value,\n defaultValue,\n onChange: onChange as any,\n finalValue: multiple ? [] : null,\n });\n\n const hasValue = Array.isArray(_value) ? _value.length !== 0 : _value !== null;\n\n const clearButton = (\n <CloseButton\n {...clearButtonProps}\n variant=\"subtle\"\n onClick={() => setValue(multiple ? [] : null)}\n size={size}\n unstyled={unstyled}\n />\n );\n\n const _clearable = clearable && hasValue && !readOnly;\n\n useEffect(() => {\n if ((Array.isArray(_value) && _value.length === 0) || _value === null) {\n resetRef.current?.();\n }\n }, [_value]);\n\n return (\n <FileButton\n onChange={setValue}\n multiple={multiple}\n accept={accept}\n name={name}\n form={form}\n resetRef={useMergedRef(resetRef, resetRefProp)}\n disabled={readOnly}\n capture={capture}\n inputProps={fileInputProps}\n >\n {(fileButtonProps) => (\n <InputBase\n component={component || 'button'}\n rightSection={rightSection}\n __clearSection={clearButton}\n __clearable={_clearable}\n __clearSectionMode={clearSectionMode}\n {...fileButtonProps}\n {...others}\n __staticSelector=\"FileInput\"\n multiline\n type=\"button\"\n pointer\n __stylesApiProps={props}\n unstyled={unstyled}\n size={size}\n classNames={classNames}\n styles={styles}\n attributes={attributes}\n >\n {!hasValue ? (\n <Input.Placeholder\n __staticSelector=\"FileInput\"\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n attributes={attributes}\n >\n {placeholder}\n </Input.Placeholder>\n ) : (\n <ValueComponent value={_value} />\n )}\n </InputBase>\n )}\n </FileButton>\n );\n});\n\nFileInput.classes = InputBase.classes;\nFileInput.displayName = '@mantine/core/FileInput';\n"],"mappings":";;;;;;;;;;;;;AAyFA,MAAM,gBAAkD,EAAE,YACxD,iBAAA,GAAA,kBAAA,KAAC,OAAD;CAAK,OAAO;EAAE,UAAU;EAAU,cAAc;EAAY,YAAY;EAAU;WAC/E,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC,KAAK,KAAK,GAAG,OAAO;CACvE,CAAA;AAGR,MAAM,eAAe;CACnB,gBAAgB;CAChB,MAAM;CACP;AAED,MAAa,YAAYA,gBAAAA,gBAAkC,WAAW;CACpE,MAAM,QAAQC,kBAAAA,SAAS,aAAa,cAAc,OAAO;CACzD,MAAM,EACJ,UACA,MACA,UACA,OACA,cACA,UACA,QACA,MACA,MACA,gBAAgB,gBAChB,WACA,kBACA,kBACA,UACA,SACA,gBACA,cACA,MACA,aACA,WACA,UAAU,cACV,YACA,QACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAA,GAAA,MAAA,QAA8B,KAAK;CACzC,MAAM,EAAE,oBAAoB,mBAAmBC,gCAAAA,qBAAuC;EACpF;EACA;EACA;EACD,CAAC;CAEF,MAAM,CAAC,QAAQ,aAAA,GAAA,eAAA,iBAAkD;EAC/D;EACA;EACU;EACV,YAAY,WAAW,EAAE,GAAG;EAC7B,CAAC;CAEF,MAAM,WAAW,MAAM,QAAQ,OAAO,GAAG,OAAO,WAAW,IAAI,WAAW;CAE1E,MAAM,cACJ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,aAAD;EACE,GAAI;EACJ,SAAQ;EACR,eAAe,SAAS,WAAW,EAAE,GAAG,KAAK;EACvC;EACI;EACV,CAAA;CAGJ,MAAM,aAAa,aAAa,YAAY,CAAC;AAE7C,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAK,MAAM,QAAQ,OAAO,IAAI,OAAO,WAAW,KAAM,WAAW,KAC/D,UAAS,WAAW;IAErB,CAAC,OAAO,CAAC;AAEZ,QACE,iBAAA,GAAA,kBAAA,KAACC,mBAAAA,YAAD;EACE,UAAU;EACA;EACF;EACF;EACA;EACN,WAAA,GAAA,eAAA,cAAuB,UAAU,aAAa;EAC9C,UAAU;EACD;EACT,YAAY;aAEV,oBACA,iBAAA,GAAA,kBAAA,KAACC,kBAAAA,WAAD;GACE,WAAW,aAAa;GACV;GACd,gBAAgB;GAChB,aAAa;GACb,oBAAoB;GACpB,GAAI;GACJ,GAAI;GACJ,kBAAiB;GACjB,WAAA;GACA,MAAK;GACL,SAAA;GACA,kBAAkB;GACR;GACJ;GACM;GACJ;GACI;aAEX,CAAC,WACA,iBAAA,GAAA,kBAAA,KAACC,cAAAA,MAAM,aAAP;IACE,kBAAiB;IACjB,YAAY;IACZ,QAAQ;IACI;cAEX;IACiB,CAAA,GAEpB,iBAAA,GAAA,kBAAA,KAAC,gBAAD,EAAgB,OAAO,QAAU,CAAA;GAEzB,CAAA;EAEH,CAAA;EAEf;AAEF,UAAU,UAAUD,kBAAAA,UAAU;AAC9B,UAAU,cAAc"}