@douyinfe/semi-ui 2.6.0-beta.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/button/__test__/button.test.js +7 -0
  2. package/button/buttonGroup.tsx +5 -2
  3. package/button/index.tsx +1 -1
  4. package/cascader/__test__/cascader.test.js +159 -81
  5. package/cascader/_story/cascader.stories.js +36 -23
  6. package/cascader/index.tsx +26 -5
  7. package/datePicker/_story/v2/InsetInput.jsx +104 -0
  8. package/datePicker/_story/v2/InsetInputE2E.jsx +69 -0
  9. package/datePicker/_story/v2/index.js +2 -0
  10. package/datePicker/dateInput.tsx +95 -9
  11. package/datePicker/datePicker.tsx +89 -15
  12. package/datePicker/index.tsx +15 -0
  13. package/datePicker/insetInput.tsx +76 -0
  14. package/datePicker/monthsGrid.tsx +14 -7
  15. package/dist/css/semi.css +105 -2
  16. package/dist/css/semi.min.css +1 -1
  17. package/dist/umd/semi-ui.js +949 -163
  18. package/dist/umd/semi-ui.js.map +1 -1
  19. package/dist/umd/semi-ui.min.js +1 -1
  20. package/dist/umd/semi-ui.min.js.map +1 -1
  21. package/form/hooks/useFormApi.tsx +3 -2
  22. package/input/_story/input.stories.js +13 -0
  23. package/lib/cjs/button/Button.d.ts +4 -4
  24. package/lib/cjs/button/buttonGroup.d.ts +3 -2
  25. package/lib/cjs/button/buttonGroup.js +6 -2
  26. package/lib/cjs/button/index.d.ts +5 -6
  27. package/lib/cjs/cascader/index.d.ts +1 -0
  28. package/lib/cjs/cascader/index.js +38 -9
  29. package/lib/cjs/datePicker/dateInput.d.ts +9 -2
  30. package/lib/cjs/datePicker/dateInput.js +92 -9
  31. package/lib/cjs/datePicker/datePicker.d.ts +7 -2
  32. package/lib/cjs/datePicker/datePicker.js +123 -18
  33. package/lib/cjs/datePicker/index.js +24 -2
  34. package/lib/cjs/datePicker/insetInput.d.ts +21 -0
  35. package/lib/cjs/datePicker/insetInput.js +80 -0
  36. package/lib/cjs/datePicker/monthsGrid.js +19 -7
  37. package/lib/cjs/form/hooks/useFormApi.d.ts +2 -1
  38. package/lib/cjs/iconButton/index.d.ts +2 -2
  39. package/lib/cjs/navigation/Item.d.ts +2 -2
  40. package/lib/cjs/navigation/Item.js +8 -6
  41. package/lib/cjs/navigation/SubNav.js +2 -2
  42. package/lib/cjs/radio/radioGroup.js +6 -0
  43. package/lib/cjs/select/index.js +5 -2
  44. package/lib/cjs/table/Body/index.d.ts +2 -0
  45. package/lib/cjs/table/Body/index.js +13 -4
  46. package/lib/cjs/tag/group.d.ts +2 -0
  47. package/lib/cjs/tag/group.js +4 -2
  48. package/lib/cjs/tooltip/index.js +6 -2
  49. package/lib/cjs/tree/index.js +5 -3
  50. package/lib/cjs/tree/interface.d.ts +1 -0
  51. package/lib/cjs/tree/nodeList.js +3 -1
  52. package/lib/cjs/treeSelect/index.js +11 -3
  53. package/lib/es/button/Button.d.ts +4 -4
  54. package/lib/es/button/buttonGroup.d.ts +3 -2
  55. package/lib/es/button/buttonGroup.js +5 -2
  56. package/lib/es/button/index.d.ts +5 -6
  57. package/lib/es/cascader/index.d.ts +1 -0
  58. package/lib/es/cascader/index.js +35 -6
  59. package/lib/es/datePicker/dateInput.d.ts +9 -2
  60. package/lib/es/datePicker/dateInput.js +91 -9
  61. package/lib/es/datePicker/datePicker.d.ts +7 -2
  62. package/lib/es/datePicker/datePicker.js +124 -18
  63. package/lib/es/datePicker/index.js +20 -0
  64. package/lib/es/datePicker/insetInput.d.ts +21 -0
  65. package/lib/es/datePicker/insetInput.js +65 -0
  66. package/lib/es/datePicker/monthsGrid.js +19 -7
  67. package/lib/es/form/hooks/useFormApi.d.ts +2 -1
  68. package/lib/es/iconButton/index.d.ts +2 -2
  69. package/lib/es/navigation/Item.d.ts +2 -2
  70. package/lib/es/navigation/Item.js +8 -6
  71. package/lib/es/navigation/SubNav.js +2 -2
  72. package/lib/es/radio/radioGroup.js +6 -0
  73. package/lib/es/select/index.js +5 -2
  74. package/lib/es/table/Body/index.d.ts +2 -0
  75. package/lib/es/table/Body/index.js +13 -4
  76. package/lib/es/tag/group.d.ts +2 -0
  77. package/lib/es/tag/group.js +4 -2
  78. package/lib/es/tooltip/index.js +6 -2
  79. package/lib/es/tree/index.js +5 -3
  80. package/lib/es/tree/interface.d.ts +1 -0
  81. package/lib/es/tree/nodeList.js +3 -1
  82. package/lib/es/treeSelect/index.js +11 -3
  83. package/navigation/Item.tsx +15 -12
  84. package/navigation/SubNav.tsx +4 -4
  85. package/package.json +9 -9
  86. package/radio/__test__/radioGroup.test.jsx +9 -1
  87. package/radio/_story/radio.stories.js +22 -1
  88. package/radio/radioGroup.tsx +9 -0
  89. package/select/_story/select.stories.js +73 -2
  90. package/select/index.tsx +5 -3
  91. package/table/Body/index.tsx +15 -4
  92. package/table/__test__/table.test.js +18 -0
  93. package/table/_story/v2/FixedExpandedRow/index.jsx +95 -0
  94. package/table/_story/v2/index.js +2 -1
  95. package/tag/group.tsx +5 -3
  96. package/tooltip/_story/tooltip.stories.js +702 -625
  97. package/tooltip/index.tsx +2 -2
  98. package/tree/__test__/tree.test.js +87 -2
  99. package/tree/_story/tree.stories.js +65 -5
  100. package/tree/index.tsx +4 -2
  101. package/tree/interface.ts +1 -0
  102. package/tree/nodeList.tsx +3 -2
  103. package/treeSelect/__test__/treeSelect.test.js +28 -0
  104. package/treeSelect/_story/treeSelect.stories.js +55 -2
  105. package/treeSelect/index.tsx +14 -3
