Browse Source

style: [c2d][Nav] modify code for c2d

zhangyumei.0319 2 years ago
parent
commit
b7af9c719b

+ 3 - 1
packages/semi-foundation/navigation/itemFoundation.ts

@@ -39,7 +39,9 @@ export interface ItemAdapter<P = Record<string, any>, S = Record<string, any>> e
     notifyMouseLeave(e: any): void;
     getIsCollapsed(): boolean;
     getSelected(): boolean;
-    getIsOpen(): boolean
+    getIsOpen(): boolean;
+    getIsInSubNav(): boolean;
+    getMode(): string
 }
 
 export default class ItemFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ItemAdapter<P, S>, P, S> {

+ 119 - 7
packages/semi-foundation/navigation/navigation.scss

@@ -76,7 +76,7 @@ $module: #{$prefix}-navigation;
         padding: $spacing-navigation_item-paddingY $spacing-navigation_item-paddingX;
         box-sizing: border-box;
         margin-top: 0;
-        margin-bottom: $spacing-navigation_item-marginBottom;
+        // margin-bottom: $spacing-navigation_item-marginBottom;
 
         @include font-size-regular;
         font-weight: $font-navigation_item_normal-fontWeight;
@@ -257,6 +257,13 @@ $module: #{$prefix}-navigation;
         text-overflow: ellipsis;
         white-space: nowrap;
         overflow: hidden;
+        display: flex;
+        flex-direction: column;
+        row-gap: $spacing-navigation_item-marginBottom;
+
+        &.#{$module}-sub-open {
+            margin-top: $spacing-navigation_sub_item_first_child-marginTop;
+        }
 
         .#{$module}-item {
             color: $color-navigation_itemLn-text-default;
@@ -268,9 +275,9 @@ $module: #{$prefix}-navigation;
             font-weight: $font-navigation_sub_item-fontWeight;
             width: 100%;
 
-            &:first-child {
-                margin-top: $spacing-navigation_sub_item_first_child-marginTop;
-            }
+            // &:first-child {
+            //     margin-top: $spacing-navigation_sub_item_first_child-marginTop;
+            // }
 
             & > &-text:first-child {
                 margin-left: $spacing-base-tight + $width-navigation_icon_left + $width-navigation_icon_text_between;
@@ -343,6 +350,12 @@ $module: #{$prefix}-navigation;
         transform: rotate(-180deg);
     }
 
+    &-icon-rotate-0-no-transition {
+        transform: rotate(0);
+    }
+    &-icon-rotate-180-no-transition {
+        transform: rotate(-180deg);
+    }
 }
 
 /* Header、Footer-Common */
@@ -430,6 +443,12 @@ $module: #{$prefix}-navigation;
             }
         }
 
+        &-list {
+            display: flex;
+            flex-direction: column;
+            row-gap: $spacing-navigation_item-marginBottom;
+        }
+
         &-list > .#{$module}-sub-wrap {
             & > .#{$module}-sub-title {
                 color: $color-navigation_itemL1-text-default;
@@ -483,9 +502,9 @@ $module: #{$prefix}-navigation;
         }
     }
 
-    .#{$module}-item:last-of-type {
-        margin-bottom: $spacing-navigation_vertical_nav_item_last-marginBottom;
-    }
+    // .#{$module}-item:last-of-type {
+    //     margin-bottom: $spacing-navigation_vertical_nav_item_last-marginBottom;
+    // }
 
     .#{$module}-inner {
         flex-direction: column;
@@ -714,4 +733,97 @@ $module: #{$prefix}-navigation;
     }
 }
 
