@yxhl/specter-pui-vtk 1.0.74 → 1.0.75

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yxhl/specter-pui-vtk",
3
- "version": "1.0.74",
3
+ "version": "1.0.75",
4
4
  "description": "雅心互联 Vue 3 + Vuetify3 组件库",
5
5
  "type": "module",
6
6
  "main": "./dist/specter-pui.umd.js",
@@ -1,19 +1,33 @@
1
1
  <template>
2
2
  <div class="vtk-date-selector" ref="selectorRef">
3
- <div v-if="!inline" class="date-input" ref="inputRef" @click="togglePicker">
4
- <input type="text" :value="displayValue" :placeholder="placeholder" :disabled="disabled" readonly
5
- class="date-input-field" />
6
- <span class="date-icon" aria-hidden="true">
7
- <svg viewBox="0 0 24 24" fill="none" class="date-icon-svg">
8
- <path
9
- d="M7 2.75a.75.75 0 0 1 .75.75V5h8.5V3.5a.75.75 0 0 1 1.5 0V5h.75A2.5 2.5 0 0 1 21 7.5v10A2.5 2.5 0 0 1 18.5 20h-13A2.5 2.5 0 0 1 3 17.5v-10A2.5 2.5 0 0 1 5.5 5h.75V3.5A.75.75 0 0 1 7 2.75ZM4.5 10v7.5c0 .552.448 1 1 1h13c.552 0 1-.448 1-1V10h-15Zm1-3.5c-.552 0-1 .448-1 1v1h15v-1c0-.552-.448-1-1-1h-.75v1a.75.75 0 0 1-1.5 0v-1h-8.5v1a.75.75 0 0 1-1.5 0v-1H5.5Zm2.25 5.75a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm-8.5 3.75a.75.75 0 0 1 .75.75V17a.75.75 0 0 1-1.5 0v-.25a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75V17a.75.75 0 0 1-1.5 0v-.25a.75.75 0 0 1 .75-.75Z"
10
- fill="currentColor"
11
- />
12
- </svg>
13
- </span>
14
- <span v-if="displayValue && !disabled" class="clear-icon" @click.stop="clearValue">✕</span>
3
+ <div v-if="!inline" class="date-input" ref="inputRef">
4
+ <VTextField
5
+ :model-value="displayValue"
6
+ :placeholder="placeholder"
7
+ :disabled="disabled"
8
+ density="compact"
9
+ variant="outlined"
10
+ hide-details
11
+ readonly
12
+ :clearable="!!displayValue && !disabled"
13
+ clear-icon="mdi-close-circle"
14
+ persistent-clear
15
+ class="date-input-field"
16
+ @click="togglePicker"
17
+ @click:clear.stop="clearValue"
18
+ >
19
+ <template #append-inner>
20
+ <span class="date-icon" aria-hidden="true">
21
+ <svg viewBox="0 0 24 24" fill="none" class="date-icon-svg">
22
+ <path
23
+ d="M7 2.75a.75.75 0 0 1 .75.75V5h8.5V3.5a.75.75 0 0 1 1.5 0V5h.75A2.5 2.5 0 0 1 21 7.5v10A2.5 2.5 0 0 1 18.5 20h-13A2.5 2.5 0 0 1 3 17.5v-10A2.5 2.5 0 0 1 5.5 5h.75V3.5A.75.75 0 0 1 7 2.75ZM4.5 10v7.5c0 .552.448 1 1 1h13c.552 0 1-.448 1-1V10h-15Zm1-3.5c-.552 0-1 .448-1 1v1h15v-1c0-.552-.448-1-1-1h-.75v1a.75.75 0 0 1-1.5 0v-1h-8.5v1a.75.75 0 0 1-1.5 0v-1H5.5Zm2.25 5.75a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75v.25a.75.75 0 0 1-1.5 0V13a.75.75 0 0 1 .75-.75Zm-8.5 3.75a.75.75 0 0 1 .75.75V17a.75.75 0 0 1-1.5 0v-.25a.75.75 0 0 1 .75-.75Zm4.25 0a.75.75 0 0 1 .75.75V17a.75.75 0 0 1-1.5 0v-.25a.75.75 0 0 1 .75-.75Z"
24
+ fill="currentColor"
25
+ />
26
+ </svg>
27
+ </span>
28
+ </template>
29
+ </VTextField>
15
30
  </div>
16
-
17
31
  <!-- 使用 Teleport 将下拉框渲染到 body 下,避免被父容器裁剪 -->
18
32
  <Teleport to="body" :disabled="inline || noTeleport">
19
33
  <div v-if="showPicker && !inline" class="date-picker-mask" @click="closePicker"></div>
@@ -318,13 +332,13 @@ const dropdownStyle = ref({});
318
332
 