@@ -1,11 +1,13 @@
1
1
  /* eslint-disable jsx-a11y/click-events-have-key-events,jsx-a11y/interactive-supports-focus */
2
2
  /* eslint-disable max-len */
3
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
4
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
3
5
  import React from 'react';
4
6
  import classnames from 'classnames';
5
7
  import PropTypes from 'prop-types';
6
- import { noop, stubFalse, isDate, get, isFunction } from 'lodash';
8
+ import { noop, stubFalse, isDate, get, isFunction, isEqual } from 'lodash';
7
9
  import ConfigContext from '../configProvider/context';
8
- import DatePickerFoundation, { DatePickerAdapter, DatePickerFoundationProps, DatePickerFoundationState, DayStatusType, PresetType, Type } from '@douyinfe/semi-foundation/datePicker/foundation';
10
+ import DatePickerFoundation, { DatePickerAdapter, DatePickerFoundationProps, DatePickerFoundationState, DayStatusType, PresetType, Type, RangeType } from '@douyinfe/semi-foundation/datePicker/foundation';
9
11
  import { cssClasses, strings, numbers } from '@douyinfe/semi-foundation/datePicker/constants';
10
12
  import { strings as popoverStrings, numbers as popoverNumbers } from '@douyinfe/semi-foundation/popover/constants';
11
13
  import BaseComponent from '../_base/baseComponent';
@@ -18,8 +20,8 @@ import Trigger from '../trigger';
18
20
  import YearAndMonth, { YearAndMonthProps } from './yearAndMonth';
19
21
  import '@douyinfe/semi-foundation/datePicker/datePicker.scss';
20
22
  import { Locale } from '../locale/interface';
21
- import { RangeType } from '@douyinfe/semi-foundation/datePicker/inputFoundation';
22
23
  import { TimePickerProps } from '../timePicker/TimePicker';
24
+ import { InsetInputValue, InsetInputChangeProps } from '@douyinfe/semi-foundation/datePicker/inputFoundation';
23
25
 
24
26
  export interface DatePickerProps extends DatePickerFoundationProps {
25
27
  'aria-describedby'?: React.AriaAttributes['aria-describedby'];
@@ -160,6 +162,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
160
162
  autoSwitchDate: true,
161
163
  syncSwitchMonth: false,
162
164
  rangeSeparator: strings.DEFAULT_SEPARATOR_RANGE,
165
+ insetInput: false,
163
166
  };
164
167
 
165
168
  triggerElRef: React.MutableRefObject<HTMLElement>;
@@ -184,7 +187,9 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
184
187
  prevTimeZone: null,
