@hbdlzy/ui-core 0.1.7 → 0.1.9

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.
Files changed (74) hide show
  1. package/README.md +30 -2
  2. package/components.manifest.json +16 -2
  3. package/dist/components/BaseTable/BaseTable.types.d.ts +6 -1
  4. package/dist/components/OutlinedCascader/OutlinedCascader.vue.d.ts +1 -1
  5. package/dist/components/OutlinedDatePicker/OutlinedDatePicker.vue.d.ts +3 -3
  6. package/dist/components/OutlinedSelect/OutlinedSelect.vue.d.ts +4 -4
  7. package/dist/components/OutlinedTimePicker/OutlinedTimePicker.vue.d.ts +6 -6
  8. package/dist/components/OutlinedTreeSelect/OutlinedTreeSelect.vue.d.ts +4 -4
  9. package/dist/index.cjs +5 -5
  10. package/dist/index.d.ts +50 -13
  11. package/dist/index.js +531 -147
  12. package/dist/ripple/index.cjs +42 -0
  13. package/dist/ripple/index.d.ts +8 -1
  14. package/dist/ripple/index.js +171 -0
  15. package/dist/style.css +1 -1
  16. package/package.json +17 -2
  17. package/src/components/BaseCard/BaseCard.types.d.ts +36 -0
  18. package/src/components/BaseCard/BaseCard.vue.d.ts +122 -0
  19. package/src/components/BaseCard/README.md +33 -0
  20. package/src/components/BaseCard/index.d.ts +3 -0
  21. package/src/components/BaseEChart/BaseEChart.types.d.ts +26 -0
  22. package/src/components/BaseEChart/BaseEChart.vue.d.ts +66 -0
  23. package/src/components/BaseEChart/README.md +33 -0
  24. package/src/components/BaseEChart/index.d.ts +3 -0
  25. package/src/components/BaseExportButton/BaseExportButton.types.d.ts +21 -0
  26. package/src/components/BaseExportButton/BaseExportButton.utils.d.ts +4 -0
  27. package/src/components/BaseExportButton/BaseExportButton.vue.d.ts +128 -0
  28. package/src/components/BaseExportButton/README.md +34 -0
  29. package/src/components/BaseExportButton/index.d.ts +5 -0
  30. package/src/components/BaseTable/BaseTable.types.d.ts +183 -0
  31. package/src/components/BaseTable/BaseTable.types.ts +15 -1
  32. package/src/components/BaseTable/BaseTable.vue +340 -111
  33. package/src/components/BaseTable/BaseTable.vue.d.ts +157 -0
  34. package/src/components/BaseTable/README.md +121 -2
  35. package/src/components/BaseTable/index.d.ts +3 -0
  36. package/src/components/OutlinedCascader/OutlinedCascader.types.d.ts +28 -0
  37. package/src/components/OutlinedCascader/OutlinedCascader.vue.d.ts +94 -0
  38. package/src/components/OutlinedCascader/README.md +34 -0
  39. package/src/components/OutlinedCascader/index.d.ts +3 -0
  40. package/src/components/OutlinedDatePicker/OutlinedDatePicker.types.d.ts +30 -0
  41. package/src/components/OutlinedDatePicker/OutlinedDatePicker.vue.d.ts +97 -0
  42. package/src/components/OutlinedDatePicker/README.md +34 -0
  43. package/src/components/OutlinedDatePicker/index.d.ts +3 -0
  44. package/src/components/OutlinedDateTimePicker/OutlinedDateTimePicker.types.d.ts +29 -0
  45. package/src/components/OutlinedDateTimePicker/OutlinedDateTimePicker.vue.d.ts +106 -0
  46. package/src/components/OutlinedDateTimePicker/README.md +33 -0
  47. package/src/components/OutlinedDateTimePicker/index.d.ts +3 -0
  48. package/src/components/OutlinedInput/OutlinedInput.types.d.ts +32 -0
  49. package/src/components/OutlinedInput/OutlinedInput.vue.d.ts +106 -0
  50. package/src/components/OutlinedInput/README.md +34 -0
  51. package/src/components/OutlinedInput/index.d.ts +3 -0
  52. package/src/components/OutlinedSelect/OutlinedSelect.types.d.ts +41 -0
  53. package/src/components/OutlinedSelect/OutlinedSelect.vue.d.ts +125 -0
  54. package/src/components/OutlinedSelect/README.md +34 -0
  55. package/src/components/OutlinedSelect/index.d.ts +3 -0
  56. package/src/components/OutlinedTimePicker/OutlinedTimePicker.types.d.ts +31 -0
  57. package/src/components/OutlinedTimePicker/OutlinedTimePicker.vue.d.ts +103 -0
  58. package/src/components/OutlinedTimePicker/README.md +33 -0
  59. package/src/components/OutlinedTimePicker/index.d.ts +3 -0
  60. package/src/components/OutlinedTreeSelect/OutlinedTreeSelect.types.d.ts +49 -0
  61. package/src/components/OutlinedTreeSelect/OutlinedTreeSelect.vue.d.ts +146 -0
  62. package/src/components/OutlinedTreeSelect/README.md +34 -0
  63. package/src/components/OutlinedTreeSelect/index.d.ts +3 -0
  64. package/src/components/SvgIcon/README.md +33 -0
  65. package/src/components/SvgIcon/SvgIcon.types.d.ts +6 -0
  66. package/src/components/SvgIcon/SvgIcon.vue.d.ts +32 -0
  67. package/src/components/SvgIcon/index.d.ts +3 -0
  68. package/src/echarts/index.d.ts +9 -0
  69. package/src/excel/exportExcel.d.ts +18 -0
  70. package/src/index.d.ts +66 -0
  71. package/src/index.ts +78 -13
  72. package/src/ripple/README.md +160 -0
  73. package/src/ripple/index.d.ts +9 -0
  74. package/src/ripple/index.ts +15 -1