+// The following css is used for the variant generation of NavItem and NavSub in C2D
+.#{$module}-first-layer {
+    > .#{$module}-sub-title {
+        .#{$module}-item-text {
+            font-weight: 600;
+        }
+    }
+
+    > .#{$module}-item-text {
+        font-weight: 600;
+    }
+}
+
+.#{$module}-sub-title-selected {
+    .#{$module}-item-icon:first-child {
+        color: $color-navigation_itemL1_selected_icon-default;
+    }
+}
+
+.#{$module}-sub-wrap {
+    .#{$module}-sub-title {
+        margin-bottom: $spacing-navigation_sub_title-marginBottom;
+    }
+
+    .#{$module}-item:last-of-type {
+        margin-bottom: $spacing-navigation_vertical_nav_item_last-marginBottom;
+    } 
+}
+
+.#{$module}-sub-title {
+    &.#{$module}-sub-title-disabled {
+        .semi-navigation-item-text {
+            color: $color-navigation_itemL1_disabled-text-default;
+        }
+    }
+}
+
+.#{$module}-item-horizontal {
+    // The width of nav NavItem and NavSub in the horizontal direction both need fit-content
+    &.#{$module}-item { 
+        width: fit-content;
+        margin-bottom: $spacing-navigation_horizontal_nav_list_item-marginBottom;
+        margin-right: $spacing-navigation_horizontal_nav_list_item_not_last-marginRight;
+
+        &.#{$module}-item-disabled {
+            color: $color-navigation_horizontal_itemL1_disabled-text-default;
+        }
+    }
+
+    .#{$module}-sub-title {
+        .#{$module}-item-icon:first-child,
+        .#{$module}-item-text {
+            color: var(--semi-color-text-2);
+            background-color: transparent;
+        }
+
+        &.#{$module}-sub-title-selected {
+            .#{$module}-item-icon:first-child,
+            .#{$module}-item-text {
+                color: $color-navigation_horizontal_itemL1_selected-text-default;
+            }
+        }
+
+        &.#{$module}-sub-title-disabled {
+            .#{$module}-item-icon:first-child,
+            .#{$module}-item-text {
+                color: $color-navigation_horizontal_itemL1_disabled-text-default;
+            }
+        }
+    }
+
+    &.#{$module}-first-layer {
+        color: $color-navigation_horizontal_itemL1-text-default;
+    }
+
+    &.#{$module}-item-selected {
+        background-color: $color-navigation_horizontal_itemL1_selected-bg-default;
+
+        .#{$module}-item-icon:first-child,
+        .#{$module}-item-text {
+            color: $color-navigation_horizontal_itemL1_selected-text-default;
+        }
+    }
+
+    .semi-navigation-item-icon:first-child {
+        margin-right: $spacing-navigation_horizontal_icon_last-marginLeft;
+    }
+
+    .semi-navigation-item-icon:last-child {
+        margin-left: $spacing-navigation_horizontal_icon_first-marginRight;
+    }
+}
+
 @import "./rtl.scss";

+ 3 - 1
packages/semi-foundation/navigation/subNavFoundation.ts

@@ -37,7 +37,9 @@ export interface SubNavAdapter<P = Record<string, any>, S = Record<string, any>>
     notifyGlobalOnSelect(data: OnSelectData): void;
     notifyGlobalOnClick(data: OnClickData): void;
     getIsSelected(itemKey: string | number): boolean;
