UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

326 lines (270 loc) 7.83 kB
import { h, ref, computed, watch, toRaw, getCurrentInstance } from 'vue' import QDialog from '../dialog/QDialog.js' import QBtn from '../btn/QBtn.js' import QCard from '../card/QCard.js' import QCardSection from '../card/QCardSection.js' import QCardActions from '../card/QCardActions.js' import QSeparator from '../separator/QSeparator.js' import QInput from '../input/QInput.js' import QOptionGroup from '../option-group/QOptionGroup.js' import QSpinner from '../spinner/QSpinner.js' import { createComponent } from '../../utils/private/create.js' import useDark, { useDarkProps } from '../../composables/private/use-dark.js' import { isKeyCode } from '../../utils/private/key-composition.js' import { isObject } from '../../utils/is.js' export default createComponent({ name: 'DialogPlugin', props: { ...useDarkProps, title: String, message: String, prompt: Object, options: Object, progress: [ Boolean, Object ], html: Boolean, ok: { type: [ String, Object, Boolean ], default: true }, cancel: [ String, Object, Boolean ], focus: { type: String, default: 'ok', validator: v => [ 'ok', 'cancel', 'none' ].includes(v) }, stackButtons: Boolean, color: String, cardClass: [ String, Array, Object ], cardStyle: [ String, Array, Object ] }, emits: [ 'ok', 'hide' ], setup (props, { emit }) { const { proxy } = getCurrentInstance() const { $q } = proxy const isDark = useDark(props, $q) const dialogRef = ref(null) const model = ref( props.prompt !== void 0 ? props.prompt.model : (props.options !== void 0 ? props.options.model : void 0) ) const classes = computed(() => 'q-dialog-plugin' + (isDark.value === true ? ' q-dialog-plugin--dark q-dark' : '') + (props.progress !== false ? ' q-dialog-plugin--progress' : '') ) const vmColor = computed(() => props.color || (isDark.value === true ? 'amber' : 'primary') ) const spinner = computed(() => ( props.progress === false ? null : ( isObject(props.progress) === true ? { component: props.progress.spinner || QSpinner, props: { color: props.progress.color || vmColor.value } } : { component: QSpinner, props: { color: vmColor.value } } ) )) const hasForm = computed(() => props.prompt !== void 0 || props.options !== void 0 ) const formProps = computed(() => { if (hasForm.value !== true) { return {} } const { model, isValid, items, ...formProps } = props.prompt !== void 0 ? props.prompt : props.options return formProps }) const okLabel = computed(() => ( isObject(props.ok) === true ? $q.lang.label.ok : ( props.ok === true ? $q.lang.label.ok : props.ok ) )) const cancelLabel = computed(() => ( isObject(props.cancel) === true ? $q.lang.label.cancel : ( props.cancel === true ? $q.lang.label.cancel : props.cancel ) )) const okDisabled = computed(() => { if (props.prompt !== void 0) { return props.prompt.isValid !== void 0 && props.prompt.isValid(model.value) !== true } if (props.options !== void 0) { return props.options.isValid !== void 0 && props.options.isValid(model.value) !== true } return false }) const okProps = computed(() => ({ color: vmColor.value, label: okLabel.value, ripple: false, disable: okDisabled.value, ...(isObject(props.ok) === true ? props.ok : { flat: true }), 'data-autofocus': (props.focus === 'ok' && hasForm.value !== true) || void 0, onClick: onOk })) const cancelProps = computed(() => ({ color: vmColor.value, label: cancelLabel.value, ripple: false, ...(isObject(props.cancel) === true ? props.cancel : { flat: true }), 'data-autofocus': (props.focus === 'cancel' && hasForm.value !== true) || void 0, onClick: onCancel })) watch(() => props.prompt && props.prompt.model, onUpdateModel) watch(() => props.options && props.options.model, onUpdateModel) function show () { dialogRef.value.show() } function hide () { dialogRef.value.hide() } function onOk () { emit('ok', toRaw(model.value)) hide() } function onCancel () { hide() } function onDialogHide () { emit('hide') } function onUpdateModel (val) { model.value = val } function onInputKeyup (evt) { // if ENTER key if ( okDisabled.value !== true && props.prompt.type !== 'textarea' && isKeyCode(evt, 13) === true ) { onOk() } } function getSection (classes, text) { return props.html === true ? h(QCardSection, { class: classes, innerHTML: text }) : h(QCardSection, { class: classes }, () => text) } function getPrompt () { return [ h(QInput, { color: vmColor.value, dense: true, autofocus: true, dark: isDark.value, ...formProps.value, modelValue: model.value, 'onUpdate:modelValue': onUpdateModel, onKeyup: onInputKeyup }) ] } function getOptions () { return [ h(QOptionGroup, { color: vmColor.value, options: props.options.items, dark: isDark.value, ...formProps.value, modelValue: model.value, 'onUpdate:modelValue': onUpdateModel }) ] } function getButtons () { const child = [] props.cancel && child.push( h(QBtn, cancelProps.value) ) props.ok && child.push( h(QBtn, okProps.value) ) return h(QCardActions, { class: props.stackButtons === true ? 'items-end' : '', vertical: props.stackButtons, align: 'right' }, () => child) } function getCardContent () { const child = [] props.title && child.push( getSection('q-dialog__title', props.title) ) props.progress !== false && child.push( h( QCardSection, { class: 'q-dialog__progress' }, () => h(spinner.value.component, spinner.value.props) ) ) props.message && child.push( getSection('q-dialog__message', props.message) ) if (props.prompt !== void 0) { child.push( h( QCardSection, { class: 'scroll q-dialog-plugin__form' }, getPrompt ) ) } else if (props.options !== void 0) { child.push( h(QSeparator, { dark: isDark.value }), h( QCardSection, { class: 'scroll q-dialog-plugin__form' }, getOptions ), h(QSeparator, { dark: isDark.value }) ) } if (props.ok || props.cancel) { child.push(getButtons()) } return child } function getContent () { return [ h(QCard, { class: [ classes.value, props.cardClass ], style: props.cardStyle, dark: isDark.value }, getCardContent) ] } // expose public methods Object.assign(proxy, { show, hide }) return () => h(QDialog, { ref: dialogRef, onHide: onDialogHide }, getContent) } })