@hbdlzy/ui-core 0.1.8 → 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.
@@ -66,6 +66,8 @@
66
66
  :stripe="stripe"
67
67
  :default-sort="normalizedDefaultSort"
68
68
  highlight-current-row
69
+ @select="handleSelectionChange"
70
+ @select-all="handleSelectionChange"
69
71
  @selection-change="handleSelectionChange"
70
72
  @sort-change="handleSortChange"
71
73
  >
@@ -77,8 +79,9 @@
77
79
  v-if="hasSelection"
78
80
  type="selection"
79
81
  :width="selectionWidth"
82
+ fixed="left"
80
83
  align="center"
81
- :selectable="rowSelectable"
84
+ :selectable="resolveRowSelectable"
82
85
  />
83
86
 
84
87
  <el-table-column
@@ -141,6 +144,7 @@
141
144
  <button
142
145
  :ref="bindHeaderSearchTrigger(column)"
143
146
  class="base-table__header-icon"
147
+ :data-base-table-id="baseTableIconPrefix"
144
148
  :class="{ 'is-active': hasHeaderSearchValue(column) }"
145
149
  type="button"
146
150
  @click.stop="toggleHeaderSearch(column)"
@@ -155,8 +159,10 @@
155
159
  <teleport to="body">
156
160
  <div
157
161
  v-if="isHeaderSearchVisible(column)"
162
+ :ref="bindHeaderSearchPanel(column)"
158
163
  :key="getHeaderSearchStateKey(column)"
159
164
  class="base-table__header-search-panel"
165
+ :data-base-table-id="baseTableIconPrefix"
160
166
  :style="getHeaderSearchPanelStyle(column)"
161
167
  @click.stop
162
168
  @mousedown.stop
@@ -165,70 +171,27 @@
165
171
  v-if="isHeaderSearchSelect(column)"
166
172
  class="base-table__header-select"
167
173
  >
168
- <button
169
- class="base-table__header-select-trigger"
170
- type="button"
171
- @click="toggleHeaderSearchSelect(column)"
172
- >
173
- <span
174
- v-if="isHeaderSearchMultiple(column) && getHeaderSearchSelectedLabels(column).length"
175
- class="base-table__header-select-tags"
176
- >
177
- <span
178
- v-for="label in getHeaderSearchSelectedLabels(column).slice(0, 2)"
179
- :key="label"
180
- class="base-table__header-select-tag"
181
- >
182
- {{ label }}
183
- </span>
184
- <span
185
- v-if="getHeaderSearchSelectedLabels(column).length > 2"
186
- class="base-table__header-select-tag base-table__header-select-tag--count"
187
- >
188
- +{{ getHeaderSearchSelectedLabels(column).length - 2 }}
189
- </span>
190
- </span>
191
- <span
192
- v-else
193
- class="base-table__header-select-text"
194
- :class="{ 'is-placeholder': !hasHeaderSearchValue(column) }"
195
- >
196
- {{ getHeaderSearchSelectLabel(column) }}
197
- </span>
198
- <span
199
- class="base-table__header-select-arrow"
200
- :class="{ 'is-open': isHeaderSearchSelectOpen(column) }"
201
- aria-hidden="true"
202
- ></span>
203
- </button>
204
-
205
- <div
206
- v-if="isHeaderSearchSelectOpen(column)"
207
- 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)"
208
186
  >
209
- <button
210
- v-if="!isHeaderSearchMultiple(column)"
211
- class="base-table__header-select-option"
212
- :class="{ 'is-selected': !hasHeaderSearchValue(column) }"
213
- type="button"
214
- @click="handleHeaderSearchSelectEmpty(column)"
215
- >
216
- {{ getHeaderSearchPlaceholder(column) }}
217
- </button>
218
- <button
187
+ <el-option
219
188
  v-for="option in getHeaderSearchOptions(column)"
220
189
  :key="String(getHeaderSearchOptionValue(option, column))"
