song-ui-u
Version:
vue3 + js的PC前端组件库
427 lines (423 loc) • 16.1 kB
JavaScript
;
var vue = require('vue');
require('../../button/index.cjs');
require('../../buttonGroup/index.cjs');
var index$1 = require('../../icon/index.cjs');
var index = require('../../input/index.cjs');
require('../../textarea/index.cjs');
require('../../row/index.cjs');
require('../../col/index.cjs');
require('../../container/index.cjs');
require('../../checkbox/index.cjs');
require('../../switch/index.cjs');
require('../../form/index.cjs');
require('../../message/index.cjs');
require('../../mask/src/mask.cjs');
require('../../modal/index.cjs');
require('../../messageBox/index.cjs');
require('../../drawer/index.cjs');
require('../../badge/index.cjs');
require('../../space/index.cjs');
require('../../image/index.cjs');
require('../../radio/index.cjs');
require('../../divider/index.cjs');
require('../../chat/index.cjs');
require('../../progress/index.cjs');
require('../../upload/index.cjs');
require('../../vTree/index.cjs');
require('../../table/index.cjs');
require('../../tabs/index.cjs');
require('../../menu/index.cjs');
require('../../steps/index.cjs');
require('../../header/index.cjs');
require('../../breadcrumble/index.cjs');
require('../../datePicker/index.cjs');
require('../../tooltip/index.cjs');
require('../../popover/index.cjs');
require('../index.cjs');
require('../../select/index.cjs');
require('../../collapse/index.cjs');
require('../../card/index.cjs');
require('../../timeline/index.cjs');
require('../../tag/index.cjs');
require('../../result/index.cjs');
require('../../sender/index.cjs');
var dateFns = require('date-fns');
var icons = require('song-ui-pro-icon');
var index$2 = require('../../../hook/use-namespace/index.cjs');
require('../../../hook/use-zindex/index.cjs');
var DateTime = /* @__PURE__ */ vue.defineComponent({
name: "x-time-picker",
props: {
modelValue: {
type: [String, Array],
default: ""
},
placeholder: {
type: String,
default: "\u8BF7\u9009\u62E9\u65F6\u95F4"
},
format: {
type: String,
default: "HH:mm:ss"
},
disabled: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
range: {
type: Boolean,
default: false
},
startPlaceholder: {
type: String,
default: "\u5F00\u59CB\u65F6\u95F4"
},
endPlaceholder: {
type: String,
default: "\u7ED3\u675F\u65F6\u95F4"
}
},
setup(props, {
emit
}) {
const ns = index$2.useNamespace("time-picker");
const visible = vue.ref(false);
const displayValue = vue.ref("");
const currentTime = vue.ref(props.modelValue ? new Date(props.modelValue) : /* @__PURE__ */ new Date());
const rangeState = vue.ref({
startTime: null,
endTime: null
});
if (props.range && Array.isArray(props.modelValue) && props.modelValue.length === 2) {
rangeState.value.startTime = new Date(props.modelValue[0]);
rangeState.value.endTime = new Date(props.modelValue[1]);
displayValue.value = `${formatTime(rangeState.value.startTime)} \u81F3 ${formatTime(rangeState.value.endTime)}`;
}
const hours = vue.computed(() => {
const hours2 = [];
for (let i = 0; i < 24; i++) {
hours2.push({
value: i,
label: i.toString().padStart(2, "0"),
isSelected: (position) => isSelectedHour(i, position)
});
}
return hours2;
});
const minutes = vue.computed(() => {
const minutes2 = [];
for (let i = 0; i < 60; i++) {
minutes2.push({
value: i,
label: i.toString().padStart(2, "0"),
isSelected: (position) => isSelectedMinute(i, position)
});
}
return minutes2;
});
const seconds = vue.computed(() => {
const seconds2 = [];
for (let i = 0; i < 60; i++) {
seconds2.push({
value: i,
label: i.toString().padStart(2, "0"),
isSelected: (position) => isSelectedSecond(i, position)
});
}
return seconds2;
});
const isSelectedHour = (hour, position) => {
if (props.range) {
if (position === "left") {
return hour === (rangeState.value.startTime ? rangeState.value.startTime.getHours() : null);
} else if (position === "right") {
return hour === (rangeState.value.endTime ? rangeState.value.endTime.getHours() : null);
}
}
return hour === currentTime.value.getHours();
};
const isSelectedMinute = (minute, position) => {
if (props.range) {
if (position === "left") {
return minute === (rangeState.value.startTime ? rangeState.value.startTime.getMinutes() : null);
} else if (position === "right") {
return minute === (rangeState.value.endTime ? rangeState.value.endTime.getMinutes() : null);
}
}
return minute === currentTime.value.getMinutes();
};
const isSelectedSecond = (second, position) => {
if (props.range) {
if (position === "left") {
return second === (rangeState.value.startTime ? rangeState.value.startTime.getSeconds() : null);
} else if (position === "right") {
return second === (rangeState.value.endTime ? rangeState.value.endTime.getSeconds() : null);
}
}
return second === currentTime.value.getSeconds();
};
const formatTime = (time) => {
return dateFns.format(time, props.format);
};
const showPanel = () => {
if (props.disabled || props.readonly) return;
visible.value = true;
};
const handleClear = () => {
emit("update:modelValue", props.range ? [] : "");
emit("change", props.range ? [] : "");
displayValue.value = "";
if (props.range) {
rangeState.value.startTime = null;
rangeState.value.endTime = null;
rangeState.value.selecting = false;
}
};
const selectTime = (type, value, position) => {
let newTime;
if (props.range) {
const baseTime = position === "left" ? rangeState.value.startTime || /* @__PURE__ */ new Date() : rangeState.value.endTime || /* @__PURE__ */ new Date();
if (type === "hour") {
newTime = dateFns.setHours(baseTime, value);
} else if (type === "minute") {
newTime = dateFns.setMinutes(baseTime, value);
} else if (type === "second") {
newTime = dateFns.setSeconds(baseTime, value);
}
if (position === "left") {
rangeState.value.startTime = newTime;
if (!rangeState.value.endTime) {
rangeState.value.endTime = dateFns.addHours(newTime, 1);
}
} else if (position === "right") {
rangeState.value.endTime = newTime;
if (!rangeState.value.startTime) {
rangeState.value.startTime = dateFns.subHours(newTime, 1);
}
}
} else {
newTime = currentTime.value;
if (type === "hour") {
newTime = dateFns.setHours(newTime, value);
} else if (type === "minute") {
newTime = dateFns.setMinutes(newTime, value);
} else if (type === "second") {
newTime = dateFns.setSeconds(newTime, value);
}
currentTime.value = newTime;
const formattedTime = formatTime(newTime);
console.log("formattedTime", formattedTime);
displayValue.value = formattedTime;
}
};
const generateUniqueId = () => {
return `time-picker-${Math.random().toString(36).substr(2, 9)}`;
};
const uniqueId = vue.ref(generateUniqueId());
const handleClickOutside = (e) => {
const root = e.currentTarget;
const panel = root.querySelector(".x-time-picker__panel");
const input = root.querySelector(".x-time-picker__input");
if (panel && !panel.contains(e.target) && !input.contains(e.target)) {
visible.value = false;
}
};
vue.onMounted(() => {
const root = document.querySelector(`[data-id="${uniqueId.value}"]`);
if (root) {
root.addEventListener("click", handleClickOutside);
}
});
vue.onUnmounted(() => {
const root = document.querySelector(`[data-id="${uniqueId.value}"]`);
if (root) {
root.removeEventListener("click", handleClickOutside);
}
});
const handleConfirm = () => {
if (props.range) {
if (rangeState.value.startTime && rangeState.value.endTime) {
const startFormatted = formatTime(rangeState.value.startTime);
const endFormatted = formatTime(rangeState.value.endTime);
emit("update:modelValue", [startFormatted, endFormatted]);
emit("change", [startFormatted, endFormatted]);
displayValue.value = `${startFormatted} \u81F3 ${endFormatted}`;
}
} else {
const formattedTime = formatTime(currentTime.value);
emit("update:modelValue", formattedTime);
emit("change", formattedTime);
displayValue.value = formattedTime;
}
visible.value = false;
};
const hanleCondel = () => {
visible.value = false;
if (props.range) {
rangeState.value.startTime = null;
rangeState.value.endTime = null;
rangeState.value.selecting = false;
}
emit("update:modelValue", props.range ? [] : "");
emit("change", props.range ? [] : "");
displayValue.value = "";
};
return () => vue.createVNode("div", {
"data-id": uniqueId.value,
"class": ns.b()
}, [vue.createVNode("div", {
"class": [ns.e("input"), ns.is("range", props.range)],
"onClick": showPanel
}, [vue.createVNode(index.XInput, {
"modelValue": displayValue.value,
"placeholder": props.range ? `${props.startPlaceholder} \u81F3 ${props.endPlaceholder}` : props.placeholder,
"disabled": props.disabled,
"readonly": props.readonly,
"clearance": props.clearable,
"onClear": handleClear
}, {
prepend: () => vue.createVNode(index$1.XIcon, null, {
default: () => [vue.createVNode(icons.Clock, null, null)]
})
})]), visible.value && vue.createVNode("div", {
"class": [ns.e("panel"), props.range ? ns.m("panel", "range") : ""]
}, [props.range && vue.createVNode("div", {
"class": ns.e("panel-left")
}, [vue.createVNode("div", {
"class": ns.e("time-columns")
}, [vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u65F6")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => vue.createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected("left"))],
"onClick": () => selectTime("hour", hour.value, "left")
}, [hour.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u5206")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => vue.createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected("left"))],
"onClick": () => selectTime("minute", minute.value, "left")
}, [minute.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u79D2")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => vue.createVNode("span", {
"key": second.value,
"class": [ns.e("cell"), ns.is("selected", second.isSelected("left"))],
"onClick": () => selectTime("second", second.value, "left")
}, [second.label]))])])])]), props.range && vue.createVNode("div", {
"class": ns.e("panel-right")
}, [vue.createVNode("div", {
"class": ns.e("time-columns")
}, [vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u65F6")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => vue.createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected("right"))],
"onClick": () => selectTime("hour", hour.value, "right")
}, [hour.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u5206")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => vue.createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected("right"))],
"onClick": () => selectTime("minute", minute.value, "right")
}, [minute.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u79D2")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => vue.createVNode("span", {
"key": second.value,
"class": [ns.e("cell"), ns.is("selected", second.isSelected("right"))],
"onClick": () => selectTime("second", second.value, "right")
}, [second.label]))])])]), vue.createVNode("div", {
"class": ns.e("bottom")
}, [vue.createVNode(vue.resolveComponent("x-button"), {
"size": "small",
"type": "primary",
"onClick": handleConfirm
}, {
default: () => [vue.createTextVNode("\u786E\u5B9A")]
}), vue.createVNode(vue.resolveComponent("x-button"), {
"size": "small",
"onClick": hanleCondel
}, {
default: () => [vue.createTextVNode("\u53D6\u6D88")]
})])]), !props.range && vue.createVNode("div", {
"class": ns.e("time-columns")
}, [vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u65F6")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => vue.createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected())],
"onClick": () => selectTime("hour", hour.value)
}, [hour.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u5206")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => vue.createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected())],
"onClick": () => selectTime("minute", minute.value)
}, [minute.label]))])]), vue.createVNode("div", {
"class": ns.e("column")
}, [vue.createVNode("div", {
"class": ns.e("column-header")
}, [vue.createTextVNode("\u79D2")]), vue.createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => vue.createVNode("span", {
"key": second.value,
"class": [ns.e("cell"), ns.is("selected", second.isSelected())],
"onClick": () => selectTime("second", second.value)
}, [second.label]))])])]), !props.range && vue.createVNode("div", {
"class": ns.e("bottom")
}, [vue.createVNode(vue.resolveComponent("x-button"), {
"size": "small",
"type": "primary",
"onClick": handleConfirm
}, {
default: () => [vue.createTextVNode("\u786E\u5B9A")]
}), vue.createVNode(vue.resolveComponent("x-button"), {
"size": "small",
"onClick": hanleCondel
}, {
default: () => [vue.createTextVNode("\u53D6\u6D88")]
})])])]);
}
});
module.exports = DateTime;
//# sourceMappingURL=index.cjs.map