Skip to content

fix(RangePicker): fix panelLeft according to wrapper width #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,6 @@
&-panel-container {
display: inline-block;
vertical-align: top;
transition: margin 0.3s;
transition: transform 0.3s;
}
}
62 changes: 45 additions & 17 deletions examples/panelRender.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import moment, { Moment } from 'moment';
import type { Moment } from 'moment';
import moment from 'moment';
import Picker from '../src/Picker';
import RangePicker from '../src/RangePicker';
import momentGenerateConfig from '../src/generate/moment';
Expand All @@ -25,7 +26,7 @@ export default () => {
locale={zhCN}
allowClear
defaultValue={defaultStartValue}
panelRender={node => (
panelRender={(node) => (
<>
<button
type="button"
Expand All @@ -43,26 +44,53 @@ export default () => {
/>
</div>
<div>
<h3>RangePicker</h3>
<h3>RangePicker - Date</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}
</>
)}
panelRender={(node) => <>{customizeNode ? <span>My Panel</span> : node}</>}
/>
</div>
<div>
<h3>RangePicker - Time</h3>
<RangePicker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultValue}
picker="time"
/>
</div>
<div>
<h3>RangePicker - week</h3>
<RangePicker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultValue}
picker="week"
/>
</div>
<div>
<h3>RangePicker - month</h3>
<RangePicker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultValue}
picker="month"
/>
</div>
<div>
<h3>RangePicker - year</h3>
<RangePicker<Moment>
generateConfig={momentGenerateConfig}
locale={zhCN}
allowClear
defaultValue={defaultValue}
picker="year"
/>
</div>
</div>
Expand Down
63 changes: 33 additions & 30 deletions src/RangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,18 @@ type RangeShowTimeObject<DateType> = Omit<SharedTimeProps<DateType>, 'defaultVal
defaultValue?: DateType[];
};

export type RangePickerBaseProps<DateType> = {} & RangePickerSharedProps<DateType> & OmitPickerProps<PickerBaseProps<DateType>>;
export type RangePickerBaseProps<DateType> = {} & RangePickerSharedProps<DateType> &
OmitPickerProps<PickerBaseProps<DateType>>;

export type RangePickerDateProps<DateType> = {
showTime?: boolean | RangeShowTimeObject<DateType>;
} & RangePickerSharedProps<DateType> & OmitPickerProps<PickerDateProps<DateType>>;
} & RangePickerSharedProps<DateType> &
OmitPickerProps<PickerDateProps<DateType>>;

export type RangePickerTimeProps<DateType> = {
order?: boolean;
} & RangePickerSharedProps<DateType> & OmitPickerProps<PickerTimeProps<DateType>>;
} & RangePickerSharedProps<DateType> &
OmitPickerProps<PickerTimeProps<DateType>>;

export type RangePickerProps<DateType> =
| RangePickerBaseProps<DateType>
Expand Down Expand Up @@ -224,6 +227,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {

const containerRef = useRef<HTMLDivElement>(null);
const panelDivRef = useRef<HTMLDivElement>(null);
const rangeWrapperRef = useRef<HTMLDivElement>(null);
const startInputDivRef = useRef<HTMLDivElement>(null);
const endInputDivRef = useRef<HTMLDivElement>(null);
const separatorRef = useRef<HTMLDivElement>(null);
Expand All @@ -239,9 +243,8 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
});

// Operation ref
const operationRef: React.MutableRefObject<ContextOperationRefProps | null> = useRef<
ContextOperationRefProps
>(null);
const operationRef: React.MutableRefObject<ContextOperationRefProps | null> =
useRef<ContextOperationRefProps>(null);

