Browse Source

style: Modify default empty data display style in Cascader, to be consistent with TreeSelect/Select (#2725)

YyumeiZhang 7 months ago
parent
commit
ff55418f9d

+ 8 - 2
packages/semi-foundation/cascader/cascader.scss

@@ -315,16 +315,20 @@ $module: #{$prefix}-cascader;
         border-bottom: $width-cascader_search-border solid $color-cascader_search-border-default;
     }
 
-    .#{$module}-option-empty {
+    .#{$module}-option-lists .#{$module}-option-empty {
         @include font-size-regular;
         border-radius: $radius-cascader_option_empty;
-        min-width: $width-cascader_option;
+        // min-width: $width-cascader_option;
         color: $color-cascader_option_empty-text-default;
         margin: 0;
         padding: $spacing-cascader_option_empty-paddingY $spacing-cascader_option_empty-paddingX;
         user-select: none;
         text-align: center;
         cursor: not-allowed;
+
+        &:hover {
+            background-color: transparent;
+        }
     }
 }
 
@@ -381,6 +385,8 @@ $module: #{$prefix}-cascader;
 
     &-empty {
         height: auto;
+        justify-content: center;
+        cursor: not-allowed;
     }
 
     ul,

+ 19 - 2
packages/semi-foundation/cascader/foundation.ts

@@ -1,4 +1,4 @@
-import { isEqual, get, difference, isUndefined, assign, isEmpty, isNumber, includes, isFunction, isObject } from 'lodash';
+import { isEqual, get, difference, isUndefined, assign, isEmpty, isNumber, includes, isFunction, isObject, isString } from 'lodash';
 import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 import {
     findAncestorKeys,
@@ -186,6 +186,7 @@ export interface BasicCascaderProps {
 }
 
 export interface BasicCascaderInnerData {
+    emptyContentMinWidth: number;
     isOpen: boolean;
     rePosKey: number;
     keyEntities: BasicEntities;
@@ -239,7 +240,9 @@ export interface CascaderAdapter extends DefaultAdapter<BasicCascaderProps, Basi
     updateLoadingKeyRefValue: (keys: Set<string>) => void;
     getLoadingKeyRefValue: () => Set<string>;
     updateLoadedKeyRefValue: (keys: Set<string>) => void;
-    getLoadedKeyRefValue: () => Set<string>
+    getLoadedKeyRefValue: () => Set<string>;
+    setEmptyContentMinWidth: (minWidth: number) => void;
+    getTriggerWidth: () => number;
 }
 
 export default class CascaderFoundation extends BaseFoundation<CascaderAdapter, BasicCascaderProps, BasicCascaderInnerData> {
@@ -259,6 +262,19 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
         }
     }
 
+    _setEmptyContentMinWidth() {
+        const { style } = this.getProps();
+        let width;
+        if (style && isNumber(style.width)) {
+            width = style.width;
+        } else if (style && isString(style.width) && !style.width.includes('%')) {
+            width = style.width;
+        } else {
+            width = this._adapter.getTriggerWidth();
+        }
+        this._adapter.setEmptyContentMinWidth(width);
+    }
+
     handleKeyDown = (e: any) => {
         if (e.key === ESC_KEY) {
             const isOpen = this.getState('isOpen');
@@ -531,6 +547,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
         }
         this._adapter.notifyDropdownVisibleChange(true);
         this._adapter.registerClickOutsideHandler(e => this.close(e));
+        this._setEmptyContentMinWidth();
     }
 
     reCalcActiveKeys() {

+ 7 - 1
packages/semi-ui/cascader/_story/cascader.stories.jsx

@@ -2417,7 +2417,13 @@ export const EmptyContent = () => {
       placeholder="输入 v 查看搜索状态下 emptyContent 为 null 效果"
       filterTreeNode
     />
-    <br />
+    <br /><br />
+    <Cascader
+      style={{ width: 400 }}
+      treeData={[]}
+      placeholder="点击 trigger 查看默认 emptyContent 效果"
+      filterTreeNode
+    />
   </>)
 }
 

+ 11 - 1
packages/semi-ui/cascader/index.tsx

@@ -236,6 +236,7 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
     constructor(props: CascaderProps) {
         super(props);
         this.state = {
+            emptyContentMinWidth: null,
             disabledKeys: new Set(),
             isOpen: props.defaultOpen,
             /* By changing rePosKey, the dropdown position can be refreshed */
@@ -342,6 +343,13 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
             ...super.adapter,
             ...filterAdapter,
             ...cascaderAdapter,
+            setEmptyContentMinWidth: minWidth => {
+                this.setState({ emptyContentMinWidth: minWidth });
+            },
+            getTriggerWidth: () => {
+                const el = this.triggerRef.current;
+                return el && el.getBoundingClientRect().width;
+            },
             updateStates: states => {
                 this.setState({ ...states } as CascaderState);
             },
@@ -721,8 +729,10 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
         const searchable = Boolean(filterTreeNode) && isSearching;
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         const renderData = this.foundation.getRenderData();
+        const isEmpty = !renderData || !renderData.length;
+        const realDropDownStyle = isEmpty ? {...dropdownStyle, minWidth: this.state.emptyContentMinWidth } : dropdownStyle;
         const content = (
-            <div className={popoverCls} role="listbox" style={dropdownStyle} onKeyDown={this.foundation.handleKeyDown}>
+            <div className={popoverCls} role="listbox" style={realDropDownStyle} onKeyDown={this.foundation.handleKeyDown}>
                 {topSlot}
                 <Item
                     activeKeys={activeKeys}