mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-30 23:37:28 +03:00 
			
		
		
		
	chore: refactor, separate active and expanded state for menu items
This commit is contained in:
		
							parent
							
								
									5ebab5f942
								
							
						
					
					
						commit
						a4f79bf8c2
					
				|  | @ -22,20 +22,15 @@ export class MenuItem extends React.Component<MenuItemProps> { | |||
|   }; | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     const item = this.props.item; | ||||
|     if (item.type !== 'group' && item.active) { | ||||
|       this.scrollIntoView(); | ||||
|     } | ||||
|     this.scrollIntoViewIfActive(); | ||||
|   } | ||||
| 
 | ||||
|   componentDidUpdate() { | ||||
|     if (this.props.item.active) { | ||||
|       this.scrollIntoView(); | ||||
|     } | ||||
|     this.scrollIntoViewIfActive(); | ||||
|   } | ||||
| 
 | ||||
|   scrollIntoView() { | ||||
|     if (this.ref) { | ||||
|   scrollIntoViewIfActive() { | ||||
|     if (this.props.item.active && this.ref) { | ||||
|       this.ref.scrollIntoViewIfNeeded(); | ||||
|     } | ||||
|   } | ||||
|  | @ -56,14 +51,14 @@ export class MenuItem extends React.Component<MenuItemProps> { | |||
|         {item.type === 'operation' ? ( | ||||
|           <OperationMenuItemContent {...this.props} item={item as OperationModel} /> | ||||
|         ) : ( | ||||
|           <MenuItemLabel depth={item.depth} active={item.active} type={item.type}> | ||||
|           <MenuItemLabel depth={item.depth} active={item.active || item.expanded} type={item.type}> | ||||
|             <MenuItemTitle title={item.name}> | ||||
|               {item.name} | ||||
|               {this.props.children} | ||||
|             </MenuItemTitle> | ||||
|             {(item.depth > 0 && | ||||
|               item.items.length > 0 && ( | ||||
|                 <ShelfIcon float={'right'} direction={item.active ? 'down' : 'right'} /> | ||||
|                 <ShelfIcon float={'right'} direction={item.expanded ? 'down' : 'right'} /> | ||||
|               )) || | ||||
|               null} | ||||
|           </MenuItemLabel> | ||||
|  | @ -71,7 +66,11 @@ export class MenuItem extends React.Component<MenuItemProps> { | |||
|         {!withoutChildren && | ||||
|           item.items && | ||||
|           item.items.length > 0 && ( | ||||
|             <MenuItems active={item.active} items={item.items} onActivate={this.props.onActivate} /> | ||||
|             <MenuItems | ||||
|               expanded={item.expanded} | ||||
|               items={item.items} | ||||
|               onActivate={this.props.onActivate} | ||||
|             /> | ||||
|           )} | ||||
|       </MenuItemLi> | ||||
|     ); | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import { MenuItemUl } from './styled.elements'; | |||
| 
 | ||||
| export interface MenuItemsProps { | ||||
|   items: IMenuItem[]; | ||||
|   active?: boolean; | ||||
|   expanded?: boolean; | ||||
|   onActivate?: (item: IMenuItem) => void; | ||||
|   style?: React.CSSProperties; | ||||
|   root?: boolean; | ||||
|  | @ -20,12 +20,12 @@ export interface MenuItemsProps { | |||
| export class MenuItems extends React.Component<MenuItemsProps> { | ||||
|   render() { | ||||
|     const { items, root, className } = this.props; | ||||
|     const active = this.props.active == null ? true : this.props.active; | ||||
|     const expanded = this.props.expanded == null ? true : this.props.expanded; | ||||
|     return ( | ||||
|       <MenuItemUl | ||||
|         className={className} | ||||
|         style={this.props.style} | ||||
|         active={active} | ||||
|         expanded={expanded} | ||||
|         {...(root ? { role: 'navigation' } : {})} | ||||
|       > | ||||
|         {items.map((item, idx) => ( | ||||
|  |  | |||
|  | @ -75,7 +75,7 @@ function menuItemActiveBg(depth): string { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| export const MenuItemUl = withProps<{ active: boolean }>(styled.ul)` | ||||
| export const MenuItemUl = withProps<{ expanded: boolean }>(styled.ul)` | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| 
 | ||||
|  | @ -83,7 +83,7 @@ export const MenuItemUl = withProps<{ active: boolean }>(styled.ul)` | |||
|     font-size: 0.929em; | ||||
|   } | ||||
| 
 | ||||
|   ${props => (props.active ? '' : 'display: none;')}; | ||||
|   ${props => (props.expanded ? '' : 'display: none;')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const MenuItemLi = withProps<{ depth: number }>(styled.li)` | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ export interface IMenuItem { | |||
|   description?: string; | ||||
|   depth: number; | ||||
|   active: boolean; | ||||
|   expanded: boolean; | ||||
|   items: IMenuItem[]; | ||||
|   parent?: IMenuItem; | ||||
|   deprecated?: boolean; | ||||
|  | @ -26,6 +27,9 @@ export interface IMenuItem { | |||
| 
 | ||||
|   deactivate(): void; | ||||
|   activate(): void; | ||||
| 
 | ||||
|   collapse(): void; | ||||
|   expand(): void; | ||||
| } | ||||
| 
 | ||||
| export const SECTION_ATTR = 'data-section-id'; | ||||
|  | @ -198,10 +202,8 @@ export class MenuStore { | |||
|       HistoryService.update(item.id, rewriteHistory); | ||||
|     } | ||||
| 
 | ||||
|     while (item !== undefined) { | ||||
|       item.activate(); | ||||
|       item = item.parent; | ||||
|     } | ||||
|     item.activate(); | ||||
|     item.expand(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  | @ -209,8 +211,12 @@ export class MenuStore { | |||
|    * @param item item to deactivate | ||||
|    */ | ||||
|   deactivate(item: IMenuItem | undefined) { | ||||
|     if (item === undefined) { | ||||
|       return; | ||||
|     } | ||||
|     item.deactivate(); | ||||
|     while (item !== undefined) { | ||||
|       item.deactivate(); | ||||
|       item.collapse(); | ||||
|       item = item.parent; | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ export class GroupModel implements IMenuItem { | |||
|   externalDocs?: OpenAPIExternalDocumentation; | ||||
| 
 | ||||
|   @observable active: boolean = false; | ||||
|   @observable expanded: boolean = false; | ||||
| 
 | ||||
|   depth: number; | ||||
|   //#endregion
 | ||||
|  | @ -41,7 +42,7 @@ export class GroupModel implements IMenuItem { | |||
| 
 | ||||
|     // groups are active (expanded) by default
 | ||||
|     if (this.type === 'group') { | ||||
|       this.active = true; | ||||
|       this.expanded = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -51,11 +52,24 @@ export class GroupModel implements IMenuItem { | |||
|   } | ||||
| 
 | ||||
|   @action | ||||
|   deactivate() { | ||||
|     // disallow deactivating groups
 | ||||
|   expand() { | ||||
|     if (this.parent) { | ||||
|       this.parent.expand(); | ||||
|     } | ||||
|     this.expanded = true; | ||||
|   } | ||||
| 
 | ||||
|   @action | ||||
|   collapse() { | ||||
|     // disallow collapsing groups
 | ||||
|     if (this.type === 'group') { | ||||
|       return; | ||||
|     } | ||||
|     this.expanded = false; | ||||
|   } | ||||
| 
 | ||||
|   @action | ||||
|   deactivate() { | ||||
|     this.active = false; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ export class OperationModel implements IMenuItem { | |||
| 
 | ||||
|   @observable ready?: boolean = true; | ||||
|   @observable active: boolean = false; | ||||
|   @observable expanded: boolean = false; | ||||
|   //#endregion
 | ||||
| 
 | ||||
|   pointer: string; | ||||
|  | @ -105,6 +106,16 @@ export class OperationModel implements IMenuItem { | |||
|     this.active = false; | ||||
|   } | ||||
| 
 | ||||
|   expand() { | ||||
|     if (this.parent) { | ||||
|       this.parent.expand(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   collapse() { | ||||
|     /* do nothing */ | ||||
|   } | ||||
| 
 | ||||
|   @memoize | ||||
|   get requestBody() { | ||||
|     return ( | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user