-    getIsOpen(): boolean
+    getIsOpen(): boolean;
+    getIsCollapsed(): boolean;
+    getMode(): string
 }
 
 export default class SubNavFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<SubNavAdapter<P, S>, P, S> {

+ 30 - 7
packages/semi-ui/navigation/Item.tsx

@@ -4,7 +4,7 @@ import BaseComponent, { BaseProps } from '../_base/baseComponent';
 import React from 'react';
 import PropTypes from 'prop-types';
 import cls from 'classnames';
-import { noop, times } from 'lodash';
+import { noop, times, isUndefined } from 'lodash';
 
 import isNullOrUndefined from '@douyinfe/semi-foundation/utils/isNullOrUndefined';
 import { cloneDeep, isSemiIcon } from '../_utils';
@@ -38,7 +38,15 @@ export interface NavItemProps extends ItemProps, BaseProps {
     onClick?(clickItems: SelectedData): void;
 
     onMouseEnter?: React.MouseEventHandler<HTMLLIElement>;
-    onMouseLeave?: React.MouseEventHandler<HTMLLIElement>
+    onMouseLeave?: React.MouseEventHandler<HTMLLIElement>;
+
+    // used for c2d
+    selected?: boolean;
+    mode?: string;
+    // Why must there be isInSubNav props?
+    // Because the styles of the first level and the second level are different, the style itself is implemented through the css selector, which is related to the upper node
+    // When used alone, there is no upper node and no context, so it is impossible to distinguish whether it is at the first level or the second level
+    isInSubNav?: boolean
 }
 
 export interface SelectedData extends SelectedItemProps<NavItemProps> {
@@ -51,6 +59,7 @@ export interface NavItemState {
 
 export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
     static contextType = NavContext;
+    static elementType: string;
 
     static propTypes = {
         text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
@@ -117,20 +126,23 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
             notifyClick: (...args) => this.props.onClick(...args),
             notifyMouseEnter: (...args) => this.props.onMouseEnter(...args),
             notifyMouseLeave: (...args) => this.props.onMouseLeave(...args),
-            getIsCollapsed: () => this.props.isCollapsed || Boolean(this.context && this.context.isCollapsed) || false,
+            getIsCollapsed: () => this.props.isCollapsed || Boolean(this.context && this.context.isCollapsed),
             getSelected: () =>
-                Boolean(this.context && this.context.selectedKeys && this.context.selectedKeys.includes(this.props.itemKey as string)),
+                this.props.selected || Boolean(this.context && this.context.selectedKeys && this.context.selectedKeys.includes(this.props.itemKey as string)),
             getIsOpen: () =>
                 Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(this.props.itemKey as string)),
+            getIsInSubNav: () => this.props.isInSubNav || Boolean(this.context && this.context.isInSubNav),
+            getMode: () => this.props.mode ?? this.context?.mode,
         };
     }
 
     renderIcon(icon: React.ReactNode, pos: string, isToggleIcon = false, key: number | string = 0) {
+        const mode = this.adapter.getMode();
         if (this.props.isSubNav) {
             return null;
         }
 
-        if (!icon && this.context.mode === strings.MODE_HORIZONTAL) {
+        if (!icon && mode === strings.MODE_HORIZONTAL) {
             return null;
         }
 
@@ -193,14 +205,17 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
             linkOptions,
             disabled,
             level = 0,
-            tabIndex
+            tabIndex,
+            mode: modeInProps,
         } = this.props;
 
-        const { mode, isInSubNav, prefixCls, limitIndent } = this.context;
+        const { prefixCls, limitIndent } = this.context;
 
         const isCollapsed = this.adapter.getIsCollapsed();
 
         const selected = this.adapter.getSelected();
+        const isInSubNav = this.adapter.getIsInSubNav();
+        const mode = this.adapter.getMode();
 
 
         let itemChildren = null;
@@ -259,6 +274,10 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
                 </Dropdown.Item>
             );
         } else {
+            // isFirstLayer 用于决定 semi-navigation-first-layers(仅在 c2中使用) 是否生效
+            // 当 this.props.isInSubNav 存在是,则由 this.props.isInSubNav 决定
+            // 否则由 this.context?.mode 决定,因为第一层节点无context
+            const isFirstLayer = !isUndefined(this.props.isInSubNav) ? !this.props.isInSubNav : isUndefined(this.context?.mode);
             // Items are divided into normal and sub-wrap
             const popoverItemCls = cls(`${className || `${clsPrefix}-normal`}`, {
                 [clsPrefix]: true,
@@ -267,6 +286,8 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
                 [`${clsPrefix}-collapsed`]: isCollapsed,
                 [`${clsPrefix}-disabled`]: disabled,
                 [`${clsPrefix}-has-link`]: typeof link === 'string',
+                [`${cssClasses.PREFIX}-first-layer`]: isFirstLayer,
+                [`${clsPrefix}-horizontal`]: modeInProps === strings.MODE_HORIZONTAL,
             });
             const ariaProps = {
                 'aria-disabled': disabled,
@@ -311,3 +332,5 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
         return itemDom;
     }
 }
