song-ui-u
Version:
vue3 + js的PC前端组件库
425 lines (422 loc) • 15.7 kB
JavaScript
import { defineComponent, ref, computed, onMounted, onUnmounted, createVNode, createTextVNode, resolveComponent } from 'vue';
import '../../button/index.mjs';
import '../../buttonGroup/index.mjs';
import { XIcon } from '../../icon/index.mjs';
import { XInput } from '../../input/index.mjs';
import '../../textarea/index.mjs';
import '../../row/index.mjs';
import '../../col/index.mjs';
import '../../container/index.mjs';
import '../../checkbox/index.mjs';
import '../../switch/index.mjs';
import '../../form/index.mjs';
import '../../message/index.mjs';
import '../../mask/src/mask.mjs';
import '../../modal/index.mjs';
import '../../messageBox/index.mjs';
import '../../drawer/index.mjs';
import '../../badge/index.mjs';
import '../../space/index.mjs';
import '../../image/index.mjs';
import '../../radio/index.mjs';
import '../../divider/index.mjs';
import '../../chat/index.mjs';
import '../../progress/index.mjs';
import '../../upload/index.mjs';
import '../../vTree/index.mjs';
import '../../table/index.mjs';
import '../../tabs/index.mjs';
import '../../menu/index.mjs';
import '../../steps/index.mjs';
import '../../header/index.mjs';
import '../../breadcrumble/index.mjs';
import '../../datePicker/index.mjs';
import '../../tooltip/index.mjs';
import '../../popover/index.mjs';
import '../index.mjs';
import '../../select/index.mjs';
import '../../collapse/index.mjs';
import '../../card/index.mjs';
import '../../timeline/index.mjs';
import '../../tag/index.mjs';
import '../../result/index.mjs';
import '../../sender/index.mjs';
import { format, setHours, setMinutes, setSeconds, addHours, subHours } from 'date-fns';
import { Clock } from 'song-ui-pro-icon';
import { useNamespace } from '../../../hook/use-namespace/index.mjs';
import '../../../hook/use-zindex/index.mjs';
var DateTime = /* @__PURE__ */ 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 = useNamespace("time-picker");
const visible = ref(false);
const displayValue = ref("");
const currentTime = ref(props.modelValue ? new Date(props.modelValue) : /* @__PURE__ */ new Date());
const rangeState = 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 = 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 = 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 = 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 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 = setHours(baseTime, value);
} else if (type === "minute") {
newTime = setMinutes(baseTime, value);
} else if (type === "second") {
newTime = setSeconds(baseTime, value);
}
if (position === "left") {
rangeState.value.startTime = newTime;
if (!rangeState.value.endTime) {
rangeState.value.endTime = addHours(newTime, 1);
}
} else if (position === "right") {
rangeState.value.endTime = newTime;
if (!rangeState.value.startTime) {
rangeState.value.startTime = subHours(newTime, 1);
}
}
} else {
newTime = currentTime.value;
if (type === "hour") {
newTime = setHours(newTime, value);
} else if (type === "minute") {
newTime = setMinutes(newTime, value);
} else if (type === "second") {
newTime = 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 = 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;
}
};
onMounted(() => {
const root = document.querySelector(`[data-id="${uniqueId.value}"]`);
if (root) {
root.addEventListener("click", handleClickOutside);
}
});
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 () => createVNode("div", {
"data-id": uniqueId.value,
"class": ns.b()
}, [createVNode("div", {
"class": [ns.e("input"), ns.is("range", props.range)],
"onClick": showPanel
}, [createVNode(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: () => createVNode(XIcon, null, {
default: () => [createVNode(Clock, null, null)]
})
})]), visible.value && createVNode("div", {
"class": [ns.e("panel"), props.range ? ns.m("panel", "range") : ""]
}, [props.range && createVNode("div", {
"class": ns.e("panel-left")
}, [createVNode("div", {
"class": ns.e("time-columns")
}, [createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u65F6")]), createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected("left"))],
"onClick": () => selectTime("hour", hour.value, "left")
}, [hour.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u5206")]), createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected("left"))],
"onClick": () => selectTime("minute", minute.value, "left")
}, [minute.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u79D2")]), createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => 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 && createVNode("div", {
"class": ns.e("panel-right")
}, [createVNode("div", {
"class": ns.e("time-columns")
}, [createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u65F6")]), createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected("right"))],
"onClick": () => selectTime("hour", hour.value, "right")
}, [hour.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u5206")]), createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected("right"))],
"onClick": () => selectTime("minute", minute.value, "right")
}, [minute.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u79D2")]), createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => createVNode("span", {
"key": second.value,
"class": [ns.e("cell"), ns.is("selected", second.isSelected("right"))],
"onClick": () => selectTime("second", second.value, "right")
}, [second.label]))])])]), createVNode("div", {
"class": ns.e("bottom")
}, [createVNode(resolveComponent("x-button"), {
"size": "small",
"type": "primary",
"onClick": handleConfirm
}, {
default: () => [createTextVNode("\u786E\u5B9A")]
}), createVNode(resolveComponent("x-button"), {
"size": "small",
"onClick": hanleCondel
}, {
default: () => [createTextVNode("\u53D6\u6D88")]
})])]), !props.range && createVNode("div", {
"class": ns.e("time-columns")
}, [createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u65F6")]), createVNode("div", {
"class": ns.e("column-content")
}, [hours.value.map((hour) => createVNode("span", {
"key": hour.value,
"class": [ns.e("cell"), ns.is("selected", hour.isSelected())],
"onClick": () => selectTime("hour", hour.value)
}, [hour.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u5206")]), createVNode("div", {
"class": ns.e("column-content")
}, [minutes.value.map((minute) => createVNode("span", {
"key": minute.value,
"class": [ns.e("cell"), ns.is("selected", minute.isSelected())],
"onClick": () => selectTime("minute", minute.value)
}, [minute.label]))])]), createVNode("div", {
"class": ns.e("column")
}, [createVNode("div", {
"class": ns.e("column-header")
}, [createTextVNode("\u79D2")]), createVNode("div", {
"class": ns.e("column-content")
}, [seconds.value.map((second) => createVNode("span", {
"key": second.value,
"class": [ns.e("cell"), ns.is("selected", second.isSelected())],
"onClick": () => selectTime("second", second.value)
}, [second.label]))])])]), !props.range && createVNode("div", {
"class": ns.e("bottom")
}, [createVNode(resolveComponent("x-button"), {
"size": "small",
"type": "primary",
"onClick": handleConfirm
}, {
default: () => [createTextVNode("\u786E\u5B9A")]
}), createVNode(resolveComponent("x-button"), {
"size": "small",
"onClick": hanleCondel
}, {
default: () => [createTextVNode("\u53D6\u6D88")]
})])])]);
}
});
export { DateTime as default };
//# sourceMappingURL=index.mjs.map