Sfoglia il codice sorgente

fix: ts error in high typescipt version && modal focus logic (#1159)

* fix: fix ts error in high typescript version && fix modal focus logic

* fix: fix ts error in high typescript version && fix modal focus logic

* chore: remove usless code

* chore: format code
代强 3 anni fa
parent
commit
c414243942

+ 2 - 0
content/start/changelog/index-en-US.md

@@ -20,6 +20,8 @@ Version:Major.Minor.Patch (follow the **Semver** specification)
 - 【Fix】
    - Fix the ButtonGroup key warning problem
    - Fix SSR setting withField、Form Field related problem with useLayoutEffect warning [#1140](https://github.com/DouyinFE/semi-design/pull/1140)
+   - Fix the problem of some type errors under typescript 4.8.3
+   - Modify the modal focus logic to automatically focus on the first focusable element in the pop-up window
 
 #### 🎉 2.20.2 (2022-09-27)
 - 【Fix】

+ 3 - 1
content/start/changelog/index.md

@@ -20,7 +20,9 @@ Semi 版本号遵循 **Semver** 规范(主版本号-次版本号-修订版本
 - 【Fix】
   - 修复 ButtonGroup 关于 key warning的问题
   - 修复 SSR 场景下 withField、Form Field 相关组件关于  useLayoutEffect warning 的问题 [#1140](https://github.com/DouyinFE/semi-design/pull/1140)
-
+  - 修复 typescript 4.8.3 下部分类型报错的问题
+  - 修改 modal 聚焦逻辑,自动聚焦到弹窗内第一个可被聚焦的元素上
+  
 #### 🎉 2.20.2 (2022-09-27)
 - 【Fix】
   - 修复 @douyinfe/semi-icons 关于 corejs 报错的问题

+ 1 - 1
packages/semi-foundation/tree/foundation.ts

@@ -300,7 +300,7 @@ export interface TreeAdapter extends DefaultAdapter<BasicTreeProps, BasicTreeInn
     updateInputValue: (value: string) => void;
     focusInput: () => void;
     updateState: (states: Partial<BasicTreeInnerData>) => void;
-    notifyExpand: (expandedKeys: Set<string>, { expanded: bool, node }: BasicExpandedOtherProps) => void;
+    notifyExpand: (expandedKeys: Set<string>, { expanded, node }: BasicExpandedOtherProps) => void;
     notifySelect: (selectKey: string, bool: boolean, node: BasicTreeNodeData) => void;
     notifyChange: (value: BasicValue) => void;
     notifySearch: (input: string) => void;

+ 1 - 0
packages/semi-ui/breadcrumb/item.tsx

@@ -89,6 +89,7 @@ export default class BreadcrumbItem extends BaseComponent<BreadcrumbItemProps, B
         const iconSize = compact ? 'small' : 'default';
         const className = `${clsPrefix}-item-icon`;
         if (React.isValidElement(iconType)) {
+            //@ts-ignore
             return React.cloneElement(iconType, { className, size: iconSize });
         }
         return iconType;

+ 1 - 0
packages/semi-ui/dropdown/index.tsx

@@ -242,6 +242,7 @@ class Dropdown extends BaseComponent<DropdownProps, DropdownState> {
             >
                 {React.isValidElement(children) ?
                     React.cloneElement(children, {
+                        //@ts-ignore
                         className: classnames(get(children, 'props.className'), {
                             [`${prefixCls}-showing`]: popVisible,
                         }),

+ 9 - 6
packages/semi-ui/modal/ModalContent.tsx

@@ -117,6 +117,11 @@ export default class ModalContent extends BaseComponent<ModalContentReactProps,
     componentDidMount() {
         this.foundation.handleKeyDownEventListenerMount();
         this.foundation.modalDialogFocus();
+        const nodes = FocusTrapHandle.getFocusableElements(this.modalDialogRef.current);
+        if (!this.modalDialogRef.current.contains(document.activeElement)) {
+            // focus on first focusable element
+            nodes[0]?.focus();
+        }
     }
 
     componentWillUnmount() {
@@ -166,7 +171,7 @@ export default class ModalContent extends BaseComponent<ModalContentReactProps,
         } = this.props;
         let closer;
         if (closable) {
-            const iconType = closeIcon || <IconClose x-semi-prop="closeIcon" />;
+            const iconType = closeIcon || <IconClose x-semi-prop="closeIcon"/>;
             closer = (
                 <Button
                     aria-label="close"
@@ -277,7 +282,6 @@ export default class ModalContent extends BaseComponent<ModalContentReactProps,
                 <div
                     role="dialog"
                     ref={this.modalDialogRef}
-                    tabIndex={-1}
                     aria-modal="true"
                     aria-labelledby={`${cssClasses.DIALOG}-title`}
                     aria-describedby={`${cssClasses.DIALOG}-body`}
@@ -290,7 +294,7 @@ export default class ModalContent extends BaseComponent<ModalContentReactProps,
                     {footer}
                 </div>
             </div>
-        );
+        ); 
         // return props.visible ? dialogElement : null;
         return dialogElement;
     };
@@ -317,10 +321,9 @@ export default class ModalContent extends BaseComponent<ModalContentReactProps,
                 {this.getMaskElement()}
                 <div
                     role="none"
-                    tabIndex={-1}
                     className={cls({
-                        [`${cssClasses.DIALOG}-wrap`]:true,
-                        [`${cssClasses.DIALOG}-wrap-center`]:this.props.centered
+                        [`${cssClasses.DIALOG}-wrap`]: true,
+                        [`${cssClasses.DIALOG}-wrap-center`]: this.props.centered
                     })}
                     onClick={maskClosable ? this.onMaskClick : null}
                     onMouseUp={maskClosable ? this.onMaskMouseUp : null}

+ 0 - 1
packages/semi-ui/navigation/Footer.tsx

@@ -47,7 +47,6 @@ export default class NavFooter extends PureComponent<NavFooterProps> {
                 locale={locale}
                 onClick={onCollapseChange}
                 collapseText={collapseText}
-                {...collapseButton}
             />
         );
     };

+ 1 - 0
packages/semi-ui/navigation/OpenIconTransition.tsx

@@ -38,6 +38,7 @@ function OpenIconTransition(props: OpenIconTransitionProps = {}) {
                 }
                 if (React.isValidElement(children)) {
                     return React.cloneElement(children, {
+                        // @ts-ignore
                         style: {
                             ...(children.props && children.props.style),
                             ...formatedStyle,

+ 3 - 3
packages/semi-ui/navigation/SubNav.tsx

@@ -195,9 +195,9 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         const isOpen = this.adapter.getIsOpen();
 
         const iconElem = React.isValidElement(icon) ? (withTransition ? (
-            <OpenIconTransition isOpen={isOpen}>
-                {React.cloneElement(icon, { size: iconSize })}
-            </OpenIconTransition>
+            // @ts-ignore
+            <OpenIconTransition isOpen={isOpen}>{React.cloneElement(icon, { size: iconSize })}</OpenIconTransition>
+            //@ts-ignore
         ) : React.cloneElement(icon, { size: iconSize })) : null;
 
         return <i key={key} className={className}>{iconElem}</i>;

+ 1 - 1
packages/semi-ui/table/Body/index.tsx

@@ -432,7 +432,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
 
         return (
             <List<Array<FlattenData | GroupFlattenData>>
-                {...virtualized}
+                {...(typeof virtualized === 'object' ? virtualized : {})}
                 initialScrollOffset={this.state.cache.virtualizedScrollTop}
                 onScroll={this.handleVirtualizedScroll}
                 onItemsRendered={this.onItemsRendered}

+ 1 - 0
packages/semi-ui/timeline/index.tsx

@@ -61,6 +61,7 @@ class Timeline extends PureComponent<TimelineProps> {
     addClassName = (items: React.ReactNode) => React.Children.map(items, (ele, idx) => {
         if (React.isValidElement(ele)) {
             return React.cloneElement(ele, {
+                // @ts-ignore
                 className: cls(
                     ele.props.className,
                     this.getPosCls(ele, idx)