+
+NavItem.elementType = 'Nav.Item';

+ 44 - 18
packages/semi-ui/navigation/SubNav.tsx

@@ -19,6 +19,8 @@ import NavContext, { NavContextType } from './nav-context';
 import { times, get } from 'lodash';
 import Collapsible from "../collapsible";
 import CSSAnimation from "../_cssAnimation";
+import { Mode } from 'navigation';
+import { isUndefined } from 'lodash';
 
 export interface ToggleIcon {
     open?: string;
@@ -38,7 +40,10 @@ export interface SubNavProps extends BaseProps {
     onMouseEnter?: React.MouseEventHandler<HTMLLIElement>;
     onMouseLeave?: React.MouseEventHandler<HTMLLIElement>;
     text?: React.ReactNode;
-    toggleIcon?: ToggleIcon
+    toggleIcon?: ToggleIcon;
+    // internal param, used for c2d NavSub variant generation
+    active?: boolean;
+    mode?: string
 }
 
 export interface SubNavState {
@@ -46,6 +51,7 @@ export interface SubNavState {
 }
 
 export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
+    static elementType: string;
     static contextType = NavContext;
 
     static propTypes = {
@@ -96,7 +102,8 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         onMouseLeave: PropTypes.func,
         // Is it disabled
         disabled: PropTypes.bool,
-        level: PropTypes.number
+        level: PropTypes.number,
+        active: PropTypes.bool
     };
 
     static defaultProps = {
@@ -110,6 +117,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             closed: <IconChevronDown aria-hidden={true} />,
         },
         disabled: false,
+        active: false,
     };
 
     titleRef: React.RefObject<HTMLDivElement>;
@@ -162,9 +170,11 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             notifyGlobalOpenChange: (...args) => this._invokeContextFunc('onOpenChange', ...args),
             notifyGlobalOnSelect: (...args) => this._invokeContextFunc('onSelect', ...args),
             notifyGlobalOnClick: (...args) => this._invokeContextFunc('onClick', ...args),
-            getIsSelected: itemKey => Boolean(!isNullOrUndefined(itemKey) && get(this.context, 'selectedKeys', []).includes(String(itemKey))),
+            getIsSelected: itemKey => this.props.active || Boolean(!isNullOrUndefined(itemKey) && get(this.context, 'selectedKeys', []).includes(String(itemKey))),
             getIsOpen: () =>
-                Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(String(this.props.itemKey))),
+                this.props.isOpen || Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(String(this.props.itemKey))),
+            getIsCollapsed: () => this.props.isCollapsed || Boolean(this.context?.isCollapsed),
+            getMode: () => this.props.mode ?? this.context?.mode
         };
     }
 
