@rainbow-oh/yee-c 0.4.4 → 0.5.0
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/cjs/Button/button.d.ts +1 -1
- package/dist/cjs/CSV/download.d.ts +1 -1
- package/dist/cjs/Carousel/carousel.d.ts +2 -2
- package/dist/cjs/Carousel/carousel.js +9 -2
- package/dist/cjs/Carousel/interface.d.ts +5 -0
- package/dist/cjs/Dialog/demo/basic.js +1 -1
- package/dist/cjs/Dialog/dialog.js +1 -1
- package/dist/cjs/Drawer/style/index.less +4 -0
- package/dist/cjs/Field/demo/validation.js +23 -3
- package/dist/cjs/Field/field.js +1 -1
- package/dist/cjs/FloatButton/float-button.d.ts +1 -1
- package/dist/cjs/Form/Field.js +1 -4
- package/dist/cjs/Form/Form.js +1 -1
- package/dist/cjs/Form/Group.js +36 -14
- package/dist/cjs/Form/List.js +23 -3
- package/dist/cjs/Form/demo/async-validate.d.ts +3 -0
- package/dist/cjs/Form/demo/async-validate.js +108 -0
- package/dist/cjs/Form/demo/basic.js +2 -2
- package/dist/cjs/Form/demo/virtual.js +1 -1
- package/dist/cjs/Form/form-store.d.ts +4 -4
- package/dist/cjs/Form/form-store.js +55 -25
- package/dist/cjs/Form/interface.d.ts +10 -7
- package/dist/cjs/Form/style/index.less +15 -0
- package/dist/cjs/Form/utils/validate.d.ts +23 -2
- package/dist/cjs/Form/utils/validate.js +59 -10
- package/dist/cjs/Input/style/index.less +0 -17
- package/dist/cjs/InputNumber/style/index.less +0 -29
- package/dist/cjs/PickerPanel/interface.d.ts +44 -2
- package/dist/cjs/PickerPanel/panels/DatePanel/DateBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DatePanel/DateHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DatePanel/DateHeader.js +1 -1
- package/dist/cjs/PickerPanel/panels/DatePanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DateTimePanel/index.d.ts +7 -1
- package/dist/cjs/PickerPanel/panels/DateTimePanel/index.js +18 -4
- package/dist/cjs/PickerPanel/panels/DecadePanel/DecadeBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DecadePanel/DecadeBody.js +1 -1
- package/dist/cjs/PickerPanel/panels/DecadePanel/DecadeHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DecadePanel/DecadeHeader.js +1 -1
- package/dist/cjs/PickerPanel/panels/DecadePanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/DecadePanel/index.js +1 -1
- package/dist/cjs/PickerPanel/panels/Header.d.ts +13 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/MonthBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/MonthHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/MonthHeader.js +1 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/index.js +1 -1
- package/dist/cjs/PickerPanel/panels/PanelBody.d.ts +21 -1
- package/dist/cjs/PickerPanel/panels/PanelBody.js +3 -3
- package/dist/cjs/PickerPanel/panels/QuarterPanel/QuarterBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/QuarterPanel/QuarterHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/QuarterPanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/RangePanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/RangePanel/index.js +2 -2
- package/dist/cjs/PickerPanel/panels/RangePanel/interface.d.ts +5 -5
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeBody.d.ts +17 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeCell.d.ts +7 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeCell.js +1 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeColumn.d.ts +14 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeColumn.js +1 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/TimeHeader.d.ts +4 -1
- package/dist/cjs/PickerPanel/panels/TimePanel/index.d.ts +9 -1
- package/dist/cjs/PickerPanel/panels/WeekPanel/WeekBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/WeekPanel/WeekHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/WeekPanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/YearPanel/YearBody.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/YearPanel/YearBody.js +2 -2
- package/dist/cjs/PickerPanel/panels/YearPanel/YearHeader.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/YearPanel/YearHeader.js +7 -1
- package/dist/cjs/PickerPanel/panels/YearPanel/index.d.ts +2 -1
- package/dist/cjs/PickerPanel/panels/YearPanel/index.js +1 -1
- package/dist/cjs/PickerPanel/utils/pickerUtils.d.ts +7 -7
- package/dist/cjs/PickerPanel/utils/pickerUtils.js +2 -2
- package/dist/cjs/Select/demo/basic.js +1 -1
- package/dist/cjs/Select/demo/virtual.d.ts +3 -0
- package/dist/cjs/Select/demo/virtual.js +55 -0
- package/dist/cjs/Select/hooks/useSelectKeyboard.d.ts +7 -1
- package/dist/cjs/Select/hooks/useSelectKeyboard.js +16 -6
- package/dist/cjs/Select/interface.d.ts +44 -0
- package/dist/cjs/Select/option.js +3 -2
- package/dist/cjs/Select/options.js +115 -15
- package/dist/cjs/Select/select.js +20 -4
- package/dist/cjs/Select/style/index.less +17 -13
- package/dist/cjs/Selector/style/index.less +2 -137
- package/dist/cjs/Table/style/index.less +19 -0
- package/dist/cjs/TextArea/style/index.less +0 -17
- package/dist/cjs/hooks/index.d.ts +2 -1
- package/dist/cjs/hooks/index.js +3 -1
- package/dist/cjs/hooks/useEvent.js +4 -1
- package/dist/cjs/hooks/useVirtualList.d.ts +71 -0
- package/dist/cjs/hooks/useVirtualList.js +117 -0
- package/dist/cjs/style/size.css +1 -0
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +2 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Button/button.d.ts +1 -1
- package/dist/esm/CSV/download.d.ts +1 -1
- package/dist/esm/Carousel/carousel.d.ts +2 -2
- package/dist/esm/Carousel/carousel.js +5 -1
- package/dist/esm/Carousel/interface.d.ts +5 -0
- package/dist/esm/Dialog/demo/basic.js +1 -1
- package/dist/esm/Dialog/dialog.js +1 -1
- package/dist/esm/Drawer/style/index.less +4 -0
- package/dist/esm/Field/demo/validation.js +30 -9
- package/dist/esm/Field/field.js +2 -1
- package/dist/esm/FloatButton/float-button.d.ts +1 -1
- package/dist/esm/Form/Field.js +3 -4
- package/dist/esm/Form/Form.js +1 -1
- package/dist/esm/Form/Group.js +142 -53
- package/dist/esm/Form/List.js +61 -42
- package/dist/esm/Form/demo/async-validate.d.ts +3 -0
- package/dist/esm/Form/demo/async-validate.js +95 -0
- package/dist/esm/Form/demo/basic.js +4 -2
- package/dist/esm/Form/demo/virtual.js +1 -1
- package/dist/esm/Form/form-store.d.ts +4 -4
- package/dist/esm/Form/form-store.js +187 -93
- package/dist/esm/Form/interface.d.ts +10 -7
- package/dist/esm/Form/style/index.less +15 -0
- package/dist/esm/Form/utils/validate.d.ts +23 -2
- package/dist/esm/Form/utils/validate.js +122 -17
- package/dist/esm/Input/style/index.less +0 -17
- package/dist/esm/InputNumber/style/index.less +0 -29
- package/dist/esm/PickerPanel/interface.d.ts +44 -2
- package/dist/esm/PickerPanel/panels/DatePanel/DateBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DatePanel/DateHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DatePanel/DateHeader.js +1 -1
- package/dist/esm/PickerPanel/panels/DatePanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DateTimePanel/index.d.ts +7 -1
- package/dist/esm/PickerPanel/panels/DateTimePanel/index.js +11 -7
- package/dist/esm/PickerPanel/panels/DecadePanel/DecadeBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DecadePanel/DecadeBody.js +2 -1
- package/dist/esm/PickerPanel/panels/DecadePanel/DecadeHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DecadePanel/DecadeHeader.js +2 -1
- package/dist/esm/PickerPanel/panels/DecadePanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/DecadePanel/index.js +1 -1
- package/dist/esm/PickerPanel/panels/Header.d.ts +13 -1
- package/dist/esm/PickerPanel/panels/MonthPanel/MonthBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/MonthPanel/MonthHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/MonthPanel/MonthHeader.js +2 -1
- package/dist/esm/PickerPanel/panels/MonthPanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/MonthPanel/index.js +1 -1
- package/dist/esm/PickerPanel/panels/PanelBody.d.ts +21 -1
- package/dist/esm/PickerPanel/panels/PanelBody.js +2 -4
- package/dist/esm/PickerPanel/panels/QuarterPanel/QuarterBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/QuarterPanel/QuarterHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/QuarterPanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/RangePanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/RangePanel/index.js +2 -2
- package/dist/esm/PickerPanel/panels/RangePanel/interface.d.ts +5 -5
- package/dist/esm/PickerPanel/panels/TimePanel/TimeBody.d.ts +17 -1
- package/dist/esm/PickerPanel/panels/TimePanel/TimeCell.d.ts +7 -1
- package/dist/esm/PickerPanel/panels/TimePanel/TimeCell.js +1 -1
- package/dist/esm/PickerPanel/panels/TimePanel/TimeColumn.d.ts +14 -1
- package/dist/esm/PickerPanel/panels/TimePanel/TimeColumn.js +1 -1
- package/dist/esm/PickerPanel/panels/TimePanel/TimeHeader.d.ts +4 -1
- package/dist/esm/PickerPanel/panels/TimePanel/index.d.ts +9 -1
- package/dist/esm/PickerPanel/panels/WeekPanel/WeekBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/WeekPanel/WeekHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/WeekPanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/YearPanel/YearBody.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/YearPanel/YearBody.js +3 -2
- package/dist/esm/PickerPanel/panels/YearPanel/YearHeader.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/YearPanel/YearHeader.js +2 -1
- package/dist/esm/PickerPanel/panels/YearPanel/index.d.ts +2 -1
- package/dist/esm/PickerPanel/panels/YearPanel/index.js +1 -1
- package/dist/esm/PickerPanel/picker-panel.js +3 -0
- package/dist/esm/PickerPanel/utils/pickerUtils.d.ts +7 -7
- package/dist/esm/PickerPanel/utils/pickerUtils.js +4 -10
- package/dist/esm/Select/demo/basic.js +1 -1
- package/dist/esm/Select/demo/virtual.d.ts +3 -0
- package/dist/esm/Select/demo/virtual.js +38 -0
- package/dist/esm/Select/hooks/useSelectKeyboard.d.ts +7 -1
- package/dist/esm/Select/hooks/useSelectKeyboard.js +25 -9
- package/dist/esm/Select/interface.d.ts +44 -0
- package/dist/esm/Select/option.js +4 -2
- package/dist/esm/Select/options.js +132 -13
- package/dist/esm/Select/select.js +19 -4
- package/dist/esm/Select/style/index.less +17 -13
- package/dist/esm/Selector/style/index.less +2 -137
- package/dist/esm/Table/style/index.less +19 -0
- package/dist/esm/TextArea/style/index.less +0 -17
- package/dist/esm/hooks/index.d.ts +2 -1
- package/dist/esm/hooks/index.js +2 -1
- package/dist/esm/hooks/useVirtualList.d.ts +71 -0
- package/dist/esm/hooks/useVirtualList.js +129 -0
- package/dist/esm/style/size.css +1 -0
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +2 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +2 -2
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Carousel/carousel.tsx +14 -3
- package/src/Carousel/interface.ts +6 -0
- package/src/Cascader/cascader.tsx +3 -1
- package/src/Cascader/column.tsx +1 -1
- package/src/Dialog/demo/basic.tsx +1 -1
- package/src/Dialog/dialog.tsx +1 -1
- package/src/Drawer/style/index.less +4 -0
- package/src/Dropdown/dropdown.tsx +1 -1
- package/src/Field/demo/validation.tsx +2 -2
- package/src/Field/field.tsx +2 -1
- package/src/Field/index.en-US.md +1 -1
- package/src/Field/index.zh-CN.md +1 -1
- package/src/FloatButton/float-button.tsx +5 -3
- package/src/Form/Field.tsx +3 -4
- package/src/Form/Form.tsx +1 -1
- package/src/Form/Group.tsx +15 -12
- package/src/Form/List.tsx +3 -3
- package/src/Form/demo/async-validate.tsx +71 -0
- package/src/Form/demo/basic.tsx +2 -2
- package/src/Form/demo/virtual.tsx +1 -1
- package/src/Form/form-store.ts +37 -21
- package/src/Form/index.en-US.md +6 -5
- package/src/Form/index.zh-CN.md +6 -5
- package/src/Form/interface.ts +13 -7
- package/src/Form/style/index.less +15 -0
- package/src/Form/utils/validate.ts +65 -13
- package/src/Input/style/index.less +0 -17
- package/src/InputNumber/style/index.less +0 -29
- package/src/PickerPanel/interface.ts +43 -2
- package/src/PickerPanel/panels/DatePanel/DateBody.tsx +2 -1
- package/src/PickerPanel/panels/DatePanel/DateHeader.tsx +3 -2
- package/src/PickerPanel/panels/DatePanel/index.tsx +2 -1
- package/src/PickerPanel/panels/DateTimePanel/index.tsx +12 -5
- package/src/PickerPanel/panels/DecadePanel/DecadeBody.tsx +3 -2
- package/src/PickerPanel/panels/DecadePanel/DecadeHeader.tsx +3 -2
- package/src/PickerPanel/panels/DecadePanel/index.tsx +3 -2
- package/src/PickerPanel/panels/Header.tsx +14 -1
- package/src/PickerPanel/panels/MonthPanel/MonthBody.tsx +2 -1
- package/src/PickerPanel/panels/MonthPanel/MonthHeader.tsx +3 -2
- package/src/PickerPanel/panels/MonthPanel/index.tsx +3 -2
- package/src/PickerPanel/panels/PanelBody.tsx +27 -5
- package/src/PickerPanel/panels/QuarterPanel/QuarterBody.tsx +2 -1
- package/src/PickerPanel/panels/QuarterPanel/QuarterHeader.tsx +2 -1
- package/src/PickerPanel/panels/QuarterPanel/index.tsx +2 -1
- package/src/PickerPanel/panels/RangePanel/index.tsx +11 -9
- package/src/PickerPanel/panels/RangePanel/interface.ts +5 -5
- package/src/PickerPanel/panels/TimePanel/TimeBody.tsx +21 -5
- package/src/PickerPanel/panels/TimePanel/TimeCell.tsx +9 -2
- package/src/PickerPanel/panels/TimePanel/TimeColumn.tsx +15 -2
- package/src/PickerPanel/panels/TimePanel/TimeHeader.tsx +5 -1
- package/src/PickerPanel/panels/TimePanel/index.tsx +10 -1
- package/src/PickerPanel/panels/WeekPanel/WeekBody.tsx +2 -1
- package/src/PickerPanel/panels/WeekPanel/WeekHeader.tsx +2 -1
- package/src/PickerPanel/panels/WeekPanel/index.tsx +2 -1
- package/src/PickerPanel/panels/YearPanel/YearBody.tsx +4 -3
- package/src/PickerPanel/panels/YearPanel/YearHeader.tsx +9 -3
- package/src/PickerPanel/panels/YearPanel/index.tsx +3 -2
- package/src/PickerPanel/picker-panel.tsx +5 -3
- package/src/PickerPanel/utils/pickerUtils.ts +17 -8
- package/src/Select/demo/basic.tsx +1 -1
- package/src/Select/demo/virtual.tsx +25 -0
- package/src/Select/hooks/useSelectKeyboard.ts +30 -6
- package/src/Select/index.en-US.md +4 -0
- package/src/Select/index.zh-CN.md +4 -0
- package/src/Select/interface.ts +48 -2
- package/src/Select/option.tsx +2 -1
- package/src/Select/options.tsx +139 -8
- package/src/Select/select.tsx +23 -1
- package/src/Select/style/index.less +17 -13
- package/src/Selector/style/index.less +2 -137
- package/src/Splitter/hooks/useMove.ts +2 -2
- package/src/Table/style/index.less +19 -0
- package/src/TextArea/style/index.less +0 -17
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useEvent.ts +7 -4
- package/src/hooks/useMergedState.ts +6 -4
- package/src/hooks/useVirtualList.ts +169 -0
- package/src/style/size.css +1 -0
- package/src/version.ts +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { Dayjs } from 'dayjs';
|
|
4
|
+
import type { PickerPanelProps } from '../../interface';
|
|
5
|
+
import type { RangePanelProps } from './interface';
|
|
4
6
|
import PickerPanel from '../../picker-panel';
|
|
5
7
|
import pickerUtils from '../../utils/pickerUtils';
|
|
6
8
|
|
|
7
|
-
function RangePanel(props:
|
|
9
|
+
function RangePanel(props: RangePanelProps) {
|
|
8
10
|
const {
|
|
9
11
|
prefixCls = 'yee-picker',
|
|
10
12
|
panel = 'start',
|
|
@@ -28,12 +30,12 @@ function RangePanel(props: any) {
|
|
|
28
30
|
picker={picker}
|
|
29
31
|
value={panel === 'start' ? value[0] : value[1]}
|
|
30
32
|
pickerView={pickerUtils.init(pickerView[panel === 'start' ? 0 : 1])}
|
|
31
|
-
onChange={onChange}
|
|
33
|
+
onChange={onChange as PickerPanelProps['onChange']}
|
|
32
34
|
onPanelChange={onPanelChange}
|
|
33
35
|
onCellMouse={onCellMouse}
|
|
34
36
|
hoverRange={hoverRange}
|
|
35
37
|
selectedRange={selectedRange}
|
|
36
|
-
disabledDate={disabledDate}
|
|
38
|
+
disabledDate={disabledDate as PickerPanelProps['disabledDate']}
|
|
37
39
|
footer={false}
|
|
38
40
|
/>
|
|
39
41
|
</div>
|
|
@@ -61,12 +63,12 @@ function RangePanel(props: any) {
|
|
|
61
63
|
picker={picker}
|
|
62
64
|
value={startValue}
|
|
63
65
|
pickerView={startViewDate}
|
|
64
|
-
onChange={onChange}
|
|
65
|
-
onPanelChange={(viewDate) => onPanelChange(viewDate, 'start')}
|
|
66
|
+
onChange={onChange as PickerPanelProps['onChange']}
|
|
67
|
+
onPanelChange={(viewDate) => onPanelChange?.(viewDate, 'start')}
|
|
66
68
|
onCellMouse={onCellMouse}
|
|
67
69
|
hoverRange={hoverRange}
|
|
68
70
|
selectedRange={selectedRange}
|
|
69
|
-
disabledDate={disabledDate}
|
|
71
|
+
disabledDate={disabledDate as PickerPanelProps['disabledDate']}
|
|
70
72
|
footer={false}
|
|
71
73
|
showNextIcon={false}
|
|
72
74
|
showSuperNextIcon={false}
|
|
@@ -76,12 +78,12 @@ function RangePanel(props: any) {
|
|
|
76
78
|
picker={picker}
|
|
77
79
|
value={endValue}
|
|
78
80
|
pickerView={endViewDate}
|
|
79
|
-
onChange={onChange}
|
|
80
|
-
onPanelChange={(viewDate) => onPanelChange(viewDate, 'end')}
|
|
81
|
+
onChange={onChange as PickerPanelProps['onChange']}
|
|
82
|
+
onPanelChange={(viewDate) => onPanelChange?.(viewDate, 'end')}
|
|
81
83
|
onCellMouse={onCellMouse}
|
|
82
84
|
hoverRange={hoverRange}
|
|
83
85
|
selectedRange={selectedRange}
|
|
84
|
-
disabledDate={disabledDate}
|
|
86
|
+
disabledDate={disabledDate as PickerPanelProps['disabledDate']}
|
|
85
87
|
footer={false}
|
|
86
88
|
showPrevIcon={false}
|
|
87
89
|
showSuperPrevIcon={false}
|
|
@@ -22,17 +22,17 @@ export type PickerType =
|
|
|
22
22
|
export interface RangePanelProps {
|
|
23
23
|
prefixCls?: string;
|
|
24
24
|
panel?: 'start' | 'end';
|
|
25
|
-
value
|
|
26
|
-
|
|
25
|
+
value: Array<Dayjs | undefined>;
|
|
26
|
+
pickerView: [Dayjs, Dayjs];
|
|
27
27
|
picker?: PickerType;
|
|
28
28
|
mode?: PickerMode;
|
|
29
29
|
format?: string;
|
|
30
30
|
saveFormat?: string;
|
|
31
31
|
onChange?: (date: Dayjs, panel: string) => void;
|
|
32
|
-
onPanelChange?: (
|
|
32
|
+
onPanelChange?: (date: Dayjs, type?: 'start' | 'end') => void;
|
|
33
33
|
onCellMouse?: (date: Dayjs | string) => void;
|
|
34
|
-
hoverRange?: Array<Dayjs | null>;
|
|
35
|
-
selectedRange?: Array<Dayjs | null>;
|
|
34
|
+
hoverRange?: Array<Dayjs | null | undefined>;
|
|
35
|
+
selectedRange?: Array<Dayjs | null | undefined>;
|
|
36
36
|
disabledDate?: (current: Dayjs, type: 'start' | 'end') => boolean;
|
|
37
37
|
showNextIcon?: boolean;
|
|
38
38
|
showSuperNextIcon?: boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Dayjs } from 'dayjs';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import type { PanelSharedProps, TimeUnit } from '../../interface';
|
|
3
4
|
import panelConfig from '../../configs';
|
|
4
5
|
import pickerUtils from '../../utils/pickerUtils';
|
|
5
6
|
import TimeColumn from './TimeColumn';
|
|
@@ -10,7 +11,7 @@ function getTimeArray(
|
|
|
10
11
|
length: number,
|
|
11
12
|
step: number,
|
|
12
13
|
viewDate: Dayjs,
|
|
13
|
-
type:
|
|
14
|
+
type: TimeUnit,
|
|
14
15
|
): Array<Dayjs> {
|
|
15
16
|
const arr = new Array(length)
|
|
16
17
|
.fill(0)
|
|
@@ -25,7 +26,22 @@ function getTimeArray(
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
interface TimeBodyProps extends PanelSharedProps {
|
|
30
|
+
value?: Dayjs;
|
|
31
|
+
showTitle?: boolean;
|
|
32
|
+
showHour?: boolean;
|
|
33
|
+
showMinute?: boolean;
|
|
34
|
+
showSecond?: boolean;
|
|
35
|
+
disabledHours?: boolean;
|
|
36
|
+
disabledMinutes?: boolean;
|
|
37
|
+
disabledSeconds?: boolean;
|
|
38
|
+
is12hour?: boolean;
|
|
39
|
+
hourStep?: number;
|
|
40
|
+
minuteStep?: number;
|
|
41
|
+
secondStep?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function TimeBody(props: TimeBodyProps) {
|
|
29
45
|
const {
|
|
30
46
|
value,
|
|
31
47
|
prefixCls,
|
|
@@ -48,10 +64,10 @@ function TimeBody(props: any) {
|
|
|
48
64
|
const columns: React.ReactNode[] = [];
|
|
49
65
|
|
|
50
66
|
function addColumnNode(
|
|
51
|
-
type:
|
|
52
|
-
selectedValue:
|
|
67
|
+
type: TimeUnit,
|
|
68
|
+
selectedValue: Dayjs | undefined,
|
|
53
69
|
cells: Array<Dayjs>,
|
|
54
|
-
disabled
|
|
70
|
+
disabled?: boolean,
|
|
55
71
|
): React.ReactNode {
|
|
56
72
|
return (
|
|
57
73
|
<TimeColumn
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
interface TimeCellProps {
|
|
5
|
+
prefixCls?: string;
|
|
6
|
+
value: number;
|
|
7
|
+
onSelect?: (value: number) => void;
|
|
8
|
+
active?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function TimeCell(props: TimeCellProps) {
|
|
5
12
|
const { prefixCls, value, onSelect, active } = props;
|
|
6
13
|
|
|
7
14
|
const cls = clsx(`${prefixCls}-time-panel-cell`, {
|
|
@@ -11,7 +18,7 @@ function TimeCell(props: any) {
|
|
|
11
18
|
const renderValue = value < 10 ? '0' + value : value;
|
|
12
19
|
|
|
13
20
|
return (
|
|
14
|
-
<li className={cls} onClick={() => onSelect(value)}>
|
|
21
|
+
<li className={cls} onClick={() => onSelect?.(value)}>
|
|
15
22
|
<div className={`${prefixCls}-time-panel-cell-inner`}>{renderValue}</div>
|
|
16
23
|
</li>
|
|
17
24
|
);
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import dayjs, { Dayjs } from 'dayjs';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import type { TimeUnit } from '../../interface';
|
|
4
5
|
import pickerUtils from '../../utils/pickerUtils';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
interface TimeColumnProps {
|
|
8
|
+
prefixCls?: string;
|
|
9
|
+
type: TimeUnit;
|
|
10
|
+
value?: Dayjs;
|
|
11
|
+
cells: Dayjs[];
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onSelect?: (date: Dayjs) => void;
|
|
14
|
+
viewDate?: Dayjs;
|
|
15
|
+
maxDate?: Dayjs;
|
|
16
|
+
minDate?: Dayjs;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TimeColumn(props: TimeColumnProps) {
|
|
7
20
|
const {
|
|
8
21
|
prefixCls,
|
|
9
22
|
type,
|
|
@@ -20,7 +33,7 @@ function TimeColumn(props: any) {
|
|
|
20
33
|
const [selectedCell, setSelectedCell] = React.useState<number>();
|
|
21
34
|
|
|
22
35
|
React.useLayoutEffect(() => {
|
|
23
|
-
if (value !==
|
|
36
|
+
if (value !== undefined && selectedRef.current) {
|
|
24
37
|
ref.current?.scrollTo({
|
|
25
38
|
top: selectedRef.current?.offsetTop,
|
|
26
39
|
behavior: 'smooth',
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import type { PanelSharedProps } from '../../interface';
|
|
2
3
|
import TimeBody from './TimeBody';
|
|
3
4
|
import TimeHeader from './TimeHeader';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
interface TimePanelProps extends PanelSharedProps {
|
|
7
|
+
format?: string;
|
|
8
|
+
hourStep?: number;
|
|
9
|
+
minuteStep?: number;
|
|
10
|
+
secondStep?: number;
|
|
11
|
+
showTitle?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function TimePanel(props: TimePanelProps) {
|
|
6
15
|
const {
|
|
7
16
|
format = 'HH:mm:ss',
|
|
8
17
|
prefixCls,
|
|
@@ -3,10 +3,11 @@ import { Dayjs } from 'dayjs';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import useEvent from '../../../hooks/useEvent';
|
|
5
5
|
import { useLocale } from '../../../locale';
|
|
6
|
+
import type { PanelSharedProps } from '../../interface';
|
|
6
7
|
import pickerUtils from '../../utils/pickerUtils';
|
|
7
8
|
import PanelBody from '../PanelBody';
|
|
8
9
|
|
|
9
|
-
function WeekBody(props:
|
|
10
|
+
function WeekBody(props: PanelSharedProps) {
|
|
10
11
|
const { locale } = useLocale();
|
|
11
12
|
const { weekpicker } = locale;
|
|
12
13
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import Button from '../../../Button';
|
|
3
3
|
import useEvent from '../../../hooks/useEvent';
|
|
4
|
+
import type { PanelSharedProps } from '../../interface';
|
|
4
5
|
import pickerUtils from '../../utils/pickerUtils';
|
|
5
6
|
import Header from '../Header';
|
|
6
7
|
|
|
7
|
-
export default function WeekHeader(props:
|
|
8
|
+
export default function WeekHeader(props: PanelSharedProps) {
|
|
8
9
|
const { viewDate, onViewDateChange, onPanelChange } = props;
|
|
9
10
|
|
|
10
11
|
const year = pickerUtils.getYear(viewDate);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { Dayjs } from 'dayjs';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import type { PanelSharedProps } from '../../interface';
|
|
4
5
|
import pickerUtils from '../../utils/pickerUtils';
|
|
5
6
|
import DateBody from '../DatePanel/DateBody';
|
|
6
7
|
import DateHeader from '../DatePanel/DateHeader';
|
|
7
8
|
|
|
8
|
-
export default function WeekPanel(props:
|
|
9
|
+
export default function WeekPanel(props: PanelSharedProps) {
|
|
9
10
|
const { prefixCls, selectedDate } = props;
|
|
10
11
|
|
|
11
12
|
const prefixColumn = (currentDate: Dayjs) => {
|
|
@@ -4,9 +4,10 @@ import * as React from 'react';
|
|
|
4
4
|
import PanelBody from '../PanelBody';
|
|
5
5
|
|
|
6
6
|
import useEvent from '../../../hooks/useEvent';
|
|
7
|
+
import type { PanelSharedProps } from '../../interface';
|
|
7
8
|
import pickerUtils from '../../utils/pickerUtils';
|
|
8
9
|
|
|
9
|
-
function YearBody(props:
|
|
10
|
+
function YearBody(props: PanelSharedProps) {
|
|
10
11
|
const {
|
|
11
12
|
prefixCls,
|
|
12
13
|
viewDate,
|
|
@@ -14,7 +15,7 @@ function YearBody(props: any) {
|
|
|
14
15
|
maxDate,
|
|
15
16
|
minDate,
|
|
16
17
|
nowDate,
|
|
17
|
-
offsetYear,
|
|
18
|
+
offsetYear = 0,
|
|
18
19
|
hoverRange = [],
|
|
19
20
|
selectedRange = [],
|
|
20
21
|
} = props;
|
|
@@ -34,7 +35,7 @@ function YearBody(props: any) {
|
|
|
34
35
|
|
|
35
36
|
const getCellTitle = useEvent((currentDate: Dayjs) => {
|
|
36
37
|
const _year = pickerUtils.getYear(currentDate) + offsetYear;
|
|
37
|
-
return _year < 1000 ? '0' + _year : _year;
|
|
38
|
+
return _year < 1000 ? '0' + _year : String(_year);
|
|
38
39
|
});
|
|
39
40
|
|
|
40
41
|
const getCellClassName = useEvent((currentDate: Dayjs) => {
|
|
@@ -2,12 +2,18 @@ import * as React from 'react';
|
|
|
2
2
|
import Button from '../../../Button';
|
|
3
3
|
import useEvent from '../../../hooks/useEvent';
|
|
4
4
|
import Header from '../Header';
|
|
5
|
+
import type { PanelSharedProps } from '../../interface';
|
|
5
6
|
|
|
6
7
|
import pickerUtils from '../../utils/pickerUtils';
|
|
7
8
|
|
|
8
|
-
export default function YearHeader(props:
|
|
9
|
-
const {
|
|
10
|
-
|
|
9
|
+
export default function YearHeader(props: PanelSharedProps) {
|
|
10
|
+
const {
|
|
11
|
+
prefixCls,
|
|
12
|
+
viewDate,
|
|
13
|
+
onViewDateChange,
|
|
14
|
+
onPanelChange,
|
|
15
|
+
offsetYear = 0,
|
|
16
|
+
} = props;
|
|
11
17
|
|
|
12
18
|
const viewYear = pickerUtils.getYear(viewDate);
|
|
13
19
|
const startYear = viewYear - (viewYear % 10) + offsetYear;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { PanelSharedProps } from '../../interface';
|
|
2
3
|
import YearBody from './YearBody';
|
|
3
4
|
import YearHeader from './YearHeader';
|
|
4
5
|
|
|
5
|
-
export default function DecadePanel(props:
|
|
6
|
+
export default function DecadePanel(props: PanelSharedProps) {
|
|
6
7
|
const { prefixCls, offset } = props;
|
|
7
8
|
|
|
8
9
|
let offsetYear = 0;
|
|
9
10
|
if (offset?.year) {
|
|
10
|
-
offsetYear =
|
|
11
|
+
offsetYear = offset.year;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
return (
|
|
@@ -76,7 +76,7 @@ const PickerPanel = React.forwardRef<HTMLDivElement, PickerPanelProps>(
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
// Panel view switch
|
|
79
|
-
const handlePanelChange = (newView:
|
|
79
|
+
const handlePanelChange = (newView: PickerType) => {
|
|
80
80
|
prevPanelView.current = panelView;
|
|
81
81
|
setPanelView(newView);
|
|
82
82
|
};
|
|
@@ -87,8 +87,10 @@ const PickerPanel = React.forwardRef<HTMLDivElement, PickerPanelProps>(
|
|
|
87
87
|
onPanelChange?.(newViewDate);
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
// `PanelBody` clears the hover by passing `''`; forward as-is to preserve
|
|
91
|
+
// the existing runtime behavior.
|
|
92
|
+
const handleMouseChange = (date: Dayjs | '') => {
|
|
93
|
+
onCellMouse?.(date as Dayjs);
|
|
92
94
|
};
|
|
93
95
|
|
|
94
96
|
const handleNowClick = () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import dayjs, { Dayjs, QUnitType } from 'dayjs';
|
|
2
|
+
import dayjs, { Dayjs, OpUnitType, QUnitType } from 'dayjs';
|
|
3
3
|
import buddhistEra from 'dayjs/plugin/buddhistEra';
|
|
4
4
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
5
5
|
import isBetween from 'dayjs/plugin/isBetween';
|
|
@@ -26,7 +26,7 @@ type PickerType =
|
|
|
26
26
|
|
|
27
27
|
const d = {
|
|
28
28
|
dayjs: dayjs,
|
|
29
|
-
init: (date?:
|
|
29
|
+
init: (date?: dayjs.ConfigType, option?: dayjs.OptionType) => dayjs(date, option),
|
|
30
30
|
getNow: () => {
|
|
31
31
|
return d.init(undefined);
|
|
32
32
|
},
|
|
@@ -40,7 +40,11 @@ const d = {
|
|
|
40
40
|
getSecond: (date: Dayjs) => date.second(),
|
|
41
41
|
|
|
42
42
|
format: (date: Dayjs, format: string) => dayjs(date).format(format),
|
|
43
|
-
isSame: (
|
|
43
|
+
isSame: (
|
|
44
|
+
date1: Dayjs | undefined,
|
|
45
|
+
date2: Dayjs | undefined,
|
|
46
|
+
type?: PickerType,
|
|
47
|
+
) => {
|
|
44
48
|
if (!d.isValid(date1) && !d.isValid(date2)) return true;
|
|
45
49
|
return date1 && date2 ? date1.isSame(date2, type as QUnitType) : false;
|
|
46
50
|
},
|
|
@@ -56,18 +60,23 @@ const d = {
|
|
|
56
60
|
addDate: (date: Dayjs, offset: number) => date?.add(offset, 'day'),
|
|
57
61
|
isAfter: (
|
|
58
62
|
date1: Dayjs,
|
|
59
|
-
date2: Dayjs,
|
|
63
|
+
date2: Dayjs | undefined,
|
|
60
64
|
type?: 'day' | 'hour' | 'minute' | 'second' | 'year' | 'month',
|
|
61
65
|
) => (date2 ? date1.isAfter(date2, type) : false),
|
|
62
66
|
isBefore: (
|
|
63
67
|
date1: Dayjs,
|
|
64
|
-
date2: Dayjs,
|
|
68
|
+
date2: Dayjs | undefined,
|
|
65
69
|
type?: 'day' | 'hour' | 'minute' | 'second' | 'year' | 'month',
|
|
66
70
|
) => (date2 ? date1.isBefore(date2, type) : false),
|
|
67
|
-
isValid: (date: Dayjs, format?: string, strict?: boolean) =>
|
|
71
|
+
isValid: (date: Dayjs | undefined, format?: string, strict?: boolean) =>
|
|
68
72
|
dayjs(date, format, strict).isValid(),
|
|
69
|
-
isBetween: (
|
|
70
|
-
date
|
|
73
|
+
isBetween: (
|
|
74
|
+
date: Dayjs,
|
|
75
|
+
start: Dayjs,
|
|
76
|
+
end: Dayjs,
|
|
77
|
+
unit?: OpUnitType,
|
|
78
|
+
nulls?: '()' | '[]' | '[)' | '(]',
|
|
79
|
+
) => (date && start && end ? date.isBetween(start, end, unit, nulls) : false),
|
|
71
80
|
|
|
72
81
|
getCellClassName: ({
|
|
73
82
|
date,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Select } from '@rainbow-oh/yee-c';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
|
|
4
|
+
// Build a large option set (5000 items) to demonstrate virtual scrolling.
|
|
5
|
+
// Even with this many options, the DOM only holds the visible window.
|
|
6
|
+
const options = Array.from({ length: 5000 }, (_, i) => ({
|
|
7
|
+
label: `Option ${i + 1}`,
|
|
8
|
+
value: i,
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
export default () => {
|
|
12
|
+
const [value, setValue] = useState<number>(100);
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Select
|
|
16
|
+
virtual
|
|
17
|
+
searchable
|
|
18
|
+
value={value}
|
|
19
|
+
onChange={(val) => setValue(val as number)}
|
|
20
|
+
options={options}
|
|
21
|
+
style={{ width: 200 }}
|
|
22
|
+
placeholder="Please select"
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
@@ -13,6 +13,12 @@ interface UseSelectKeyboardParams {
|
|
|
13
13
|
onClose?: () => void;
|
|
14
14
|
onOpenChange?: (open: boolean) => void;
|
|
15
15
|
containerRef?: React.RefObject<HTMLElement>;
|
|
16
|
+
/**
|
|
17
|
+
* Virtual-mode scroll hook. When provided, keyboard navigation drives the
|
|
18
|
+
* virtual viewport through this callback instead of calling scrollIntoView
|
|
19
|
+
* (the focused option may not be in the DOM while virtualized).
|
|
20
|
+
*/
|
|
21
|
+
scrollToIndex?: (index: number) => void;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export default function useSelectKeyboard({
|
|
@@ -23,6 +29,7 @@ export default function useSelectKeyboard({
|
|
|
23
29
|
onClose,
|
|
24
30
|
onOpenChange,
|
|
25
31
|
containerRef,
|
|
32
|
+
scrollToIndex,
|
|
26
33
|
}: UseSelectKeyboardParams) {
|
|
27
34
|
const [focusedKey, setFocusedKey] = useState<string | number>('');
|
|
28
35
|
const latestFocusedKey = useLatest(focusedKey);
|
|
@@ -59,6 +66,13 @@ export default function useSelectKeyboard({
|
|
|
59
66
|
|
|
60
67
|
// Scroll the focused option into view
|
|
61
68
|
const scrollOptionIntoView = (index: number) => {
|
|
69
|
+
// Virtual mode: drive the virtual viewport directly, since the option
|
|
70
|
+
// element may not be mounted when it lies outside the render window.
|
|
71
|
+
if (scrollToIndex) {
|
|
72
|
+
scrollToIndex(index);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
const container = containerRef?.current;
|
|
63
77
|
if (!container) return;
|
|
64
78
|
|
|
@@ -163,20 +177,30 @@ export default function useSelectKeyboard({
|
|
|
163
177
|
useEffect(() => {
|
|
164
178
|
if (open) {
|
|
165
179
|
// Focus the first selected option, or the first enabled option
|
|
180
|
+
let focusedValue: string | number = '';
|
|
166
181
|
if (selectedKeys?.length > 0) {
|
|
167
182
|
const firstSelected = options?.find(
|
|
168
183
|
(opt) => opt.value === selectedKeys[0],
|
|
169
184
|
);
|
|
170
185
|
if (firstSelected && !firstSelected.disabled) {
|
|
171
|
-
|
|
172
|
-
return;
|
|
186
|
+
focusedValue = firstSelected.value;
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
189
|
+
if (!focusedValue) {
|
|
190
|
+
// Find the first enabled option
|
|
191
|
+
const firstEnabled = options?.find((opt) => !opt.disabled);
|
|
192
|
+
if (firstEnabled) {
|
|
193
|
+
focusedValue = firstEnabled.value;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (focusedValue) {
|
|
198
|
+
setFocusedKey(focusedValue);
|
|
179
199
|
}
|
|
200
|
+
// Scrolling the focused option into view in virtual mode is handled by
|
|
201
|
+
// <Options> itself (it owns the viewport + virtual list), which avoids
|
|
202
|
+
// the first-open timing issue where this effect runs before the virtual
|
|
203
|
+
// API ref is wired up.
|
|
180
204
|
} else {
|
|
181
205
|
// Clear focused key when closing
|
|
182
206
|
setFocusedKey('');
|
|
@@ -21,6 +21,7 @@ Select component for choosing from a set of options.
|
|
|
21
21
|
<code src="./demo/multiple.tsx" title="Multiple" description="Multiple selection mode"></code>
|
|
22
22
|
<code src="./demo/search.tsx" title="Search" description="Searchable Select"></code>
|
|
23
23
|
<code src="./demo/tags.tsx" title="Tags" description="Tags mode Select"></code>
|
|
24
|
+
<code src="./demo/virtual.tsx" title="Virtual Scroll" description="Virtual scrolling for large datasets (thousands of options)"></code>
|
|
24
25
|
|
|
25
26
|
## API
|
|
26
27
|
|
|
@@ -46,6 +47,9 @@ Select component for choosing from a set of options.
|
|
|
46
47
|
| optionLabelProp | `string \| (() => string)` | Property to display in the input box | - |
|
|
47
48
|
| onChange | `(value: string \| number \| Array<string \| number>, options?: Option \| undefined \| Option[]) => void` | Value change callback | - |
|
|
48
49
|
| onFilter | `(value: string, options: Array<Option>) => Array<Option>` | Search callback | - |
|
|
50
|
+
| virtual | `boolean` | Enable virtual scrolling. Only the options in the visible window are rendered, so the DOM node count stays constant regardless of the total. Recommended for hundreds or thousands of options | `false` |
|
|
51
|
+
| itemHeight | `number` | Fixed height of each option in pixels. Must be a fixed value when `virtual` is enabled | `32` |
|
|
52
|
+
| listHeight | `number` | Max height of the dropdown popup in pixels | `200` |
|
|
49
53
|
| data-* | `string` | - | Supports all data-* attributes, forwarded to root DOM element |
|
|
50
54
|
|
|
51
55
|
### Option
|
|
@@ -21,6 +21,7 @@ toc: 'content'
|
|
|
21
21
|
<code src="./demo/multiple.tsx" title="多选" description="多选模式"></code>
|
|
22
22
|
<code src="./demo/search.tsx" title="可搜索" description="可搜索的Select"></code>
|
|
23
23
|
<code src="./demo/tags.tsx" title="标签模式" description="标签模式的Select"></code>
|
|
24
|
+
<code src="./demo/virtual.tsx" title="虚拟滚动" description="大数据量(几千条)下的虚拟滚动"></code>
|
|
24
25
|
|
|
25
26
|
## API
|
|
26
27
|
|
|
@@ -46,6 +47,9 @@ toc: 'content'
|
|
|
46
47
|
| optionLabelProp | `string \| (() => string)` | 回填到选择框里的属性 | - |
|
|
47
48
|
| onChange | `(value: string \| number \| Array<string \| number>, options?: Option \| undefined \| Option[]) => void` | 值改变时的回调函数 | - |
|
|
48
49
|
| onFilter | `(value: string, options: Array<Option>) => Array<Option>` | 搜索时的回调函数 | - |
|
|
50
|
+
| virtual | `boolean` | 是否开启虚拟滚动。开启后仅渲染可视区内的选项,DOM 节点数与数据总量无关,适合成百上千条数据 | `false` |
|
|
51
|
+
| itemHeight | `number` | 每个选项的固定高度(px),开启 `virtual` 时必须为定值 | `32` |
|
|
52
|
+
| listHeight | `number` | 下拉框最大高度(px) | `200` |
|
|
49
53
|
| data-* | `string` | - | 支持所有 data-* 属性,透传到组件根 DOM 元素 |
|
|
50
54
|
|
|
51
55
|
### Option
|
package/src/Select/interface.ts
CHANGED
|
@@ -104,6 +104,26 @@ export interface SelectProps extends DataAttributeProps {
|
|
|
104
104
|
* Callback when searching
|
|
105
105
|
*/
|
|
106
106
|
onFilter?: (value: string, options: Array<Option>) => Array<Option>;
|
|
107
|
+
/**
|
|
108
|
+
* Enable virtual scrolling for the dropdown.
|
|
109
|
+
*
|
|
110
|
+
* When enabled, only the options inside the visible window are rendered
|
|
111
|
+
* (the DOM node count stays constant regardless of how many options there
|
|
112
|
+
* are). Recommended for large option sets (hundreds or thousands).
|
|
113
|
+
* @default false
|
|
114
|
+
*/
|
|
115
|
+
virtual?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Height of each option in pixels. Required to be a fixed value when
|
|
118
|
+
* `virtual` is enabled (the list assumes every option has exactly this height).
|
|
119
|
+
* @default 32
|
|
120
|
+
*/
|
|
121
|
+
itemHeight?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Max height of the dropdown popup in pixels.
|
|
124
|
+
* @default 200
|
|
125
|
+
*/
|
|
126
|
+
listHeight?: number;
|
|
107
127
|
}
|
|
108
128
|
|
|
109
129
|
/**
|
|
@@ -130,6 +150,11 @@ export interface OptionProps {
|
|
|
130
150
|
* Test id forwarded to the option element
|
|
131
151
|
*/
|
|
132
152
|
dataTestId?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Inline style forwarded to the option element.
|
|
155
|
+
* Used by virtual scrolling to position each option absolutely.
|
|
156
|
+
*/
|
|
157
|
+
style?: React.CSSProperties;
|
|
133
158
|
}
|
|
134
159
|
|
|
135
160
|
/**
|
|
@@ -149,8 +174,10 @@ export interface OptionsContextValue {
|
|
|
149
174
|
/**
|
|
150
175
|
* Props for the internal Options (popup list) component.
|
|
151
176
|
*/
|
|
152
|
-
export interface OptionsProps
|
|
153
|
-
|
|
177
|
+
export interface OptionsProps extends Omit<
|
|
178
|
+
React.HTMLAttributes<HTMLDivElement>,
|
|
179
|
+
'onSelect'
|
|
180
|
+
> {
|
|
154
181
|
/**
|
|
155
182
|
* Custom class name prefix
|
|
156
183
|
*/
|
|
@@ -184,6 +211,25 @@ export interface OptionsProps
|
|
|
184
211
|
* Whether multiple selection mode is active
|
|
185
212
|
*/
|
|
186
213
|
multiple: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Whether virtual scrolling is enabled
|
|
216
|
+
*/
|
|
217
|
+
virtual?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Fixed option height in pixels (only meaningful when `virtual` is enabled)
|
|
220
|
+
*/
|
|
221
|
+
itemHeight?: number;
|
|
222
|
+
/**
|
|
223
|
+
* Max popup height in pixels (only meaningful when `virtual` is enabled)
|
|
224
|
+
*/
|
|
225
|
+
listHeight?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Ref that receives the virtual list API (currently `scrollToIndex`),
|
|
228
|
+
* so the parent can wire keyboard navigation to the virtual viewport.
|
|
229
|
+
*/
|
|
230
|
+
virtualApiRef?: React.MutableRefObject<{
|
|
231
|
+
scrollToIndex: (index: number) => void;
|
|
232
|
+
} | null>;
|
|
187
233
|
/**
|
|
188
234
|
* Callback when an option is selected
|
|
189
235
|
*/
|
package/src/Select/option.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import type { OptionProps } from './interface';
|
|
|
6
6
|
import { OptionsCtx } from './options';
|
|
7
7
|
|
|
8
8
|
const Option = (props: OptionProps) => {
|
|
9
|
-
const { label, value, disabled, title, dataTestId } = props;
|
|
9
|
+
const { label, value, disabled, title, dataTestId, style } = props;
|
|
10
10
|
const { prefixCls, selectedKeys, focusedKey, multiple, onSelect } =
|
|
11
11
|
useContext(OptionsCtx);
|
|
12
12
|
|
|
@@ -42,6 +42,7 @@ const Option = (props: OptionProps) => {
|
|
|
42
42
|
tabIndex={disabled ? undefined : 0}
|
|
43
43
|
title={htmlTitle}
|
|
44
44
|
data-testid={dataTestId}
|
|
45
|
+
style={style}
|
|
45
46
|
>
|
|
46
47
|
<div className={`${prefixCls}-option-content`}>{label}</div>
|
|
47
48
|
{multiple && selected && (
|