221
- class="base-table__header-select-option"
222
- :class="{ 'is-selected': isHeaderSearchOptionSelected(option, column) }"
223
- type="button"
190
+ :label="getHeaderSearchOptionLabel(option, column)"
191
+ :value="getHeaderSearchOptionValue(option, column)"
224
192
  :disabled="isHeaderSearchOptionDisabled(option, column)"
225
- @click="handleHeaderSearchSelectValue(column, getHeaderSearchOptionValue(option, column))"
226
- >
227
- <span class="base-table__header-select-option-label">
228
- {{ getHeaderSearchOptionLabel(option, column) }}
229
- </span>
230
- </button>
231
- </div>
193
+ />
194
+ </el-select>
232
195
  </div>
233
196
 
234
197
  <div
@@ -287,6 +250,38 @@
287
250
  </div>
288
251
  </div>
289
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
+
290
285
  <input
291
286
  v-else
292
287
  class="base-table__header-search-input"
@@ -484,6 +479,8 @@ const headerSearchSelectOpen = reactive<Record<string, boolean>>({})
484
479
  const headerSearchCascaderActivePaths = reactive<Record<string, BaseTableHeaderSearchPrimitiveValue[]>>({})
485
480
  const headerSearchTriggerRects = reactive<Record<string, DOMRect>>({})
486
481
  const headerSearchTriggerRefs = ref<Record<string, HTMLElement>>({})
482
+ const headerSearchPanelRefs = ref<Record<string, HTMLElement>>({})
483
+ const headerSearchPositionTick = ref(0)
487
484
  const baseTableIconPrefix = `base-table-icon-${++baseTableIconSeed}`
488
485
  let headerSearchPositionFrame = 0