185
188
  motionEnd: false, // Monitor if popover animation ends
186
189
  rangeInputFocus: undefined, // Optional'rangeStart ',' rangeEnd ', false
187
- autofocus: props.autoFocus || (this.isRangeType(props.type, props.triggerRender) && (props.open || props.defaultOpen))
190
+ autofocus: props.autoFocus || (this.isRangeType(props.type, props.triggerRender) && (props.open || props.defaultOpen)),
191
+ insetInputValue: null,
192
+ triggerDisabled: undefined,
188
193
  };
189
194
 
190
195
  this.adapter.setCache('cachedSelectedValue', null);
@@ -255,6 +260,12 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
255
260
  updateInputValue: inputValue => {
256
261
  this.setState({ inputValue });
257
262
  },
263
+ updateInsetInputValue: (insetInputValue: InsetInputValue) => {
264
+ const { insetInput } = this.props;
265
+ if (insetInput && !isEqual(insetInputValue, this.state.insetInputValue)) {
266
+ this.setState({ insetInputValue });
267
+ }
268
+ },
258
269
  needConfirm: () =>
259
270
  ['dateTime', 'dateTimeRange'].includes(this.props.type) && this.props.needConfirm === true,
260
271
  typeIsYearOrMonth: () => ['month', 'year'].includes(this.props.type),
@@ -310,6 +321,27 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
310
321
  },
311
322
  couldPanelClosed: () => this.focusRecordsRef.current.rangeStart && this.focusRecordsRef.current.rangeEnd,
312
323
  isEventTarget: e => e && e.target === e.currentTarget,
324
+ setInsetInputFocus: () => {
325
+ const { rangeInputFocus } = this.state;
326
+ switch (rangeInputFocus) {
327
+ case 'rangeEnd':
328
+ if (document.activeElement !== this.rangeInputEndRef.current) {
329
+ const inputEndNode = get(this, 'rangeInputEndRef.current');
330
+ inputEndNode && inputEndNode.focus();
331
+ }
332
+ break;
333
+ case 'rangeStart':
334
+ default:
335
+ if (document.activeElement !== this.rangeInputStartRef.current) {
336
+ const inputStartNode = get(this, 'rangeInputStartRef.current');
337
+ inputStartNode && inputStartNode.focus();
338
+ }
339
+ break;
340
+ }
341
+ },
342
+ setTriggerDisabled: (disabled: boolean) => {
343
+ this.setState({ triggerDisabled: disabled });
344
+ }
313
345
  };
314
346
  }
315
347
 
@@ -379,7 +411,8 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
379
411
  syncSwitchMonth,
380
412
  onPanelChange,
381
413
  timeZone,
382
- triggerRender
414
+ triggerRender,
415
+ insetInput
383
416
  } = this.props;
384
417
  const { value, cachedSelectedValue, motionEnd, rangeInputFocus } = this.state;
385
418
 
@@ -426,6 +459,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
426
459
  timeZone={timeZone}
427
460
  focusRecordsRef={this.focusRecordsRef}
428
461
  triggerRender={triggerRender}
462
+ insetInput={insetInput}
429
463
  />
430
464
  );
431
465
  }
@@ -443,6 +477,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
443
477
 
444
478
  handleOpenPanel = () => this.foundation.openPanel();
445
479
  handleInputChange: DatePickerFoundation['handleInputChange'] = (...args) => this.foundation.handleInputChange(...args);
480
+ handleInsetInputChange = (options: InsetInputChangeProps) => this.foundation.handleInsetInputChange(options);
446
481
  handleInputComplete: DatePickerFoundation['handleInputComplete'] = v => this.foundation.handleInputComplete(v);
447
482
  handleInputBlur: DateInputProps['onBlur'] = e => this.foundation.handleInputBlur(get(e, 'nativeEvent.target.value'), e);
448
483
  handleInputFocus: DatePickerFoundation['handleInputFocus'] = (...args) => this.foundation.handleInputFocus(...args);
@@ -459,6 +494,25 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
459
494
  return this.focusRecordsRef.current.rangeStart;
460
495
  }
461
496
  };
497
+ handleInsetDateFocus = (e: React.FocusEvent, rangeType: 'rangeStart' | 'rangeEnd') => {
498
+ const monthGridFoundation = get(this, 'monthGrid.current.foundation');
499
+ if (monthGridFoundation) {
500
+ monthGridFoundation.showDatePanel(strings.PANEL_TYPE_LEFT);
501
+ monthGridFoundation.showDatePanel(strings.PANEL_TYPE_RIGHT);
502
+ }
503
+ this.handleInputFocus(e, rangeType);
504
+ }
505
+
506
+ handleInsetTimeFocus = () => {
507
+ const monthGridFoundation = get(this, 'monthGrid.current.foundation');
508
+ if (monthGridFoundation) {
509
+ monthGridFoundation.showTimePicker(strings.PANEL_TYPE_LEFT);
510
+ monthGridFoundation.showTimePicker(strings.PANEL_TYPE_RIGHT);
511
+ }
512
+ }
513
+ handlePanelVisibleChange = (visible: boolean) => {
514
+ this.foundation.handlePanelVisibleChange(visible);
515
+ }
462
516
 