319
333
  // 当前日期(用于判断未来日期)
320
334
  const today = new Date();
321
- const todayYear = today.getFullYear();
322
- const todayMonth = today.getMonth();
323
- const todayDate = today.getDate();
324
-
325
- // 年份面板固定展示 12 个年份,并尽量让锚点年份落在中间偏前位置
326
- const YEAR_PANEL_SIZE = 12;
327
- const YEAR_PANEL_CENTER_OFFSET = 4;
335
+ const todayYear = today.getFullYear();
336
+ const todayMonth = today.getMonth();
337
+ const todayDate = today.getDate();
338
+
339
+ // 年份面板固定展示 12 个年份,并尽量让锚点年份落在中间偏前位置
340
+ const YEAR_PANEL_SIZE = 12;
341
+ const YEAR_PANEL_CENTER_OFFSET = 4;
328
342
 
329
343
  // 周和月份名称
330
344
  const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
@@ -362,11 +376,11 @@ const formatDisplay = (value) => {
362
376
  };
363
377
 
364
378
  // 年份列表(显示12年)
365
- const yearList = computed(() => {
366
- // 年份面板打开时,以当前锚点年份为中心生成 12 个年份选项
367
- const startYear = currentYear.value - YEAR_PANEL_CENTER_OFFSET;
368
- return Array.from({ length: YEAR_PANEL_SIZE }, (_, i) => startYear + i);
369
- });
379
+ const yearList = computed(() => {
380
+ // 年份面板打开时,以当前锚点年份为中心生成 12 个年份选项
381
+ const startYear = currentYear.value - YEAR_PANEL_CENTER_OFFSET;
382
+ return Array.from({ length: YEAR_PANEL_SIZE }, (_, i) => startYear + i);
383
+ });
370
384
 
371
385
  // 周列表
