@douyinfe/semi-foundation 2.1.6-alpha.0 → 2.2.1
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.
- package/cascader/cascader.scss +1 -1
- package/cascader/constants.ts +4 -0
- package/cascader/foundation.ts +29 -15
- package/cascader/util.ts +13 -0
- package/datePicker/_utils/parser.ts +4 -3
- package/datePicker/datePicker.scss +29 -0
- package/datePicker/foundation.ts +31 -11
- package/datePicker/inputFoundation.ts +2 -0
- package/datePicker/monthsGridFoundation.ts +101 -8
- package/datePicker/rtl.scss +15 -1
- package/datePicker/variables.scss +2 -0
- package/gulpfile.js +3 -1
- package/lib/cjs/cascader/cascader.css +2 -2
- package/lib/cjs/cascader/cascader.scss +1 -1
- package/lib/cjs/cascader/constants.d.ts +3 -0
- package/lib/cjs/cascader/constants.js +6 -1
- package/lib/cjs/cascader/foundation.d.ts +4 -1
- package/lib/cjs/cascader/foundation.js +24 -11
- package/lib/cjs/cascader/util.d.ts +1 -0
- package/lib/cjs/cascader/util.js +17 -0
- package/lib/cjs/datePicker/_utils/parser.d.ts +6 -1
- package/lib/cjs/datePicker/_utils/parser.js +3 -1
- package/lib/cjs/datePicker/datePicker.css +32 -3
- package/lib/cjs/datePicker/datePicker.scss +29 -0
- package/lib/cjs/datePicker/foundation.d.ts +6 -3
- package/lib/cjs/datePicker/foundation.js +40 -14
- package/lib/cjs/datePicker/inputFoundation.js +3 -0
- package/lib/cjs/datePicker/monthsGridFoundation.d.ts +35 -3
- package/lib/cjs/datePicker/monthsGridFoundation.js +139 -6
- package/lib/cjs/datePicker/rtl.scss +15 -1
- package/lib/cjs/datePicker/variables.scss +2 -0
- package/lib/cjs/navigation/navigation.css +0 -1
- package/lib/cjs/notification/notification.css +8 -4
- package/lib/cjs/notification/notification.scss +9 -5
- package/lib/cjs/notification/variables.scss +1 -0
- package/lib/cjs/select/foundation.d.ts +10 -1
- package/lib/cjs/select/foundation.js +11 -9
- package/lib/cjs/table/table.css +0 -2
- package/lib/cjs/table/table.scss +0 -2
- package/lib/cjs/tree/treeUtil.js +14 -14
- package/lib/cjs/upload/foundation.d.ts +1 -0
- package/lib/cjs/upload/foundation.js +106 -0
- package/lib/cjs/upload/rtl.scss +0 -4
- package/lib/cjs/upload/upload.css +30 -18
- package/lib/cjs/upload/upload.scss +31 -8
- package/lib/cjs/upload/variables.scss +5 -1
- package/lib/es/cascader/cascader.css +2 -2
- package/lib/es/cascader/cascader.scss +1 -1
- package/lib/es/cascader/constants.d.ts +3 -0
- package/lib/es/cascader/constants.js +6 -1
- package/lib/es/cascader/foundation.d.ts +4 -1
- package/lib/es/cascader/foundation.js +24 -12
- package/lib/es/cascader/util.d.ts +1 -0
- package/lib/es/cascader/util.js +14 -0
- package/lib/es/datePicker/_utils/parser.d.ts +6 -1
- package/lib/es/datePicker/_utils/parser.js +3 -1
- package/lib/es/datePicker/datePicker.css +32 -3
- package/lib/es/datePicker/datePicker.scss +29 -0
- package/lib/es/datePicker/foundation.d.ts +6 -3
- package/lib/es/datePicker/foundation.js +40 -14
- package/lib/es/datePicker/inputFoundation.js +3 -0
- package/lib/es/datePicker/monthsGridFoundation.d.ts +35 -3
- package/lib/es/datePicker/monthsGridFoundation.js +139 -6
- package/lib/es/datePicker/rtl.scss +15 -1
- package/lib/es/datePicker/variables.scss +2 -0
- package/lib/es/navigation/navigation.css +0 -1
- package/lib/es/notification/notification.css +8 -4
- package/lib/es/notification/notification.scss +9 -5
- package/lib/es/notification/variables.scss +1 -0
- package/lib/es/select/foundation.d.ts +10 -1
- package/lib/es/select/foundation.js +12 -9
- package/lib/es/table/table.css +0 -2
- package/lib/es/table/table.scss +0 -2
- package/lib/es/tree/treeUtil.js +13 -12
- package/lib/es/upload/foundation.d.ts +1 -0
- package/lib/es/upload/foundation.js +107 -0
- package/lib/es/upload/rtl.scss +0 -4
- package/lib/es/upload/upload.css +30 -18
- package/lib/es/upload/upload.scss +31 -8
- package/lib/es/upload/variables.scss +5 -1
- package/notification/notification.scss +9 -5
- package/notification/variables.scss +1 -0
- package/package.json +4 -4
- package/select/foundation.ts +11 -9
- package/table/table.scss +0 -2
- package/tree/treeUtil.ts +6 -2
- package/upload/foundation.ts +81 -0
- package/upload/rtl.scss +0 -4
- package/upload/upload.scss +31 -8
- package/upload/variables.scss +5 -1
package/cascader/cascader.scss
CHANGED
package/cascader/constants.ts
CHANGED
|
@@ -12,6 +12,10 @@ const strings = {
|
|
|
12
12
|
IS_VALUE: 'isValue',
|
|
13
13
|
SHOW_NEXT_BY_CLICK: 'click',
|
|
14
14
|
SHOW_NEXT_BY_HOVER: 'hover',
|
|
15
|
+
/* Merge Type */
|
|
16
|
+
LEAF_ONLY_MERGE_TYPE: 'leafOnly',
|
|
17
|
+
AUTO_MERGE_VALUE_MERGE_TYPE: 'autoMergeValue',
|
|
18
|
+
NONE_MERGE_TYPE: 'none',
|
|
15
19
|
} as const;
|
|
16
20
|
|
|
17
21
|
const numbers = {};
|
package/cascader/foundation.ts
CHANGED
|
@@ -14,8 +14,11 @@ import {
|
|
|
14
14
|
convertDataToEntities,
|
|
15
15
|
findKeysForValues,
|
|
16
16
|
normalizedArr,
|
|
17
|
-
isValid
|
|
17
|
+
isValid,
|
|
18
|
+
calcMergeType
|
|
18
19
|
} from './util';
|
|
20
|
+
import { strings } from './constants';
|
|
21
|
+
|
|
19
22
|
export interface BasicData {
|
|
20
23
|
data: BasicCascaderData;
|
|
21
24
|
disabled: boolean;
|
|
@@ -99,6 +102,7 @@ export interface BasicScrollPanelProps {
|
|
|
99
102
|
export interface BasicCascaderProps {
|
|
100
103
|
mouseEnterDelay?: number;
|
|
101
104
|
mouseLeaveDelay?: number;
|
|
105
|
+
separator?: string;
|
|
102
106
|
arrowIcon?: any;
|
|
103
107
|
changeOnSelect?: boolean;
|
|
104
108
|
multiple?: boolean;
|
|
@@ -138,6 +142,8 @@ export interface BasicCascaderProps {
|
|
|
138
142
|
topSlot?: any;
|
|
139
143
|
showNext?: ShowNextType;
|
|
140
144
|
disableStrictly?: boolean;
|
|
145
|
+
leafOnly?: boolean;
|
|
146
|
+
enableLeafClick?: boolean;
|
|
141
147
|
onClear?: () => void;
|
|
142
148
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
143
149
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -168,7 +174,7 @@ export interface BasicCascaderInnerData {
|
|
|
168
174
|
isHovering: boolean;
|
|
169
175
|
checkedKeys: Set<string>;
|
|
170
176
|
halfCheckedKeys: Set<string>;
|
|
171
|
-
|
|
177
|
+
resolvedCheckedKeys: Set<string>;
|
|
172
178
|
loadedKeys: Set<string>;
|
|
173
179
|
loadingKeys: Set<string>;
|
|
174
180
|
loading: boolean;
|
|
@@ -601,10 +607,11 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
601
607
|
}
|
|
602
608
|
|
|
603
609
|
_defaultRenderText(path: any[], displayRender?: BasicCascaderProps['displayRender']) {
|
|
610
|
+
const separator = this.getProp('separator');
|
|
604
611
|
if (displayRender && typeof displayRender === 'function') {
|
|
605
612
|
return displayRender(path);
|
|
606
613
|
} else {
|
|
607
|
-
return path.join(
|
|
614
|
+
return path.join(separator);
|
|
608
615
|
}
|
|
609
616
|
}
|
|
610
617
|
|
|
@@ -649,7 +656,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
649
656
|
}
|
|
650
657
|
|
|
651
658
|
handleSingleSelect(e: any, item: BasicEntity | BasicData) {
|
|
652
|
-
const { changeOnSelect: allowChange, filterLeafOnly, multiple } = this.getProps();
|
|
659
|
+
const { changeOnSelect: allowChange, filterLeafOnly, multiple, enableLeafClick } = this.getProps();
|
|
653
660
|
const { keyEntities, selectedKeys, isSearching } = this.getStates();
|
|
654
661
|
const filterable = this._isFilterable();
|
|
655
662
|
const { data, key } = item;
|
|
@@ -667,6 +674,9 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
667
674
|
}
|
|
668
675
|
if (multiple) {
|
|
669
676
|
this._adapter.updateStates({ activeKeys: new Set(activeKeys) });
|
|
677
|
+
if (isLeaf && enableLeafClick) {
|
|
678
|
+
this.onItemCheckboxClick(item);
|
|
679
|
+
}
|
|
670
680
|
} else {
|
|
671
681
|
this._adapter.notifySelect(data.value);
|
|
672
682
|
if (hasChanged) {
|
|
@@ -703,8 +713,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
703
713
|
|
|
704
714
|
_handleMultipleSelect(item: BasicEntity | BasicData) {
|
|
705
715
|
const { key } = item;
|
|
706
|
-
const { checkedKeys, keyEntities,
|
|
707
|
-
const { autoMergeValue, max, disableStrictly } = this.getProps();
|
|
716
|
+
const { checkedKeys, keyEntities, resolvedCheckedKeys } = this.getStates();
|
|
717
|
+
const { autoMergeValue, max, disableStrictly, leafOnly } = this.getProps();
|
|
708
718
|
// prev checked status
|
|
709
719
|
const prevCheckedStatus = checkedKeys.has(key);
|
|
710
720
|
// next checked status
|
|
@@ -719,18 +729,22 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
719
729
|
this.calcNonDisabedCheckedKeys(key, curCheckedStatus) :
|
|
720
730
|
this.calcCheckedKeys(key, curCheckedStatus);
|
|
721
731
|
|
|
722
|
-
const
|
|
732
|
+
const mergeType = calcMergeType(autoMergeValue, leafOnly);
|
|
733
|
+
const isLeafOnlyMerge = mergeType === strings.LEAF_ONLY_MERGE_TYPE;
|
|
734
|
+
const isNoneMerge = mergeType === strings.NONE_MERGE_TYPE;
|
|
735
|
+
|
|
736
|
+
const curResolvedCheckedKeys = new Set(normalizeKeyList(curCheckedKeys, keyEntities, isLeafOnlyMerge));
|
|
723
737
|
|
|
724
|
-
const curRealCheckedKeys =
|
|
725
|
-
|
|
726
|
-
|
|
738
|
+
const curRealCheckedKeys = isNoneMerge
|
|
739
|
+
? curCheckedKeys
|
|
740
|
+
: curResolvedCheckedKeys;
|
|
727
741
|
|
|
728
742
|
if (isNumber(max)) {
|
|
729
|
-
if (
|
|
743
|
+
if (!isNoneMerge) {
|
|
730
744
|
// When it exceeds max, the quantity is allowed to be reduced, and no further increase is allowed
|
|
731
|
-
if (
|
|
745
|
+
if (resolvedCheckedKeys.size < curResolvedCheckedKeys.size && curResolvedCheckedKeys.size > max) {
|
|
732
746
|
const checkedEntities: BasicEntity[] = [];
|
|
733
|
-
|
|
747
|
+
curResolvedCheckedKeys.forEach(itemKey => {
|
|
734
748
|
checkedEntities.push(keyEntities[itemKey]);
|
|
735
749
|
});
|
|
736
750
|
this._adapter.notifyOnExceed(checkedEntities);
|
|
@@ -752,7 +766,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
752
766
|
this._adapter.updateStates({
|
|
753
767
|
checkedKeys: curCheckedKeys,
|
|
754
768
|
halfCheckedKeys: curHalfCheckedKeys,
|
|
755
|
-
|
|
769
|
+
resolvedCheckedKeys: curResolvedCheckedKeys
|
|
756
770
|
});
|
|
757
771
|
}
|
|
758
772
|
|
|
@@ -868,7 +882,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
868
882
|
newState.halfCheckedKeys = new Set([]);
|
|
869
883
|
newState.selectedKeys = new Set([]);
|
|
870
884
|
newState.activeKeys = new Set([]);
|
|
871
|
-
newState.
|
|
885
|
+
newState.resolvedCheckedKeys = new Set([]);
|
|
872
886
|
this._adapter.notifyChange([]);
|
|
873
887
|
} else {
|
|
874
888
|
// if click clearBtn when not searching, clear selected and active values as well
|
package/cascader/util.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
isUndefined,
|
|
4
4
|
isEqual
|
|
5
5
|
} from 'lodash';
|
|
6
|
+
import { strings } from './constants';
|
|
6
7
|
|
|
7
8
|
function getPosition(level: any, index: any) {
|
|
8
9
|
return `${level}-${index}`;
|
|
@@ -79,4 +80,16 @@ export function findKeysForValues(value: any, keyEntities: any) {
|
|
|
79
80
|
.filter((item: any) => isEqual(item.valuePath, valuePath))
|
|
80
81
|
.map((item: any) => item.key);
|
|
81
82
|
return res;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function calcMergeType(autoMergeValue: boolean, leafOnly: boolean): string {
|
|
86
|
+
let mergeType: string;
|
|
87
|
+
if (leafOnly) {
|
|
88
|
+
mergeType = strings.LEAF_ONLY_MERGE_TYPE;
|
|
89
|
+
} else if (autoMergeValue) {
|
|
90
|
+
mergeType = strings.AUTO_MERGE_VALUE_MERGE_TYPE;
|
|
91
|
+
} else {
|
|
92
|
+
mergeType = strings.NONE_MERGE_TYPE;
|
|
93
|
+
}
|
|
94
|
+
return mergeType;
|
|
82
95
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @file
|
|
3
3
|
* Various date-related analysis methods
|
|
4
4
|
*/
|
|
5
|
-
import { isValid, parseISO, parse } from 'date-fns';
|
|
5
|
+
import { isValid, parseISO, parse, Locale } from 'date-fns';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parsing value to Date object
|
|
@@ -11,7 +11,7 @@ export function compatiableParse(
|
|
|
11
11
|
value: string,
|
|
12
12
|
formatToken?: string,
|
|
13
13
|
baseDate?: Date,
|
|
14
|
-
locale?:
|
|
14
|
+
locale?: Locale
|
|
15
15
|
): Date | null {
|
|
16
16
|
let result = null;
|
|
17
17
|
if (value) {
|
|
@@ -25,7 +25,8 @@ export function compatiableParse(
|
|
|
25
25
|
if (!isValid(result)) {
|
|
26
26
|
result = new Date(Date.parse(value));
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
const yearInvalid = isValid(result) && String(result.getFullYear()).length > 4;
|
|
29
|
+
if (!isValid(result) || yearInvalid) {
|
|
29
30
|
result = null;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -94,6 +94,15 @@ $module: #{$prefix}-datepicker;
|
|
|
94
94
|
min-height: $height-datepicker_timepicker_header_min;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
|
|
98
|
+
// 为了防止 scrollList 因为 weeks 变化高度发生变化导致年月可能发生滚动
|
|
99
|
+
// In order to prevent scrollList from scrolling due to changes in the height of weeks, the year and month may be scrolled
|
|
100
|
+
&[x-panel-yearandmonth-open-type="left"],
|
|
101
|
+
&[x-panel-yearandmonth-open-type="right"] {
|
|
102
|
+
.#{$module}-weeks {
|
|
103
|
+
min-height: 6 * $width-datepicker_day;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
// 年月选择器
|
|
@@ -131,6 +140,17 @@ $module: #{$prefix}-datepicker;
|
|
|
131
140
|
padding-bottom: $spacing-datepicker_footer-paddingBottom;
|
|
132
141
|
text-align: right;
|
|
133
142
|
background-color: $color-datepicker_footer-bg-default;
|
|
143
|
+
|
|
144
|
+
.#{$prefix}-button {
|
|
145
|
+
// cancel button
|
|
146
|
+
&:first-of-type {
|
|
147
|
+
margin-right: $spacing-datepicker_footer_cancel_button-marginRight;
|
|
148
|
+
}
|
|
149
|
+
// confirm button
|
|
150
|
+
&:nth-of-type(2) {
|
|
151
|
+
margin-right: $spacing-datepicker_footer_confirm_button-marginRight;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
134
154
|
}
|
|
135
155
|
|
|
136
156
|
// 年月选择
|
|
@@ -833,6 +853,15 @@ $module: #{$prefix}-datepicker;
|
|
|
833
853
|
}
|
|
834
854
|
}
|
|
835
855
|
}
|
|
856
|
+
|
|
857
|
+
// 为了防止 scrollList 因为 weeks 变化高度发生变化导致年月可能发生滚动
|
|
858
|
+
// In order to prevent scrollList from scrolling due to changes in the height of weeks, the year and month may be scrolled
|
|
859
|
+
&[x-panel-yearandmonth-open-type="left"],
|
|
860
|
+
&[x-panel-yearandmonth-open-type="right"] {
|
|
861
|
+
.#{$module}-weeks {
|
|
862
|
+
min-height: 6 * $width-datepicker_day_compact;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
836
865
|
}
|
|
837
866
|
|
|
838
867
|
// 年月选择器
|
package/datePicker/foundation.ts
CHANGED
|
@@ -323,10 +323,8 @@ export default class DatePickerFoundation extends BaseFoundation<DatePickerAdapt
|
|
|
323
323
|
* 2. set cachedSelectedValue using given dates(in needConfirm mode)
|
|
324
324
|
* - directly closePanel without click confirm will set cachedSelectedValue to state value
|
|
325
325
|
* - select one date(which means that the selection value is incomplete) and click confirm also set cachedSelectedValue to state value
|
|
326
|
-
* @param {String} inputValue
|
|
327
|
-
* @param {Date[]} dates
|
|
328
326
|
*/
|
|
329
|
-
rangeTypeSideEffectsWhenClosePanel(inputValue: string,
|
|
327
|
+
rangeTypeSideEffectsWhenClosePanel(inputValue: string, willUpdateDates: Date[]) {
|
|
330
328
|
if (this._isRangeType()) {
|
|
331
329
|
this._adapter.setRangeInputFocus(false);
|
|
332
330
|
/**
|
|
@@ -334,11 +332,29 @@ export default class DatePickerFoundation extends BaseFoundation<DatePickerAdapt
|
|
|
334
332
|
* when inputValue is null, picker value will back to last selected value
|
|
335
333
|
*/
|
|
336
334
|
this.handleInputBlur(inputValue);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
this.resetCachedSelectedValue(willUpdateDates);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* clear input value when selected date is not confirmed
|
|
341
|
+
*/
|
|
342
|
+
needConfirmSideEffectsWhenClosePanel(willUpdateDates: Date[] | null | undefined) {
|
|
343
|
+
if (this._adapter.needConfirm() && !this._isRangeType()) {
|
|
344
|
+
/**
|
|
345
|
+
* if `null` input element will show `cachedSelectedValue` formatted value(format in DateInput render)
|
|
346
|
+
* if `` input element will show `` directly
|
|
347
|
+
*/
|
|
348
|
+
this._adapter.updateInputValue(null);
|
|
349
|
+
this.resetCachedSelectedValue(willUpdateDates);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
resetCachedSelectedValue(willUpdateDates?: Date[]) {
|
|
354
|
+
const { value, cachedSelectedValue } = this._adapter.getStates();
|
|
355
|
+
const newCachedSelectedValue = Array.isArray(willUpdateDates) ? willUpdateDates : value;
|
|
356
|
+
if (!isEqual(newCachedSelectedValue, cachedSelectedValue)) {
|
|
357
|
+
this._adapter.updateCachedSelectedValue(newCachedSelectedValue);
|
|
342
358
|
}
|
|
343
359
|
}
|
|
344
360
|
|
|
@@ -354,13 +370,16 @@ export default class DatePickerFoundation extends BaseFoundation<DatePickerAdapt
|
|
|
354
370
|
* @param {String} inputValue
|
|
355
371
|
* @param {Date[]} dates
|
|
356
372
|
*/
|
|
357
|
-
closePanel(e?: any, inputValue: string = null, dates
|
|
373
|
+
closePanel(e?: any, inputValue: string = null, dates?: Date[]) {
|
|
374
|
+
const { value, cachedSelectedValue } = this._adapter.getStates();
|
|
375
|
+
const willUpdateDates = isNullOrUndefined(dates) ? this._adapter.needConfirm() ? value : cachedSelectedValue : dates;
|
|
358
376
|
if (!this._isControlledComponent('open')) {
|
|
359
377
|
this._adapter.togglePanel(false);
|
|
360
378
|
this._adapter.unregisterClickOutSide();
|
|
361
379
|
}
|
|
362
380
|
// range type picker, closing panel requires the following side effects
|
|
363
|
-
this.rangeTypeSideEffectsWhenClosePanel(inputValue,
|
|
381
|
+
this.rangeTypeSideEffectsWhenClosePanel(inputValue, willUpdateDates as Date[]);
|
|
382
|
+
this.needConfirmSideEffectsWhenClosePanel(willUpdateDates as Date[]);
|
|
364
383
|
this._adapter.notifyOpenChange(false);
|
|
365
384
|
this._adapter.notifyBlur(e);
|
|
366
385
|
}
|
|
@@ -416,7 +435,8 @@ export default class DatePickerFoundation extends BaseFoundation<DatePickerAdapt
|
|
|
416
435
|
if (parsedResult && parsedResult.length) {
|
|
417
436
|
this._updateValueAndInput(parsedResult, input === '');
|
|
418
437
|
} else if (input === '') {
|
|
419
|
-
|
|
438
|
+
// if clear input, set input to `''`
|
|
439
|
+
this._updateValueAndInput('' as any, true, '');
|
|
420
440
|
} else {
|
|
421
441
|
this._updateValueAndInput(stateValue);
|
|
422
442
|
}
|
|
@@ -47,6 +47,7 @@ interface MonthsGridElementProps {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export type PanelType = 'left' | 'right';
|
|
50
|
+
export type YearMonthChangeType = 'prevMonth' | 'nextMonth' | 'prevYear' | 'nextYear';
|
|
50
51
|
|
|
51
52
|
export interface MonthsGridFoundationProps extends MonthsGridElementProps {
|
|
52
53
|
type?: Type;
|
|
@@ -268,9 +269,65 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
|
|
|
268
269
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
269
270
|
destroy() { }
|
|
270
271
|
|
|
272
|
+
/**
|
|
273
|
+
* sync change another panel month when change months from the else yam panel
|
|
274
|
+
* call it when
|
|
275
|
+
* - current change panel targe date month is same with another panel date
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* - panelType=right, target=new Date('2022-09-01') and left panel is in '2022-09' => call it, left panel minus one month to '2022-08'
|
|
279
|
+
* - panelType=left, target=new Date('2021-12-01') and right panel is in '2021-12' => call it, right panel add one month to '2021-01'
|
|
280
|
+
*/
|
|
281
|
+
handleSyncChangeMonths(options: { panelType: PanelType, target: Date }) {
|
|
282
|
+
const { panelType, target } = options;
|
|
283
|
+
const { type } = this._adapter.getProps();
|
|
284
|
+
const { monthLeft, monthRight } = this._adapter.getStates();
|
|
285
|
+
if (this.isRangeType(type)) {
|
|
286
|
+
if (panelType === 'right' && differenceInCalendarMonths(target, monthLeft.pickerDate) === 0) {
|
|
287
|
+
this.handleYearOrMonthChange('prevMonth', 'left', 1, true);
|
|
288
|
+
} else if (panelType === 'left' && differenceInCalendarMonths(monthRight.pickerDate, target) === 0) {
|
|
289
|
+
this.handleYearOrMonthChange('nextMonth', 'right', 1, true);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get the target date based on the panel type and switch type
|
|
296
|
+
*/
|
|
297
|
+
getTargetChangeDate(options: { panelType: PanelType, switchType: YearMonthChangeType }) {
|
|
298
|
+
const { panelType, switchType } = options;
|
|
299
|
+
const { monthRight, monthLeft } = this._adapter.getStates();
|
|
300
|
+
const currentDate = panelType === 'left' ? monthLeft.pickerDate : monthRight.pickerDate;
|
|
301
|
+
let target: Date;
|
|
302
|
+
|
|
303
|
+
switch (switchType) {
|
|
304
|
+
case 'prevMonth':
|
|
305
|
+
target = addMonths(currentDate, -1);
|
|
306
|
+
break;
|
|
307
|
+
case 'nextMonth':
|
|
308
|
+
target = addMonths(currentDate, 1);
|
|
309
|
+
break;
|
|
310
|
+
case 'prevYear':
|
|
311
|
+
target = addYears(currentDate, -1);
|
|
312
|
+
break;
|
|
313
|
+
case 'nextYear':
|
|
314
|
+
target = addYears(currentDate, 1);
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
return target;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Change month by yam panel
|
|
322
|
+
*/
|
|
271
323
|
toMonth(panelType: PanelType, target: Date) {
|
|
324
|
+
const { type } = this._adapter.getProps();
|
|
272
325
|
const diff = this._getDiff('month', target, panelType);
|
|
273
326
|
this.handleYearOrMonthChange(diff < 0 ? 'prevMonth' : 'nextMonth', panelType, Math.abs(diff), false);
|
|
327
|
+
|
|
328
|
+
if (this.isRangeType(type)) {
|
|
329
|
+
this.handleSyncChangeMonths({ panelType, target });
|
|
330
|
+
}
|
|
274
331
|
}
|
|
275
332
|
|
|
276
333
|
toYear(panelType: PanelType, target: Date) {
|
|
@@ -289,30 +346,43 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
|
|
|
289
346
|
return typeof realType === 'string' && /range/i.test(realType);
|
|
290
347
|
}
|
|
291
348
|
|
|
292
|
-
|
|
349
|
+
handleSwitchMonthOrYear(switchType: YearMonthChangeType, panelType: PanelType) {
|
|
293
350
|
const { type, syncSwitchMonth } = this.getProps();
|
|
294
|
-
|
|
351
|
+
const rangeType = this.isRangeType(type);
|
|
352
|
+
|
|
353
|
+
// range type and syncSwitchMonth, we should change panels at same time
|
|
354
|
+
if (rangeType && syncSwitchMonth) {
|
|
295
355
|
this.handleYearOrMonthChange(switchType, 'left', 1, true);
|
|
296
356
|
this.handleYearOrMonthChange(switchType, 'right', 1, true);
|
|
297
357
|
} else {
|
|
298
358
|
this.handleYearOrMonthChange(switchType, panelType);
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* default behavior (v2.2.0)
|
|
362
|
+
* In order to prevent the two panels from being the same month, this will confuse the user when selecting the range
|
|
363
|
+
* https://github.com/DouyinFE/semi-design/issues/260
|
|
364
|
+
*/
|
|
365
|
+
if (rangeType) {
|
|
366
|
+
const target = this.getTargetChangeDate({ panelType, switchType });
|
|
367
|
+
this.handleSyncChangeMonths({ panelType, target });
|
|
368
|
+
}
|
|
299
369
|
}
|
|
300
370
|
}
|
|
301
371
|
|
|
302
372
|
prevMonth(panelType: PanelType) {
|
|
303
|
-
this.
|
|
373
|
+
this.handleSwitchMonthOrYear('prevMonth', panelType);
|
|
304
374
|
}
|
|
305
375
|
|
|
306
376
|
nextMonth(panelType: PanelType) {
|
|
307
|
-
this.
|
|
377
|
+
this.handleSwitchMonthOrYear('nextMonth', panelType);
|
|
308
378
|
}
|
|
309
379
|
|
|
310
380
|
prevYear(panelType: PanelType) {
|
|
311
|
-
this.
|
|
381
|
+
this.handleSwitchMonthOrYear('prevYear', panelType);
|
|
312
382
|
}
|
|
313
383
|
|
|
314
384
|
nextYear(panelType: PanelType) {
|
|
315
|
-
this.
|
|
385
|
+
this.handleSwitchMonthOrYear('nextYear', panelType);
|
|
316
386
|
}
|
|
317
387
|
|
|
318
388
|
/**
|
|
@@ -414,7 +484,7 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
|
|
|
414
484
|
}
|
|
415
485
|
|
|
416
486
|
handleYearOrMonthChange(
|
|
417
|
-
type:
|
|
487
|
+
type: YearMonthChangeType,
|
|
418
488
|
panelType: PanelType = strings.PANEL_TYPE_LEFT,
|
|
419
489
|
step = 1,
|
|
420
490
|
notSeparateInRange = false
|
|
@@ -458,7 +528,7 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
|
|
|
458
528
|
* @param {*} targetDate
|
|
459
529
|
*/
|
|
460
530
|
updateDateAfterChangeYM(
|
|
461
|
-
type:
|
|
531
|
+
type: YearMonthChangeType,
|
|
462
532
|
targetDate: Date
|
|
463
533
|
) {
|
|
464
534
|
const { multiple, disabledDate } = this.getProps();
|
|
@@ -839,4 +909,27 @@ export default class MonthsGridFoundation extends BaseFoundation<MonthsGridAdapt
|
|
|
839
909
|
showDatePanel(panelType: PanelType) {
|
|
840
910
|
this._updatePanelDetail(panelType, { isTimePickerOpen: false, isYearPickerOpen: false });
|
|
841
911
|
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Get year and month panel open type
|
|
915
|
+
*
|
|
916
|
+
* It is useful info to set minHeight of weeks.
|
|
917
|
+
* - When yam open type is 'left' or 'right', weeks minHeight should be set
|
|
918
|
+
* If the minHeight is not set, the change of the number of weeks will cause the scrollList to be unstable
|
|
919
|
+
*/
|
|
920
|
+
getYAMOpenType() {
|
|
921
|
+
const { monthLeft, monthRight } = this._adapter.getStates();
|
|
922
|
+
const leftYearPickerOpen = monthLeft.isYearPickerOpen;
|
|
923
|
+
const rightYearPickerOpen = monthRight.isYearPickerOpen;
|
|
924
|
+
|
|
925
|
+
if (leftYearPickerOpen && rightYearPickerOpen) {
|
|
926
|
+
return 'both';
|
|
927
|
+
} else if (leftYearPickerOpen) {
|
|
928
|
+
return 'left';
|
|
929
|
+
} else if (rightYearPickerOpen) {
|
|
930
|
+
return 'right';
|
|
931
|
+
} else {
|
|
932
|
+
return 'none';
|
|
933
|
+
}
|
|
934
|
+
}
|
|
842
935
|
}
|
package/datePicker/rtl.scss
CHANGED
|
@@ -9,6 +9,18 @@ $module: #{$prefix}-datepicker;
|
|
|
9
9
|
padding-right: 0;
|
|
10
10
|
padding-left: $spacing-datepicker_footer-paddingRight;
|
|
11
11
|
text-align: left;
|
|
12
|
+
|
|
13
|
+
.#{$prefix}-button {
|
|
14
|
+
&:first-of-type {
|
|
15
|
+
margin-left: 0;
|
|
16
|
+
margin-right: 0;
|
|
17
|
+
}
|
|
18
|
+
// confirm button
|
|
19
|
+
&:nth-of-type(2) {
|
|
20
|
+
margin-right: $spacing-datepicker_footer_cancel_button-marginRight;
|
|
21
|
+
margin-left: 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
&-day {
|
|
@@ -66,7 +78,9 @@ $module: #{$prefix}-datepicker;
|
|
|
66
78
|
&-yam {
|
|
67
79
|
// rtl 对箭头进行翻转
|
|
68
80
|
.#{$prefix}-icon-chevron_left,
|
|
69
|
-
.#{$prefix}-icon-chevron_right
|
|
81
|
+
.#{$prefix}-icon-chevron_right,
|
|
82
|
+
.#{$prefix}-icon-double_chevron_left,
|
|
83
|
+
.#{$prefix}-icon-double_chevron_right {
|
|
70
84
|
transform: scaleX(-1);
|
|
71
85
|
}
|
|
72
86
|
}
|
|
@@ -33,6 +33,8 @@ $spacing-datepicker_scrolllist_body-padding: 0; // 时间选择滚动菜单内
|
|
|
33
33
|
$spacing-datepicker_footer-paddingTop: 10px; // 确认选择 footer 顶部内边距
|
|
34
34
|
$spacing-datepicker_footer-paddingBottom: 10px; // 确认选择 footer 底部内边距
|
|
35
35
|
$spacing-datepicker_footer-paddingRight: 8px; // 确认选择 footer 右侧内边距
|
|
36
|
+
$spacing-datepicker_footer_cancel_button-marginRight: 12px; // 确认选择 footer 取消按钮右外边距
|
|
37
|
+
$spacing-datepicker_footer_confirm_button-marginRight: 8px; // 确认选择 footer 确认按钮右外边距
|
|
36
38
|
$spacing-datepicker_navigation-paddingY: $spacing-base-tight; // 年月切换 header 垂直内边距
|
|
37
39
|
$spacing-datepicker_navigation-paddingX: $spacing-base; // 年月切换 header 水平内边距
|
|
38
40
|
$spacing-datepicker_month-padding: $spacing-base;
|
package/gulpfile.js
CHANGED
|
@@ -52,7 +52,9 @@ gulp.task('compileScss', function compileScss() {
|
|
|
52
52
|
cb(null, chunk);
|
|
53
53
|
}
|
|
54
54
|
))
|
|
55
|
-
.pipe(sass(
|
|
55
|
+
.pipe(sass({
|
|
56
|
+
charset: false
|
|
57
|
+
}).on('error', sass.logError))
|
|
56
58
|
.pipe(gulp.dest('lib/es'))
|
|
57
59
|
.pipe(gulp.dest('lib/cjs'));
|
|
58
60
|
});
|
|
@@ -99,11 +99,11 @@
|
|
|
99
99
|
.semi-cascader-selection-tag:first-child {
|
|
100
100
|
margin-left: 0;
|
|
101
101
|
}
|
|
102
|
-
.semi-cascader-selection-tag-disabled {
|
|
102
|
+
.semi-cascader-selection-tag-disabled.semi-tag {
|
|
103
103
|
color: var(--semi-color-disabled-text);
|
|
104
104
|
cursor: not-allowed;
|
|
105
105
|
}
|
|
106
|
-
.semi-cascader-selection-tag-disabled .semi-tag-close {
|
|
106
|
+
.semi-cascader-selection-tag-disabled.semi-tag .semi-tag-close {
|
|
107
107
|
color: var(--semi-color-disabled-text);
|
|
108
108
|
cursor: not-allowed;
|
|
109
109
|
pointer-events: none;
|
|
@@ -9,6 +9,9 @@ declare const strings: {
|
|
|
9
9
|
readonly IS_VALUE: "isValue";
|
|
10
10
|
readonly SHOW_NEXT_BY_CLICK: "click";
|
|
11
11
|
readonly SHOW_NEXT_BY_HOVER: "hover";
|
|
12
|
+
readonly LEAF_ONLY_MERGE_TYPE: "leafOnly";
|
|
13
|
+
readonly AUTO_MERGE_VALUE_MERGE_TYPE: "autoMergeValue";
|
|
14
|
+
readonly NONE_MERGE_TYPE: "none";
|
|
12
15
|
};
|
|
13
16
|
declare const numbers: {};
|
|
14
17
|
export { cssClasses, strings, numbers };
|
|
@@ -21,7 +21,12 @@ const strings = {
|
|
|
21
21
|
IS_KEY: 'isKey',
|
|
22
22
|
IS_VALUE: 'isValue',
|
|
23
23
|
SHOW_NEXT_BY_CLICK: 'click',
|
|
24
|
-
SHOW_NEXT_BY_HOVER: 'hover'
|
|
24
|
+
SHOW_NEXT_BY_HOVER: 'hover',
|
|
25
|
+
|
|
26
|
+
/* Merge Type */
|
|
27
|
+
LEAF_ONLY_MERGE_TYPE: 'leafOnly',
|
|
28
|
+
AUTO_MERGE_VALUE_MERGE_TYPE: 'autoMergeValue',
|
|
29
|
+
NONE_MERGE_TYPE: 'none'
|
|
25
30
|
};
|
|
26
31
|
exports.strings = strings;
|
|
27
32
|
const numbers = {};
|
|
@@ -57,6 +57,7 @@ export interface BasicScrollPanelProps {
|
|
|
57
57
|
export interface BasicCascaderProps {
|
|
58
58
|
mouseEnterDelay?: number;
|
|
59
59
|
mouseLeaveDelay?: number;
|
|
60
|
+
separator?: string;
|
|
60
61
|
arrowIcon?: any;
|
|
61
62
|
changeOnSelect?: boolean;
|
|
62
63
|
multiple?: boolean;
|
|
@@ -96,6 +97,8 @@ export interface BasicCascaderProps {
|
|
|
96
97
|
topSlot?: any;
|
|
97
98
|
showNext?: ShowNextType;
|
|
98
99
|
disableStrictly?: boolean;
|
|
100
|
+
leafOnly?: boolean;
|
|
101
|
+
enableLeafClick?: boolean;
|
|
99
102
|
onClear?: () => void;
|
|
100
103
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
101
104
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -125,7 +128,7 @@ export interface BasicCascaderInnerData {
|
|
|
125
128
|
isHovering: boolean;
|
|
126
129
|
checkedKeys: Set<string>;
|
|
127
130
|
halfCheckedKeys: Set<string>;
|
|
128
|
-
|
|
131
|
+
resolvedCheckedKeys: Set<string>;
|
|
129
132
|
loadedKeys: Set<string>;
|
|
130
133
|
loadingKeys: Set<string>;
|
|
131
134
|
loading: boolean;
|