UNPKG

mui-file-input

Version:

A file input designed for the React library MUI

257 lines (250 loc) 6.18 kB
import { jsxs as y, jsx as s } from "react/jsx-runtime"; import h from "react"; import { styled as N } from "@mui/material/styles"; import U from "@mui/material/IconButton"; import b from "@mui/material/InputAdornment"; import G from "@mui/material/TextField"; import R from "@mui/material/Typography"; const Z = [ "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" ], _ = [ "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" ], j = [ "b", "kbit", "Mbit", "Gbit", "Tbit", "Pbit", "Ebit", "Zbit", "Ybit" ], O = [ "b", "kibit", "Mibit", "Gibit", "Tibit", "Pibit", "Eibit", "Zibit", "Yibit" ], F = (e, t, i) => { let n = e; return typeof t == "string" || Array.isArray(t) ? n = e.toLocaleString(t, i) : (t === !0 || i !== void 0) && (n = e.toLocaleString(void 0, i)), n; }; function A(e, t) { if (!Number.isFinite(e)) throw new TypeError(`Expected a finite number, got ${typeof e}: ${e}`); t = { bits: !1, binary: !1, space: !0, ...t }; const i = t.bits ? t.binary ? O : j : t.binary ? _ : Z, n = t.space ? " " : ""; if (t.signed && e === 0) return ` 0${n}${i[0]}`; const l = e < 0, c = l ? "-" : t.signed ? "+" : ""; l && (e = -e); let r; if (t.minimumFractionDigits !== void 0 && (r = { minimumFractionDigits: t.minimumFractionDigits }), t.maximumFractionDigits !== void 0 && (r = { maximumFractionDigits: t.maximumFractionDigits, ...r }), e < 1) { const u = F(e, t.locale, r); return c + u + n + i[0]; } const f = Math.min(Math.floor(t.binary ? Math.log(e) / Math.log(1024) : Math.log10(e) / 3), i.length - 1); e /= (t.binary ? 1024 : 1e3) ** f, r || (e = e.toPrecision(3)); const g = F(Number(e), t.locale, r), p = i[f]; return c + g + n + p; } const W = N("label")` position: relative; flex-grow: 1; input { opacity: 0 !important; } & > span { position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 2; display: flex; align-items: center; } span.MuiFileInput-placeholder { color: gray; } `, H = N("div")` display: flex; width: 100%; & > span { display: block; } & > span:first-of-type { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } & > span:last-of-type { flex-shrink: 0; display: block; } `, M = { Label: W, Filename: H }, K = ({ text: e, isPlaceholder: t, placeholder: i, ...n }, l) => /* @__PURE__ */ y(M.Label, { children: [ /* @__PURE__ */ s("input", { ...n, ref: l }), e ? /* @__PURE__ */ s( "span", { "aria-placeholder": i, className: t ? "MuiFileInput-placeholder" : "", children: typeof e == "string" ? e : /* @__PURE__ */ y(M.Filename, { children: [ /* @__PURE__ */ s("span", { children: e.filename }), /* @__PURE__ */ y("span", { children: [ ".", e.extension ] }) ] }) } ) : null ] }), V = h.forwardRef(K); function q(e) { return e.length > 0; } function J(e) { return e.reduce((t, i) => t + i.size, 0); } function B(e) { return typeof window < "u" && e instanceof File; } function Q(e) { return Array.from(e); } function X(e) { const i = (B(e) ? e.name : e[0]?.name || "").split("."), n = i.pop(); return { filename: i.join("."), extension: n }; } const tt = typeof window < "u" ? h.useLayoutEffect : h.useEffect, at = (e) => { const { value: t, onChange: i, disabled: n, getInputText: l, getSizeText: c, placeholder: r, hideSizeText: f, ref: g, inputProps: p, InputProps: u, multiple: I, className: P, clearIconButtonProps: S = {}, ...E } = e, { className: w = "", ...v } = S, d = h.useRef(null), { startAdornment: C, ...z } = u || {}, L = I || p?.multiple || u?.inputProps?.multiple || !1, T = () => { d.current && (d.current.value = ""); }, D = (o) => { const x = o.target.files, m = x ? Q(x) : []; I ? (i?.(m), m.length === 0 && T()) : (i?.(m[0] || null), m[0] || T()); }, $ = (o) => { o.preventDefault(), !n && i?.(I ? [] : null); }, a = Array.isArray(t) ? q(t) : B(t); tt(() => { const o = d.current; o && !a && (o.value = ""); }, [a]); const k = () => t === null || Array.isArray(t) && t.length === 0 ? r || "" : typeof l == "function" && t !== void 0 ? l(t) : t && a ? Array.isArray(t) && t.length > 1 ? `${t.length} files` : X(t) : "", Y = () => { if (typeof c == "function" && t !== void 0) return c(t); if (a) { if (Array.isArray(t)) { const o = J(t); return A(o); } if (B(t)) return A(t.size); } return ""; }; return /* @__PURE__ */ s( G, { ref: g, type: "file", disabled: n, onChange: D, className: `MuiFileInput-TextField ${P || ""}`, InputProps: { startAdornment: /* @__PURE__ */ s(b, { position: "start", children: C }), endAdornment: /* @__PURE__ */ y( b, { position: "end", style: { visibility: a ? "visible" : "hidden" }, children: [ f ? null : /* @__PURE__ */ s( R, { variant: "caption", mr: "2px", lineHeight: 1, className: "MuiFileInput-Typography-size-text", children: Y() } ), /* @__PURE__ */ s( U, { "aria-label": "Clear", title: "Clear", size: "small", disabled: n, className: `${w} MuiFileInput-ClearIconButton`, onClick: $, ...v } ) ] } ), ...z, inputProps: { text: k(), multiple: L, ref: d, isPlaceholder: !a, placeholder: r, ...p, ...u?.inputProps }, // @ts-expect-error inputComponent: V }, ...E } ); }; export { at as MuiFileInput };