@@ -38,19 +38,21 @@
38
38
  <slot name="toolbar"></slot>
39
39
  </div>
40
40
  <div v-if="showPagination" class="base-table__toolbar-right">
41
- <el-pagination
42
- small
43
- background
44
- layout="total, prev, pager, next, sizes, jumper"
45
- :total="paginationState.total"
46
- :current-page="paginationState.currentPage"
47
- :page-size="paginationState.pageSize"
48
- :page-sizes="paginationState.pageSizes"
49
- :pager-count="5"
50
- :popper-append-to-body="false"
51
- @size-change="handleSizeChange"
52
- @current-change="handleCurrentChange"
53
- />
41
+ <el-config-provider :locale="zhCn">
42
+ <el-pagination
43
+ small
44
+ background
45
+ layout="total, prev, pager, next, sizes, jumper"
46
+ :total="paginationState.total"
47
+ :current-page="paginationState.currentPage"
48
+ :page-size="paginationState.pageSize"
49
+ :page-sizes="paginationState.pageSizes"
50
+ :pager-count="5"
51
+ :popper-append-to-body="false"
52
+ @size-change="handleSizeChange"
53
+ @current-change="handleCurrentChange"
54
+ />
55
+ </el-config-provider>
54
56
  </div>
55
57
  </div>
56
58
 
@@ -64,6 +66,8 @@
64
66
  :stripe="stripe"
65
67
  :default-sort="normalizedDefaultSort"
66
68
  highlight-current-row
69
+ @select="handleSelectionChange"
70
+ @select-all="handleSelectionChange"
67
71
  @selection-change="handleSelectionChange"
68
72
  @sort-change="handleSortChange"
69
73
  >
@@ -75,8 +79,9 @@
75
79
  v-if="hasSelection"
76
80
  type="selection"
77
81
  :width="selectionWidth"
82
+ fixed="left"
78
83
  align="center"
79
- :selectable="rowSelectable"
84
+ :selectable="resolveRowSelectable"
80
85
  />
81
86
 
82
87
  <el-table-column
@@ -139,6 +144,7 @@
139
144
  <button
140
145
  :ref="bindHeaderSearchTrigger(column)"
141
146
  class="base-table__header-icon"
147
+ :data-base-table-id="baseTableIconPrefix"
142
148
  :class="{ 'is-active': hasHeaderSearchValue(column) }"
143
149
  type="button"
144
150
  @click.stop="toggleHeaderSearch(column)"
@@ -153,8 +159,10 @@
153
159
  <teleport to="body">
154
160
  <div
155
161
  v-if="isHeaderSearchVisible(column)"
162
+ :ref="bindHeaderSearchPanel(column)"
156
163
  :key="getHeaderSearchStateKey(column)"
157
164
  class="base-table__header-search-panel"
165
+ :data-base-table-id="baseTableIconPrefix"
158
166
  :style="getHeaderSearchPanelStyle(column)"
159
167
  @click.stop
160
168
  @mousedown.stop
@@ -163,70 +171,27 @@
163
171
  v-if="isHeaderSearchSelect(column)"
164
172
  class="base-table__header-select"
165
173
  >
