Skip to content

Commit d4eaec7

Browse files
committed
refactor: Move renderFooter out of Panel
1 parent a556e02 commit d4eaec7

File tree

8 files changed

+204
-106
lines changed

8 files changed

+204
-106
lines changed

assets/index.less

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@
122122
}
123123
}
124124

125+
&-footer,
126+
&-picker-footer {
127+
background: green;
128+
}
129+
125130
&-ranges {
126131
margin: 0;
127132
padding: 0;
@@ -286,6 +291,10 @@
286291
position: absolute;
287292
box-shadow: 0 0 1px red;
288293

294+
&-range {
295+
padding: 10px 0;
296+
}
297+
289298
&-hidden {
290299
display: none;
291300
}
@@ -339,10 +348,6 @@
339348
transparent;
340349
}
341350
}
342-
343-
.@{prefix-cls}-panel {
344-
margin: 10px 0;
345-
}
346351
}
347352

348353
// ========================================================

src/Picker.tsx

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import PickerTrigger from './PickerTrigger';
2424
import { isEqual } from './utils/dateUtil';
2525
import getDataOrAriaProps, { toArray } from './utils/miscUtil';
2626
import PanelContext, { ContextOperationRefProps } from './PanelContext';
27-
import { PickerMode } from './interface';
27+
import { PickerMode, PanelMode } from './interface';
2828
import { getDefaultFormat, getInputSize } from './utils/uiUtil';
2929
import usePickerInput from './hooks/usePickerInput';
3030
import useTextValueMapping from './hooks/useTextValueMapping';
3131
import useMergedState from './hooks/useMergeState';
3232
import useValueTexts from './hooks/useValueTexts';
33+
import getExtraFooter from './utils/getExtraFooter';
34+
import getRanges from './utils/getRanges';
3335

3436
export interface PickerRefConfig {
3537
focus: () => void;
@@ -136,6 +138,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
136138
value,
137139
defaultValue,
138140
open,
141+
mode,
139142
defaultOpen,
140143
suffixIcon,
141144
clearIcon,
@@ -144,16 +147,19 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
144147
placeholder,
145148
getPopupContainer,
146149
pickerRef,
150+
renderExtraFooter,
147151
onChange,
148152
onOpenChange,
149153
onFocus,
150154
onBlur,
155+
onPanelChange,
151156
onMouseDown,
152157
onMouseUp,
153158
onMouseEnter,
154159
onMouseLeave,
155160
onContextMenu,
156161
onClick,
162+
onOk,
157163
} = props as MergedPickerProps<DateType>;
158164

159165
const inputRef = React.useRef<HTMLInputElement>(null);
@@ -225,6 +231,20 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
225231
},
226232
});
227233

234+
// ============================= Modes =============================
235+
const [mergedMode, setInnerMode] = useMergedState<PanelMode>({
236+
value: mode,
237+
defaultStateValue: picker,
238+
});
239+
240+
const triggerModeChange = (newValue: DateType, newMode: PanelMode) => {
241+
setInnerMode(newMode);
242+
243+
if (onPanelChange) {
244+
onPanelChange(newValue, newMode);
245+
}
246+
};
247+
228248
// ============================ Trigger ============================
229249
const triggerChange = (newValue: DateType | null) => {
230250
setSelectedValue(newValue);
@@ -338,8 +358,32 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
338358
onPickerValueChange: undefined,
339359
};
340360

361+
const extraNode = getExtraFooter(prefixCls, mergedMode, renderExtraFooter);
362+
363+
const rangesNode = getRanges({
364+
prefixCls,
365+
needConfirmButton,
366+
okDisabled: !selectedValue,
367+
locale,
368+
onOk: () => {
369+
if (selectedValue) {
370+
triggerChange(selectedValue);
371+
triggerOpen(false, true);
372+
373+
if (onOk) {
374+
onOk(selectedValue!);
375+
}
376+
}
377+
},
378+
});
379+
341380
const panel = (
342-
<div className={`${prefixCls}-panel-container`}>
381+
<div
382+
className={`${prefixCls}-panel-container`}
383+
onMouseDown={e => {
384+
e.preventDefault();
385+
}}
386+
>
343387
<PickerPanel<DateType>
344388
{...panelProps}
345389
generateConfig={generateConfig}
@@ -349,11 +393,14 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
349393
value={selectedValue}
350394
locale={locale}
351395
tabIndex={-1}
352-
onMouseDown={e => {
353-
e.preventDefault();
354-
}}
396+
mode={mergedMode}
355397
onChange={setSelectedValue}
398+
onPanelChange={triggerModeChange}
356399
/>
400+
<div className={`${prefixCls}-picker-footer`}>
401+
{extraNode}
402+
{rangesNode}
403+
</div>
357404
</div>
358405
);
359406