const mergedDisabled = React.useMemo<[boolean, boolean]>(() => {
if (Array.isArray(disabled)) {
Expand All @@ -255,7 +258,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
const [mergedValue, setInnerValue] = useMergedState<RangeValue<DateType>>(null, {
value,
defaultValue,
postState: values =>
postState: (values) =>
picker === 'time' && !order ? values : reorderValues(values, generateConfig),
});

Expand All @@ -270,7 +273,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {

// ========================= Select Values =========================
const [selectedValue, setSelectedValue] = useMergedState(mergedValue, {
postState: values => {
postState: (values) => {
let postValues = values;

if (mergedDisabled[0] && mergedDisabled[1]) {
Expand Down Expand Up @@ -322,8 +325,8 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
const [mergedOpen, triggerInnerOpen] = useMergedState(false, {
value: open,
defaultValue: defaultOpen,
postState: postOpen => (mergedDisabled[mergedActivePickerIndex] ? false : postOpen),
onChange: newOpen => {
postState: (postOpen) => (mergedDisabled[mergedActivePickerIndex] ? false : postOpen),
onChange: (newOpen) => {
if (onOpenChange) {
onOpenChange(newOpen);
}
Expand Down Expand Up @@ -533,12 +536,12 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {

const [startText, triggerStartTextChange, resetStartText] = useTextValueMapping({
valueTexts: startValueTexts,
onTextChange: newText => onTextChange(newText, 0),
onTextChange: (newText) => onTextChange(newText, 0),
});

const [endText, triggerEndTextChange, resetEndText] = useTextValueMapping({
valueTexts: endValueTexts,
onTextChange: newText => onTextChange(newText, 1),
onTextChange: (newText) => onTextChange(newText, 1),
});

const [rangeHoverValue, setRangeHoverValue] = useState<RangeValue<DateType>>(null);
Expand Down Expand Up @@ -731,7 +734,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
// ============================ Ranges =============================
const rangeLabels = Object.keys(ranges || {});

const rangeList = rangeLabels.map(label => {
const rangeList = rangeLabels.map((label) => {
const range = ranges![label];
const newValues = typeof range === 'function' ? range() : range;

Expand Down Expand Up @@ -766,10 +769,8 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
panelHoverRangedValue = hoverRangedValue;
}

let panelShowTime:
| boolean
| SharedTimeProps<DateType>
| undefined = showTime as SharedTimeProps<DateType>;
let panelShowTime: boolean | SharedTimeProps<DateType> | undefined =
showTime as SharedTimeProps<DateType>;
if (showTime && typeof showTime === 'object' && showTime.defaultValue) {
const timeDefaultValues: DateType[] = showTime.defaultValue!;
panelShowTime = {
Expand Down Expand Up @@ -805,7 +806,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
style={undefined}
direction={direction}
disabledDate={mergedActivePickerIndex === 0 ? disabledStartDate : disabledEndDate}
disabledTime={date => {
disabledTime={(date) => {
if (disabledTime) {
return disabledTime(date, mergedActivePickerIndex === 0 ? 'start' : 'end');
}
Expand Down Expand Up @@ -855,14 +856,15 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
mergedActivePickerIndex &&
startInputDivRef.current &&
separatorRef.current &&
panelDivRef.current
panelDivRef.current &&
rangeWrapperRef.current
) {
// Arrow offset
arrowLeft = startInputDivRef.current.offsetWidth + separatorRef.current.offsetWidth;
const panelDivOffsetLeft = panelDivRef.current.offsetLeft;
const distanceToWrapper = rangeWrapperRef.current.offsetWidth - panelDivRef.current.offsetWidth;

if (panelDivRef.current.offsetWidth && arrowLeft > panelDivRef.current.offsetWidth) {
panelLeft = arrowLeft;
}
panelLeft = panelDivOffsetLeft === 0 ? distanceToWrapper : distanceToWrapper * -1;
}

const arrowPositionStyle = direction === 'rtl' ? { right: arrowLeft } : { left: arrowLeft };
Expand Down Expand Up @@ -903,13 +905,13 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
const showDoublePanel = currentMode === picker;
const leftPanel = renderPanel(showDoublePanel ? 'left' : false, {
pickerValue: viewDate,
onPickerValueChange: newViewDate => {
onPickerValueChange: (newViewDate) => {
setViewDate(newViewDate, mergedActivePickerIndex);
},
});
const rightPanel = renderPanel('right', {
pickerValue: nextViewDate,
onPickerValueChange: newViewDate => {
onPickerValueChange: (newViewDate) => {
setViewDate(
getClosingViewDate(newViewDate, picker, generateConfig, -1),
mergedActivePickerIndex,
Expand Down Expand Up @@ -955,9 +957,9 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
return (
<div
className={`${prefixCls}-panel-container`}
style={{ marginLeft: panelLeft }}
style={{ transform: `translateX(${panelLeft}px)` }}
ref={panelDivRef}
onMouseDown={e => {
onMouseDown={(e) => {
e.preventDefault();
}}
>
Expand All @@ -970,6 +972,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
<div
className={classNames(`${prefixCls}-range-wrapper`, `${prefixCls}-${picker}-range-wrapper`)}
style={{ minWidth: popupMinWidth }}
ref={rangeWrapperRef}
>
<div className={`${prefixCls}-range-arrow`} style={arrowPositionStyle} />

Expand All @@ -991,11 +994,11 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
) {
clearNode = (
<span
onMouseDown={e => {
onMouseDown={(e) => {
e.preventDefault();
e.stopPropagation();
}}
onMouseUp={e => {
onMouseUp={(e) => {
e.preventDefault();
e.stopPropagation();
let values = mergedValue;
Expand Down Expand Up @@ -1101,7 +1104,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
disabled={mergedDisabled[0]}
readOnly={inputReadOnly || typeof formatList[0] === 'function' || !startTyping}
value={startHoverValue || startText}
onChange={e => {
onChange={(e) => {
triggerStartTextChange(e.target.value);
}}
autoFocus={autoFocus}
Expand All @@ -1126,7 +1129,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
disabled={mergedDisabled[1]}
readOnly={inputReadOnly || typeof formatList[0] === 'function' || !endTyping}
value={endHoverValue || endText}
onChange={e => {
onChange={(e) => {
triggerEndTextChange(e.target.value);
}}
placeholder={getValue(placeholder, 1) || ''}
Expand Down
4 changes: 2 additions & 2 deletions tests/range.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@ describe('Picker.Range', () => {
const wrapper = mount(<MomentRangePicker />);
wrapper.openPicker(1);
wrapper.update();
expect((wrapper.find('.rc-picker-panel-container').props() as any).style.marginLeft).toEqual(
200,
expect((wrapper.find('.rc-picker-panel-container').props() as any).style.transform).toEqual(
'translateX(200px)',
);
});
});
Expand Down