'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var core = require('@vue-layout/core'); var vue = require('vue'); function buildFormBaseOptions(options, component, defaults) { defaults = defaults || {}; const { buildOrFail } = core.createOptionBuilder(component); return { ...options, slotItems: options.slotItems || {}, class: buildOrFail({ key: 'class', value: options.class, alt: defaults.class || '' }), props: buildOrFail({ key: 'props', value: options.props, alt: defaults.props || {} }) }; } function handleFormValueChanged(options, value) { if (typeof options.value !== 'undefined') { options.value = core.setMaybeRefValue(options.value, value); } if (options.onChange) { options.onChange.call(null, value); } return options; } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ exports.Component = void 0; (function(Component) { Component["FormGroup"] = "formGroup"; Component["FormInput"] = "formInput"; Component["FormInputCheckbox"] = "formInputCheckbox"; Component["FormInputText"] = "formInputText"; Component["FormSelect"] = "formSelect"; Component["FormSubmit"] = "formSubmit"; Component["FormTextarea"] = "formTextarea"; })(exports.Component || (exports.Component = {})); exports.SlotName = void 0; (function(SlotName) { SlotName["DEFAULT"] = "default"; SlotName["LABEL"] = "label"; SlotName["VALIDATION_GROUP"] = "validationGroup"; SlotName["VALIDATION_ITEM"] = "validationItem"; })(exports.SlotName || (exports.SlotName = {})); function isValidationRuleResultWithoutParams(input) { return core.isObject(input) && core.hasOwnProperty(input, '$message') && core.hasOwnProperty(input, '$pending') && core.hasOwnProperty(input, '$invalid') && core.hasOwnProperty(input, '$response'); } function isValidationRuleResultWithParams(input) { return isValidationRuleResultWithoutParams(input) && core.hasOwnProperty(input, '$params'); } function template(str, data, regex = /\{\{(.+?)\}\}/g) { return Array.from(str.matchAll(regex)).reduce((acc, match)=>{ if (typeof data[match[1]] !== 'undefined') { return acc.replace(match[0], data[match[1]]); } return acc; }, str); } function buildValidationGroupOptions(options) { return { ...options, slotItems: options.slotItems || {}, validationMessages: options.validationMessages || {}, validationResult: options.validationResult || {} }; } function buildValidationGroup(input) { const options = buildValidationGroupOptions(input); const translate = (validator, properties)=>{ if (options.validationMessages && Object.prototype.hasOwnProperty.call(options.validationMessages, validator)) { return template(options.validationMessages[validator], properties || {}); } if (typeof options.validationTranslator !== 'undefined') { let translation = options.validationTranslator(validator, properties || {}); if (typeof translation === 'string') { translation = template(translation, properties || {}); if (translation !== validator) { return translation; } } } return `The ${validator} operator condition is not fulfilled.`; }; const errors = []; const keys = Object.keys(options.validationResult); for(let i = 0; i < keys.length; i++){ if (core.isObject(options.validationResult[keys[i]]) && options.validationResult[keys[i]].$invalid) { if (isValidationRuleResultWithParams(options.validationResult[keys[i]])) { errors.push(translate(keys[i], options.validationResult[keys[i]].$params)); } else if (isValidationRuleResultWithoutParams(options.validationResult[keys[i]])) { errors.push(translate(keys[i])); } } } const invalid = !!options.validationResult && !!options.validationResult.$dirty && !!options.validationResult.$invalid; if (core.hasNormalizedSlot(exports.SlotName.VALIDATION_GROUP, options.slotItems)) { return core.normalizeSlot(exports.SlotName.VALIDATION_GROUP, { data: errors, invalid }, options.slotItems); } const children = []; for(let i = 0; i < errors.length; i++){ if (core.hasNormalizedSlot(exports.SlotName.VALIDATION_ITEM, options.slotItems)) { children.push(core.normalizeSlot(exports.SlotName.VALIDATION_ITEM, { data: errors[i], invalid }, options.slotItems)); } else { children.push(vue.h('div', { class: 'form-group-hint group-required' }, [ errors[i] ])); } } return children; } function buildFormGroupOptions(input) { const { buildOrFail } = core.createOptionBuilder(exports.Component.FormGroup); return { ...input, slotItems: input.slotItems || {}, hint: buildOrFail({ key: 'hint', value: input.hint, alt: undefined }), hintClass: buildOrFail({ key: 'hintClass', value: input.hintClass, alt: [] }), hintContent: buildOrFail({ key: 'hintContent', value: input.hintContent, alt: '' }), class: buildOrFail({ key: 'class', value: input.class, alt: [] }), props: buildOrFail({ key: 'props', value: input.props, alt: {} }), label: buildOrFail({ key: 'label', value: input.label, alt: true }), labelClass: buildOrFail({ key: 'labelClass', value: input.labelClass, alt: [] }), labelContent: buildOrFail({ key: 'labelContent', value: input.labelContent, alt: 'Input' }), validation: buildOrFail({ key: 'validation', value: input.validation, alt: true }), validationMessages: input.validationMessages || {}, validationResult: input.validationResult || {}, // errorClass validationErrorClass: buildOrFail({ key: 'validationErrorClass', value: input.validationErrorClass, alt: [] }), // warningClass validationWarningClass: buildOrFail({ key: 'validationWarningClass', value: input.validationWarningClass, alt: [] }) }; } function buildFormGroup(input) { const options = buildFormGroupOptions(input); const children = []; if (options.label) { if (core.hasNormalizedSlot(exports.SlotName.LABEL, options.slotItems)) { children.push(core.normalizeSlot(exports.SlotName.LABEL, { class: options.class }, options.slotItems)); } else { children.push(vue.h('label', { class: options.labelClass }, [ options.labelContent ])); } } if (core.hasNormalizedSlot(exports.SlotName.DEFAULT, options.slotItems)) { children.push(core.normalizeSlot(exports.SlotName.DEFAULT, {}, options.slotItems)); } else if (options.content) { children.push(options.content); } if (options.validation) { children.push(buildValidationGroup({ slotItems: options.slotItems, validationResult: options.validationResult, validationMessages: options.validationMessages, validationTranslator: options.validationTranslator })); } if (options.hint && options.hintContent) { children.push(vue.h('div', { class: options.hintClass }, [ options.hintContent ])); } return vue.h('div', { class: [ options.class, ...options.validationResult && options.validationResult.$invalid && options.validationResult.$dirty ? [ options.validationErrorClass ] : [], ...options.validationResult && options.validationResult.$invalid && !options.validationResult.$dirty ? [ options.validationWarningClass ] : [] ], ...options.props }, children); } const VCFormGroup = vue.defineComponent({ slots: Object, props: { label: { type: Boolean, default: false }, labelClass: { type: String, default: '' }, labelContent: { type: String, default: '' }, hint: { type: Boolean, default: undefined }, hintClass: { type: [ String, Array, Object ], default: '' }, hintContent: { type: String, default: '' }, validation: { type: Boolean, default: true }, validationResult: { type: Object, default: undefined }, validationMessages: { type: Object, default: undefined }, validationTranslator: { type: Function, default: undefined } }, setup (props, { attrs, slots }) { return ()=>buildFormGroup({ label: props.label, labelClass: props.labelClass, labelContent: props.labelContent, hint: props.hint, validation: props.validation, validationResult: props.validationResult, validationMessages: props.validationMessages, validationTranslator: props.validationTranslator, slotItems: slots, props: attrs }); } }); function buildFormInputOptions(input, component) { component = component || exports.Component.FormInput; const options = buildFormBaseOptions(input, component); const { build, buildOrFail } = core.createOptionBuilder(component); return { ...options, type: buildOrFail({ key: 'type', value: options.type, alt: 'text' }), group: buildOrFail({ key: 'group', value: options.group, alt: false }), groupClass: buildOrFail({ key: 'groupClass', value: options.groupClass, alt: [] }), groupAppend: buildOrFail({ key: 'groupAppend', value: options.groupAppend, alt: false }), groupAppendClass: build({ key: 'groupAppendClass', value: options.groupAppendClass, alt: '' }), groupAppendContent: build({ key: 'groupAppendContent', value: options.groupAppendContent, alt: '' }), groupPrepend: buildOrFail({ key: 'groupPrepend', value: options.groupPrepend, alt: false }), groupPrependClass: build({ key: 'groupPrependClass', value: options.groupPrependClass, alt: '' }), groupPrependContent: build({ key: 'groupPrependContent', value: options.groupPrependContent, alt: '' }) }; } function buildFormInput(input) { const options = buildFormInputOptions(input); return buildFormInputFromOptions(options); } function buildFormInputFromOptions(options) { const children = []; if (options.groupPrepend) { children.push(vue.h('span', { class: options.groupPrependClass }, [ options.groupPrependContent ])); } const rawValue = vue.unref(options.value); children.push(vue.h('input', vue.mergeProps({ type: options.type, class: options.class, onInput ($event) { if ($event.target.composing) { return; } handleFormValueChanged(options, $event.target.value); }, ...typeof rawValue !== 'undefined' ? { value: rawValue } : {} }, options.props))); if (options.groupAppend) { children.push(vue.h('span', { class: options.groupAppendClass }, [ options.groupAppendContent ])); } if (children.length > 1 || options.group) { return vue.h('div', { class: options.groupClass }, children); } return children[0]; } const VCFormInput = vue.defineComponent({ props: { modelValue: { type: String, default: '' }, type: { type: String, default: 'text' } }, emits: [ 'update:modelValue' ], setup (props, { attrs, emit }) { return ()=>buildFormInput({ type: props.type, value: props.modelValue, onChange (input) { emit('update:modelValue', input); }, props: attrs }); } }); function buildFormInputCheckboxOptions(input) { const options = buildFormBaseOptions(input, exports.Component.FormInputCheckbox); const { buildOrFail } = core.createOptionBuilder(exports.Component.FormInputCheckbox); return { ...options, group: buildOrFail({ key: 'group', value: options.group, alt: false }), groupClass: buildOrFail({ key: 'groupClass', value: vue.unref(options.groupClass), alt: '' }), label: buildOrFail({ key: 'label', value: options.label, alt: true }), labelClass: buildOrFail({ key: 'labelClass', value: options.labelClass, alt: [] }), labelContent: buildOrFail({ key: 'labelContent', value: options.labelContent, alt: 'Input' }) }; } function buildFormInputCheckbox(input) { const options = buildFormInputCheckboxOptions(input); const id = (Math.random() + 1).toString(36).substring(7); const rawValue = vue.unref(options.value); let isChecked; let index = -1; if (typeof rawValue !== 'undefined') { if (Array.isArray(rawValue)) { if (typeof options.props.value !== 'undefined') { index = rawValue.indexOf(options.props.value); isChecked = index !== -1; } } else { isChecked = !!rawValue; } } const element = vue.h('input', vue.mergeProps({ id, type: 'checkbox', class: options.class, onInput ($event) { if ($event.target.composing) { return; } if (Array.isArray(rawValue)) { if (typeof options.props.value !== 'undefined') { if (index === -1) { rawValue.push(options.props.value); } else { rawValue.splice(index, 1); } } handleFormValueChanged(options, rawValue); } else { handleFormValueChanged(options, !rawValue); } }, ...typeof isChecked === 'boolean' ? { checked: isChecked } : {} }, options.props)); if (options.label || options.group) { const children = []; if (options.label) { if (core.hasNormalizedSlot(exports.SlotName.LABEL, options.slotItems)) { children.push(core.normalizeSlot(exports.SlotName.LABEL, { class: options.class, id }, options.slotItems)); } else { children.push(vue.h('label', { class: options.labelClass, for: id }, [ options.labelContent ])); } } children.push(element); return vue.h('div', { class: options.groupClass }, children); } return element; } const VCFormInputCheckbox = vue.defineComponent({ slots: Object, props: { modelValue: { type: [ Object, Boolean, String, Number, Array ] }, group: { type: Boolean }, groupClass: { type: String }, label: { type: Boolean }, labelClass: { type: String }, labelContent: { type: String } }, emits: [ 'update:modelValue' ], setup (props, { attrs, emit, slots }) { return ()=>buildFormInputCheckbox({ group: props.group, groupClass: props.groupClass, label: props.label, labelClass: props.labelClass, labelContent: props.labelContent, value: props.modelValue, onChange (input) { emit('update:modelValue', input); }, slotItems: slots, props: attrs }); } }); function buildFormInputText(input) { const options = buildFormInputOptions(input, exports.Component.FormInputText); return buildFormInputFromOptions(options); } function buildFormSelectOptions(input) { const options = buildFormBaseOptions(input, exports.Component.FormSelect); const { buildOrFail } = core.createOptionBuilder(exports.Component.FormSelect); return { ...options, options: options.options, optionDefault: buildOrFail({ key: 'optionDefault', value: options.optionDefault, alt: true }), optionDefaultId: buildOrFail({ key: 'optionDefaultId', value: options.optionDefaultId, alt: '' }), optionDefaultValue: buildOrFail({ key: 'optionDefaultValue', value: options.optionDefaultValue, alt: '-- Select --' }) }; } function buildFormSelect(input) { const options = buildFormSelectOptions(input); const rawValue = vue.unref(options.value); const children = []; if (options.optionDefault) { children.push(vue.h('option', { value: options.optionDefaultId }, [ options.optionDefaultValue ])); } for(let i = 0; i < options.options.length; i++){ children.push(vue.h('option', { key: options.options[i].id, value: options.options[i].id, selected: options.options[i].id === rawValue }, options.options[i].value)); } return vue.h('select', vue.mergeProps({ class: options.class, onChange ($event) { const $$selectedVal = Array.prototype.filter.call($event.target.options, (o)=>o.selected).map((o)=>'_value' in o ? o._value : o.value); const value = $event.target.multiple ? $$selectedVal : $$selectedVal[0]; handleFormValueChanged(options, value); }, ...typeof rawValue !== 'undefined' ? { value: rawValue } : {} }, options.props), children); } const VCFormSelect = vue.defineComponent({ props: { modelValue: { type: String, default: '' }, options: { type: Object, required: true }, optionDefault: { type: Boolean, default: true }, optionDefaultId: { type: [ String, Number ] }, optionDefaultValue: { type: String } }, emits: [ 'update:modelValue' ], setup (props, { attrs, emit }) { return ()=>buildFormSelect({ value: props.modelValue, onChange (input) { emit('update:modelValue', input); }, props: attrs, options: props.options, optionDefault: props.optionDefault, optionDefaultId: props.optionDefaultId, optionDefaultValue: props.optionDefaultValue }); } }); function buildFormSubmitOptions(options) { const { buildOrFail } = core.createOptionBuilder(exports.Component.FormSubmit); return { ...options, type: buildOrFail({ key: 'type', value: options.type, alt: 'button' }), class: buildOrFail({ key: 'class', value: options.class, alt: [] }), props: buildOrFail({ key: 'props', value: options.props, alt: {} }), icon: buildOrFail({ key: 'icon', value: options.icon, alt: true }), validationResult: core.unrefWithDefault(options.validationResult, {}), updateText: buildOrFail({ key: 'updateText', value: options.updateText, alt: 'Update' }), updateIconClass: buildOrFail({ key: 'updateIconClass', value: options.updateIconClass, alt: [] }), updateButtonClass: buildOrFail({ key: 'updateButtonClass', value: options.updateButtonClass, alt: [] }), createText: buildOrFail({ key: 'createText', value: options.createText, alt: 'Create' }), createIconClass: buildOrFail({ key: 'createIconClass', value: options.createIconClass, alt: [] }), createButtonClass: buildOrFail({ key: 'createButtonClass', value: options.createButtonClass, alt: [] }), busy: options.busy ?? false, valid: options.valid ?? true, isEditing: options.isEditing ?? false }; } function buildFormSubmit(input) { const options = buildFormSubmitOptions(input); let icon = []; if (options.icon) { icon = [ vue.h('i', { class: [ ...options.isEditing ? [ options.updateIconClass ] : [], ...!options.isEditing ? [ options.createIconClass ] : [] ] }) ]; } return vue.h(options.type, vue.mergeProps({ ...options.type === 'button' ? { type: 'submit' } : {}, class: [ ...options.isEditing ? [ options.updateButtonClass ] : [], ...!options.isEditing ? [ options.createButtonClass ] : [] ], disabled: options.validationResult.$invalid || !options.valid || vue.unref(options.busy), onClick ($event) { $event.preventDefault(); options.busy = core.setMaybeRefValue(options.busy, true); const promise = options.submit(); if (core.isPromise(promise)) { promise.finally(()=>{ options.busy = core.setMaybeRefValue(options.busy, false); }); } return promise; } }, options.props), [ icon, ' ', options.isEditing ? options.updateText : options.createText ]); } const VCFormSubmit = vue.defineComponent({ props: { modelValue: { type: Boolean, default: false }, icon: { type: Boolean, default: true }, isEditing: { type: Boolean, default: false }, busy: { type: Boolean, default: false }, createText: { type: [ String, Object ], default: undefined }, createIconClass: { type: [ String, Object ], default: undefined }, createButtonClass: { type: [ String, Object ], default: undefined }, updateText: { type: [ String, Object ], default: undefined }, updateIconClass: { type: [ String, Object ], default: undefined }, updateButtonClass: { type: [ String, Object ], default: undefined }, submit: { type: Function }, validationResult: { type: Object, default: undefined } }, emits: [ 'update:modelValue' ], setup (props, { attrs, emit }) { return ()=>buildFormSubmit({ icon: props.icon, busy: props.modelValue || props.busy, isEditing: props.isEditing, createText: props.createText, createIconClass: props.createIconClass, createButtonClass: props.createButtonClass, updateText: props.updateText, updateIconClass: props.updateIconClass, updateButtonClass: props.updateButtonClass, submit () { if (!props.submit) { return; } emit('update:modelValue', true); Promise.resolve().then(props.submit).then(()=>{ emit('update:modelValue', false); }); }, validationResult: props.validationResult, props: attrs }); } }); function buildFormTextareaOptions(input) { const options = buildFormBaseOptions(input, exports.Component.FormTextarea); return { ...options }; } function buildFormTextarea(input) { const options = buildFormTextareaOptions(input); const rawValue = vue.unref(options.value); return vue.h('textarea', vue.mergeProps({ placeholder: '...', class: options.class, onInput ($event) { if ($event.target.composing) { return; } handleFormValueChanged(options, $event.target.value); }, ...typeof rawValue !== 'undefined' ? { value: rawValue } : {} }, options.props)); } const VCFormTextarea = vue.defineComponent({ props: { modelValue: { type: String, default: '' } }, emits: [ 'update:modelValue' ], setup (props, { attrs, emit }) { return ()=>buildFormTextarea({ value: props.modelValue, onChange (input) { emit('update:modelValue', input); }, props: attrs }); } }); function install(instance, options) { options ?? (options = {}); core.applyPluginBaseOptions(instance, options); Object.entries({ VCFormGroup, VCFormInputCheckbox, VCFormInput, VCFormSelect, VCFormSubmit, VCFormTextarea }).forEach(([componentName, component])=>{ instance.component(componentName, component); }); } var index = { install }; exports.VCFormGroup = VCFormGroup; exports.VCFormInput = VCFormInput; exports.VCFormInputCheckbox = VCFormInputCheckbox; exports.VCFormSelect = VCFormSelect; exports.VCFormSubmit = VCFormSubmit; exports.VCFormTextarea = VCFormTextarea; exports.buildFormBaseOptions = buildFormBaseOptions; exports.buildFormGroup = buildFormGroup; exports.buildFormGroupOptions = buildFormGroupOptions; exports.buildFormInput = buildFormInput; exports.buildFormInputCheckbox = buildFormInputCheckbox; exports.buildFormInputCheckboxOptions = buildFormInputCheckboxOptions; exports.buildFormInputFromOptions = buildFormInputFromOptions; exports.buildFormInputOptions = buildFormInputOptions; exports.buildFormInputText = buildFormInputText; exports.buildFormSelect = buildFormSelect; exports.buildFormSelectOptions = buildFormSelectOptions; exports.buildFormSubmit = buildFormSubmit; exports.buildFormSubmitOptions = buildFormSubmitOptions; exports.buildFormTextarea = buildFormTextarea; exports.buildFormTextareaOptions = buildFormTextareaOptions; exports.buildValidationGroup = buildValidationGroup; exports.buildValidationGroupOptions = buildValidationGroupOptions; exports.default = index; exports.handleFormValueChanged = handleFormValueChanged; exports.install = install; module.exports = Object.assign(exports.default, exports); //# sourceMappingURL=index.cjs.map