Skip to content

Commit c3724af

Browse files
authored
feat: support panelRender (#100)
* feat: support panelRender * update demo * update test case
1 parent db04beb commit c3724af

File tree

7 files changed

+220
-19
lines changed

7 files changed

+220
-19
lines changed

examples/panelRender.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React from 'react';
2+
import moment, { Moment } from 'moment';
3+
import Picker from '../src/Picker';
4+
import RangePicker from '../src/RangePicker';
5+
import momentGenerateConfig from '../src/generate/moment';
6+
import zhCN from '../src/locale/zh_CN';
7+
import '../assets/index.less';
8+
import './common.less';
9+
10+
const defaultStartValue = moment('2019-09-03 05:02:03');
11+
const defaultEndValue = moment('2019-11-28 01:02:03');
12+
const defaultValue: [Moment, Moment] = [defaultStartValue, defaultEndValue];
13+
14+
export default () => {
15+
const [customizeNode, setCustomizeNode] = React.useState(false);
16+
17+
return (
18+
<>
19+
{String(customizeNode)}
20+
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
21+
<div>
22+
<h3>Picker</h3>
23+
<Picker<Moment>
24+
generateConfig={momentGenerateConfig}
25+
locale={zhCN}
26+
allowClear
27+
defaultValue={defaultStartValue}
28+
panelRender={node => (
29+
<>
30+
<button
31+
type="button"
32+
style={{ display: 'block' }}
33+
onClick={() => {
34+
setCustomizeNode(!customizeNode);
35+
}}
36+
>
37+
Change
38+
</button>
39+
40+
{customizeNode ? <span>My Panel</span> : node}
41+
</>
42+
)}
43+
/>
44+
</div>
45+
<div>
46+
<h3>RangePicker</h3>
47+
<RangePicker<Moment>
48+
generateConfig={momentGenerateConfig}
49+
locale={zhCN}
50+
allowClear
51+
defaultValue={defaultValue}
52+
panelRender={node => (
53+
<>
54+
<button
55+
type="button"
56+
style={{ display: 'block' }}
57+
onClick={() => {
58+
setCustomizeNode(!customizeNode);
59+
}}
60+
>
61+
Change
62+
</button>
63+
{customizeNode ? <span>My Panel</span> : node}
64+
</>
65+
)}
66+
/>
67+
</div>
68+
</div>
69+
</>
70+
);
71+
};

src/Picker.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export interface PickerSharedProps<DateType> extends React.AriaAttributes {
6363
superPrevIcon?: React.ReactNode;
6464
superNextIcon?: React.ReactNode;
6565
getPopupContainer?: (node: HTMLElement) => HTMLElement;
66+
panelRender?: (originPanel: React.ReactNode) => React.ReactNode;
6667

6768
// Events
6869
onChange?: (value: DateType | null, dateString: string) => void;
@@ -157,6 +158,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
157158
placeholder,
158159
getPopupContainer,
159160
pickerRef,
161+
panelRender,
160162
onChange,
161163
onOpenChange,
162164
onFocus,
@@ -359,25 +361,33 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
359361
onPickerValueChange: undefined,
360362
};
361363

364+
let panelNode: React.ReactNode = (
365+
<PickerPanel<DateType>
366+
{...panelProps}
367+
generateConfig={generateConfig}
368+
className={classNames({
369+
[`${prefixCls}-panel-focused`]: !typing,
370+
})}
371+
value={selectedValue}
372+
locale={locale}
373+
tabIndex={-1}
374+
onChange={setSelectedValue}
375+
direction={direction}
376+
/>
377+
);
378+
379+
if (panelRender) {
380+
panelNode = panelRender(panelNode);
381+
}
382+
362383
const panel = (
363384
<div
364385
className={`${prefixCls}-panel-container`}
365386
onMouseDown={e => {
366387
e.preventDefault();
367388
}}
368389
>
369-
<PickerPanel<DateType>
370-
{...panelProps}
371-
generateConfig={generateConfig}
372-
className={classNames({
373-
[`${prefixCls}-panel-focused`]: !typing,
374-
})}
375-
value={selectedValue}
376-
locale={locale}
377-
tabIndex={-1}
378-
onChange={setSelectedValue}
379-
direction={direction}
380-
/>
390+
{panelNode}
381391
</div>
382392
);
383393

src/RangePicker.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface RangePickerSharedProps<DateType> {
9696
/** @private Internal control of active picker. Do not use since it's private usage */
9797
activePickerIndex?: 0 | 1;
9898
dateRender?: RangeDateRender<DateType>;
99+
panelRender?: (originPanel: React.ReactNode) => React.ReactNode;
99100
}
100101

101102
type OmitPickerProps<Props> = Omit<
@@ -181,6 +182,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
181182
disabledDate,
182183
disabledTime,
183184
dateRender,
185+
panelRender,
184186
ranges,
185187
allowEmpty,
186188
allowClear,
@@ -869,6 +871,22 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
869871
panels = renderPanel();
870872
}
871873