372
386
  const weekList = computed(() => {
@@ -649,7 +663,12 @@ const selectMonth = (month) => {
649
663
  // 如果是未来月份且禁用未来日期,则不允许选择
650
664
  if (isFutureMonth(month, currentYear.value)) return;
651
665
 
652
- console.log('selectMonth', month);
666
+ if (props.displayMode !== 'month') {
667
+ currentMonth.value = month;
668
+ viewMode.value = props.displayMode;
669
+ return;
670
+ }
671
+
653
672
  const monthStr = `${currentYear.value}-${String(month + 1).padStart(2, '0')}`;
654
673
  if (props.mode === 'single') {
655
674
  tempValue.value = monthStr;
@@ -855,18 +874,18 @@ const changeViewMode = (mode) => {
855
874
  };
856
875
 
857
876
  // 面板操作
858
- const togglePicker = () => {
859
- if (props.disabled) return;
860
- showPicker.value = !showPicker.value;
861
- if (showPicker.value) {
862
- // 年份单选打开面板时,优先围绕当前自然年展示年份列表
863
- if (props.displayMode === 'year' && props.mode === 'single') {
864
- currentYear.value = todayYear;
865
- }
866
-
867
- tempValue.value = selectedValue.value ?
868
- (Array.isArray(selectedValue.value) ? [...selectedValue.value] : selectedValue.value) :
869
- (props.mode === 'range' ? [] : null);
877
+ const togglePicker = () => {
878
+ if (props.disabled) return;
879
+ showPicker.value = !showPicker.value;
880
+ if (showPicker.value) {
881
+ // 年份单选打开面板时,优先围绕当前自然年展示年份列表
882
+ if (props.displayMode === 'year' && props.mode === 'single') {
883
+ currentYear.value = todayYear;
884
+ }
885
+
886
+ tempValue.value = selectedValue.value ?
887
+ (Array.isArray(selectedValue.value) ? [...selectedValue.value] : selectedValue.value) :
888
+ (props.mode === 'range' ? [] : null);
870
889
  viewMode.value = props.displayMode;
871
890
 
872
891
  // 初始化右侧日历/年份
@@ -983,34 +1002,16 @@ watch(() => props.modelValue, (newValue) => {
983
1002
  }
984
1003
 
985
1004
  .date-input {
986
- position: relative;
987
- display: flex;
988
- align-items: center;
989
- border: 1px solid rgb(var(--v-theme-on-surface), 0.3);
990
- border-radius: 4px;
991
- padding: 0 12px;
992
- background: rgb(var(--v-theme-surface));
993
- cursor: pointer;
994
- transition: border-color 0.2s;
995
- }
996
-
997
- .date-input:hover {
998
- border-color: rgb(var(--v-theme-on-surface), 0.8);
1005
+ width: 100%;
999
1006
  }
1000
1007
 
1001
1008
  .date-input-field {
1002
- flex: 1;
1003
- border: none;
1004
- outline: none;
1005
- padding: 8px 0;
1006
- font-size: 14px;
1007
1009
  cursor: pointer;
1008
- background: transparent;
1009
- color: rgb(var(--v-theme-on-surface), 0.8);
1010
1010
  }
1011
1011
 
1012
- .date-input-field::placeholder {
1013
- color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
1012
+ :deep(.date-input-field .v-field),
1013
+ :deep(.date-input-field input) {
1014
+ cursor: pointer;
1014
1015
  }
1015
1016
 
1016
1017
  .date-icon {
@@ -1027,18 +1028,6 @@ watch(() => props.modelValue, (newValue) => {
1027
1028
  display: block;
1028
1029
  }
1029
1030
 
1030
- .clear-icon {
1031
- margin-left: 8px;
1032
- color: rgb(var(--v-theme-on-surface), 0.6);
1033
- font-size: 14px;
1034
- cursor: pointer;
1035
- padding: 2px;
1036
- }
1037
-
1038
- .clear-icon:hover {
1039
- color: rgb(var(--v-theme-on-surface), 0.87);
1040
- }
1041
-
1042
1031
  .date-picker-mask {
1043
1032
  position: fixed;
1044
1033
  top: 0;
@@ -41,7 +41,7 @@
41
41
  </VTextField>
42
42
  </template>
43
43
 
44
- <VCard style="width: 380px; margin-right: -16px; overflow: visible;">
44
+ <VCard class="search-panel">
45
45
  <VCardTitle class="pr-3 d-flex justify-space-between align-center pb-5">
46
46
  <span>高级搜索</span>
47
47
  <VBtn class="mx-0" variant="text" icon @click="close" size="small">
@@ -49,7 +49,7 @@
49
49
  </VBtn>
50
50
  </VCardTitle>
51
51
 
52
- <VCardText style="overflow: visible;">
52
+ <VCardText class="search-panel__content" :style="contentStyle">
53
53
  <slot :query-param="queryParam"></slot>
54
54
  </VCardText>
55
55
 
@@ -79,6 +79,10 @@ const props = defineProps({
79
79
  value: {
80
80
  type: Object,
81
81
  default: () => ({})
82
+ },
83
+ contentMaxHeight: {
84
+ type: [Number, String],
85
+ default: 360
82
86
  }
83
87
  });
84
88
 
@@ -101,6 +105,15 @@ const initialIndex = computed(() => {
101
105
  }).length;
102
106
  });
103
107
 
108
+ const contentStyle = computed(() => {
109
+ const value = props.contentMaxHeight;
110
+ const maxHeight = typeof value === 'number' ? `${value}px` : value;
111
+
112
+ return {
113
+ maxHeight,
114
+ };
115
+ });
116
+
104
117
  watch(
105
118
  () => props.value,
106
119
  (newVal) => {
@@ -166,6 +179,37 @@ defineExpose({ search, reset });
166
179
  min-height: 40px;
167
180
  }
168
181
 
182
+ .search-panel {
183
+ width: 380px;
184
+ margin-right: -16px;
185
+ display: flex;
186
+ flex-direction: column;
187
+ }
188
+
189
+ .search-panel__content {
190
+ overflow-y: auto;
191
+ overflow-x: hidden;
192
+ scrollbar-width: thin;
193
+ scrollbar-color: rgb(var(--v-theme-primary)) transparent;
194
+ }
195
+
196
+ .search-panel__content::-webkit-scrollbar {
197
+ width: 8px;
198
+ }
199
+
200
+ .search-panel__content::-webkit-scrollbar-track {
201
+ background: transparent;
202
+ }
203
+
204
+ .search-panel__content::-webkit-scrollbar-thumb {
205
+ background: rgba(var(--v-theme-primary), 0.8);
206
+ border-radius: 999px;
207
+ }
208
+
209
+ .search-panel__content::-webkit-scrollbar-thumb:hover {
210
+ background: rgb(var(--v-theme-primary));
211
+ }
212
+
169
213
  :deep(.box .v-field__append-inner) {
170
214
  cursor: pointer;
171
215
  padding-left: 16px !important;
@@ -141,7 +141,7 @@ $color-dark-bg: #1e1e1e;
141
141
 
142
142
  .last-box::after {
143
143
  position: absolute;
144
- right: -70px;
144
+ right: -69px;
145
145
  content: "";
146
146
  z-index: 1;
147
147
  width: 0;
@@ -39,7 +39,7 @@ const onModelUpdate = (value) => {
39
39
  };
40
40
  </script>
41
41
  <style lang="scss" scoped>
42
- ::v-deep .v-snackbar__wrapper {
43
- top: 24px;
44
- }
42
+ :deep(.v-snackbar__wrapper) {
43
+ top: 24px;
44
+ }
45
45
  </style>