src/PickerPanel.tsx

Lines changed: 23 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PickerMode,
2727
DisabledTime,
2828
OnPanelChange,
29+
Components,
2930
} from './interface';
3031
import { isEqual } from './utils/dateUtil';
3132
import PanelContext from './PanelContext';
@@ -35,6 +36,7 @@ import { MonthCellRender } from './panels/MonthPanel/MonthBody';
3536
import RangeContext from './RangeContext';
3637
import useMergedState from './hooks/useMergeState';
3738
import getExtraFooter from './utils/getExtraFooter';
39+
import getRanges from './utils/getRanges';
3840

3941
export interface PickerPanelSharedProps<DateType> {
4042
prefixCls?: string;
@@ -77,10 +79,7 @@ export interface PickerPanelSharedProps<DateType> {
7779
onPickerValueChange?: (date: DateType) => void;
7880

7981
/** @private Internal usage. Do not use in your production env */
80-
components?: {
81-
button?: React.ComponentType | string;
82-
rangeItem?: React.ComponentType | string;
83-
};
82+
components?: Components;
8483
}
8584

8685
export interface PickerPanelBaseProps<DateType>
@@ -143,7 +142,6 @@ function PickerPanel<DateType>(props: PickerPanelProps<DateType>) {
143142
onMouseDown,
144143
onPickerValueChange,
145144
onOk,
146-
components = {},
147145
} = props as MergedPickerPanelProps<DateType>;
148146

149147
const needConfirmButton: boolean =
@@ -174,7 +172,6 @@ function PickerPanel<DateType>(props: PickerPanelProps<DateType>) {
174172
panelPosition,
175173
rangedValue,
176174
hoverRangedValue,
177-
rangeList = [],
178175
} = React.useContext(RangeContext);
179176
const panelRef = React.useRef<PanelRefProps>({});
180177

@@ -424,81 +421,30 @@ function PickerPanel<DateType>(props: PickerPanelProps<DateType>) {
424421
}
425422

426423
// ============================ Footer ============================
427-
const extraFooter: React.ReactNode = inRange
428-
? null
429-
: getExtraFooter(prefixCls, mergedMode, renderExtraFooter);
430-
424+
let extraFooter: React.ReactNode;
431425
let rangesNode: React.ReactNode;
432-
let todayNode: React.ReactNode;
433-
434-
if (rangeList.length || needConfirmButton) {
435-
let presetNode: React.ReactNode;
436-
let okNode: React.ReactNode;
437-
438-
if (rangeList.length) {
439-
const Item = (components.rangeItem || 'span') as any;
440-
441-
presetNode = (
442-
<>
443-
{rangeList.map(({ label, onClick, onMouseEnter, onMouseLeave }) => (
444-
<li key={label} className={`${prefixCls}-range`}>
445-
<Item
446-
onClick={onClick}
447-
onMouseEnter={onMouseEnter}
448-
onMouseLeave={onMouseLeave}
449-
>
450-
{label}
451-
</Item>
452-
</li>
453-
))}
454-
</>
455-
);
456-
}
457426

458-
if (needConfirmButton) {
459-
const Button = (components.button || 'button') as any;
460-
461-
if (!inRange && !presetNode) {
462-
presetNode = (
463-
<li className={`${prefixCls}-now`}>
464-
<a
465-
className={`${prefixCls}-now-btn`}
466-
onClick={() => {
467-
triggerSelect(generateConfig.getNow(), 'submit', true);
468-
}}
469-
>
470-
{locale.now}
471-
</a>
472-
</li>
473-
);
474-
}
427+
if (!onContextSelect) {
428+
extraFooter = getExtraFooter(prefixCls, mergedMode, renderExtraFooter);
429+
rangesNode = getRanges({
430+
prefixCls,
431+
needConfirmButton,
432+
okDisabled: !value,
433+
locale,
434+
onOk: () => {
435+
if (value) {
436+
triggerSelect(value, 'submit', true);
437+
if (onOk) {
438+
onOk(value);
439+
}
440+
}
441+
},
442+
});
443+
}
475444

476-
okNode = (
477-
<li className={`${prefixCls}-ok`}>
478-
<Button
479-
disabled={!value}
480-
onClick={() => {
481-
if (value) {
482-
triggerSelect(value, 'submit', true);
483-
if (onOk) {
484-
onOk(value);
485-
}
486-
}
487-
}}
488-
>
489-
{locale.ok}
490-
</Button>
491-
</li>
492-
);
493-
}
445+
let todayNode: React.ReactNode;
494446

495-
rangesNode = (
496-
<ul className={`${prefixCls}-ranges`}>
497-
{presetNode}
498-
{okNode}
499-
</ul>
500-
);
501-
} else if (showToday && mergedMode === 'date' && picker === 'date') {
447+
if (showToday && mergedMode === 'date' && picker === 'date' && !showTime) {
502448
todayNode = (
503449
<a
504450
className={`${prefixCls}-today-btn`}

src/RangeContext.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { NullableDateType, RangeValue } from './interface';
33

4-
interface RangeContextProps {
4+
export interface RangeContextProps {
55
/**
66
* Set displayed range value style.
77
* Panel only has one value, this is only style effect.
@@ -10,12 +10,6 @@ interface RangeContextProps {
1010
hoverRangedValue?: RangeValue<any>;
1111
inRange?: boolean;
1212
panelPosition?: 'left' | 'right' | false;
13-
rangeList?: {
14-
label: string;
15-
onClick: () => void;
16-
onMouseEnter: () => void;
17-
onMouseLeave: () => void;
18-
}[];
1913
}
2014

2115
const RangeContext = React.createContext<RangeContextProps>({});

src/RangePicker.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { PickerPanelProps } from '.';
3434
import RangeContext from './RangeContext';
3535
import useRangeDisabled from './hooks/useRangeDisabled';
3636
import getExtraFooter from './utils/getExtraFooter';
37+
import getRanges from './utils/getRanges';
3738
import useRangeViewDates from './hooks/useRangeViewDates';
3839

3940
function reorderValues<DateType>(
@@ -464,12 +465,6 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
464465
}
465466
};
466467

467-
const onInternalOk = (date: DateType) => {
468-
if (onOk) {
469-
onOk(updateValues(selectedValue, date, activePickerIndex));
470-
}
471-
};
472-
473468
// ============================= Text ==============================
474469
const sharedTextHooksProps = {
475470
formatList,
@@ -693,7 +688,6 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
693688
panelPosition,
694689
rangedValue: rangeHoverValue || selectedValue,
695690
hoverRangedValue: panelHoverRangedValue,
696-
rangeList,
697691
}}
698692
>
699693
<PickerPanel<DateType>
@@ -730,7 +724,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
730724

731725
setViewDate(date, activePickerIndex);
732726
}}
733-
onOk={onInternalOk}
727+
onOk={null}
734728
onSelect={undefined}
735729
onChange={undefined}
736730
defaultValue={undefined}
@@ -768,6 +762,22 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
768762
renderExtraFooter,
769763
);
770764

765+
const rangesNode = getRanges({
766+
prefixCls,
767+
needConfirmButton,
768+
okDisabled: !getValue(selectedValue, activePickerIndex),
769+
locale,
770+
rangeList,
771+
onOk: () => {
772+
if (getValue(selectedValue, activePickerIndex)) {
773+
triggerChange(selectedValue);
774+
if (onOk) {
775+
onOk(selectedValue);
776+
}
777+
}
778+
},
779+
});
780+
771781
if (picker !== 'time' && !showTime) {
772782
const viewDate = getViewDate(activePickerIndex);
773783
const nextViewDate = getClosingViewDate(viewDate, picker, generateConfig);
@@ -809,7 +819,10 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
809819
}}
810820
>
811821
<div className={`${prefixCls}-panels`}>{panels}</div>
812-
{extraNode}
822+
<div className={`${prefixCls}-picker-footer`}>
823+
{extraNode}
824+
{rangesNode}
825+
</div>
813826
</div>
814827
);
815828
}

0 commit comments

Comments
 (0)