Просмотр исходного кода

fix(datepicker): dateRange triggerRender close panel bug #410 (#448)

走鹃 3 лет назад
Родитель
Сommit
44dbd8e37d

+ 10 - 3
packages/semi-foundation/datePicker/monthsGridFoundation.ts

@@ -16,7 +16,7 @@ import {
 import { isBefore, isValidDate, getDefaultFormatToken, getFullDateOffset } from './_utils/index';
 import { formatFullDate, WeekStartNumber } from './_utils/getMonthTable';
 import { compatiableParse } from './_utils/parser';
-import { includes, isSet, isEqual } from 'lodash';
+import { includes, isSet, isEqual, isFunction } from 'lodash';
 import { zonedTimeToUtc } from '../utils/date-fns-extra';
 import { getDefaultFormatTokenByType } from './_utils/getDefaultFormatToken';
 import isNullOrUndefined from '../utils/isNullOrUndefined';
@@ -85,6 +85,7 @@ export interface MonthsGridFoundationProps extends MonthsGridElementProps {
     setRangeInputFocus?: (rangeInputFocus: 'rangeStart' | 'rangeEnd') => void;
     isAnotherPanelHasOpened?: (currentRangeInput: 'rangeStart' | 'rangeEnd') => boolean;
     focusRecordsRef?: any;
+    triggerRender?: (props: Record<string, any>) => any;
 }
 
 export interface MonthInfo {
@@ -636,7 +637,7 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
 
     handleRangeSelected(day: MonthDayInfo) {
         let { rangeStart, rangeEnd } = this.getStates();
-        const { startDateOffset, endDateOffset, type, dateFnsLocale, rangeInputFocus } = this.getProps();
+        const { startDateOffset, endDateOffset, type, dateFnsLocale, rangeInputFocus, triggerRender } = this._adapter.getProps();
         const { fullDate } = day;
         let rangeStartReset = false;
         let rangeEndReset = false;
@@ -712,7 +713,13 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
                     date = [start, end];
                 }
             }
-            this._adapter.notifySelectedChange(date, { needCheckFocusRecord: !(type === 'dateRange' && isDateRangeAndHasOffset) });
+            /**
+             * no need to check focus then
+             *  - dateRange and isDateRangeAndHasOffset
+             *  - dateRange and triggerRender
+             */
+            const needCheckFocusRecord = !(type === 'dateRange' && (isDateRangeAndHasOffset || isFunction(triggerRender)));
+            this._adapter.notifySelectedChange(date, { needCheckFocusRecord });
         }
     }
 

+ 28 - 0
packages/semi-ui/datePicker/__test__/datePicker.test.js

@@ -968,4 +968,32 @@ describe(`DatePicker`, () => {
 
     it('test month sync change dateRange type', () => { testMonthSyncChange('dateRange') });
     it('test month sync change dateTimeRange type', () => { testMonthSyncChange('dateTimeRange')});
+    it('test dateRange triggerRender', async () => {
+        const elem = mount(
+            <DatePicker
+                motion={false}
+                // defaultOpen
+                type="dateRange"
+                triggerRender={({ placeholder }) => (
+                    <button>
+                        {placeholder}
+                    </button>
+                )}
+            />
+        );
+        const trigger = document.querySelector('button');
+        trigger.click();
+        await sleep();
+        const leftPanel = document.querySelector(`.${BASE_CLASS_PREFIX}-datepicker-month-grid-left`);
+        const leftSecondWeek = leftPanel.querySelectorAll(`.${BASE_CLASS_PREFIX}-datepicker-week`)[1];
+        const leftSecondWeekDays = leftSecondWeek.querySelectorAll(`.${BASE_CLASS_PREFIX}-datepicker-day`);
+        const rightPanel = document.querySelector(`.${BASE_CLASS_PREFIX}-datepicker-month-grid-right`);
+        const rightSecondWeek = rightPanel.querySelectorAll(`.${BASE_CLASS_PREFIX}-datepicker-week`)[1];
+        const rightSecondWeekDays = rightSecondWeek.querySelectorAll(`.${BASE_CLASS_PREFIX}-datepicker-day`);
+        leftSecondWeekDays[0].click();
+        rightSecondWeekDays[0].click();
+
+        const baseElem = elem.find(BaseDatePicker);
+        expect(baseElem.state('panelShow')).toBeFalsy();
+    });
 });

+ 40 - 1
packages/semi-ui/datePicker/_story/datePicker.stories.js

@@ -10,7 +10,7 @@ import {
   startOfWeek,
   endOfWeek,
 } from 'date-fns';
-import { Space, ConfigProvider, InputGroup, InputNumber, Form, withField } from '../../index';
+import { Space, ConfigProvider, InputGroup, InputNumber, Form, withField, Button } from '../../index';
 
 // stores
 import NeedConfirmDemo from './NeedConfirm';
@@ -723,3 +723,42 @@ export const FixNeedConfirm = () => {
   )
 }
 FixNeedConfirm.storyName = '修复 needConfirm 取消后输入框显示错误';
+
+/**
+ * fix https://github.com/DouyinFE/semi-design/issues/410
+ */
+export const FixTriggerRenderClosePanel = () => {
+  const [value, setValue] = useState([]);
+
+  const handleChange = v => {
+    console.log('change', v);
+    setValue(v);
+  };
+
+  const formatValue = (dates) => {
+    const dateStrs = dates.map(v => String(v));
+    return dateStrs.join(' ~ ');
+  };
+
+  const showClear = Array.isArray(value) && value.length > 1;
+
+  return (
+    <Space>
+      <DatePicker
+        value={value}
+        type="dateRange"
+        onChange={handleChange}
+        motion={false}
+        triggerRender={({ placeholder }) => (
+            <Button>
+                {(value && formatValue(value)) || placeholder}
+            </Button>
+        )}
+      />
+      {showClear && (
+        <Button onClick={() => setValue([])}>清除</Button>
+      )}
+    </Space>
+  );
+};
+FixTriggerRenderClosePanel.storyName = "fix triggerRender close bug"

+ 2 - 0
packages/semi-ui/datePicker/datePicker.tsx

@@ -363,6 +363,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
             syncSwitchMonth,
             onPanelChange,
             timeZone,
+            triggerRender
         } = this.props;
         const { value, cachedSelectedValue, motionEnd, rangeInputFocus } = this.state;
 
@@ -408,6 +409,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
                 onPanelChange={onPanelChange}
                 timeZone={timeZone}
                 focusRecordsRef={this.focusRecordsRef}
+                triggerRender={triggerRender}
             />
         );
     }

+ 2 - 1
packages/semi-ui/datePicker/monthsGrid.tsx

@@ -71,7 +71,8 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
         syncSwitchMonth: PropTypes.bool,
         // Callback function for panel date switching
         onPanelChange: PropTypes.func,
-        focusRecordsRef: PropTypes.object
+        focusRecordsRef: PropTypes.object,
+        triggerRender: PropTypes.func,
     };
 
     static defaultProps = {