@oruga-ui/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
387 lines (386 loc) • 15.4 kB
JavaScript
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */
import { defineComponent, mergeModels, computed, useTemplateRef, ref, watch, nextTick, useModel, useAttrs, createElementBlock, openBlock, normalizeClass, createBlock, renderSlot, mergeProps, createSlots, withCtx, createVNode, withKeys, unref } from "vue";
import { _ as _sfc_main$1, a as _sfc_main$2 } from "./Dropdown.vue_vue_type_script_setup_true_lang-Cjs2BSms.mjs";
import { _ as _sfc_main$3 } from "./Input.vue_vue_type_script_setup_true_lang-BmEqNFiY.mjs";
import { isTrueish, isMobileAgent, isDefined, isDate } from "./helpers.mjs";
import { i as isClient } from "./config-Dl7tu_Ly.mjs";
import { g as getActiveClasses } from "./defineClasses-CWB9NuS-.mjs";
import { u as useEventListener } from "./useEventListener-nW3U5kAY.mjs";
import { u as useInputHandler } from "./useInputHandler-Cv7NmM5J.mjs";
import { i as injectField } from "./fieldInjection-DJwnFcxS.mjs";
const _hoisted_1 = ["data-oruga"];
const _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "OPickerWrapper"
},
__name: "PickerWrapper",
props: /* @__PURE__ */ mergeModels({
/** the internal input value */
value: {
type: [Date, Array],
default: void 0
},
/** the active state of the dropdown */
active: { type: Boolean, default: false },
/** parent picker component props */
pickerProps: { type: Object, required: true },
/** data-oruga attribute value */
dataOruga: { type: String, required: true },
/** format props value to input value */
formatter: {
type: Function,
required: true
},
/** parse input value to props value */
parser: {
type: Function,
required: true
},
type: { type: String, required: true },
step: { type: String, default: void 0 },
min: { type: Date, default: void 0 },
max: { type: Date, default: void 0 },
stayOpen: { type: Boolean, default: false },
/** the DateTimeFormat object to watch for to update the parsed input value */
dtf: { type: Object, default: void 0 },
rootClasses: { type: Array, required: true },
dropdownClasses: { type: Array, required: true },
boxClass: { type: Array, required: true }
}, {
"active": { type: Boolean, ...{ default: false } },
"activeModifiers": {}
}),
emits: /* @__PURE__ */ mergeModels(["update:value", "update:active", "focus", "blur", "invalid", "icon-click", "icon-right-click", "left", "right"], ["update:active"]),
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emits = __emit;
const isMobileNative = computed(
() => !isTrueish(props.pickerProps.inline) && isTrueish(props.pickerProps.mobileNative) && isMobileAgent.any()
);
const { parentField } = injectField();
const dropdownRef = useTemplateRef("dropdownComponent");
const inputRef = useTemplateRef("inputComponent");
const nativeInputRef = useTemplateRef("nativeInputComponent");
const elementRef = computed(
() => isMobileNative.value ? nativeInputRef.value : inputRef.value
);
const {
input,
checkHtml5Validity,
setFocus,
onBlur,
onFocus,
onInvalid,
isValid
} = useInputHandler(elementRef, emits, props.pickerProps);
const initialNativeType = !isDefined(props.pickerProps.placeholder) || isTrueish(props.value) ? props.type : "text";
const inputValue = ref("");
watch(
() => props.value,
(value) => {
inputValue.value = props.formatter(value, isMobileNative.value);
if (!isMobileNative.value && !props.stayOpen) togglePicker(false);
if (!isValid.value) checkHtml5Validity();
},
{ immediate: true }
);
watch(
() => props.dtf,
() => setValue(inputValue.value)
);
function setValue(value) {
let date = props.parser(value, isMobileNative.value);
if (Array.isArray(date)) date = date.map(checkMinMaxDate);
else if (isDefined(date)) date = checkMinMaxDate(date);
nextTick(
() => (
// reparse to string for internal value
inputValue.value = props.formatter(date, isMobileNative.value)
)
);
emits("update:value", date);
}
function checkMinMaxDate(date) {
if (!isDate(date)) return date;
if (props.min && date < props.min) date = props.min;
else if (props.max && date > props.max) date = props.max;
return date;
}
const isActive = useModel(__props, "active");
watch(isActive, onActiveChange);
const triggers = computed(
() => isTrueish(props.pickerProps.openOnFocus) ? ["click"] : []
);
if (isClient) useEventListener(document, "keyup", onKeyPress);
function onKeyPress(event) {
if (isActive.value && (event.key === "Escape" || event.key === "Esc"))
togglePicker(false);
}
function togglePicker(active) {
if (!dropdownRef.value) return;
if (active || isTrueish(props.pickerProps.closeOnClick))
nextTick(() => isActive.value = active);
}
function onInputClick(event) {
if (isActive.value) event.stopPropagation();
}
function onActiveChange(value) {
if (value) onFocus(new Event("focus"));
else if (!value) onBlur(new Event("blur"));
}
function onChange(event) {
setValue(event.target.value);
}
function onNativeClick(event) {
if (!isMobileNative.value || !input.value) return;
if (input.value.type === "text") {
event.preventDefault();
event.stopPropagation();
input.value.blur();
setTimeout(() => {
if (!input.value) return;
input.value.readOnly = false;
input.value.type = props.type;
setFocus();
}, 50);
}
}
function onNativeFocus(event) {
if (!isMobileNative.value || !input.value) return;
if (input.value.type === "text") {
event.preventDefault();
event.stopPropagation();
} else onFocus(event);
}
function onNativeBlur(event) {
if (!isMobileNative.value || !input.value) return;
if (!input.value.value) {
input.value.readOnly = true;
input.value.type = "text";
}
onBlur(event);
}
function onNativeChange(event) {
const value = event.target.value ? event.target.value : "";
if (!value && input.value) {
input.value.value = value;
input.value.blur();
}
setValue(value);
}
const attrs = useAttrs();
const inputBind = computed(() => {
var _a;
return {
...(_a = parentField == null ? void 0 : parentField.value) == null ? void 0 : _a.inputAttrs,
...attrs,
inputClass: props.pickerProps.inputClass,
...props.pickerProps.inputClasses
};
});
const dropdownBind = computed(() => ({
"root-class": getActiveClasses(props.dropdownClasses),
"teleport-class": getActiveClasses(props.rootClasses),
...props.pickerProps.dropdownClasses
}));
__expose({ checkHtml5Validity, focus: setFocus });
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
"data-oruga": __props.dataOruga,
class: normalizeClass(__props.rootClasses),
onClick: onNativeClick
}, [
!isMobileNative.value ? (openBlock(), createBlock(_sfc_main$1, mergeProps({
key: 0,
ref: "dropdownComponent"
}, dropdownBind.value, {
active: isActive.value,
"onUpdate:active": _cache[6] || (_cache[6] = ($event) => isActive.value = $event),
triggers: triggers.value,
position: __props.pickerProps.position,
disabled: __props.pickerProps.disabled,
inline: __props.pickerProps.inline,
"mobile-modal": __props.pickerProps.mobileModal,
"desktop-modal": __props.pickerProps.desktopModal,
"mobile-breakpoint": __props.pickerProps.mobileBreakpoint,
teleport: __props.pickerProps.teleport
}), createSlots({
default: withCtx(() => [
createVNode(_sfc_main$2, {
override: "",
tag: "div",
"item-class": __props.boxClass,
disabled: __props.pickerProps.disabled,
clickable: false,
onKeydown: [
_cache[4] || (_cache[4] = withKeys(($event) => _ctx.$emit("left", $event), ["left"])),
_cache[5] || (_cache[5] = withKeys(($event) => _ctx.$emit("right", $event), ["right"]))
]
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["item-class", "disabled"])
]),
_: 2
}, [
!__props.pickerProps.inline ? {
name: "trigger",
fn: withCtx(() => [
renderSlot(_ctx.$slots, "trigger", {}, () => [
createVNode(_sfc_main$3, mergeProps({ ref: "inputComponent" }, inputBind.value, {
modelValue: inputValue.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => inputValue.value = $event),
placeholder: __props.pickerProps.placeholder,
size: __props.pickerProps.size,
"icon-pack": __props.pickerProps.iconPack,
icon: __props.pickerProps.icon,
"icon-right": __props.pickerProps.iconRight,
"icon-right-clickable": __props.pickerProps.iconRightClickable,
expanded: __props.pickerProps.expanded,
rounded: __props.pickerProps.rounded,
disabled: __props.pickerProps.disabled,
readonly: __props.pickerProps.readonly,
autocomplete: "off",
"use-html5-validation": false,
onInvalid: unref(onInvalid),
onClick: onInputClick,
onKeyup: _cache[1] || (_cache[1] = withKeys(($event) => togglePicker(true), ["enter"])),
onChange,
onFocus: unref(onFocus),
onBlur: unref(onBlur),
onIconClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("icon-click", $event)),
onIconRightClick: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("icon-right-click", $event))
}), null, 16, ["modelValue", "placeholder", "size", "icon-pack", "icon", "icon-right", "icon-right-clickable", "expanded", "rounded", "disabled", "readonly", "onInvalid", "onFocus", "onBlur"])
])
]),
key: "0"
} : void 0
]), 1040, ["active", "triggers", "position", "disabled", "inline", "mobile-modal", "desktop-modal", "mobile-breakpoint", "teleport"])) : renderSlot(_ctx.$slots, "trigger", { key: 1 }, () => [
createVNode(_sfc_main$3, mergeProps({ ref: "nativeInputComponent" }, inputBind.value, {
modelValue: inputValue.value,
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => inputValue.value = $event),
type: unref(initialNativeType),
min: __props.formatter(__props.min, true),
max: __props.formatter(__props.max, true),
step: __props.step,
placeholder: __props.pickerProps.placeholder,
size: __props.pickerProps.size,
"icon-pack": __props.pickerProps.iconPack,
icon: __props.pickerProps.icon,
"icon-right": __props.pickerProps.iconRight,
"icon-right-clickable": __props.pickerProps.iconRightClickable,
rounded: __props.pickerProps.rounded,
disabled: __props.pickerProps.disabled,
readonly: unref(initialNativeType) == "text",
autocomplete: "off",
"use-html5-validation": false,
onChange: onNativeChange,
onFocus: onNativeFocus,
onBlur: onNativeBlur,
onInvalid: unref(onInvalid),
onIconClick: _cache[8] || (_cache[8] = ($event) => _ctx.$emit("icon-click", $event)),
onIconRightClick: _cache[9] || (_cache[9] = ($event) => _ctx.$emit("icon-right-click", $event))
}), null, 16, ["modelValue", "type", "min", "max", "step", "placeholder", "size", "icon-pack", "icon", "icon-right", "icon-right-clickable", "rounded", "disabled", "readonly", "onInvalid"])
])
], 10, _hoisted_1);
};
}
});
function getMonthNames(locale, format = "long") {
const dates = [];
for (let i = 0; i < 12; i++) {
dates.push(new Date(2e3, i, 15));
}
const dtf = new Intl.DateTimeFormat(locale, {
month: format
});
return dates.map((d) => dtf.format(d));
}
function getWeekdayNames(locale, firstDayOfWeek = 0, format = "narrow") {
const dates = [];
for (let i = 1, j = 0; j < 7; i++) {
const d = new Date(2e3, 0, i);
const day = d.getDay();
if (day === firstDayOfWeek || j > 0) {
dates.push(d);
j++;
}
}
const dtf = new Intl.DateTimeFormat(locale, {
weekday: format
});
return dates.map((d) => dtf.format(d));
}
function matchWithGroups(pattern, str) {
var _a;
const matches = str.match(pattern);
return (
// get the pattern as a string
(_a = pattern.toString().match(/<(.+?)>/g)) == null ? void 0 : _a.map((group) => {
const groupMatches = group.match(/<(.+)>/);
if (!groupMatches || groupMatches.length <= 0) {
return null;
}
const match = group.match(/<(.+)>/);
return match && (match == null ? void 0 : match.length) > 1 ? match[1] : null;
}).reduce((acc, curr, index) => {
if (curr === null) return acc;
if (matches && matches.length > index) {
acc[curr] = matches[index + 1];
} else {
acc[curr] = null;
}
return acc;
}, {})
);
}
function weekBuilder(startingDate, month, year, firstDayOfWeek) {
const thisMonth = new Date(year, month);
const thisWeek = [];
const dayOfWeek = new Date(year, month, startingDate).getDay();
const end = dayOfWeek >= firstDayOfWeek ? dayOfWeek - firstDayOfWeek : 7 - firstDayOfWeek + dayOfWeek;
let daysAgo = 1;
for (let i = 0; i < end; i++) {
thisWeek.unshift(
new Date(
thisMonth.getFullYear(),
thisMonth.getMonth(),
startingDate - daysAgo
)
);
daysAgo++;
}
thisWeek.push(new Date(year, month, startingDate));
let daysForward = 1;
while (thisWeek.length < 7) {
thisWeek.push(new Date(year, month, startingDate + daysForward));
daysForward++;
}
return thisWeek;
}
function firstWeekOffset(year, dow, doy) {
const fwd = 7 + dow - doy;
const firstJanuary = new Date(year, 0, fwd);
const fwdlw = (7 + firstJanuary.getDay() - dow) % 7;
return -fwdlw + fwd - 1;
}
function daysInYear(year) {
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0 ? 366 : 365;
}
function weeksInYear(year, dow, doy) {
const weekOffset = firstWeekOffset(year, dow, doy);
const weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
}
export {
_sfc_main as _,
weekBuilder as a,
getWeekdayNames as b,
firstWeekOffset as f,
getMonthNames as g,
matchWithGroups as m,
weeksInYear as w
};
//# sourceMappingURL=utils-9gIvy7A3.mjs.map