@douyinfe/semi-foundation 2.7.1 → 2.8.0-beta.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.
- package/datePicker/_utils/getDefaultPickerDate.ts +54 -0
- package/datePicker/datePicker.scss +2 -2
- package/form/form.scss +12 -4
- package/inputNumber/foundation.ts +1 -1
- package/lib/cjs/datePicker/_utils/getDefaultPickerDate.d.ts +15 -0
- package/lib/cjs/datePicker/_utils/getDefaultPickerDate.js +73 -0
- package/lib/cjs/datePicker/datePicker.css +14 -14
- package/lib/cjs/datePicker/datePicker.scss +2 -2
- package/lib/cjs/form/form.css +11 -2
- package/lib/cjs/form/form.scss +12 -4
- package/lib/cjs/inputNumber/foundation.js +1 -1
- package/lib/cjs/tooltip/foundation.d.ts +27 -1
- package/lib/cjs/tooltip/foundation.js +159 -3
- package/lib/cjs/utils/isEscPress.d.ts +4 -0
- package/lib/cjs/utils/isEscPress.js +22 -0
- package/lib/cjs/utils/keyCode.d.ts +1 -0
- package/lib/cjs/utils/keyCode.js +3 -1
- package/lib/es/datePicker/_utils/getDefaultPickerDate.d.ts +15 -0
- package/lib/es/datePicker/_utils/getDefaultPickerDate.js +57 -0
- package/lib/es/datePicker/datePicker.css +14 -14
- package/lib/es/datePicker/datePicker.scss +2 -2
- package/lib/es/form/form.css +11 -2
- package/lib/es/form/form.scss +12 -4
- package/lib/es/inputNumber/foundation.js +1 -1
- package/lib/es/tooltip/foundation.d.ts +27 -1
- package/lib/es/tooltip/foundation.js +159 -3
- package/lib/es/utils/isEscPress.d.ts +4 -0
- package/lib/es/utils/isEscPress.js +8 -0
- package/lib/es/utils/keyCode.d.ts +1 -0
- package/lib/es/utils/keyCode.js +1 -0
- package/package.json +3 -3
- package/tooltip/foundation.ts +131 -3
- package/utils/isEscPress.ts +8 -0
- package/utils/keyCode.ts +1 -0
package/tooltip/foundation.ts
CHANGED
|
@@ -46,6 +46,7 @@ export interface TooltipAdapter<P = Record<string, any>, S = Record<string, any>
|
|
|
46
46
|
click: string;
|
|
47
47
|
focus: string;
|
|
48
48
|
blur: string;
|
|
49
|
+
keydown: string;
|
|
49
50
|
};
|
|
50
51
|
registerTriggerEvent(...args: any[]): void;
|
|
51
52
|
getTriggerBounding(...args: any[]): DOMRect;
|
|
@@ -61,6 +62,12 @@ export interface TooltipAdapter<P = Record<string, any>, S = Record<string, any>
|
|
|
61
62
|
updateContainerPosition(): void;
|
|
62
63
|
updatePlacementAttr(placement: Position): void;
|
|
63
64
|
getContainerPosition(): string;
|
|
65
|
+
getFocusableElements(node: any): any[];
|
|
66
|
+
getActiveElement(): any;
|
|
67
|
+
getContainer(): any;
|
|
68
|
+
setInitialFocus(): void;
|
|
69
|
+
notifyEscKeydown(event: any): void;
|
|
70
|
+
getTriggerNode(): any;
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
export type Position = ArrayElement<typeof strings.POSITION_SET>;
|
|
@@ -154,7 +161,12 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
|
|
|
154
161
|
|
|
155
162
|
_generateEvent(types: ArrayElement<typeof strings.TRIGGER_SET>) {
|
|
156
163
|
const eventNames = this._adapter.getEventName();
|
|
157
|
-
const triggerEventSet = {
|
|
164
|
+
const triggerEventSet = {
|
|
165
|
+
// bind esc keydown on trigger for a11y
|
|
166
|
+
[eventNames.keydown]: (event) => {
|
|
167
|
+
this._handleTriggerKeydown(event);
|
|
168
|
+
},
|
|
169
|
+
};
|
|
158
170
|
let portalEventSet = {};
|
|
159
171
|
switch (types) {
|
|
160
172
|
case 'focus':
|
|
@@ -186,6 +198,13 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
|
|
|
186
198
|
this.delayHide();
|
|
187
199
|
// this.hide('trigger');
|
|
188
200
|
};
|
|
201
|
+
// bind focus to hover trigger for a11y
|
|
202
|
+
triggerEventSet[eventNames.focus] = () => {
|
|
203
|
+
this.delayShow();
|
|
204
|
+
};
|
|
205
|
+
triggerEventSet[eventNames.blur] = () => {
|
|
206
|
+
this.delayHide();
|
|
207
|
+
};
|
|
189
208
|
|
|
190
209
|
portalEventSet = { ...triggerEventSet };
|
|
191
210
|
if (this.getProp('clickToHide')) {
|
|
@@ -205,7 +224,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
|
|
|
205
224
|
break;
|
|
206
225
|
case 'custom':
|
|
207
226
|
// when trigger type is 'custom', no need to bind eventHandler
|
|
208
|
-
// show/hide completely
|
|
227
|
+
// show/hide completely depend on props.visible which change by user
|
|
209
228
|
break;
|
|
210
229
|
default:
|
|
211
230
|
break;
|
|
@@ -292,7 +311,12 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
|
|
|
292
311
|
_togglePortalVisible(isVisible: boolean) {
|
|
293
312
|
const nowVisible = this.getState('visible');
|
|
294
313
|
if (nowVisible !== isVisible) {
|
|
295
|
-
this._adapter.togglePortalVisible(isVisible, () =>
|
|
314
|
+
this._adapter.togglePortalVisible(isVisible, () => {
|
|
315
|
+
if (isVisible) {
|
|
316
|
+
this._adapter.setInitialFocus();
|
|
317
|
+
}
|
|
318
|
+
this._adapter.notifyVisibleChange(isVisible);
|
|
319
|
+
});
|
|
296
320
|
}
|
|
297
321
|
}
|
|
298
322
|
|
|
@@ -797,4 +821,108 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
|
|
|
797
821
|
_initContainerPosition() {
|
|
798
822
|
this._adapter.updateContainerPosition();
|
|
799
823
|
}
|
|
824
|
+
|
|
825
|
+
handleContainerKeydown = (event: any) => {
|
|
826
|
+
const { guardFocus, closeOnEsc } = this.getProps();
|
|
827
|
+
switch (event && event.key) {
|
|
828
|
+
case "Escape":
|
|
829
|
+
closeOnEsc && this._handleEscKeyDown(event);
|
|
830
|
+
break;
|
|
831
|
+
case "Tab":
|
|
832
|
+
if (guardFocus) {
|
|
833
|
+
const container = this._adapter.getContainer();
|
|
834
|
+
const focusableElements = this._adapter.getFocusableElements(container);
|
|
835
|
+
const focusableNum = focusableElements.length;
|
|
836
|
+
|
|
837
|
+
if (focusableNum) {
|
|
838
|
+
// Shift + Tab will move focus backward
|
|
839
|
+
if (event.shiftKey) {
|
|
840
|
+
this._handleContainerShiftTabKeyDown(focusableElements, event);
|
|
841
|
+
} else {
|
|
842
|
+
this._handleContainerTabKeyDown(focusableElements, event);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
break;
|
|
847
|
+
default:
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
_handleTriggerKeydown(event: any) {
|
|
853
|
+
const { closeOnEsc } = this.getProps();
|
|
854
|
+
const container = this._adapter.getContainer();
|
|
855
|
+
const focusableElements = this._adapter.getFocusableElements(container);
|
|
856
|
+
const focusableNum = focusableElements.length;
|
|
857
|
+
|
|
858
|
+
switch (event && event.key) {
|
|
859
|
+
case "Escape":
|
|
860
|
+
closeOnEsc && this._handleEscKeyDown(event);
|
|
861
|
+
break;
|
|
862
|
+
case "ArrowUp":
|
|
863
|
+
focusableNum && this._handleTriggerArrowUpKeydown(focusableElements, event);
|
|
864
|
+
break;
|
|
865
|
+
case "ArrowDown":
|
|
866
|
+
focusableNum && this._handleTriggerArrowDownKeydown(focusableElements, event);
|
|
867
|
+
break;
|
|
868
|
+
default:
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* focus trigger
|
|
875
|
+
*
|
|
876
|
+
* when trigger is 'focus' or 'hover', onFocus is bind to show popup
|
|
877
|
+
* if we focus trigger, popup will show again
|
|
878
|
+
*
|
|
879
|
+
* 如果 trigger 是 focus 或者 hover,则它绑定了 onFocus,这里我们如果重新 focus 的话,popup 会再次打开
|
|
880
|
+
* 因此 returnFocusOnClose 只支持 click trigger
|
|
881
|
+
*/
|
|
882
|
+
_focusTrigger() {
|
|
883
|
+
const { trigger, returnFocusOnClose } = this.getProps();
|
|
884
|
+
if (returnFocusOnClose && trigger === 'click') {
|
|
885
|
+
const triggerNode = this._adapter.getTriggerNode();
|
|
886
|
+
if (triggerNode && 'focus' in triggerNode) {
|
|
887
|
+
triggerNode.focus();
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
_handleEscKeyDown(event: any) {
|
|
893
|
+
const { trigger } = this.getProps();
|
|
894
|
+
if (trigger !== 'custom') {
|
|
895
|
+
this.hide();
|
|
896
|
+
this._focusTrigger();
|
|
897
|
+
}
|
|
898
|
+
this._adapter.notifyEscKeydown(event);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
_handleContainerTabKeyDown(focusableElements: any[], event: any) {
|
|
902
|
+
const activeElement = this._adapter.getActiveElement();
|
|
903
|
+
const isLastCurrentFocus = focusableElements[focusableElements.length - 1] === activeElement;
|
|
904
|
+
if (isLastCurrentFocus) {
|
|
905
|
+
focusableElements[0].focus();
|
|
906
|
+
event.preventDefault(); // prevent browser default tab move behavior
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
_handleContainerShiftTabKeyDown(focusableElements: any[], event: any) {
|
|
911
|
+
const activeElement = this._adapter.getActiveElement();
|
|
912
|
+
const isFirstCurrentFocus = focusableElements[0] === activeElement;
|
|
913
|
+
if (isFirstCurrentFocus) {
|
|
914
|
+
focusableElements[focusableElements.length - 1].focus();
|
|
915
|
+
event.preventDefault(); // prevent browser default tab move behavior
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
_handleTriggerArrowDownKeydown(focusableElements: any[], event: any) {
|
|
920
|
+
focusableElements[0].focus();
|
|
921
|
+
event.preventDefault(); // prevent browser default scroll behavior
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
_handleTriggerArrowUpKeydown(focusableElements: any[], event: any) {
|
|
925
|
+
focusableElements[focusableElements.length - 1].focus();
|
|
926
|
+
event.preventDefault(); // prevent browser default scroll behavior
|
|
927
|
+
}
|
|
800
928
|
}
|