File upload

When to use this component

Use the file upload component to help users select and upload one or more files.

How it works

There are two ways of using and presenting the file upload component:

  • Single, large file upload component
  • Multile file upload components in a fieldset

Single, large file upload component

The single, large file upload component can be used to let users select and upload one or more files using a single, large file upload component with a drop area where files can be dragged to to select and upload them. See the example.

The single, large file upload component is the best solution if the user typically will or should only select and upload one single file.

Multiple file upload components in a fieldset

In some cases, especially if the user can select one or more files, for instance, one or more attachments or photos, the single, large file upload component is not the best solution.

In these cases, a smaller file upload component can be used and repeated in a fieldset. See the example.

Usage, behavior, layout and validation

The file upload component is a form element that should always be used in a form. For a description of the usage, the behavior, the layout and validation of form elements, see the form component documentation.

<!-- Default -->
<section class="file-upload">
  <div class="form-item">
    {% include '@label' with {
      "label": label,
      "for": id ~ '--' ~ _self.name,
    } %}
    <div class="form-columns">
      <div class="form-item-column">
        {% render '@file' with {
          "id": id ~ '--' ~ _self.name,
          "name": name ~ '--' ~ _self.name|default(id ~ '--' ~ _self.name),
        } %}
      </div>
      <div class="form-item-column"></div>
    </div>
  </div>
</section>

<!-- Multiple -->
<fieldset class="file-upload">
  <legend>{{ label }}</legend>

  <div class="form-item">
    {% include '@label' with {
      "label": label,
      "for": id ~ '--' ~ _self.name,
    } %}
    <div class="form-columns">
      <div class="form-item-column">
        {% render '@file' with {
          id: id ~ '--' ~ _self.name,
          name: name ~ '--' ~ _self.name|default(id ~ '--' ~ _self.name),
          multiple: true
        } %}

        <ul class="inline">
          <li>{% render '@tag--filter-tag' with { tag_text: 'my uploaded file.pdf' } %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'another_file.pdf' }  %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'my_image.jpg' }  %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'super_secret.txt' }  %}</li>
        </ul>
      </div>
      <div class="form-item-column"></div>
    </div>
  </div>

</fieldset>

<!-- Stacked -->
<fieldset class="file-upload">
  <legend>{{ label }}</legend>

  {% for i in 1..2 %}
    <div class="form-item">
      {% include '@label' with {
          "label": itemLabel|replace({'%s': i}),
          "for": id ~ '--' ~ _self.name ~ '--' ~ i,
        } %}
      <div class="form-columns">
        <div class="form-item-column">
          {% render '@file' with {
              "id":  id ~ '--' ~ _self.name ~ '--' ~ i,
              "name": (name ~ '--' ~ _self.name ~ '--' ~ i)|default( id ~ '--' ~ _self.name ~ '--' ~ i),
            } %}
        </div>
        <div class="form-item-column"></div>
      </div>
    </div>
  {% endfor %}

  {% render '@button' with {
    text: 'Add attachment',
    type: 'primary',
    modifier: 'icon-plus'
  } %}
</fieldset>
<!-- Default -->
<section class="file-upload">
    <div class="form-item">
        <label for="file-upload--default">Attachment
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--default" aria-describedby="file-upload--default-description" name="--default" />

                    <span id="file-upload--default-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>
</section>

<!-- Multiple -->
<fieldset class="file-upload">
    <legend>Attachments (max. 3)</legend>

    <div class="form-item">
        <label for="file-upload--multiple">Attachments (max. 3)
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--multiple" aria-describedby="file-upload--multiple-description" name="--multiple" multiple />

                    <span id="file-upload--multiple-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>

                <ul class="inline">
                    <li>
                        <span class="tag filter ">
                            my uploaded file.pdf
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            another_file.pdf
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            my_image.jpg
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            super_secret.txt
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                </ul>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>

</fieldset>

<!-- Stacked -->
<fieldset class="file-upload">
    <legend>Attachments (max. 3)</legend>

    <div class="form-item">
        <label for="file-upload--stacked--1">Attachment 1 of 3
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--stacked--1" aria-describedby="file-upload--stacked--1-description" name="--stacked--1" />

                    <span id="file-upload--stacked--1-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>
    <div class="form-item">
        <label for="file-upload--stacked--2">Attachment 2 of 3
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--stacked--2" aria-describedby="file-upload--stacked--2-description" name="--stacked--2" />

                    <span id="file-upload--stacked--2-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>

    <button type="button" class="button button-primary icon-plus ">
        Add attachment
    </button>
</fieldset>

/* Default */
{
  "id": "file-upload",
  "label": "Attachment"
}

/* Multiple */
{
  "id": "file-upload",
  "label": "Attachments (max. 3)"
}

/* Stacked */
{
  "id": "file-upload",
  "label": "Attachments (max. 3)",
  "itemLabel": "Attachment %s of 3"
}

  • Content:
    .file-upload {
    
      ul.inline {
        margin-top: .8rem;
    
        li {
          margin-right: .4rem;
          margin-bottom: .4rem;
        }
      }
    
      .button {
        margin-bottom: .8rem;
      }
    }
    
  • URL: /components/raw/file-upload/_file-upload.scss
  • Filesystem Path: components/31-molecules/file-upload/_file-upload.scss
  • Size: 173 Bytes