166
- <button
167
- class="base-table__header-select-trigger"
168
- type="button"
169
- @click="toggleHeaderSearchSelect(column)"
170
- >
171
- <span
172
- v-if="isHeaderSearchMultiple(column) && getHeaderSearchSelectedLabels(column).length"
173
- class="base-table__header-select-tags"
174
- >
175
- <span
176
- v-for="label in getHeaderSearchSelectedLabels(column).slice(0, 2)"
177
- :key="label"
178
- class="base-table__header-select-tag"
179
- >
180
- {{ label }}
181
- </span>
182
- <span
183
- v-if="getHeaderSearchSelectedLabels(column).length > 2"
184
- class="base-table__header-select-tag base-table__header-select-tag--count"
185
- >
186
- +{{ getHeaderSearchSelectedLabels(column).length - 2 }}
187
- </span>
188
- </span>
189
- <span
190
- v-else
191
- class="base-table__header-select-text"
192
- :class="{ 'is-placeholder': !hasHeaderSearchValue(column) }"
193
- >
194
- {{ getHeaderSearchSelectLabel(column) }}
195
- </span>
196
- <span
197
- class="base-table__header-select-arrow"
198
- :class="{ 'is-open': isHeaderSearchSelectOpen(column) }"
199
- aria-hidden="true"
200
- ></span>
201
- </button>
202
-
203
- <div
204
- v-if="isHeaderSearchSelectOpen(column)"
205
- class="base-table__header-select-options"
174
+ <el-select
175
+ class="base-table__header-el-select"
176
+ :model-value="getHeaderSearchSelectModelValue(column)"
177
+ :placeholder="getHeaderSearchPlaceholder(column)"
178
+ :multiple="isHeaderSearchMultiple(column)"
179
+ :filterable="isHeaderSearchFilterable(column)"
180
+ :clearable="isHeaderSearchClearable(column)"
181
+ :collapse-tags="isHeaderSearchMultiple(column)"
182
+ :collapse-tags-tooltip="isHeaderSearchMultiple(column)"
183
+ :teleported="false"
184
+ @update:model-value="handleHeaderSearchSelectModelValue(column, $event)"
185
+ @clear="handleHeaderSearchSelectEmpty(column)"
206
186
  >
207
- <button
208
- v-if="!isHeaderSearchMultiple(column)"
209
- class="base-table__header-select-option"
210
- :class="{ 'is-selected': !hasHeaderSearchValue(column) }"
211
- type="button"
212
- @click="handleHeaderSearchSelectEmpty(column)"
213
- >
214
- {{ getHeaderSearchPlaceholder(column) }}
215
- </button>
216
- <button
187
+ <el-option
217
188
  v-for="option in getHeaderSearchOptions(column)"
218
189
  :key="String(getHeaderSearchOptionValue(option, column))"
219
- class="base-table__header-select-option"
220
- :class="{ 'is-selected': isHeaderSearchOptionSelected(option, column) }"
221
- type="button"
190
+ :label="getHeaderSearchOptionLabel(option, column)"
191
+ :value="getHeaderSearchOptionValue(option, column)"
222
192
  :disabled="isHeaderSearchOptionDisabled(option, column)"
223
- @click="handleHeaderSearchSelectValue(column, getHeaderSearchOptionValue(option, column))"
224
- >
225
- <span class="base-table__header-select-option-label">
226
- {{ getHeaderSearchOptionLabel(option, column) }}
227
- </span>
228
- </button>
229
- </div>
193
+ />
194
+ </el-select>
230
195
  </div>
231
196
 
232
197
  <div
@@ -285,6 +250,38 @@
285
250
  </div>
286
251
  </div>
287
252
 
253
+ <el-date-picker
254
+ v-else-if="isHeaderSearchDatePicker(column)"
255
+ class="base-table__header-picker"
256
+ :model-value="getHeaderSearchPickerValue(column)"
257
+ :type="getHeaderSearchPickerType(column)"
258
+ :placeholder="getHeaderSearchPlaceholder(column)"
259
+ :start-placeholder="getHeaderSearchStartPlaceholder(column)"
260
+ :end-placeholder="getHeaderSearchEndPlaceholder(column)"
261
+ :range-separator="getHeaderSearchRangeSeparator(column)"
262
+ :format="getHeaderSearchDateFormat(column)"
263
+ :value-format="getHeaderSearchDateValueFormat(column)"
264
+ :clearable="isHeaderSearchClearable(column)"
265
+ :teleported="false"
266
+ @update:model-value="handleHeaderSearchPickerValue(column, $event)"
267
+ />
268
+
269
+ <el-time-picker
270
+ v-else-if="isHeaderSearchTimePicker(column)"
271
+ class="base-table__header-picker"
272
+ :model-value="getHeaderSearchPickerValue(column)"
273
+ :is-range="isHeaderSearchRange(column)"
274
+ :placeholder="getHeaderSearchPlaceholder(column)"
275
+ :start-placeholder="getHeaderSearchStartPlaceholder(column)"
276
+ :end-placeholder="getHeaderSearchEndPlaceholder(column)"
277
+ :range-separator="getHeaderSearchRangeSeparator(column)"
278
+ :format="getHeaderSearchTimeFormat(column)"
279
+ :value-format="getHeaderSearchTimeValueFormat(column)"
280
+ :clearable="isHeaderSearchClearable(column)"
281
+ :teleported="false"
282
+ @update:model-value="handleHeaderSearchPickerValue(column, $event)"
283
+ />
284
+
288
285
  <input
