Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions examples/panelRender.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import moment, { Moment } from 'moment';
import Picker from '../src/Picker';
import RangePicker from '../src/RangePicker';
import momentGenerateConfig from '../src/generate/moment';
import zhCN from '../src/locale/zh_CN';
import '../assets/index.less';
import './common.less';

const defaultStartValue = moment('2019-09-03 05:02:03');
const defaultEndValue = moment('2019-11-28 01:02:03');
const defaultValue: [Moment, Moment] = [defaultStartValue, defaultEndValue];

export default () => {
const [customizeNode, setCustomizeNode] = React.useState(false);

return (
<>
{String(customizeNode)}
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<div>
<h3>Picker</h3>
<Picker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultStartValue}
panelRender={node => (
<>
<button
type="button"
style={{ display: 'block' }}
onClick={() => {
setCustomizeNode(!customizeNode);
}}
>
Change
</button>

{customizeNode ? <span>My Panel</span> : node}
</>
)}
/>
</div>
<div>
<h3>RangePicker</h3>
<RangePicker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultValue}
panelRender={node => (
<>
<button
type="button"
style={{ display: 'block' }}
onClick={() => {
setCustomizeNode(!customizeNode);
}}
>
Change
</button>
{customizeNode ? <span>My Panel</span> : node}
</>
)}
/>
</div>
</div>
</>
);
};
34 changes: 22 additions & 12 deletions src/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export interface PickerSharedProps<DateType> extends React.AriaAttributes {
superPrevIcon?: React.ReactNode;
superNextIcon?: React.ReactNode;
getPopupContainer?: (node: HTMLElement) => HTMLElement;
panelRender?: (originPanel: React.ReactNode) => React.ReactNode;

// Events
onChange?: (value: DateType | null, dateString: string) => void;
Expand Down Expand Up @@ -157,6 +158,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
placeholder,
getPopupContainer,
pickerRef,
panelRender,
onChange,
onOpenChange,
onFocus,
Expand Down Expand Up @@ -359,25 +361,33 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
onPickerValueChange: undefined,
};

let panelNode: React.ReactNode = (
<PickerPanel<DateType>
{...panelProps}
generateConfig={generateConfig}
className={classNames({
[`${prefixCls}-panel-focused`]: !typing,
})}
value={selectedValue}
locale={locale}
tabIndex={-1}
onChange={setSelectedValue}
direction={direction}
/>
);

if (panelRender) {
panelNode = panelRender(panelNode);
}

const panel = (
<div
className={`${prefixCls}-panel-container`}
onMouseDown={e => {
e.preventDefault();
}}
>
<PickerPanel<DateType>
{...panelProps}
generateConfig={generateConfig}
className={classNames({
[`${prefixCls}-panel-focused`]: !typing,
})}
value={selectedValue}
locale={locale}
tabIndex={-1}
onChange={setSelectedValue}
direction={direction}
/>
{panelNode}
</div>
);

Expand Down
26 changes: 19 additions & 7 deletions src/RangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export interface RangePickerSharedProps<DateType> {
/** @private Internal control of active picker. Do not use since it's private usage */
activePickerIndex?: 0 | 1;
dateRender?: RangeDateRender<DateType>;
panelRender?: (originPanel: React.ReactNode) => React.ReactNode;
}

type OmitPickerProps<Props> = Omit<
Expand Down Expand Up @@ -181,6 +182,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
disabledDate,
disabledTime,
dateRender,
panelRender,
ranges,
allowEmpty,
allowClear,
Expand Down Expand Up @@ -869,6 +871,22 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
panels = renderPanel();
}

let mergedNodes: React.ReactNode = (
<>
<div className={`${prefixCls}-panels`}>{panels}</div>
{(extraNode || rangesNode) && (
<div className={`${prefixCls}-footer`}>
{extraNode}
{rangesNode}
</div>
)}
</>
);

if (panelRender) {
mergedNodes = panelRender(mergedNodes);
}

return (
<div
className={`${prefixCls}-panel-container`}
Expand All @@ -878,13 +896,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
e.preventDefault();
}}
>
<div className={`${prefixCls}-panels`}>{panels}</div>
{(extraNode || rangesNode) && (
<div className={`${prefixCls}-footer`}>
{extraNode}
{rangesNode}
</div>
)}
{mergedNodes}
</div>
);
}
Expand Down
34 changes: 34 additions & 0 deletions tests/__snapshots__/picker.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,40 @@ exports[`Picker.Basic icon 1`] = `
</div>
`;

exports[`Picker.Basic panelRender 1`] = `
Array [
<div
class="rc-picker"
>
<div
class="rc-picker-input"
>
<input
autocomplete="off"
readonly=""
size="12"
title=""
value=""
/>
</div>
</div>,
<div>
<div
class="rc-picker-dropdown"
style="opacity: 0;"
>
<div
class="rc-picker-panel-container"
>
<h1>
Light
</h1>
</div>
</div>
</div>,
]
`;

exports[`Picker.Basic pass data- & aria- & role 1`] = `
<div
class="rc-picker"
Expand Down
64 changes: 64 additions & 0 deletions tests/__snapshots__/range.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,67 @@ exports[`Picker.Range onPanelChange is array args should render correctly in rtl
/>
</div>
`;

exports[`Picker.Range panelRender 1`] = `
Array [
<div
class="rc-picker rc-picker-range"
>
<div
class="rc-picker-input rc-picker-input-active"
>
<input
autocomplete="off"
placeholder=""
readonly=""
size="12"
value=""
/>
</div>
<div
class="rc-picker-range-separator"
>
~
</div>
<div
class="rc-picker-input"
>
<input
autocomplete="off"
placeholder=""
readonly=""
size="12"
value=""
/>
</div>
<div
class="rc-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;"
/>
</div>,
<div>
<div
class="rc-picker-dropdown rc-picker-dropdown-range"
style="opacity: 0;"
>
<div
class="rc-picker-range-wrapper rc-picker-date-range-wrapper"
style="min-width: 0;"
>
<div
class="rc-picker-range-arrow"
style="left: 0px;"
/>
<div
class="rc-picker-panel-container"
style="margin-left: 0px;"
>
<h1>
Light
</h1>
</div>
</div>
</div>
</div>,
]
`;
5 changes: 5 additions & 0 deletions tests/picker.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -724,4 +724,9 @@ describe('Picker.Basic', () => {
wrapper.closePicker();
expect(wrapper.find('input').prop('value')).toEqual('20000101');
});

it('panelRender', () => {
const wrapper = mount(<MomentPicker open panelRender={() => <h1>Light</h1>} />);
expect(wrapper.render()).toMatchSnapshot();
});
});
5 changes: 5 additions & 0 deletions tests/range.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1382,4 +1382,9 @@ describe('Picker.Range', () => {
jest.useRealTimers();
});
});

it('panelRender', () => {
const wrapper = mount(<MomentRangePicker open panelRender={() => <h1>Light</h1>} />);
expect(wrapper.render()).toMatchSnapshot();
});
});