@stihl-design-system/components
Version:
Welcome to the STIHL Design System react component library.
261 lines (260 loc) • 10.8 kB
JavaScript
"use client";
import { jsxs as I, Fragment as ve, jsx as i } from "react/jsx-runtime";
import { c as p } from "./index.DQOqod3i.js";
import { forwardRef as Se, useState as te, useRef as Fe, useCallback as we } from "react";
import { f as ke } from "./AriaLiveRegions.utils.xoETe2Ps.js";
import { Asterisk as ze } from "../asterisk.Dwtdwpkq.js";
import { D as Ne } from "./Button.CCol--xy.js";
import { D as Le } from "./Icon.DYtaQgbw.js";
import { D as Be } from "./Popover.CxZZ_y1Z.js";
import { D as Pe } from "./SystemFeedback.DhWcYjnu.js";
import { FileList as Te } from "../filelist.CabPo1pv.js";
import { g as y } from "./helpers.CexwVao7.js";
import { u as q } from "./useBreakpoint.1txsny17.js";
import { t as Ce } from "./translate.DSb-TdWR.js";
import '../assets/InputFile.CDtghZtl.css';const Ae = "ds-input-file_root_sryt8_1", $e = "ds-input-file_browse-button--is-dragging-filled_sryt8_1", Ue = "ds-input-file_browse-button--is-dragging_sryt8_1", We = "ds-input-file_hint_sryt8_14", qe = "ds-input-file_label-wrapper_sryt8_14", Re = "ds-input-file_label_sryt8_14", Ee = "ds-input-file_label--disabled_sryt8_33", xe = "ds-input-file_label--dark_sryt8_37", He = "ds-input-file_label-wrapper--hidden_sryt8_53", Me = "ds-input-file_hint--dark_sryt8_80", Oe = "ds-input-file_feedback_sryt8_84", Ve = "ds-input-file_dropzone_sryt8_88", je = "ds-input-file_dropzone--disabled_sryt8_94", Ze = "ds-input-file_dropzone--invalid_sryt8_108", Ge = "ds-input-file_dropzone--is-dragging_sryt8_111", Je = "ds-input-file_hint-drop-zone_sryt8_114", Ke = "ds-input-file_upload-icon_sryt8_117", Qe = "ds-input-file_browse-button-dropzone--is-dragging_sryt8_120", Xe = "ds-input-file_instructions_sryt8_123", Ye = "ds-input-file_root--dark_sryt8_161", et = "ds-input-file_dropzone--dark_sryt8_168", tt = "ds-input-file_input_sryt8_199", ot = "ds-input-file_required-sr-info_sryt8_203", e = {
root: Ae,
browseButtonIsDraggingFilled: $e,
browseButtonIsDragging: Ue,
hint: We,
labelWrapper: qe,
label: Re,
labelDisabled: Ee,
labelDark: xe,
labelWrapperHidden: He,
hintDark: Me,
feedback: Oe,
dropzone: Ve,
dropzoneDisabled: je,
dropzoneInvalid: Ze,
dropzoneIsDragging: Ge,
hintDropZone: Je,
uploadIcon: Ke,
browseButtonDropzoneIsDragging: Qe,
instructions: Xe,
rootDark: Ye,
dropzoneDark: et,
input: tt,
requiredSrInfo: ot
}, nt = {
dragAndDropInstructions: "Drag and drop files here or",
feedbackFileSize: "File too large. Maximum file size is",
feedbackFileType: "File type not allowed",
fileListRemoveSelectionButtonLabel: "Remove {fileName} from selected files",
fileListCancelUploadButtonLabel: "Cancel upload of {fileName}",
fileListDeleteFileButtonLabel: "Delete file {fileName}",
fileListIndeterminate: "{fileName} is uploading",
fileListPreviewAltText: "Preview of {fileName}",
filesSelectedHint: "The following files are selected",
required: "required",
uploadStatus: "Upload status",
uploading: "Uploading...",
success: "Upload complete",
retry: "Retry upload",
togglePopover: "Toggle popover"
}, it = {
dragAndDropInstructions: "Dateien hier hin ziehen oder",
feedbackFileSize: "Datei zu groß. Maximale Dateigröße ist",
feedbackFileType: "Dateityp nicht zugelassen",
fileListRemoveSelectionButtonLabel: "Datei {fileName} aus der Auswahl entfernen",
fileListCancelUploadButtonLabel: "Upload von {fileName} abbrechen",
fileListDeleteFileButtonLabel: "Datei {fileName} löschen",
fileListIndeterminate: "{fileName} wird hochgeladen",
fileListPreviewAltText: "Vorschau von {fileName}",
filesSelectedHint: "Die folgenden Dateien sind ausgewählt",
required: "erforderlich",
uploadStatus: "Upload-Status",
uploading: "Wird hochgeladen...",
success: "Upload abgeschlossen",
retry: "Upload erneut versuchen",
togglePopover: "Popover öffnen/schließen"
}, z = {
en: nt,
de: it
}, st = (c, d) => {
const n = d.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean), u = c.name.toLowerCase(), r = c.type.toLowerCase();
return n.some((a) => {
if (a.startsWith("."))
return u.endsWith(a);
if (a.endsWith("/*")) {
const [s] = r.split("/");
return s === a.slice(0, -2);
}
return r === a;
});
}, rt = ({
id: c,
label: d,
inputFileButtonProps: n,
hideLabel: u,
popoverContent: r
}) => {
if (!c)
throw new Error(y("DSInputFile", 'A unique "id" prop is required. Please add a unique "id" prop to the DSInputFile component.'));
if (!d)
throw new Error(y("DSInputFile", `A label is always required for a11y reasons. Please add a descriptive "label" prop to the DSInputFile component. If you don't want to display a label, set hideLabel={true}.`));
if (n && n.label?.trim() === "")
throw new Error(y("DSInputFile", "The input file button needs to have a label for a11y reasons. Please add a label to the inputFileButtonProps."));
if (n && n.variant && n.variant !== "outline" && n.variant !== "filled")
throw new Error(y("DSInputFile", "The inputFileButtonProps variant value can only be 'outline' for DSInputFile components inside forms or 'filled' for standalone DSInputFile components."));
u && r && console.warn(y("DSInputFile", "Using a popover when hideLabel is set to true is not supported."));
}, at = Se((c, d) => {
const {
id: n,
label: u,
accept: r,
className: a,
disabled: s = !1,
files: f,
hideLabel: R = !1,
hint: h,
inputFileButtonProps: E,
invalid: v = !1,
isHintOutsideDropzone: oe = {
base: !0,
m: !1
},
lang: S = "en",
maxSizeInMb: N = 7,
multiple: _ = !1,
popoverContent: L,
popoverInfoButtonProps: x,
required: H = !1,
showFileList: ne = !0,
showDropzone: b = !1,
systemFeedback: B,
theme: g = "light",
translations: P,
onFilesSelect: T,
showProgress: ie,
...se
} = c, m = Ce(P || z[S] || z.en, S);
process.env.NODE_ENV !== "production" && rt({
id: n,
label: u,
inputFileButtonProps: E,
hideLabel: q(R),
popoverContent: L
});
const {
label: re = S === "en" ? `Choose File${_ ? "s" : ""}` : `Datei${_ ? "en" : ""} auswählen`,
variant: C = "outline",
...ae
} = E || {}, [M, O] = te([]), le = {
...x,
label: P && P.togglePopover || x?.label || (z[S] || z.en).togglePopover
}, F = Fe(null), [D, A] = te(!1), de = N * 1024 * 1024, $ = `${n}-label`, V = `${n}-feedback`, U = `${n}-hint`, j = h ? ` ${U}` : "", Z = q(R), G = q(oe), w = g === "dark", pe = p(e.root, a, {
[e.rootDark]: w
}), ce = p(e.dropzone, {
[e.dropzoneDark]: w,
[e.dropzoneDisabled]: s,
[e.dropzoneInvalid]: v,
[e.dropzoneIsDragging]: D
}), ue = p(e.label, {
[e.labelDark]: w,
[e.labelDisabled]: s
}), fe = p(e.labelWrapper, {
// hide label only visually to keep them available for assistive technologies
[e.labelWrapperHidden]: Z
}), be = p(e.browseButton, {
[e.browseButtonIsDragging]: D && C === "outline",
[e.browseButtonIsDraggingFilled]: D && C === "filled"
}), ge = p(e.browseButtonDropzone, {
[e.browseButtonDropzoneIsDragging]: D
}), me = [v && B && V].filter(Boolean).join(" ") || void 0, De = (t) => {
F.current = t, typeof d == "function" ? d(t) : d && (d.current = t);
}, J = (t) => {
if (!t)
return;
const l = [];
for (const o of t)
if (r && !st(o, r) && (o.feedback = `${m("feedbackFileType")}: ${o.type}.`, o.uploadStatus = "error"), o.size > de && (o.feedback = `${m("feedbackFileSize")} ${N} MB.`, o.uploadStatus = "error"), o.uploadPercent = "indeterminate", l.push(o), !_ && l.length > 0)
break;
l.length > 0 && !f && O(() => {
const o = [...l], k = o.map(({
name: W,
feedback: ye = ""
}) => `${W} ${ye}`).join(", ");
return setTimeout(() => {
Ie(`${m("filesSelectedHint")}: ${k}.`);
}, 1e3), o;
}), T?.(l);
}, K = (t) => {
s || (F.current?.click(), t.stopPropagation());
}, Q = (t) => {
t.preventDefault(), D || A(!0);
}, X = (t) => {
t.preventDefault(), D && A(!1);
}, Y = we((t) => {
t.preventDefault(), !s && (A(!1), J(t.dataTransfer.files));
}, [_, r, N, s]), he = (t) => {
J(t.target.files), F?.current && (F.current.value = "");
}, _e = (t) => {
if (f) {
const l = f.filter((o, k) => k !== t);
T?.(l);
} else
O((l) => {
const o = l.filter((k, W) => W !== t);
return T?.(o), o;
});
}, Ie = (t) => {
ke(t, "DSInputFile");
}, ee = () => /* @__PURE__ */ i(Ne, { ...ae, className: b ? ge : be, type: "button", variant: C, size: b ? "small" : "medium", disabled: s, iconName: b ? void 0 : "upload", onClick: K, "aria-describedby": me, "aria-invalid": v, theme: g, children: re });
return /* @__PURE__ */ I("div", { className: pe, children: [
/* @__PURE__ */ I("div", { className: fe, children: [
/* @__PURE__ */ I("label", { className: ue, id: $, htmlFor: n, children: [
u,
H && /* @__PURE__ */ I(ve, { children: [
/* @__PURE__ */ i(ze, {}),
/* @__PURE__ */ i("span", { className: e.requiredSrInfo, children: m("required") })
] })
] }),
L && !Z && /* @__PURE__ */ i(Be, { placement: "top", defaultAnchorButtonProps: le, theme: g, children: L })
] }),
h && (G || !b) && /* @__PURE__ */ i("div", { className: p(e.hint, {
[e.hintDark]: w
}), id: U, children: h }),
!b && /* @__PURE__ */ i(
"div",
{
onDragOver: Q,
onDragLeave: X,
onDrop: Y,
"aria-labelledby": `${$}${j}`,
"aria-disabled": s,
children: ee()
}
),
b && /* @__PURE__ */ I(
"div",
{
className: ce,
onClick: (t) => K(t),
onDragOver: Q,
onDragLeave: X,
onDrop: Y,
"aria-labelledby": `${$}${j}`,
"aria-disabled": s,
children: [
/* @__PURE__ */ i(Le, { name: "upload", className: e.uploadIcon, size: "x-large", theme: g }),
/* @__PURE__ */ i("p", { id: "file-upload-instructions", className: e.instructions, children: m("dragAndDropInstructions") }),
ee(),
h && !G && /* @__PURE__ */ i("div", { className: e.hintDropZone, id: U, children: h })
]
}
),
/* @__PURE__ */ i("input", { ...se, type: "file", className: e.input, id: n, ref: De, accept: r, multiple: _, "aria-hidden": "true", required: H, disabled: s, onChange: he }),
v && B && /* @__PURE__ */ i(Pe, { className: e.feedback, message: B, variant: "error", id: V, theme: g }),
(f ? f.length > 0 : M.length > 0) && ne && /* @__PURE__ */ i(Te, { files: f || M, onRemoveFile: _e, t: m, showProgress: ie, theme: g })
] });
});
at.displayName = "DSInputFile";
export {
at as D,
z as a,
it as b,
nt as c,
st as f,
rt as v
};