@yxhl/specter-pui-vtk 1.0.96 → 1.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/specter-pui-vtk.css +1 -1
- package/dist/specter-pui.es.js +2699 -2674
- package/dist/specter-pui.es.js.map +1 -1
- package/dist/specter-pui.umd.js +1 -1
- package/dist/specter-pui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/assembly/VtkDatePanelHeader.vue +12 -2
- package/src/components/assembly/VtkDateSelector.vue +72 -89
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="panel-header" @keydown.esc.stop="closePicker">
|
|
2
|
+
<div ref="headerRef" class="panel-header" @keydown.esc.stop="closePicker">
|
|
3
3
|
<button type="button" class="panel-nav" aria-label="上一周期" @click="handleNavigate('prev')">‹</button>
|
|
4
4
|
|
|
5
5
|
<div class="panel-title">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
52
|
<script setup>
|
|
53
|
-
import { computed, ref, watch } from 'vue';
|
|
53
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
54
54
|
|
|
55
55
|
defineOptions({
|
|
56
56
|
name: 'VtkDatePanelHeader',
|
|
@@ -89,6 +89,7 @@ const getYearPageStart = (year) => year - YEAR_PAGE_CENTER_OFFSET;
|
|
|
89
89
|
|
|
90
90
|
const openPicker = ref(null);
|
|
91
91
|
const yearPageStart = ref(getYearPageStart(props.year));
|
|
92
|
+
const headerRef = ref(null);
|
|
92
93
|
|
|
93
94
|
const yearPage = computed(() =>
|
|
94
95
|
Array.from({ length: YEAR_PAGE_SIZE }, (_, index) => yearPageStart.value + index)
|
|
@@ -153,11 +154,20 @@ const handleNavigate = (direction) => {
|
|
|
153
154
|
emit(direction);
|
|
154
155
|
};
|
|
155
156
|
|
|
157
|
+
const handleOutsideClick = (event) => {
|
|
158
|
+
if (openPicker.value && !headerRef.value?.contains(event.target)) {
|
|
159
|
+
closePicker();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
156
163
|
watch(() => props.year, (year) => {
|
|
157
164
|
if (openPicker.value !== 'year') {
|
|
158
165
|
yearPageStart.value = getYearPageStart(year);
|
|
159
166
|
}
|
|
160
167
|
});
|
|
168
|
+
|
|
169
|
+
onMounted(() => document.addEventListener('click', handleOutsideClick));
|
|
170
|
+
onBeforeUnmount(() => document.removeEventListener('click', handleOutsideClick));
|
|
161
171
|
</script>
|
|
162
172
|
|
|
163
173
|
<style scoped>
|
|
@@ -1076,55 +1076,76 @@ const changeViewMode = (mode) => {
|
|
|
1076
1076
|
viewMode.value = mode;
|
|
1077
1077
|
};
|
|
1078
1078
|
|
|
1079
|
-
// 面板操作
|
|
1080
|
-
const
|
|
1081
|
-
if (
|
|
1082
|
-
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
|
|
1079
|
+
// 面板操作
|
|
1080
|
+
const parseCalendarValue = (value) => {
|
|
1081
|
+
if (typeof value !== 'string') return null;
|
|
1082
|
+
|
|
1083
|
+
const match = value.match(/^(\d{4})(?:-(\d{2}))?/);
|
|
1084
|
+
if (!match) return null;
|
|
1085
|
+
|
|
1086
|
+
const month = match[2] ? Number(match[2]) - 1 : null;
|
|
1087
|
+
return {
|
|
1088
|
+
year: Number(match[1]),
|
|
1089
|
+
month: month !== null && month >= 0 && month <= 11 ? month : null
|
|
1090
|
+
};
|
|
1091
|
+
};
|
|
1092
|
+
|
|
1093
|
+
const setRightPanelToNextMonth = () => {
|
|
1094
|
+
if (currentMonth.value === 11) {
|
|
1095
|
+
rightYear.value = currentYear.value + 1;
|
|
1096
|
+
rightMonth.value = 0;
|
|
1097
|
+
} else {
|
|
1098
|
+
rightYear.value = currentYear.value;
|
|
1099
|
+
rightMonth.value = currentMonth.value + 1;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
const syncCalendarPanels = () => {
|
|
1104
|
+
const values = Array.isArray(selectedValue.value) ? selectedValue.value : [selectedValue.value];
|
|
1105
|
+
const start = parseCalendarValue(values[0]);
|
|
1106
|
+
const end = parseCalendarValue(values[1]);
|
|
1107
|
+
|
|
1108
|
+
if (start) {
|
|
1109
|
+
currentYear.value = start.year;
|
|
1110
|
+
if (start.month !== null) currentMonth.value = start.month;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
if (props.displayMode === 'year') return;
|
|
1114
|
+
|
|
1115
|
+
if (props.displayMode === 'month') {
|
|
1116
|
+
rightYear.value = end && end.year !== currentYear.value ? end.year : currentYear.value + 1;
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
const endUsesDifferentMonth = end && end.month !== null &&
|
|
1121
|
+
(end.year !== currentYear.value || end.month !== currentMonth.value);
|
|
1122
|
+
|
|
1123
|
+
if (props.mode === 'range' && endUsesDifferentMonth) {
|
|
1124
|
+
rightYear.value = end.year;
|
|
1125
|
+
rightMonth.value = end.month;
|
|
1126
|
+
} else {
|
|
1127
|
+
setRightPanelToNextMonth();
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
const initializePicker = () => {
|
|
1132
|
+
tempValue.value = selectedValue.value ?
|
|
1133
|
+
(Array.isArray(selectedValue.value) ? [...selectedValue.value] : selectedValue.value) :
|
|
1134
|
+
(props.mode === 'range' ? [] : null);
|
|
1135
|
+
viewMode.value = props.displayMode;
|
|
1136
|
+
syncCalendarPanels();
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
watch(showPicker, (isOpen) => {
|
|
1104
1140
|
if (isOpen) {
|
|
1105
|
-
initializePicker();
|
|
1106
|
-
}
|
|
1107
|
-
});
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
viewMode.value = props.displayMode;
|
|
1114
|
-
|
|
1115
|
-
// 初始化右侧日历/年份
|
|
1116
|
-
if (props.displayMode === 'month') {
|
|
1117
|
-
rightYear.value = currentYear.value + 1;
|
|
1118
|
-
} else {
|
|
1119
|
-
if (currentMonth.value === 11) {
|
|
1120
|
-
rightYear.value = currentYear.value + 1;
|
|
1121
|
-
rightMonth.value = 0;
|
|
1122
|
-
} else {
|
|
1123
|
-
rightYear.value = currentYear.value;
|
|
1124
|
-
rightMonth.value = currentMonth.value + 1;
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1141
|
+
initializePicker();
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
|
|
1145
|
+
watch(() => props.modelValue, (newValue) => {
|
|
1146
|
+
selectedValue.value = newValue;
|
|
1147
|
+
if (props.inline) initializePicker();
|
|
1148
|
+
}, { immediate: true });
|
|
1128
1149
|
|
|
1129
1150
|
const closePicker = () => {
|
|
1130
1151
|
showPicker.value = false;
|
|
@@ -1162,11 +1183,7 @@ const handleConfirm = () => {
|
|
|
1162
1183
|
}
|
|
1163
1184
|
};
|
|
1164
1185
|
|
|
1165
|
-
|
|
1166
|
-
watch(() => props.modelValue, (newValue) => {
|
|
1167
|
-
selectedValue.value = newValue;
|
|
1168
|
-
}, { immediate: true });
|
|
1169
|
-
</script>
|
|
1186
|
+
</script>
|
|
1170
1187
|
|
|
1171
1188
|
<style scoped>
|
|
1172
1189
|
.vtk-date-selector {
|
|
@@ -1301,42 +1318,8 @@ watch(() => props.modelValue, (newValue) => {
|
|
|
1301
1318
|
max-width: 340px;
|
|
1302
1319
|
}
|
|
1303
1320
|
|
|
1304
|
-
.
|
|
1305
|
-
|
|
1306
|
-
align-items: center;
|
|
1307
|
-
justify-content: space-between;
|
|
1308
|
-
padding: 4px 0;
|
|
1309
|
-
margin-bottom: 4px;
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
.month-title {
|
|
1313
|
-
font-size: 12px;
|
|
1314
|
-
font-weight: 500;
|
|
1315
|
-
color: rgb(var(--v-theme-on-surface));
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
.nav-btn-small {
|
|
1319
|
-
border: none;
|
|
1320
|
-
background: none;
|
|
1321
|
-
font-size: 14px;
|
|
1322
|
-
color: rgb(var(--v-theme-on-surface), 0.6);
|
|
1323
|
-
cursor: pointer;
|
|
1324
|
-
padding: 2px 4px;
|
|
1325
|
-
border-radius: 4px;
|
|
1326
|
-
transition: background 0.2s;
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
.nav-btn-small:hover {
|
|
1330
|
-
background: rgb(var(--v-theme-on-surface), 0.08);
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
.nav-btn-small.invisible {
|
|
1334
|
-
visibility: hidden;
|
|
1335
|
-
pointer-events: none;
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
.year-grid,
|
|
1339
|
-
.month-grid {
|
|
1321
|
+
.year-grid,
|
|
1322
|
+
.month-grid {
|
|
1340
1323
|
display: grid;
|
|
1341
1324
|
grid-template-columns: repeat(3, 1fr);
|
|
1342
1325
|
gap: 6px;
|