463
517
  renderInner(extraProps?: Partial<DatePickerProps>) {
464
518
  const {
@@ -478,16 +532,18 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
478
532
  triggerRender,
479
533
  size,
480
534
  inputReadOnly,
481
- rangeSeparator
535
+ rangeSeparator,
536
+ insetInput,
482
537
  } = this.props;
483
- const { value, inputValue, rangeInputFocus } = this.state;
538
+ const { value, inputValue, rangeInputFocus, triggerDisabled } = this.state;
484
539
  // This class is not needed when triggerRender is function
485
540
  const isRangeType = this.isRangeType(type, triggerRender);
541
+ const inputDisabled = disabled || insetInput && triggerDisabled;
486
542
  const inputCls = classnames(`${cssClasses.PREFIX}-input`, {
487
543
  [`${cssClasses.PREFIX}-range-input`]: isRangeType,
488
544
  [`${cssClasses.PREFIX}-range-input-${size}`]: isRangeType && size,
489
- [`${cssClasses.PREFIX}-range-input-active`]: isRangeType && rangeInputFocus && !disabled,
490
- [`${cssClasses.PREFIX}-range-input-disabled`]: isRangeType && disabled,
545
+ [`${cssClasses.PREFIX}-range-input-active`]: isRangeType && rangeInputFocus && !inputDisabled,
546
+ [`${cssClasses.PREFIX}-range-input-disabled`]: isRangeType && inputDisabled,
491
547
  [`${cssClasses.PREFIX}-range-input-${validateStatus}`]: isRangeType && validateStatus,
492
548
  });
493
549
  const phText = placeholder || locale.placeholder[type]; // i18n
@@ -495,9 +551,9 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
495
551
  const props = {
496
552
  ...extraProps,
497
553
  placeholder: phText,
498
- disabled,
554
+ disabled: inputDisabled,
499
555
  inputValue,
500
- value,
556
+ value: value as Date[],
501
557
  onChange: this.handleInputChange,
502
558
  onEnterPress: this.handleInputComplete,
503
559
  // TODO: remove in next major version
@@ -510,7 +566,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
510
566
  format,
511
567
  multiple,
512
568
  validateStatus,
513
- inputReadOnly,
569
+ inputReadOnly: inputReadOnly || insetInput,
514
570
  // onClick: this.handleOpenPanel,
515
571
  onBlur: this.handleInputBlur,
516
572
  onFocus: this.handleInputFocus,
@@ -519,13 +575,13 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
519
575
  size,
520
576
  autofocus: this.state.autofocus,
521
577
  dateFnsLocale,
522
- rangeInputStartRef: this.rangeInputStartRef,
523
- rangeInputEndRef: this.rangeInputEndRef,
524
578
  rangeInputFocus,
525
579
  rangeSeparator,
526
580
  onRangeBlur: this.handleRangeInputBlur,
527
581
  onRangeClear: this.handleRangeInputClear,
528
582
  onRangeEndTabPress: this.handleRangeEndTabPress,
583
+ rangeInputStartRef: insetInput ? null : this.rangeInputStartRef,
584
+ rangeInputEndRef: insetInput ? null : this.rangeInputEndRef,
529
585
  };
530
586
 
531
587
  return (
@@ -572,7 +628,8 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
572
628
  };
573
629
 
574
630
  renderPanel = (locale: Locale['DatePicker'], localeCode: string, dateFnsLocale: Locale['dateFnsLocale']) => {
575
- const { dropdownClassName, dropdownStyle, density, topSlot, bottomSlot } = this.props;
631
+ const { dropdownClassName, dropdownStyle, density, topSlot, bottomSlot, insetInput, type, format, rangeSeparator } = this.props;
632
+ const { insetInputValue, value } = this.state;
576
633
  const wrapCls = classnames(
577
634
  cssClasses.PREFIX,
578
635
  {
@@ -582,9 +639,25 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
582
639
  dropdownClassName
583
640
  );
584
641
 
642
+ const insetInputProps = {
643
+ dateFnsLocale,
644
+ format,
645
+ insetInputValue,
646
+ rangeSeparator,
647
+ type,
648
+ value: value as Date[],
649
+ handleInsetDateFocus: this.handleInsetDateFocus,
650
+ handleInsetTimeFocus: this.handleInsetTimeFocus,
651
+ onInsetInputChange: this.handleInsetInputChange,
652
+ rangeInputStartRef: this.rangeInputStartRef,
653
+ rangeInputEndRef: this.rangeInputEndRef,
654
+ density,
655
+ };
656
+
585
657
  return (
586
658
  <div ref={this.panelRef} className={wrapCls} style={dropdownStyle}>
587
659
  {topSlot && <div className={`${cssClasses.PREFIX}-topSlot`}>{topSlot}</div>}
660
+ {insetInput && <DateInput {...insetInputProps} insetInput={true} />}
588
661
  {this.adapter.typeIsYearOrMonth() ?
589
662
  this.renderYearMonthPanel(locale, localeCode) :
590
663
  this.renderMonthGrid(locale, localeCode, dateFnsLocale)}
@@ -653,6 +726,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
653
726
  visible={panelShow}
654
727
  stopPropagation={stopPropagation}
655
728
  spacing={spacing}
729
+ onVisibleChange={this.handlePanelVisibleChange}
656
730
  >
657
731
  {children}
658
732
  </Popover>
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { forwardStatics } from '@douyinfe/semi-foundation/utils/object';
4
+ import { numbers, strings } from '@douyinfe/semi-foundation/datePicker/constants';
4
5
  import DatePicker, { DatePickerProps } from './datePicker';
5
6
  import ConfigContext from '../configProvider/context';
6
7
  import LocaleConsumer from '../locale/localeConsumer';
@@ -33,6 +34,20 @@ export default forwardStatics(
33
34
  propsObj.rangeSeparator = ` ${rangeSeparator.trim()} `;
34
35
  }
35
36
 
37
+ if (propsObj.insetInput) {
38
+ if (!propsObj.position) {
39
+ propsObj.position = strings.POSITION_INLINE_INPUT;
40
+ }
41
+ /**
42
+ * When insetInput is `true` and `position` includes `over`, use 1px `spacing` to solve the problem of border-radius leakage in the upper left corner
43
+ *
44
+ * @see https://user-images.githubusercontent.com/26477537/158817185-126a5f33-41f7-414a-8e36-8d1be2dda5cd.png
45
+ */
46
+ if (propsObj.position.includes('Over') && !propsObj.spacing) {
47
+ propsObj.spacing = numbers.SPACING_INSET_INPUT;
48
+ }
49
+ }
50
+
36
51
  return (
37
52
  <ConfigContext.Consumer>
38
53
  {({ timeZone }: { timeZone?: string | number }) => (
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import { get } from 'lodash';
3
+
4
+ import {
5
+ InsetInputValue,
6
+ Type,
7
+ InsetInputChangeFoundationProps,
8
+ } from '@douyinfe/semi-foundation/datePicker/inputFoundation';
9
+ import Input, { InputProps } from '../input';
10
+
11
+ export interface InsetDateInputProps {
12
+ forwardRef: InputProps['forwardRef'];
13
+ insetInputValue: InsetInputValue;
14
+ placeholder: string;
15
+ valuePath: string;
16
+ onChange: (options: InsetInputChangeFoundationProps) => void;
17
+ onFocus: InputProps['onFocus'];
18
+ }
19
+
20
+ export interface InsetTimeInputProps {
21
+ disabled: boolean;
22
+ insetInputValue: InsetInputValue;
23
+ placeholder: string;
24
+ valuePath: string;
25
+ type: Type;
26
+ onChange: (options: InsetInputChangeFoundationProps) => void;
27
+ onFocus: InputProps['onFocus'];
28
+ }
29
+
30
+ export function InsetDateInput(props: InsetDateInputProps) {
31
+ const { insetInputValue, valuePath, onFocus, onChange, placeholder, forwardRef } = props;
32
+ const value = get(insetInputValue, valuePath);
33
+
34
+ return (
35
+ <Input
36
+ value={value}
37
+ onChange={(value, event) => {
38
+ onChange({
39
+ value,
40
+ event,
41
+ insetInputValue,
42
+ valuePath,
43
+ });
44
+ }}
45
+ onFocus={onFocus}
46
+ placeholder={placeholder}
47
+ ref={forwardRef}
48
+ />
49
+ );
50
+ }
51
+
52
+ export function InsetTimeInput(props: InsetTimeInputProps) {
53
+ const { insetInputValue, valuePath, type, onFocus, onChange, placeholder, disabled } = props;
54
+ const _isTimeType = type.includes('Time');
55
+ if (!_isTimeType) {
56
+ return null;
57
+ }
58
+ const value = get(insetInputValue, valuePath);
59
+
60
+ return (
61
+ <Input
62
+ value={value}
63
+ onChange={(value, event) => {
64
+ onChange({
65
+ value,
66
+ event,
67
+ insetInputValue,
68
+ valuePath,
69
+ });
70
+ }}
71
+ onFocus={onFocus}
72
+ placeholder={placeholder}
73
+ disabled={disabled}
74
+ />
75
+ );
76
+ }
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable jsx-a11y/interactive-supports-focus,jsx-a11y/click-events-have-key-events */
2
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
2
3
  /* eslint-disable react/no-did-update-set-state */
3
4
  /* eslint-disable max-len */
4
5
  /* eslint-disable no-nested-ternary */
@@ -274,6 +275,7 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
274
275
  renderPanel(month: Date, panelType: PanelType) {
275
276
  let monthCls = classnames(`${prefixCls}-month-grid-${panelType}`);
276
277
  const { monthLeft, monthRight, currentPanelHeight } = this.state;
278
+ const { insetInput } = this.props;
277
279
  const panelDetail = panelType === strings.PANEL_TYPE_RIGHT ? monthRight : monthLeft;
278
280
  const { isTimePickerOpen, isYearPickerOpen } = panelDetail;
279
281
 
@@ -296,7 +298,7 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
296
298
  style.minWidth = wrap.getBoundingClientRect().width;
297
299
  }
298
300
 
299
- if (this.leftIsYearOrTime() && this.rightIsYearOrTime()) {
301
+ if (this.leftIsYearOrTime() && this.rightIsYearOrTime() && !insetInput) {
300
302
  /**
301
303
  * left和right同时为tpk时,panel会有一个minHeight
302
304
  * 如果缓存的currentPanelHeight为0,则需要计算滚动列表的高度
@@ -306,7 +308,7 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
306
308
  * When left and right are tpk at the same time, the panel will have a minHeight
307
309
  * If the cached currentPanelHeight is 0, you need to calculate the height of the scrolling list
308
310
  * If there is a cached value, use currentPanelHeight (if this height is less than the actual value, it will affect the number of cycles in the ScrollList to render the list)
309
- * See packages/semi-foundation/scrollList/itemF oundation.js initWheelList function
311
+ * See packages/semi-foundation/scrollList/itemFoundation.js initWheelList function
310
312
  */
311
313
 
312
314
  style.minHeight = currentPanelHeight ? currentPanelHeight : this.calcScrollListHeight();
@@ -319,8 +321,11 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
319
321
  monthCls = classnames(monthCls, `${prefixCls}-yam-showing`);
320
322
  }
321
323
 
324
+ const _isDatePanelOpen = !(isYearPickerOpen || isTimePickerOpen);
325
+ const xOpenType = _isDatePanelOpen ? 'date' : isYearPickerOpen ? 'year' : 'time';
326
+
322
327
  return (
323
- <div className={monthCls} key={panelType} style={style}>
328
+ <div className={monthCls} key={panelType} style={style} x-open-type={xOpenType}>
324
329
  {yearAndMonthLayer}
325
330
  {timePickerLayer}
326
331
  {/* {isYearPickerOpen || isTimePickerOpen ? null : panelContent} */}
@@ -536,9 +541,9 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
536
541
 
537
542
  renderSwitch(panelType: PanelType) {
538
543
  const { rangeStart, rangeEnd, monthLeft, monthRight } = this.state;
539
- const { type, locale, disabledTimePicker, density, dateFnsLocale } = this.props;
540
- // Type: date, dateRange, year, month, no rendering required
541
- if (!type.includes('Time')) {
544
+ const { type, locale, disabledTimePicker, density, dateFnsLocale, insetInput } = this.props;
545
+ // Type: date, dateRange, year, month, inset input no rendering required
546
+ if (!type.includes('Time') || insetInput) {
542
547
  return null;
543
548
  }
544
549
 
@@ -606,7 +611,7 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
606
611
 
607
612
  render() {
608
613
  const { monthLeft, monthRight } = this.state;
609
- const { type } = this.props;
614
+ const { type, insetInput } = this.props;
610
615
  const monthGridCls = classnames({
611
616
  [`${prefixCls }-month-grid`]: true,
612
617
  });
@@ -630,6 +635,8 @@ export default class MonthsGrid extends BaseComponent<MonthsGridProps, MonthsGri
630
635
  className={monthGridCls}
631
636
  x-type={type}
632
637
  x-panel-yearandmonth-open-type={yearOpenType}
638
+ // FIXME:
639
+ x-insetInput={insetInput ? "true" : "false"}
633
640
  ref={current => this.cacheRefCurrent('monthGrid', current)}
634
641
  >
635
642
  {content}
package/dist/css/semi.css CHANGED
@@ -3447,6 +3447,7 @@ body[theme-mode=dark], body .semi-always-dark {
3447
3447
  .semi-datepicker {
3448
3448
  box-sizing: border-box;
3449
3449
  display: inline-block;
3450
+ vertical-align: top;
3450
3451
  }
3451
3452
  .semi-datepicker-month-grid {
3452
3453
  user-select: none;
@@ -3472,6 +3473,24 @@ body[theme-mode=dark], body .semi-always-dark {
3472
3473
  .semi-datepicker-month-grid[x-type=date] .semi-datepicker-yam-showing {
3473
3474
  min-height: 325px;
3474
3475
  }
3476
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-left[x-open-type=year],
3477
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-right[x-open-type=year] {
3478
+ min-height: 312px;
3479
+ }
3480
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-left[x-open-type=time],
3481
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-right[x-open-type=time] {
3482
+ min-height: 314px;
3483
+ }
3484
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-navigation {
3485
+ padding-top: 8px;
3486
+ padding-bottom: 8px;
3487
+ }
3488
+ .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-tpk {
3489
+ min-height: 100%;
3490
+ }
3491
+ .semi-datepicker-month-grid[x-insetInput=true][x-type=dateTime] .semi-datepicker-yam, .semi-datepicker-month-grid[x-insetInput=true][x-type=dateTimeRange] .semi-datepicker-yam {
3492
+ height: 100%;
3493
+ }
3475
3494
  .semi-datepicker-month-grid .semi-datepicker-yearmonth-header {
3476
3495
  background: var(--semi-color-bg-3);
3477
3496
  padding: 12px 16px;
@@ -3513,6 +3532,7 @@ body[theme-mode=dark], body .semi-always-dark {
3513
3532
  line-height: 20px;
3514
3533
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
3515
3534
  min-height: 24px;
3535
+ line-height: 24px;
3516
3536
  }
3517
3537
  .semi-datepicker-month-grid[x-panel-yearandmonth-open-type=left] .semi-datepicker-weeks, .semi-datepicker-month-grid[x-panel-yearandmonth-open-type=right] .semi-datepicker-weeks {
3518
3538
  min-height: 216px;
@@ -3813,6 +3833,34 @@ body[theme-mode=dark], body .semi-always-dark {
3813
3833
  .semi-datepicker .semi-datepicker-input-readonly {
3814
3834
  cursor: pointer;
3815
3835
  }
3836
+ .semi-datepicker-inset-input-wrapper {
3837
+ display: flex;
3838
+ flex-wrap: nowrap;
3839
+ justify-content: space-between;
3840
+ box-sizing: border-box;
3841
+ column-gap: 8px;
3842
+ padding: 12px 16px;
3843
+ padding-bottom: 0;
3844
+ width: 284px;
3845
+ }
3846
+ .semi-datepicker-inset-input-wrapper[x-type=dateRange], .semi-datepicker-inset-input-wrapper[x-type=dateTimeRange] {
3847
+ width: 568px;
3848
+ }
3849
+ .semi-datepicker-inset-input-wrapper[x-type=month] {
3850
+ width: 204px;
3851
+ }
3852
+ .semi-datepicker-inset-input-wrapper .semi-input-wrapper {
3853
+ flex: 1;
3854
+ flex-shrink: 0;
3855
+ }
3856
+ .semi-datepicker-inset-input-separator {
3857
+ flex-grow: 0;
3858
+ flex-shrink: 0;
3859
+ height: 32px;
3860
+ line-height: 32px;
3861
+ padding: 0 4px;
3862
+ color: var(--semi-color-text-3);
3863
+ }
3816
3864
  .semi-datepicker-range-input {
3817
3865
  display: flex;
3818
3866
  align-items: center;
@@ -4015,6 +4063,23 @@ body[theme-mode=dark], body .semi-always-dark {
4015
4063
  .semi-datepicker-compact .semi-datepicker-month-grid[x-panel-yearandmonth-open-type=left] .semi-datepicker-weeks, .semi-datepicker-compact .semi-datepicker-month-grid[x-panel-yearandmonth-open-type=right] .semi-datepicker-weeks {
4016
4064
  min-height: 168px;
4017
4065
  }
4066
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-left[x-open-type=year],
4067
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-right[x-open-type=year] {
4068
+ min-height: 236px;
4069
+ }
4070
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-left[x-open-type=time],
4071
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-month-grid-right[x-open-type=time] {
4072
+ min-height: 236px;
4073
+ }
4074
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-yam-showing {
4075
+ min-height: 236px;
4076
+ }
4077
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true] .semi-datepicker-tpk {
4078
+ min-height: 100%;
4079
+ }
4080
+ .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true][x-type=dateTime] .semi-datepicker-yam, .semi-datepicker-compact .semi-datepicker-month-grid[x-insetInput=true][x-type=dateTimeRange] .semi-datepicker-yam {
4081
+ height: 100%;
4082
+ }
4018
4083
  .semi-datepicker-compact.semi-datepicker-panel-yam .semi-scrolllist {
4019
4084
  font-size: 12px;
4020
4085
  line-height: 16px;
@@ -4130,11 +4195,42 @@ body[theme-mode=dark], body .semi-always-dark {
4130
4195
  padding-right: 8px;
4131
4196
  padding-bottom: 10px;
4132
4197
  }
4198
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper {
4199
+ column-gap: 4px;
4200
+ padding: 8px 8px;
4201
+ padding-bottom: 0;
4202
+ width: 216px;
4203
+ }
4204
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper[x-type=dateRange], .semi-datepicker-compact .semi-datepicker-inset-input-wrapper[x-type=dateTimeRange] {
4205
+ width: 432px;
4206
+ padding-top: 0;
4207
+ }
4208
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper[x-type=dateRange] .semi-input-wrapper, .semi-datepicker-compact .semi-datepicker-inset-input-wrapper[x-type=dateTimeRange] .semi-input-wrapper {
4209
+ margin-top: 8px;
4210
+ }
4211
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper[x-type=month] {
4212
+ width: 195px;
4213
+ }
4214
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper .semi-input-wrapper {
4215
+ height: 28px;
4216
+ box-sizing: border-box;
4217
+ }
4218
+ .semi-datepicker-compact .semi-datepicker-inset-input-wrapper .semi-input-wrapper .semi-input {
4219
+ font-size: 12px;
4220
+ line-height: 26px;
4221
+ height: 26px;
4222
+ vertical-align: top;
4223
+ }
4224
+ .semi-datepicker-compact .semi-datepicker-inset-input-separator {
4225
+ border-left: 1px solid var(--semi-color-border);
4226
+ transform: translateX(50%);
4227
+ height: auto;
4228
+ }
4133
4229
 
4134
- .semi-popover-wrapper[x-placement*=top] .semi-datepicker .semi-datepicker-weeks, .semi-popover-wrapper[x-placement*=Top] .semi-datepicker .semi-datepicker-weeks {
4230
+ .semi-popover-wrapper[x-placement^=top] .semi-datepicker .semi-datepicker-weeks, .semi-popover-wrapper[x-placement=leftTop] .semi-datepicker .semi-datepicker-weeks, .semi-popover-wrapper[x-placement=rightTop] .semi-datepicker .semi-datepicker-weeks, .semi-popover-wrapper[x-placement*=BottomOver] .semi-datepicker .semi-datepicker-weeks {
4135
4231
  min-height: 216px;
4136
4232
  }
4137
- .semi-popover-wrapper[x-placement*=top] .semi-datepicker-compact .semi-datepicker-weeks, .semi-popover-wrapper[x-placement*=Top] .semi-datepicker-compact .semi-datepicker-weeks {
4233
+ .semi-popover-wrapper[x-placement^=top] .semi-datepicker-compact .semi-datepicker-weeks, .semi-popover-wrapper[x-placement=leftTop] .semi-datepicker-compact .semi-datepicker-weeks, .semi-popover-wrapper[x-placement=rightTop] .semi-datepicker-compact .semi-datepicker-weeks, .semi-popover-wrapper[x-placement*=BottomOver] .semi-datepicker-compact .semi-datepicker-weeks {
4138
4234
  min-height: 168px;
4139
4235
  }
4140
4236
 
@@ -4280,6 +4376,12 @@ body[theme-mode=dark], body .semi-always-dark {
4280
4376
  padding-left: 8px;
4281
4377
  padding-right: auto;
4282
4378
  }
4379
+ .semi-rtl .semi-datepicker-compact .semi-datepicker-inset-input-separator,
4380
+ .semi-portal-rtl .semi-datepicker-compact .semi-datepicker-inset-input-separator {
4381
+ border-right: 1px solid var(--semi-color-border);
4382
+ border-left: 0;
4383
+ transform: translateX(-50%);
4384
+ }
4283
4385
 
4284
4386
  .semi-descriptions {
4285
4387
  line-height: 20px;
@@ -17055,6 +17157,7 @@ body[theme-mode=dark], body .semi-always-dark {
17055
17157
  user-select: none;
17056
17158
  overflow: hidden;
17057
17159
  white-space: nowrap;
17160
+ vertical-align: bottom;
17058
17161
  }
17059
17162
  .semi-tag-default, .semi-tag-small {
17060
17163
  font-size: 12px;