@@ -179,22 +189,23 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
     handleDropdownVisible = (visible: boolean) => this.foundation.handleDropdownVisibleChange(visible);
 
     renderIcon(icon: React.ReactNode, pos: string, withTransition?: boolean, isToggleIcon = false, key: number | string = 0) {
-        const { prefixCls } = this.context;
+        const { prefixCls = cssClasses.PREFIX } = this.context;
 
         let iconSize = 'large';
         if (pos === strings.ICON_POS_RIGHT) {
             iconSize = 'default';
         }
 
+        const isOpen = this.adapter.getIsOpen();
+
         const className = cls(`${prefixCls}-item-icon`, {
-            [`${prefixCls}-item-icon-toggle-${this.context.toggleIconPosition}`]: isToggleIcon,
-            [`${prefixCls}-item-icon-info`]: !isToggleIcon
+            [`${prefixCls}-item-icon-toggle-${this.context.toggleIconPosition ?? 'right'}`]: isToggleIcon,
+            [`${prefixCls}-item-icon-info`]: !isToggleIcon,
+            [`${prefixCls}-icon-rotate-${isOpen?"180":"0"}-no-transition`]: !withTransition && isToggleIcon,
         });
 
-        const isOpen = this.adapter.getIsOpen();
-
         const iconElem = React.isValidElement(icon) ? (withTransition ? (
-            <CSSAnimation animationState={isOpen?"enter":"leave"} startClassName={`${cssClasses.PREFIX}-icon-rotate-${isOpen?"180":"0"}`}>
+            <CSSAnimation animationState={isOpen?"enter":"leave"} startClassName={`${prefixCls}-icon-rotate-${isOpen?"180":"0"}`}>
                 {({ animationClassName })=>{
                     // @ts-ignore
                     return React.cloneElement(icon, { size: iconSize, className: animationClassName });
@@ -209,13 +220,17 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
     renderTitleDiv() {
         const { text, icon, itemKey, indent, disabled, level } = this.props;
 
-        const { mode, isInSubNav, isCollapsed, prefixCls, subNavMotion, limitIndent } = this.context;
-
+        const { isInSubNav, prefixCls = cssClasses.PREFIX, subNavMotion, limitIndent } = this.context;
+        const isFirstLayer = isUndefined(this.context.mode);
+        const mode = this.adapter.getMode();
         const isOpen = this.adapter.getIsOpen();
+        const isCollapsed = this.adapter.getIsCollapsed();
 
         const titleCls = cls(`${prefixCls}-sub-title`, {
             [`${prefixCls}-sub-title-selected`]: this.adapter.getIsSelected(itemKey),
             [`${prefixCls}-sub-title-disabled`]: disabled,
+            [`${prefixCls}-first-layer`]: isFirstLayer,
+            [`${prefixCls}-sub-title-horizontal`]: mode === strings.MODE_HORIZONTAL,
         });
 
         let withTransition = false;
@@ -250,6 +265,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         }
 
         const isIconChevronRightShow = (!isCollapsed && isInSubNav && mode === strings.MODE_HORIZONTAL) || (isCollapsed && isInSubNav);
+        const toggleIconPositionLeft = this.context.toggleIconPosition === strings.TOGGLE_ICON_LEFT;
 
         const titleDiv = (
             <div
@@ -264,12 +280,12 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             >
                 <div className={`${prefixCls}-item-inner`}>
                     {placeholderIcons}
-                    {this.context.toggleIconPosition === strings.TOGGLE_ICON_LEFT && this.renderIcon(toggleIconType, strings.ICON_POS_RIGHT, withTransition, true, 'key-toggle-position-left')}
+                    {toggleIconPositionLeft && this.renderIcon(toggleIconType, strings.ICON_POS_RIGHT, withTransition, true, 'key-toggle-position-left')}
                     {icon || indent || (isInSubNav && mode !== strings.MODE_HORIZONTAL)
                         ? this.renderIcon(icon, strings.ICON_POS_LEFT, false, false, 'key-inSubNav-position-left')
                         : null}
                     <span className={`${prefixCls}-item-text`}>{text}</span>
-                    {this.context.toggleIconPosition === strings.TOGGLE_ICON_RIGHT && this.renderIcon(toggleIconType, strings.ICON_POS_RIGHT, withTransition, true, 'key-toggle-position-right')}
+                    {!toggleIconPositionLeft && this.renderIcon(toggleIconType, strings.ICON_POS_RIGHT, withTransition, true, 'key-toggle-position-right')}
                 </div>
             </div>
         );
@@ -280,9 +296,11 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
     renderSubUl() {
         const { children, maxHeight } = this.props;
 
-        const { isCollapsed, mode, subNavMotion, prefixCls } = this.context;
+        const { subNavMotion, prefixCls = cssClasses.PREFIX } = this.context;
 
+        const isCollapsed = this.adapter.getIsCollapsed();
         const isOpen = this.adapter.getIsOpen();
+        const mode = this.adapter.getMode();
 
         const isHorizontal = mode === strings.MODE_HORIZONTAL;
 
@@ -315,8 +333,10 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         let _elem: React.ReactNode = elem;
         const { children, dropdownStyle, disabled } = this.props;
 
-        const { mode, isInSubNav, isCollapsed, subNavCloseDelay, subNavOpenDelay, prefixCls, getPopupContainer } = this.context;
+        const { isInSubNav, subNavCloseDelay, subNavOpenDelay, prefixCls = cssClasses.PREFIX, getPopupContainer } = this.context;
 
+        const isCollapsed = this.adapter.getIsCollapsed();
+        const mode = this.adapter.getMode();
         const isOpen = this.adapter.getIsOpen();
         const openKeysIsControlled = this.adapter.getOpenKeysIsControlled();
 
@@ -365,7 +385,10 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
     render() {
         const { itemKey, style, onMouseEnter, onMouseLeave, disabled, text } = this.props;
 
-        const { mode, isCollapsed, prefixCls } = this.context;
+        const { prefixCls = cssClasses.PREFIX } = this.context;
+
+        const mode = this.adapter.getMode();
+        const isCollapsed = this.adapter.getIsCollapsed();
 
         let titleDiv: React.ReactNode = this.renderTitleDiv();
         const subUl = this.renderSubUl();
@@ -387,8 +410,9 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
                 onMouseLeave={onMouseLeave}
                 disabled={disabled}
                 text={text}
+                mode={mode}
             >
-                <NavContext.Provider value={{ ...this.context, isInSubNav: true }}>
+                <NavContext.Provider value={{ ...this.context, mode: mode as Mode, isInSubNav: true }}>
                     {titleDiv}
                     {subUl}
                 </NavContext.Provider>
@@ -396,3 +420,5 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         );
     }
 }
+
+SubNav.elementType = 'Nav.Sub';

+ 255 - 0
packages/semi-ui/navigation/_story/navigation.stories.jsx

@@ -30,6 +30,7 @@ import {
   IconDescend,
   IconSetting,
   IconUserGroup,
+  IconHome
 } from '@douyinfe/semi-icons';
 
 export default {
@@ -334,3 +335,257 @@ export const PopupDemo = () => <GetPopupNav />;
 PopupDemo.story = {
   name: 'getPopupContainer'
 }
+
+export const NavItem = () => {
+  const level1ComProps = {
+    itemKey: 'union',
+    text: '一级导航选项',
+    icon: <IconHome />
+  };
+
+  const level1VerticalComProps = {
+    ...level1ComProps,
+    mode: 'vertical',
+    style: { width: 200 }
+  };
+
+  const level1HorizontalComProps = {
+    ...level1ComProps,
+    mode: 'horizontal'
+  };
+
+  const level2ComProps = {
+    ...level1ComProps,
+    text: '二级导航选项',
+    icon: undefined,
+  };
+
+  const level2VerticalComProps = {
+    ...level2ComProps,
+    style: { width: 200 },
+  }
+
+  const level2HorizontalComProps = {
+    ...level2ComProps,
+    mode: 'horizontal'
+  };
+
+  const collapseProps = {
+    isCollapsed: true,
+    style: { width: 43 },
+  }
+
+  const subNodeChildren = <>
+    <Nav.Item itemKey={'active'} text={'活跃用户'} />
+    <Nav.Item itemKey={'negative'} text={'非活跃用户'} />
+  </>
+
+  return (
+    <>
+      <p>本用例用于C2D</p>
+      <p>形式为vertical</p>
+      <p>Nav.Item 的变体</p>
+      <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+        <p>作为一级变体</p>
+        <Nav.Item
+          {...level1VerticalComProps}
+          isInSubNav={false}
+        />
+        <Nav.Item 
+          {...level1VerticalComProps}
+          isInSubNav={false}
+          selected={true}
+        />
+        <Nav.Item 
+          {...level1VerticalComProps}
+          isInSubNav={false}
+          disabled={true}
+        />
+        <p>isCollapsed</p>
+        <Nav.Item
+          {...level1VerticalComProps}
+          isInSubNav={false}
+          {...collapseProps}
+        />
+        <Nav.Item 
+          {...level1VerticalComProps}
+          isInSubNav={false}
+          selected={true}
+          {...collapseProps}
+
+        />
+        <Nav.Item 
+          {...level1VerticalComProps}
+          isInSubNav={false}
+          disabled={true}
+          {...collapseProps}
+        />
+      </div>
+      <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+        <p>作为二级变体</p>
+        <Nav.Item
+          {...level2VerticalComProps}
+          isInSubNav={true}
+        />
+        <Nav.Item 
+          {...level2VerticalComProps}
+          isInSubNav={true}
+          selected={true}
+        />
+        <Nav.Item 
+          {...level2VerticalComProps}
+          isInSubNav={true}
+          disabled={true}
+        />
+      </div>
+      <p>NavSub变体生成</p>
+      {/* 
+        isOpen 为 true 的状态下,需要在semi-linker中对 ul 进行样式覆盖
+          .semi-navigation-sub-wrap {
+            ul {
+                margin-block-start: 0em;
+                margin-block-end: 0em;
+            }
+          } 
+      */}
+      <div style={{ display: 'flex', alignItems: 'flex-start'}}>
+        <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+          <p>isOpen=true</p>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            isOpen={true}
+            isInSubNav={false}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            isOpen={true}
+            active={true}
+            isInSubNav={false}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            isOpen={true}
+            disabled={true}
+            isInSubNav={false}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+        </div>
+        <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+          <p>isOpen=false</p>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            active={true}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            disabled={true}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <p>collapse</p>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            {...collapseProps}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            active={true}
+            {...collapseProps}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+          <Nav.Sub 
+            {...level1VerticalComProps}
+            disabled={true}
+            {...collapseProps}
+          >
+              {subNodeChildren}
+          </Nav.Sub>
+        </div>
+      </div>
+      {/* horizontal */}
+      <p>horizontal</p>
+      <p>Nav.Item 的变体</p>
+      <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+        <Nav.Item
+          {...level1HorizontalComProps} 
+          isInSubNav={false}
+        />
+        <Nav.Item
+          {...level1HorizontalComProps} 
+          selected={true}
+        />
+        <Nav.Item
+          {...level1HorizontalComProps} 
+          disabled={true}
+        />
+      </div>
+      <p>NavSub变体生成</p>
+      {/*       
+        isOpen 为 true 的状态下,需要在semi-linker中对 ul 进行样式覆盖
+          .semi-navigation-sub-wrap {
+            ul {
+                margin-block-start: 0em;
+                margin-block-end: 0em;
+            }
+          } 
+      */}
+      <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+        <Nav.Sub 
+          {...level1HorizontalComProps} 
+          isOpen={true}
+        >
+            {subNodeChildren}
+        </Nav.Sub>
+        <Nav.Sub 
+          {...level1HorizontalComProps} 
+          active={true}
+          isOpen={true}
+        >
+            {subNodeChildren}
+        </Nav.Sub>
+        <Nav.Sub 
+          {...level1HorizontalComProps} 
+          isOpen={true}
+          disabled={true}
+        >
+            {subNodeChildren}
+        </Nav.Sub>
+      </div>
+      <div style={{ display: 'inline-block', border: '1px solid grey', width: 'fit-content' }}>
+        <Nav.Sub 
+        {...level1HorizontalComProps} 
+          active={false}
+        >
+          {subNodeChildren}
+        </Nav.Sub>
+        <Nav.Sub 
+          {...level1HorizontalComProps} 
+          active={true}
+        >
+          {subNodeChildren}
+        </Nav.Sub>
+        <Nav.Sub 
+          {...level1HorizontalComProps} 
+          disabled={true}
+        >
+          {subNodeChildren}
+        </Nav.Sub>
+     </div>
+    </>
+  )
+}