UNPKG

quasar

Version:

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

327 lines (272 loc) 8 kB
import { h, ref, computed, watch, toRaw, getCurrentInstance } from 'vue' import QDialog from '../../../components/dialog/QDialog.js' import QBtn from '../../../components/btn/QBtn.js' import QCard from '../../../components/card/QCard.js' import QCardSection from '../../../components/card/QCardSection.js' import QCardActions from '../../../components/card/QCardActions.js' import QSeparator from '../../../components/separator/QSeparator.js' import QInput from '../../../components/input/QInput.js' import QOptionGroup from '../../../components/option-group/QOptionGroup.js' import QSpinner from '../../../components/spinner/QSpinner.js' import { createComponent } from '../../../utils/private.create/create.js' import useDark, { useDarkProps } from '../../../composables/private.use-dark/use-dark.js' import { isKeyCode } from '../../../utils/private.keyboard/key-composition.js' import { isObject } from '../../../utils/is/is.js' export default createComponent({ name: 'DialogPluginComponent', 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 {} // oxlint-disable-next-line no-shadow const { model, isValid, items, ...acc } = props.prompt !== void 0 ? props.prompt : props.options return acc }) 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(sectionClass, text) { return props.html === true ? h(QCardSection, { class: sectionClass, innerHTML: text }) : h(QCardSection, { class: sectionClass }, () => 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 = [] if (props.cancel) child.push(h(QBtn, cancelProps.value)) if (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 = [] if (props.title) child.push(getSection('q-dialog__title', props.title)) if (props.progress !== false) { child.push( h(QCardSection, { class: 'q-dialog__progress' }, () => h(spinner.value.component, spinner.value.props) ) ) } if (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 ) } })