mittwald Flow Logo

Components

FileField

Das FileField stellt eine kompakte Lösung dar, um Uploads von Dateien zu ermöglichen.GitHub

Playground

Verwende <FileField />, um ein FileField darzustellen. Innerhalb des FileFields kommen die Components Label und Button zum Einsatz.

import {
  Button,
  FileField,
  Label,
} from "@mittwald/flow-react-components";

<FileField>
  <Label>Zertifikat</Label>
  <Button variant="outline" color="secondary">
    Auswählen
  </Button>
</FileField>

Disabled

Ist das FileField disabled, ist keine Interaktion möglich. Sobald die Ursache behoben ist, kann es wieder wie gewohnt verwendet werden.

import {
  Button,
  FileField,
  Label,
} from "@mittwald/flow-react-components";

<FileField isDisabled>
  <Label>Zertifikat</Label>
  <Button variant="outline" color="secondary">
    Auswählen
  </Button>
</FileField>

Mit FieldDescription

Um wichtige Hinweise zum FileField bereitzustellen, kann unterhalb eine <FieldDescription /> eingebaut werden. In vielen Fällen empfiehlt es sich, die erlaubten Dateitypen dort anzugeben.

Erlaubte Dateitypen sind .jpeg und .png
import {
  Button,
  FieldDescription,
  FileField,
  Label,
} from "@mittwald/flow-react-components";

<FileField accept={"image/png, image/jpeg"}>
  <Label>Zertifikat</Label>
  <Button variant="outline" color="secondary">
    Auswählen
  </Button>
  <FieldDescription>
    Erlaubte Dateitypen sind .jpeg und .png
  </FieldDescription>
</FileField>

Invalid

Bei ungültiger Eingabe wird das FileField invalidiert. Über <FieldError /> kann eine entsprechende Fehlermeldung ausgegeben werden.

Wir konnten das Zertifikat nicht hochladen. Bitte verwende eine .txt-Datei.
import {
  Button,
  FieldError,
  FileField,
  Label,
} from "@mittwald/flow-react-components";

<FileField isInvalid>
  <Label>Zertifikat</Label>
  <Button variant="outline" color="secondary">
    Auswählen
  </Button>
  <FieldError>
    Wir konnten das Zertifikat nicht hochladen. Bitte
    verwende eine .txt-Datei.
  </FieldError>
</FileField>

Kombiniere mit ...

ContextualHelp

Verwende ContextualHelp, um zusätzliche Informationen bereitzustellen.

import {
  Button,
  ContextualHelp,
  ContextualHelpTrigger,
  FileField,
  Heading,
  Label,
  Text,
} from "@mittwald/flow-react-components";

<FileField>
  <Label>
    Zertifikat
    <ContextualHelpTrigger>
      <Button />
      <ContextualHelp>
        <Heading>Weitere Informationen</Heading>
        <Text>
          Hier gibt es weitere Informationen, die zu lang
          für die FieldDescription sind.
        </Text>
      </ContextualHelp>
    </ContextualHelpTrigger>
  </Label>
  <Button variant="outline" color="secondary">
    Auswählen
  </Button>
</FileField>

React Hook Form

Weitere Details zur Formularlogik und -validierung ist in der Component Form (React Hook Form) zu finden.

    import {
      Button,
      FileCard,
      FileCardList,
      FileField,
      Label,
      Section,
    } from "@mittwald/flow-react-components";
    import { useForm } from "react-hook-form";
    import {
      Form,
      typedField,
    } from "@mittwald/flow-react-components/react-hook-form";
    import { sleep } from "@/content/03-components/actions/action/examples/lib";
    
    export default () => {
      const form = useForm<{
        files: FileList | File[] | [];
      }>({ defaultValues: { files: [] } });
      const Field = typedField(form);
    
      const watchedFiles = [...form.watch("files")];
    
      return (
        <Section>
          <Form form={form} onSubmit={sleep}>
            <Field
              name="files"
              rules={{
                required:
                  "Bitte wähle mindestens eine Datei aus",
              }}
            >
              <FileField multiple>
                <Label>Dateien</Label>
                <Button variant="outline" color="secondary">
                  Auswählen
                </Button>
              </FileField>
            </Field>
            <FileCardList>
              {watchedFiles.map((file) => (
                <FileCard
                  name={file.name}
                  type={file.type}
                  key={file.name}
                  sizeInBytes={file.size}
                  onDelete={() =>
                    form.setValue(
                      "files",
                      watchedFiles.filter(
                        (watched) => watched !== file,
                      ),
                    )
                  }
                />
              ))}
            </FileCardList>
            <Button type="submit">Hochladen</Button>
          </Form>
        </Section>
      );
    }
    

    Overview