City of Ghent Style Guide

No notes defined.

File

<div class="file" data-file="No file chosen.">

  <input type="file" id="{{ id }}"
      aria-describedby="{{ id  ~ '-description' }}"
    {% if name %}
      name="{{ name }}"
    {% endif %}
    {% if value %}
      value="{{ value }}"
    {% endif %}
    {% if disabled %}
      disabled="disabled"
    {% endif %}
    {% if required %}
      required="{{ required }}"
    {% endif %}
    {% if invalid %}
      aria-invalid="{{ invalid }}"
    {% endif %}
    {% if multiple %}
      multiple
    {% endif %}
  />

  <span id="{{ id ~ '-description' }}" class="file__button">{{ buttonText|default('Select your files here to upload') }}</span>
</div>

{% if help %}
  <span class="help-text">{{ help }}</span>
{% endif %}
<div class="file" data-file="No file chosen.">

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

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

<span class="help-text">Allowed file formats: jpg, jpeg, png and gif. Maximum file size: 2 MB. Images must be larger than 744x465 pixels.</span>
{
  "id": "file",
  "help": "Allowed file formats: jpg, jpeg, png and gif. Maximum file size: 2 MB. Images must be larger than 744x465 pixels."
}
  • Content:
    .file {
      display: inline-flex;
      position: relative;
      flex-wrap: wrap;
      align-items: center;
      max-width: 100%;
      margin: 0 -.6rem;
      margin-top: .2rem;
    
      .file__button {
        @include button;
        @include button-small;
        @include theme('background-color', 'color-secondary', 'button-secondary-background');
        @include theme('color', 'color-primary', 'button-secondary-color');
        @include theme('border-color', 'color-primary--lighten-1', 'button-secondary-border-color');
    
        max-width: 100%;
        margin: 0 .6rem;
        padding-top: .6rem;
        padding-bottom: .6rem;
        content: attr(data-text);
      }
    
      &::after {
        max-width: 100%;
        margin: .6rem;
        color: color('dark-gray', -1);
        font-size: .7rem;
        font-style: italic;
        text-overflow: ellipsis;
        content: attr(data-file);
        overflow: hidden;
      }
    
      input[type="file"] {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        cursor: pointer;
        opacity: 0;
    
        &:disabled {
          pointer-events: none;
    
          + .file__button {
            @include button-disabled;
          }
        }
    
        &:hover + .file__button,
        &:focus + .file__button,
        &:focus-within + .file__button {
          @include theme('background-color', 'color-primary--lighten-5', 'button-secondary-hover-background');
          @include theme('color', 'color-primary', 'button-secondary-hover-color');
          @include theme('border-color', 'color-primary--lighten-2', 'button-secondary-hover-border-color');
        }
    
        &:active + .file__button {
          @include theme('background-color', 'color-primary--lighten-3', 'button-secondary-focus-background');
          @include theme('color', 'color-primary--darken-3', 'button-secondary-focus-color');
          @include theme('border-color', 'color-primary', 'button-secondary-focus-border-color');
    
          box-shadow: none;
        }
    
        &:focus + .file__button {
          @include focus-bare;
        }
      }
    
      +.help-text {
        @include theme('color', 'color-tertiary--lighten-1', 'file-size-color');
        display: block;
        margin-top: .4rem;
        font-size: .6rem;
      }
    }
    
  • URL: /components/raw/file/_file.scss
  • Filesystem Path: components/21-atoms/file/_file.scss
  • Size: 2.1 KB
  • Content:
    'use strict';
    
    (function () {
    
      if (!File) {
        return;
      }
    
      const selected = document.querySelectorAll('.file');
      for (let i = selected.length; i--;) {
        new File(selected[i]);
      }
    
    })();
    
  • URL: /components/raw/file/file.bindings.js
  • Filesystem Path: components/21-atoms/file/file.bindings.js
  • Size: 196 Bytes
  • Content:
    'use strict';
    
    (function (root, factory) {
      if (typeof define === 'function' && define.amd) {
        define(factory);
      }
      else {
        if (typeof exports === 'object') {
          module.exports = factory();
        }
        else {
          root.File = factory();
        }
      }
    }(this || window, function () {
      return function (elem, options) {
        const input = elem.querySelector('input[type="file"]');
    
        if (!input) {
          throw new Error('Element input[type="file"] not found.');
        }
    
        options = options || {};
    
        /**
         * Update the filename of the uploaded file.
         *
         * @param {Event} e
         *  Event object for the change event.
         *
         */
        const updateFile = e => {
          if (!input.files.length) {
            elem.dataset.file = options.emptyText || elem.dataset.emptyText || 'No file chosen.';
            return;
          }
    
          if (input.files.length > 1) {
            elem.dataset.file = options.multipleText || elem.dataset.multipleText || 'Multiple files.';
            return;
          }
    
          elem.dataset.file = input.files[0].name;
        };
    
        /**
         * Initialize the FileUpload component
         */
        const init = () => {
          if (input.hasAttribute('multiple')) {
            return;
          }
    
          input.addEventListener('change', updateFile);
          updateFile();
        };
    
        init();
    
        return {updateFile};
      };
    }));
    
  • URL: /components/raw/file/file.functions.js
  • Filesystem Path: components/21-atoms/file/file.functions.js
  • Size: 1.3 KB