489
486
  const sortState = reactive({
@@ -551,6 +548,7 @@ watch(
551
548
  )
552
549
 
553
550
  onMounted(() => {
551
+ document.addEventListener('click', handleDocumentClick, true)
554
552
  window.addEventListener('scroll', scheduleHeaderSearchPositionUpdate, true)
555
553
  window.addEventListener('resize', scheduleHeaderSearchPositionUpdate)
556
554
 
@@ -565,6 +563,7 @@ onMounted(() => {
565
563
  })
566
564
 
567
565
  onBeforeUnmount(() => {
566
+ document.removeEventListener('click', handleDocumentClick, true)
568
567
  window.removeEventListener('scroll', scheduleHeaderSearchPositionUpdate, true)
569
568
  window.removeEventListener('resize', scheduleHeaderSearchPositionUpdate)
570
569
 
@@ -671,6 +670,10 @@ function handleSelectionChange(value: BaseTableRow[]) {
671
670
  emit('selection-change', value)
672
671
  }
673
672
 
673
+ function resolveRowSelectable(row: BaseTableRow, index: number) {
674
+ return props.rowSelectable ? props.rowSelectable(row, index) : true
675
+ }
676
+
674
677
  function handleSortChange(payload: { prop?: string; order: BaseTableSortOrder }) {
675
678
  const column = props.columns.find((item) => String(item.prop || '') === String(payload.prop || ''))
676
679
 
@@ -793,6 +796,26 @@ function bindHeaderSearchTrigger(column: BaseTableColumn<BaseTableRow>) {
793
796
  }
794
797
  }
795
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
+
796
819
  function isHeaderSearchVisible(column: BaseTableColumn<BaseTableRow>) {
797
820
  return Boolean(headerSearchVisible[getHeaderSearchStateKey(column)])
798
821
  }
@@ -805,6 +828,7 @@ function toggleHeaderSearch(column: BaseTableColumn<BaseTableRow>) {
805
828
  closeAllHeaderSearch()
806
829
  updateHeaderSearchTriggerRect(column)
807
830
  syncHeaderSearchCascaderActivePath(column)
831
+ scheduleHeaderSearchPositionUpdate()
808
832
  }
809
833
 
810
834
  headerSearchVisible[stateKey] = nextVisible
@@ -818,6 +842,21 @@ function closeAllHeaderSearch() {
818
842
  })
819
843
  }
820
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
+
821
860
  function updateHeaderSearchTriggerRect(column: BaseTableColumn<BaseTableRow>) {
822
861
  const stateKey = getHeaderSearchStateKey(column)
823
862
  const rect = headerSearchTriggerRefs.value[stateKey]?.getBoundingClientRect()
@@ -842,33 +881,78 @@ function scheduleHeaderSearchPositionUpdate() {
842
881
 
843
882
  headerSearchPositionFrame = window.requestAnimationFrame(() => {
844
883
  headerSearchPositionFrame = 0
884
+ headerSearchPositionTick.value += 1
845
885
  updateVisibleHeaderSearchPosition()
846
886
  })
847
887
  }
848
888
 
849
889
  function getHeaderSearchPanelStyle(column: BaseTableColumn<BaseTableRow>) {
890
+ headerSearchPositionTick.value
850
891
  const stateKey = getHeaderSearchStateKey(column)
851
892
  const triggerRect = headerSearchTriggerRects[stateKey]
852
- 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
+ }
853
899
 
854
900
  if (!triggerRect) {
855
- return {
856
- width
857
- }
901
+ return style
858
902
  }
859
903
 
860
- const panelWidth = Number.parseFloat(String(getHeaderSearchWidth(column))) || 280
861
- const maxLeft = Math.max(8, window.innerWidth - panelWidth - 8)
862
- 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))
863
906
  const top = triggerRect.bottom + 8
864
907
 
865
908
  return {
866
- width,
909
+ ...style,
867
910
  left: `${left}px`,
868
911
  top: `${top}px`
869
912
  }
870
913
  }
871
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
+
872
956
  function getHeaderSearchValue(column: BaseTableColumn<BaseTableRow>): BaseTableHeaderSearchValue {
873
957
  const stateKey = getHeaderSearchStateKey(column)
874
958
  const value = headerSearchValues[stateKey]
@@ -905,6 +989,25 @@ function isHeaderSearchCascader(column: BaseTableColumn<BaseTableRow>) {
905
989
  return getHeaderSearchConfig(column)?.type === 'cascader'
906
990
  }
907
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
+
908
1011
  function isHeaderSearchChoice(column: BaseTableColumn<BaseTableRow>) {
909
1012
  return isHeaderSearchSelect(column) || isHeaderSearchCascader(column)
910
1013
  }
@@ -961,8 +1064,60 @@ function getHeaderSearchPlaceholder(column: BaseTableColumn<BaseTableRow>) {
961
1064
  return getHeaderSearchConfig(column)?.placeholder || (isHeaderSearchChoice(column) ? '请选择' : '请输入搜索内容')
962
1065
  }
963
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
+
964
1113
  function getHeaderSearchWidth(column: BaseTableColumn<BaseTableRow>) {
965
- 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
966
1121
  }
967
1122
 
968
1123
  function getHeaderSearchSearchText(column: BaseTableColumn<BaseTableRow>) {
@@ -1025,9 +1180,14 @@ function getHeaderSearchSelectedLabels(column: BaseTableColumn<BaseTableRow>) {
1025
1180
  })
1026
1181
  }
1027
1182
 
1028
- function isHeaderSearchOptionSelected(option: BaseTableOption, column: BaseTableColumn<BaseTableRow>) {
1029
- const optionValue = String(getHeaderSearchOptionValue(option, column))
1030
- 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
1031
1191
  }
1032
1192
 
1033
1193
  function handleHeaderSearchSelectEmpty(column: BaseTableColumn<BaseTableRow>) {
@@ -1035,33 +1195,17 @@ function handleHeaderSearchSelectEmpty(column: BaseTableColumn<BaseTableRow>) {
1035
1195
  headerSearchSelectOpen[getHeaderSearchStateKey(column)] = false
1036
1196
  }
1037
1197
 
1038
- function handleHeaderSearchSelectValue(
1039
- column: BaseTableColumn<BaseTableRow>,
1040
- optionValue: BaseTableHeaderSearchPrimitiveValue
1041
- ) {
1042
- if (!isHeaderSearchMultiple(column)) {
1043
- updateHeaderSearchValue(column, optionValue)
1044
- headerSearchSelectOpen[getHeaderSearchStateKey(column)] = false
1045
- return
1046
- }
1047
-
1048
- const currentValues = Array.isArray(getHeaderSearchValue(column))
1049
- ? [...getHeaderSearchValue(column) as BaseTableHeaderSearchPrimitiveValue[]]
1050
- : []
1051
- const comparableValue = String(optionValue)
1052
- const matchedIndex = currentValues.findIndex((item) => String(item) === comparableValue)
1053
-
1054
- if (matchedIndex >= 0) {
1055
- currentValues.splice(matchedIndex, 1)
1056
- } else {
1057
- currentValues.push(optionValue)
1058
- }
1198
+ function handleHeaderSearchSelectModelValue(column: BaseTableColumn<BaseTableRow>, value: unknown) {
1199
+ updateHeaderSearchValue(column, value)
1200
+ }
1059
1201
 
1060
- updateHeaderSearchValue(column, currentValues)
1202
+ function getHeaderSearchPickerValue(column: BaseTableColumn<BaseTableRow>) {
1203
+ const value = getHeaderSearchValue(column)
1204
+ return Array.isArray(value) ? [...value] : value
1061
1205
  }
1062
1206
 
1063
- function handleHeaderSearchSelectOption(column: BaseTableColumn<BaseTableRow>, option: BaseTableOption) {
1064
- handleHeaderSearchSelectValue(column, getHeaderSearchOptionValue(option, column))
1207
+ function handleHeaderSearchPickerValue(column: BaseTableColumn<BaseTableRow>, value: unknown) {
1208
+ updateHeaderSearchValue(column, value)
1065
1209
  }
1066
1210
 
1067
1211
  function getHeaderSearchCascaderValue(column: BaseTableColumn<BaseTableRow>) {
@@ -1271,13 +1415,17 @@ function filterLocalRows(data: BaseTableRow[]) {
1271
1415
  return matchesHeaderSearchCascaderValue(value, searchValue)
1272
1416
  }
1273
1417
 
1418
+ if (isHeaderSearchPicker(column)) {
1419
+ return matchesHeaderSearchPickerValue(value, searchValue, column)
1420
+ }
1421
+
1274
1422
  return toSearchableText(value).includes(toHeaderSearchKeyword(searchValue))
1275
1423
  })
1276
1424
  })
1277
1425
  }
1278
1426
 
1279
1427
  function getHeaderSearchEmptyValue(column: BaseTableColumn<BaseTableRow>): BaseTableHeaderSearchValue {
1280
- return isHeaderSearchMultiple(column) || isHeaderSearchCascader(column) ? [] : ''
1428
+ return isHeaderSearchMultiple(column) || isHeaderSearchCascader(column) || isHeaderSearchRange(column) ? [] : ''
1281
1429
  }
1282
1430
 
1283
1431
  function normalizeHeaderSearchValue(
@@ -1288,6 +1436,18 @@ function normalizeHeaderSearchValue(
1288
1436
  return normalizeHeaderSearchPathValue(value)
1289
1437
  }
1290
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
+
1291
1451
  if (!isHeaderSearchSelect(column)) {
1292
1452
  if (value === undefined || value === null) {
1293
1453
  return ''
@@ -1389,6 +1549,53 @@ function matchesHeaderSearchCascaderValue(rowValue: unknown, searchValue: BaseTa
1389
1549
  return selectedPath.every((item, index) => String(rowPath[index]) === String(item))
1390
1550
  }
1391
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
+
1392
1599
  function toComparableValues(value: unknown) {
1393
1600
  const values = Array.isArray(value) ? value : [value]
1394
1601
  return values
@@ -1956,6 +2163,25 @@ defineExpose<BaseTableExpose>({
1956
2163
  width: 100%;
1957
2164
  }
1958
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
+
1959
2185
  .base-table__header-select-trigger {
1960
2186
  display: flex;
1961
2187
  align-items: center;