UNPKG

@ishitatsuyuki/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

230 lines (224 loc) 8.28 kB
'use strict'; var vue = require('vue'); var BaseComponentMixin = require('./BaseComponentMixin-a03c02e3.js'); var FormElementMixin = require('./FormElementMixin-facf6e30.js'); var ssr = require('./ssr-4e5033ea.js'); /** * Upload one or more files * @displayName Upload * @style _upload.scss */ var script = vue.defineComponent({ name: 'OUpload', mixins: [BaseComponentMixin.BaseComponentMixin, FormElementMixin.FormElementMixin], configField: 'upload', inheritAttrs: false, emits: ['update:modelValue'], props: { /** @model */ modelValue: [Object, ssr.File, Array], /** Same as native, also push new item to v-model instead of replacing */ multiple: Boolean, /** Same as native disabled */ disabled: Boolean, /** Same as native accept */ accept: String, /** Accepts drag & drop and change its style */ dragDrop: Boolean, /** * Color of the control, optional * @values primary, info, success, warning, danger, and any other custom color */ variant: { type: String }, /** Replace last chosen files every time (like native file input element) */ native: { type: Boolean, default: false }, /** Upload will be expanded (full-width) */ expanded: { type: Boolean, default: false }, rootClass: [String, Function, Array], draggableClass: [String, Function, Array], variantClass: [String, Function, Array], expandedClass: [String, Function, Array], disabledClass: [String, Function, Array], hoveredClass: [String, Function, Array] }, data() { return { newValue: this.modelValue, dragDropFocus: false }; }, computed: { rootClasses() { return [ this.computedClass('rootClass', 'o-upl'), { [this.computedClass('expandedClass', 'o-upl--expanded')]: this.expanded }, { [this.computedClass('disabledClass', 'o-upl--disabled')]: this.disabled } ]; }, draggableClasses() { return [ this.computedClass('draggableClass', 'o-upl__draggable'), { [this.computedClass('hoveredClass', 'o-upl__draggable--hovered')]: !this.variant && this.dragDropFocus }, { [this.computedClass('variantClass', 'o-upl__draggable--hovered-', this.variant)]: this.variant && this.dragDropFocus }, ]; }, $elementRef() { return 'input'; } }, watch: { /** * When v-model is changed: * 1. Set internal value. * 2. Reset interna input file value * 3. If it's invalid, validate again. */ modelValue(value) { this.newValue = value; if (!value || (Array.isArray(value) && value.length === 0)) { this.$refs.input.value = null; } !this.isValid && !this.dragDrop && this.checkHtml5Validity(); }, }, methods: { /** * Listen change event on input type 'file', * emit 'input' event and validate */ onFileChange(event) { if (this.disabled) return; if (this.dragDrop) this.updateDragDropFocus(false); const value = event.target.files || event.dataTransfer.files; if (value.length === 0) { if (!this.newValue) return; if (this.native) this.newValue = null; } else if (!this.multiple) { // only one element in case drag drop mode and isn't multiple if (this.dragDrop && value.length !== 1) return; else { const file = value[0]; if (this.checkType(file)) this.newValue = file; else if (this.newValue) { this.newValue = null; this.clearInput(); } else { // Force input back to empty state and recheck validity this.clearInput(); this.checkHtml5Validity(); return; } } } else { // always new values if native or undefined local let newValues = false; if (this.native || !this.newValue) { this.newValue = []; newValues = true; } for (let i = 0; i < value.length; i++) { const file = value[i]; if (this.checkType(file)) { this.newValue.push(file); newValues = true; } } if (!newValues) return; } this.$emit('update:modelValue', this.newValue); !this.dragDrop && this.checkHtml5Validity(); }, /* * Reset file input value */ clearInput() { this.$refs.input.value = null; }, /** * Listen drag-drop to update internal variable */ updateDragDropFocus(focus) { if (!this.disabled) { this.dragDropFocus = focus; } }, /** * Check mime type of file */ checkType(file) { if (!this.accept) return true; const types = this.accept.split(','); if (types.length === 0) return true; for (let i = 0; i < types.length; i++) { const type = types[i].trim(); if (type) { if (type.substring(0, 1) === '.') { const extension = file.name.toLowerCase().slice(-type.length); if (extension === type.toLowerCase()) { return true; } } else { // check mime type if (file.type.match(type)) return true; } } } return false; } } }); function render(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createBlock("label", { class: _ctx.rootClasses }, [!_ctx.dragDrop ? vue.renderSlot(_ctx.$slots, "default", { key: 0 }) : (vue.openBlock(), vue.createBlock("div", { key: 1, class: _ctx.draggableClasses, onMouseenter: _cache[1] || (_cache[1] = $event => _ctx.updateDragDropFocus(true)), onMouseleave: _cache[2] || (_cache[2] = $event => _ctx.updateDragDropFocus(false)), onDragover: _cache[3] || (_cache[3] = vue.withModifiers($event => _ctx.updateDragDropFocus(true), ["prevent"])), onDragleave: _cache[4] || (_cache[4] = vue.withModifiers($event => _ctx.updateDragDropFocus(false), ["prevent"])), onDragenter: _cache[5] || (_cache[5] = vue.withModifiers($event => _ctx.updateDragDropFocus(true), ["prevent"])), onDrop: _cache[6] || (_cache[6] = vue.withModifiers((...args) => _ctx.onFileChange(...args), ["prevent"])) }, [vue.renderSlot(_ctx.$slots, "default")], 34 /* CLASS, HYDRATE_EVENTS */ )), vue.createVNode("input", vue.mergeProps({ ref: "input", type: "file" }, _ctx.$attrs, { multiple: _ctx.multiple, accept: _ctx.accept, disabled: _ctx.disabled, onChange: _cache[7] || (_cache[7] = (...args) => _ctx.onFileChange(...args)) }), null, 16 /* FULL_PROPS */ , ["multiple", "accept", "disabled"])], 2 /* CLASS */ ); } script.render = render; script.__file = "src/components/upload/Upload.vue"; exports.script = script;