289
286
  v-else
290
287
  class="base-table__header-search-input"
@@ -392,6 +389,7 @@
392
389
  import { computed, onBeforeUnmount, onMounted, reactive, ref, useSlots, watch } from 'vue'
393
390
  import type { ComponentPublicInstance } from 'vue'
394
391
  import type { TableInstance } from 'element-plus'
392
+ import zhCn from 'element-plus/es/locale/lang/zh-cn'
395
393
  import SvgIcon from '../SvgIcon'
396
394
  import type {
397
395
  BaseTableAction,
@@ -481,6 +479,8 @@ const headerSearchSelectOpen = reactive<Record<string, boolean>>({})
481
479
  const headerSearchCascaderActivePaths = reactive<Record<string, BaseTableHeaderSearchPrimitiveValue[]>>({})
482
480
  const headerSearchTriggerRects = reactive<Record<string, DOMRect>>({})
483
481
  const headerSearchTriggerRefs = ref<Record<string, HTMLElement>>({})
482
+ const headerSearchPanelRefs = ref<Record<string, HTMLElement>>({})
483
+ const headerSearchPositionTick = ref(0)
484
484
  const baseTableIconPrefix = `base-table-icon-${++baseTableIconSeed}`
485
485
  let headerSearchPositionFrame = 0
486
486
  const sortState = reactive({
@@ -548,6 +548,7 @@ watch(
548
548
  )
549
549
 
550
550
  onMounted(() => {
551
+ document.addEventListener('click', handleDocumentClick, true)
551
552
  window.addEventListener('scroll', scheduleHeaderSearchPositionUpdate, true)
552
553
  window.addEventListener('resize', scheduleHeaderSearchPositionUpdate)
553
554
 
@@ -562,6 +563,7 @@ onMounted(() => {
562
563
  })
563
564
 
564
565
  onBeforeUnmount(() => {
566
+ document.removeEventListener('click', handleDocumentClick, true)
565
567
  window.removeEventListener('scroll', scheduleHeaderSearchPositionUpdate, true)
566
568
  window.removeEventListener('resize', scheduleHeaderSearchPositionUpdate)
567
569
 
@@ -668,6 +670,10 @@ function handleSelectionChange(value: BaseTableRow[]) {
668
670
  emit('selection-change', value)
669
671
  }
670
672
 
673
+ function resolveRowSelectable(row: BaseTableRow, index: number) {
674
+ return props.rowSelectable ? props.rowSelectable(row, index) : true
675
+ }
676
+
671
677
  function handleSortChange(payload: { prop?: string; order: BaseTableSortOrder }) {
672
678
  const column = props.columns.find((item) => String(item.prop || '') === String(payload.prop || ''))
673
679
 
@@ -790,6 +796,26 @@ function bindHeaderSearchTrigger(column: BaseTableColumn<BaseTableRow>) {
790
796
  }
791
797
  }
792
798
 
799
+ function setHeaderSearchPanelRef(
800
+ instance: Element | ComponentPublicInstance | null,
801
+ column: BaseTableColumn<BaseTableRow>
802
+ ) {
803
+ const stateKey = getHeaderSearchStateKey(column)
804
+
805
+ if (!(instance instanceof HTMLElement)) {
806
+ delete headerSearchPanelRefs.value[stateKey]
807
+ return
808
+ }
809
+
810
+ headerSearchPanelRefs.value[stateKey] = instance
811
+ }
812
+
813
+ function bindHeaderSearchPanel(column: BaseTableColumn<BaseTableRow>) {
814
+ return (instance: Element | ComponentPublicInstance | null) => {
815
+ setHeaderSearchPanelRef(instance, column)
816
+ }
817
+ }
818
+
793
819
  function isHeaderSearchVisible(column: BaseTableColumn<BaseTableRow>) {
794
820
  return Boolean(headerSearchVisible[getHeaderSearchStateKey(column)])
795
821
  }
@@ -802,6 +828,7 @@ function toggleHeaderSearch(column: BaseTableColumn<BaseTableRow>) {
802
828
  closeAllHeaderSearch()
803
829
  updateHeaderSearchTriggerRect(column)
804
830
  syncHeaderSearchCascaderActivePath(column)
831
+ scheduleHeaderSearchPositionUpdate()
805
832
  }
806
833
 
807
834
  headerSearchVisible[stateKey] = nextVisible
@@ -815,6 +842,21 @@ function closeAllHeaderSearch() {
815
842
  })
816
843
  }
817
844
 
845
+ function handleDocumentClick(event: MouseEvent) {
846
+ const target = event.target
847
+
848
+ if (target instanceof Element) {
849
+ if (
850
+ target.closest(`[data-base-table-id="${baseTableIconPrefix}"].base-table__header-search-panel`) ||
851
+ target.closest(`[data-base-table-id="${baseTableIconPrefix}"].base-table__header-icon`)
852
+ ) {
853
+ return
854
+ }
855
+ }
856
+
857
+ closeAllHeaderSearch()
858
+ }
859
+
818
860
  function updateHeaderSearchTriggerRect(column: BaseTableColumn<BaseTableRow>) {
819
861
  const stateKey = getHeaderSearchStateKey(column)
820
862
  const rect = headerSearchTriggerRefs.value[stateKey]?.getBoundingClientRect()
@@ -839,33 +881,78 @@ function scheduleHeaderSearchPositionUpdate() {
839
881
 
840
882
  headerSearchPositionFrame = window.requestAnimationFrame(() => {
841
883
  headerSearchPositionFrame = 0
884
+ headerSearchPositionTick.value += 1
842
885
  updateVisibleHeaderSearchPosition()
843
886
  })
844
887
  }
845
888
 
846
889
  function getHeaderSearchPanelStyle(column: BaseTableColumn<BaseTableRow>) {
890
+ headerSearchPositionTick.value
847
891
  const stateKey = getHeaderSearchStateKey(column)
848
892
  const triggerRect = headerSearchTriggerRects[stateKey]
849
- const width = toCssValue(getHeaderSearchWidth(column)) || '280px'
893
+ const panelWidth = getHeaderSearchPanelWidth(column)
894
+ const style = {
895
+ width: panelWidth.width,
896
+ minWidth: panelWidth.minWidth,
897
+ maxWidth: panelWidth.maxWidth
898
+ }
850
899
 
851
900
  if (!triggerRect) {
852
- return {
853
- width
854
- }
901
+ return style
855
902
  }
856
903
 
857
- const panelWidth = Number.parseFloat(String(getHeaderSearchWidth(column))) || 280
858
- const maxLeft = Math.max(8, window.innerWidth - panelWidth - 8)
859
- const left = Math.min(maxLeft, Math.max(8, triggerRect.right - panelWidth))
904
+ const maxLeft = Math.max(8, window.innerWidth - panelWidth.positionWidth - 8)
905
+ const left = Math.min(maxLeft, Math.max(8, triggerRect.right - panelWidth.positionWidth))
860
906
  const top = triggerRect.bottom + 8
861
907
 
862
908
  return {
863
- width,
909
+ ...style,
864
910
  left: `${left}px`,
865
911
  top: `${top}px`
866
912
  }
867
913
  }
868
914
 
915
+ function getHeaderSearchPanelWidth(column: BaseTableColumn<BaseTableRow>) {
916
+ const rawWidth = getHeaderSearchWidth(column)
917
+ const viewportMaxWidth = Math.max(220, window.innerWidth - 16)
918
+ const renderedWidth = getRenderedHeaderSearchPanelWidth(column)
919
+
920
+ if (rawWidth === 'auto') {
921
+ const positionWidth = Math.min(renderedWidth || getHeaderSearchAutoWidth(column), viewportMaxWidth)
922
+ return {
923
+ width: 'max-content',
924
+ minWidth: '280px',
925
+ maxWidth: `${viewportMaxWidth}px`,
926
+ positionWidth
927
+ }
928
+ }
929
+
930
+ const width = toCssValue(rawWidth) || '280px'
931
+ const positionWidth = Math.min(Number.parseFloat(String(rawWidth)) || 280, viewportMaxWidth)
932
+
933
+ return {
934
+ width,
935
+ minWidth: width,
936
+ maxWidth: `${viewportMaxWidth}px`,
937
+ positionWidth
938
+ }
939
+ }
940
+
941
+ function getRenderedHeaderSearchPanelWidth(column: BaseTableColumn<BaseTableRow>) {
942
+ const stateKey = getHeaderSearchStateKey(column)
943
+ const panelElement = headerSearchPanelRefs.value[stateKey]
944
+ return panelElement ? panelElement.getBoundingClientRect().width : 0
945
+ }
946
+
947
+ function getHeaderSearchAutoWidth(column: BaseTableColumn<BaseTableRow>) {
948
+ if (isHeaderSearchRange(column)) {
949
+ const type = getHeaderSearchConfig(column)?.type
950
+ return type === 'daterange' || type === 'timerange' ? 420 : 560
951
+ }
952
+
953
+ return 280
954
+ }
955
+
869
956
  function getHeaderSearchValue(column: BaseTableColumn<BaseTableRow>): BaseTableHeaderSearchValue {
870
957
  const stateKey = getHeaderSearchStateKey(column)
871
958
  const value = headerSearchValues[stateKey]
@@ -902,6 +989,25 @@ function isHeaderSearchCascader(column: BaseTableColumn<BaseTableRow>) {
902
989
  return getHeaderSearchConfig(column)?.type === 'cascader'
903
990
  }
904
991
 
992
+ function isHeaderSearchDatePicker(column: BaseTableColumn<BaseTableRow>) {
993
+ const type = getHeaderSearchConfig(column)?.type
994
+ return type === 'date' || type === 'daterange' || type === 'datetime' || type === 'datetimerange'
995
+ }
996
+
997
+ function isHeaderSearchTimePicker(column: BaseTableColumn<BaseTableRow>) {
998
+ const type = getHeaderSearchConfig(column)?.type
999
+ return type === 'time' || type === 'timerange'
1000
+ }
1001
+
1002
+ function isHeaderSearchPicker(column: BaseTableColumn<BaseTableRow>) {
1003
+ return isHeaderSearchDatePicker(column) || isHeaderSearchTimePicker(column)
1004
+ }
1005
+
1006
+ function isHeaderSearchRange(column: BaseTableColumn<BaseTableRow>) {
1007
+ const type = getHeaderSearchConfig(column)?.type
1008
+ return type === 'daterange' || type === 'datetimerange' || type === 'timerange'
1009
+ }
1010
+
905
1011
  function isHeaderSearchChoice(column: BaseTableColumn<BaseTableRow>) {
906
1012
  return isHeaderSearchSelect(column) || isHeaderSearchCascader(column)
907
1013
  }
@@ -958,8 +1064,60 @@ function getHeaderSearchPlaceholder(column: BaseTableColumn<BaseTableRow>) {
958
1064
  return getHeaderSearchConfig(column)?.placeholder || (isHeaderSearchChoice(column) ? '请选择' : '请输入搜索内容')
959
1065
  }
960
1066
 
1067
+ function getHeaderSearchStartPlaceholder(column: BaseTableColumn<BaseTableRow>) {
1068
+ return getHeaderSearchConfig(column)?.startPlaceholder || '开始时间'
1069
+ }
1070
+
1071
+ function getHeaderSearchEndPlaceholder(column: BaseTableColumn<BaseTableRow>) {
1072
+ return getHeaderSearchConfig(column)?.endPlaceholder || '结束时间'
1073
+ }
1074
+
1075
+ function getHeaderSearchRangeSeparator(column: BaseTableColumn<BaseTableRow>) {
1076
+ return getHeaderSearchConfig(column)?.rangeSeparator || '至'
1077
+ }
1078
+
1079
+ function getHeaderSearchPickerType(column: BaseTableColumn<BaseTableRow>) {
1080
+ const type = getHeaderSearchConfig(column)?.type
1081
+
1082
+ if (type === 'datetime' || type === 'datetimerange') {
1083
+ return type
1084
+ }
1085
+
1086
+ return type === 'daterange' ? 'daterange' : 'date'
1087
+ }
1088
+
1089
+ function getHeaderSearchDateFormat(column: BaseTableColumn<BaseTableRow>) {
1090
+ const config = getHeaderSearchConfig(column)
1091
+
1092
+ if (config?.format) {
1093
+ return config.format
1094
+ }
1095
+
1096
+ return getHeaderSearchConfig(column)?.type === 'datetime' || getHeaderSearchConfig(column)?.type === 'datetimerange'
1097
+ ? 'YYYY-MM-DD HH:mm:ss'
1098
+ : 'YYYY-MM-DD'
1099
+ }
1100
+
1101
+ function getHeaderSearchDateValueFormat(column: BaseTableColumn<BaseTableRow>) {
1102
+ return getHeaderSearchConfig(column)?.valueFormat || getHeaderSearchDateFormat(column)
1103
+ }
1104
+
1105
+ function getHeaderSearchTimeFormat(column: BaseTableColumn<BaseTableRow>) {
1106
+ return getHeaderSearchConfig(column)?.format || 'HH:mm:ss'
1107
+ }
1108
+
1109
+ function getHeaderSearchTimeValueFormat(column: BaseTableColumn<BaseTableRow>) {
1110
+ return getHeaderSearchConfig(column)?.valueFormat || getHeaderSearchTimeFormat(column)
1111
+ }
1112
+
961
1113
  function getHeaderSearchWidth(column: BaseTableColumn<BaseTableRow>) {
962
- return getHeaderSearchConfig(column)?.width || 280
1114
+ const configuredWidth = getHeaderSearchConfig(column)?.width
1115
+
1116
+ if (configuredWidth !== undefined && configuredWidth !== null && configuredWidth !== '') {
1117
+ return configuredWidth
1118
+ }
1119
+
1120
+ return isHeaderSearchRange(column) ? 'auto' : 280
963
1121
  }
964
1122
 
965
1123
  function getHeaderSearchSearchText(column: BaseTableColumn<BaseTableRow>) {
@@ -1022,9 +1180,14 @@ function getHeaderSearchSelectedLabels(column: BaseTableColumn<BaseTableRow>) {
1022
1180
  })
1023
1181
  }
1024
1182
 
1025
- function isHeaderSearchOptionSelected(option: BaseTableOption, column: BaseTableColumn<BaseTableRow>) {
1026
- const optionValue = String(getHeaderSearchOptionValue(option, column))
1027
- return toComparableValues(getHeaderSearchValue(column)).includes(optionValue)
1183
+ function getHeaderSearchSelectModelValue(column: BaseTableColumn<BaseTableRow>) {
1184
+ const value = getHeaderSearchValue(column)
1185
+
1186
+ if (isHeaderSearchMultiple(column)) {
1187
+ return Array.isArray(value) ? value : []
1188
+ }
1189
+
1190
+ return Array.isArray(value) ? value[0] ?? '' : value
1028
1191
  }
1029
1192
 
1030
1193
  function handleHeaderSearchSelectEmpty(column: BaseTableColumn<BaseTableRow>) {
@@ -1032,33 +1195,17 @@ function handleHeaderSearchSelectEmpty(column: BaseTableColumn<BaseTableRow>) {
1032
1195
  headerSearchSelectOpen[getHeaderSearchStateKey(column)] = false
1033
1196
  }
1034
1197
 
1035
- function handleHeaderSearchSelectValue(
1036
- column: BaseTableColumn<BaseTableRow>,
1037
- optionValue: BaseTableHeaderSearchPrimitiveValue
1038
- ) {
1039
- if (!isHeaderSearchMultiple(column)) {
1040
- updateHeaderSearchValue(column, optionValue)
1041
- headerSearchSelectOpen[getHeaderSearchStateKey(column)] = false
1042
- return
1043
- }
1044
-
1045
- const currentValues = Array.isArray(getHeaderSearchValue(column))
1046
- ? [...getHeaderSearchValue(column) as BaseTableHeaderSearchPrimitiveValue[]]
1047
- : []
1048
- const comparableValue = String(optionValue)
1049
- const matchedIndex = currentValues.findIndex((item) => String(item) === comparableValue)
1050
-
1051
- if (matchedIndex >= 0) {
1052
- currentValues.splice(matchedIndex, 1)
1053
- } else {
1054
- currentValues.push(optionValue)
1055
- }
1198
+ function handleHeaderSearchSelectModelValue(column: BaseTableColumn<BaseTableRow>, value: unknown) {
1199
+ updateHeaderSearchValue(column, value)
1200
+ }
1056
1201
 
1057
- updateHeaderSearchValue(column, currentValues)
1202
+ function getHeaderSearchPickerValue(column: BaseTableColumn<BaseTableRow>) {
1203
+ const value = getHeaderSearchValue(column)
1204
+ return Array.isArray(value) ? [...value] : value
1058
1205
  }
1059
1206
 
1060
- function handleHeaderSearchSelectOption(column: BaseTableColumn<BaseTableRow>, option: BaseTableOption) {
1061
- handleHeaderSearchSelectValue(column, getHeaderSearchOptionValue(option, column))
1207
+ function handleHeaderSearchPickerValue(column: BaseTableColumn<BaseTableRow>, value: unknown) {
1208
+ updateHeaderSearchValue(column, value)
1062
1209
  }
1063
1210
 
1064
1211
  function getHeaderSearchCascaderValue(column: BaseTableColumn<BaseTableRow>) {
@@ -1268,13 +1415,17 @@ function filterLocalRows(data: BaseTableRow[]) {
1268
1415
  return matchesHeaderSearchCascaderValue(value, searchValue)
1269
1416
  }
1270
1417
 
1418
+ if (isHeaderSearchPicker(column)) {
1419
+ return matchesHeaderSearchPickerValue(value, searchValue, column)
1420
+ }
1421
+
1271
1422
  return toSearchableText(value).includes(toHeaderSearchKeyword(searchValue))
1272
1423
  })
1273
1424
  })
1274
1425
  }
1275
1426
 
1276
1427
  function getHeaderSearchEmptyValue(column: BaseTableColumn<BaseTableRow>): BaseTableHeaderSearchValue {
1277
- return isHeaderSearchMultiple(column) || isHeaderSearchCascader(column) ? [] : ''
1428
+ return isHeaderSearchMultiple(column) || isHeaderSearchCascader(column) || isHeaderSearchRange(column) ? [] : ''
1278
1429
  }
1279
1430
 
1280
1431
  function normalizeHeaderSearchValue(
@@ -1285,6 +1436,18 @@ function normalizeHeaderSearchValue(
1285
1436
  return normalizeHeaderSearchPathValue(value)
1286
1437
  }
1287
1438
 
1439
+ if (isHeaderSearchPicker(column)) {
1440
+ if (isHeaderSearchRange(column)) {
1441
+ return normalizeHeaderSearchPathValue(value)
1442
+ }
1443
+
1444
+ if (value === undefined || value === null) {
1445
+ return ''
1446
+ }
1447
+
1448
+ return normalizeHeaderSearchPrimitiveValue(value)
1449
+ }
1450
+
1288
1451
  if (!isHeaderSearchSelect(column)) {
1289
1452
  if (value === undefined || value === null) {
1290
1453
  return ''
@@ -1386,6 +1549,53 @@ function matchesHeaderSearchCascaderValue(rowValue: unknown, searchValue: BaseTa
1386
1549
  return selectedPath.every((item, index) => String(rowPath[index]) === String(item))
1387
1550
  }
1388
1551
 
1552
+ function matchesHeaderSearchPickerValue(
1553
+ rowValue: unknown,
1554
+ searchValue: BaseTableHeaderSearchValue,
1555
+ column: BaseTableColumn<BaseTableRow>
1556
+ ) {
1557
+ if (isHeaderSearchRange(column)) {
1558
+ const selectedRange = normalizeHeaderSearchPathValue(searchValue)
1559
+
1560
+ if (!selectedRange.length) {
1561
+ return true
1562
+ }
1563
+
1564
+ const rowTime = toComparableTime(rowValue)
1565
+ const startTime = toComparableTime(selectedRange[0])
1566
+ const endTime = toComparableTime(selectedRange[1])
1567
+
1568
+ if (rowTime === null) {
1569
+ return false
1570
+ }
1571
+
1572
+ return (startTime === null || rowTime >= startTime) && (endTime === null || rowTime <= endTime)
1573
+ }
1574
+
1575
+ return String(rowValue || '') === String(searchValue || '')
1576
+ }
1577
+
1578
+ function toComparableTime(value: unknown) {
1579
+ if (value === undefined || value === null || value === '') {
1580
+ return null
1581
+ }
1582
+
1583
+ if (value instanceof Date) {
1584
+ return value.getTime()
1585
+ }
1586
+
1587
+ const normalizedValue = String(value).trim()
1588
+ const parsedValue = Date.parse(normalizedValue)
1589
+
1590
+ if (!Number.isNaN(parsedValue)) {
1591
+ return parsedValue
1592
+ }
1593
+
1594
+ const today = new Date().toISOString().slice(0, 10)
1595
+ const parsedTime = Date.parse(`${today} ${normalizedValue}`)
1596
+ return Number.isNaN(parsedTime) ? null : parsedTime
1597
+ }
1598
+
1389
1599
  function toComparableValues(value: unknown) {
1390
1600
  const values = Array.isArray(value) ? value : [value]
1391
1601
  return values
@@ -1953,6 +2163,25 @@ defineExpose<BaseTableExpose>({
1953
2163
  width: 100%;
1954
2164
  }
1955
2165
 
2166
+ .base-table__header-el-select {
2167
+ width: 100%;
2168
+ }
2169
+
2170
+ .base-table__header-el-select :deep(.el-select__wrapper) {
2171
+ min-height: 32px;
2172
+ }
2173
+
2174
+ .base-table__header-picker {
2175
+ width: 100%;
2176
+ }
2177
+
2178
+ .base-table__header-picker :deep(.el-input__wrapper),
2179
+ .base-table__header-picker :deep(.el-range-editor.el-input__wrapper) {
2180
+ width: 100%;
2181
+ min-height: 32px;
2182
+ box-sizing: border-box;
2183
+ }
2184
+
1956
2185
  .base-table__header-select-trigger {
1957
2186
  display: flex;
1958
2187
  align-items: center;