874+
let mergedNodes: React.ReactNode = (
875+
<>
876+
<div className={`${prefixCls}-panels`}>{panels}</div>
877+
{(extraNode || rangesNode) && (
878+
<div className={`${prefixCls}-footer`}>
879+
{extraNode}
880+
{rangesNode}
881+
</div>
882+
)}
883+
</>
884+
);
885+
886+
if (panelRender) {
887+
mergedNodes = panelRender(mergedNodes);
888+
}
889+
872890
return (
873891
<div
874892
className={`${prefixCls}-panel-container`}
@@ -878,13 +896,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
878896
e.preventDefault();
879897
}}
880898
>
881-
<div className={`${prefixCls}-panels`}>{panels}</div>
882-
{(extraNode || rangesNode) && (
883-
<div className={`${prefixCls}-footer`}>
884-
{extraNode}
885-
{rangesNode}
886-
</div>
887-
)}
899+
{mergedNodes}
888900
</div>
889901
);
890902
}

tests/__snapshots__/picker.spec.tsx.snap

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,40 @@ exports[`Picker.Basic icon 1`] = `
2828
</div>
2929
`;
3030

31+
exports[`Picker.Basic panelRender 1`] = `
32+
Array [
33+
<div
34+
class="rc-picker"
35+
>
36+
<div
37+
class="rc-picker-input"
38+
>
39+
<input
40+
autocomplete="off"
41+
readonly=""
42+
size="12"
43+
title=""
44+
value=""
45+
/>
46+
</div>
47+
</div>,
48+
<div>
49+
<div
50+
class="rc-picker-dropdown"
51+
style="opacity: 0;"
52+
>
53+
<div
54+
class="rc-picker-panel-container"
55+
>
56+
<h1>
57+
Light
58+
</h1>
59+
</div>
60+
</div>
61+
</div>,
62+
]
63+
`;
64+
3165
exports[`Picker.Basic pass data- & aria- & role 1`] = `
3266
<div
3367
class="rc-picker"

tests/__snapshots__/range.spec.tsx.snap

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,67 @@ exports[`Picker.Range onPanelChange is array args should render correctly in rtl
8989
/>
9090
</div>
9191
`;
92+
93+
exports[`Picker.Range panelRender 1`] = `
94+
Array [
95+
<div
96+
class="rc-picker rc-picker-range"
97+
>
98+
<div
99+
class="rc-picker-input rc-picker-input-active"
100+
>
101+
<input
102+
autocomplete="off"
103+
placeholder=""
104+
readonly=""
105+
size="12"
106+
value=""
107+
/>
108+
</div>
109+
<div
110+
class="rc-picker-range-separator"
111+
>
112+
~
113+
</div>
114+
<div
115+
class="rc-picker-input"
116+
>
117+
<input
118+
autocomplete="off"
119+
placeholder=""
120+
readonly=""
121+
size="12"
122+
value=""
123+
/>
124+
</div>
125+
<div
126+
class="rc-picker-active-bar"
127+
style="left: 0px; width: 0px; position: absolute;"
128+
/>
129+
</div>,
130+
<div>
131+
<div
132+
class="rc-picker-dropdown rc-picker-dropdown-range"
133+
style="opacity: 0;"
134+
>
135+
<div
136+
class="rc-picker-range-wrapper rc-picker-date-range-wrapper"
137+
style="min-width: 0;"
138+
>
139+
<div
140+
class="rc-picker-range-arrow"
141+
style="left: 0px;"
142+
/>
143+
<div
144+
class="rc-picker-panel-container"
145+
style="margin-left: 0px;"
146+
>
147+
<h1>
148+
Light
149+
</h1>
150+
</div>
151+
</div>
152+
</div>
153+
</div>,
154+
]
155+
`;

tests/picker.spec.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,4 +724,9 @@ describe('Picker.Basic', () => {
724724
wrapper.closePicker();
725725
expect(wrapper.find('input').prop('value')).toEqual('20000101');
726726
});
727+
728+
it('panelRender', () => {
729+
const wrapper = mount(<MomentPicker open panelRender={() => <h1>Light</h1>} />);
730+
expect(wrapper.render()).toMatchSnapshot();
731+
});
727732
});

tests/range.spec.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,4 +1382,9 @@ describe('Picker.Range', () => {
13821382
jest.useRealTimers();
13831383
});
13841384
});
1385+
1386+
it('panelRender', () => {
1387+
const wrapper = mount(<MomentRangePicker open panelRender={() => <h1>Light</h1>} />);
1388+
expect(wrapper.render()).toMatchSnapshot();
1389+
});
13851390
});

0 commit comments

Comments
 (0)