157 lines
5.8 KiB
JavaScript
157 lines
5.8 KiB
JavaScript
import { Fragment as _Fragment, mergeProps as _mergeProps, createVNode as _createVNode } from "vue";
|
|
// Components
|
|
import { makeVConfirmEditProps, VConfirmEdit } from "../../components/VConfirmEdit/VConfirmEdit.mjs";
|
|
import { makeVDatePickerProps, VDatePicker } from "../../components/VDatePicker/VDatePicker.mjs";
|
|
import { VMenu } from "../../components/VMenu/VMenu.mjs";
|
|
import { makeVTextFieldProps, VTextField } from "../../components/VTextField/VTextField.mjs"; // Composables
|
|
import { useDate } from "../../composables/date/index.mjs";
|
|
import { makeFocusProps, useFocus } from "../../composables/focus.mjs";
|
|
import { forwardRefs } from "../../composables/forwardRefs.mjs";
|
|
import { useLocale } from "../../composables/locale.mjs";
|
|
import { useProxiedModel } from "../../composables/proxiedModel.mjs"; // Utilities
|
|
import { computed, ref, shallowRef } from 'vue';
|
|
import { genericComponent, omit, propsFactory, useRender, wrapInArray } from "../../util/index.mjs"; // Types
|
|
// Types
|
|
export const makeVDateInputProps = propsFactory({
|
|
hideActions: Boolean,
|
|
location: {
|
|
type: String,
|
|
default: 'bottom start'
|
|
},
|
|
...makeFocusProps(),
|
|
...makeVConfirmEditProps(),
|
|
...makeVTextFieldProps({
|
|
placeholder: 'mm/dd/yyyy',
|
|
prependIcon: '$calendar'
|
|
}),
|
|
...omit(makeVDatePickerProps({
|
|
weeksInMonth: 'dynamic',
|
|
hideHeader: true
|
|
}), ['active', 'location', 'rounded'])
|
|
}, 'VDateInput');
|
|
export const VDateInput = genericComponent()({
|
|
name: 'VDateInput',
|
|
props: makeVDateInputProps(),
|
|
emits: {
|
|
'update:modelValue': val => true
|
|
},
|
|
setup(props, _ref) {
|
|
let {
|
|
slots
|
|
} = _ref;
|
|
const {
|
|
t
|
|
} = useLocale();
|
|
const adapter = useDate();
|
|
const {
|
|
isFocused,
|
|
focus,
|
|
blur
|
|
} = useFocus(props);
|
|
const model = useProxiedModel(props, 'modelValue', props.multiple ? [] : null, val => Array.isArray(val) ? val.map(item => adapter.toJsDate(item)) : val ? adapter.toJsDate(val) : val, val => Array.isArray(val) ? val.map(item => adapter.date(item)) : val ? adapter.date(val) : val);
|
|
const menu = shallowRef(false);
|
|
const vDateInputRef = ref();
|
|
const display = computed(() => {
|
|
const value = wrapInArray(model.value);
|
|
if (!value.length) return null;
|
|
if (props.multiple === true) {
|
|
return t('$vuetify.datePicker.itemsSelected', value.length);
|
|
}
|
|
if (props.multiple === 'range') {
|
|
const start = value[0];
|
|
const end = value[value.length - 1];
|
|
return adapter.isValid(start) && adapter.isValid(end) ? `${adapter.format(adapter.date(start), 'keyboardDate')} - ${adapter.format(adapter.date(end), 'keyboardDate')}` : '';
|
|
}
|
|
return adapter.isValid(model.value) ? adapter.format(adapter.date(model.value), 'keyboardDate') : '';
|
|
});
|
|
const isInteractive = computed(() => !props.disabled && !props.readonly);
|
|
function onKeydown(e) {
|
|
if (e.key !== 'Enter') return;
|
|
if (!menu.value || !isFocused.value) {
|
|
menu.value = true;
|
|
return;
|
|
}
|
|
const target = e.target;
|
|
model.value = target.value;
|
|
}
|
|
function onClick(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
menu.value = true;
|
|
}
|
|
function onSave() {
|
|
menu.value = false;
|
|
}
|
|
function onUpdateModel(value) {
|
|
if (value != null) return;
|
|
model.value = null;
|
|
}
|
|
useRender(() => {
|
|
const confirmEditProps = VConfirmEdit.filterProps(props);
|
|
const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
|
|
const textFieldProps = VTextField.filterProps(props);
|
|
return _createVNode(VTextField, _mergeProps({
|
|
"ref": vDateInputRef
|
|
}, textFieldProps, {
|
|
"class": props.class,
|
|
"style": props.style,
|
|
"modelValue": display.value,
|
|
"onKeydown": isInteractive.value ? onKeydown : undefined,
|
|
"focused": menu.value || isFocused.value,
|
|
"onFocus": focus,
|
|
"onBlur": blur,
|
|
"onClick:control": isInteractive.value ? onClick : undefined,
|
|
"onClick:prepend": isInteractive.value ? onClick : undefined,
|
|
"onUpdate:modelValue": onUpdateModel
|
|
}), {
|
|
...slots,
|
|
default: () => _createVNode(_Fragment, null, [_createVNode(VMenu, {
|
|
"modelValue": menu.value,
|
|
"onUpdate:modelValue": $event => menu.value = $event,
|
|
"activator": "parent",
|
|
"min-width": "0",
|
|
"location": props.location,
|
|
"closeOnContentClick": false,
|
|
"openOnClick": false
|
|
}, {
|
|
default: () => [_createVNode(VConfirmEdit, _mergeProps(confirmEditProps, {
|
|
"modelValue": model.value,
|
|
"onUpdate:modelValue": $event => model.value = $event,
|
|
"onSave": onSave,
|
|
"onCancel": () => menu.value = false
|
|
}), {
|
|
default: _ref2 => {
|
|
let {
|
|
actions,
|
|
model: proxyModel,
|
|
save,
|
|
cancel,
|
|
isPristine
|
|
} = _ref2;
|
|
return _createVNode(VDatePicker, _mergeProps(datePickerProps, {
|
|
"modelValue": props.hideActions ? model.value : proxyModel.value,
|
|
"onUpdate:modelValue": val => {
|
|
if (!props.hideActions) {
|
|
proxyModel.value = val;
|
|
} else {
|
|
model.value = val;
|
|
if (!props.multiple) menu.value = false;
|
|
}
|
|
},
|
|
"onMousedown": e => e.preventDefault()
|
|
}), {
|
|
actions: !props.hideActions ? () => slots.actions?.({
|
|
save,
|
|
cancel,
|
|
isPristine
|
|
}) ?? actions() : undefined
|
|
});
|
|
}
|
|
})]
|
|
}), slots.default?.()])
|
|
});
|
|
});
|
|
return forwardRefs({}, vDateInputRef);
|
|
}
|
|
});
|
|
//# sourceMappingURL=VDateInput.mjs.map
|