Only load sections into the DOM if their tag is clicked.

This commit is contained in:
Chris Bojemski 2020-01-10 16:12:52 -08:00
parent 1f05af52ff
commit 8d982ae27d
7 changed files with 47 additions and 19 deletions

View File

@ -11,14 +11,19 @@ import { Operation } from '../Operation/Operation';
@observer
export class ContentItems extends React.Component<{
activeSelection?: string;
items: ContentItemModel[];
}> {
render() {
const items = this.props.items;
const activeSelection = this.props.activeSelection;
if (items.length === 0) {
return null;
}
return items.map(item => <ContentItem item={item} key={item.id} />);
const filteredItems = items.filter(item => {
return item.type == "tag" ? item.name == `${activeSelection}` : true;
});
return filteredItems.map(item => <ContentItem item={item} key={item.id} />);
}
}

View File

@ -4,7 +4,7 @@ import * as React from 'react';
import { ThemeProvider } from '../../styled-components';
import { OptionsProvider } from '../OptionsProvider';
import { AppStore } from '../../services';
import { AppStore, IMenuItem } from '../../services';
import { ApiInfo } from '../ApiInfo/';
import { ApiLogo } from '../ApiLogo/ApiLogo';
import { ContentItems } from '../ContentItems/ContentItems';
@ -19,11 +19,17 @@ export interface RedocProps {
store: AppStore;
}
export class Redoc extends React.Component<RedocProps> {
export interface AppState {
activeSelection: string | undefined;
}
export class Redoc extends React.Component<RedocProps, AppState> {
static propTypes = {
store: PropTypes.instanceOf(AppStore).isRequired,
};
state = { activeSelection: undefined };
componentDidMount() {
this.props.store.onDidMount();
}
@ -32,6 +38,12 @@ export class Redoc extends React.Component<RedocProps> {
this.props.store.dispose();
}
setActiveSelection = (item: IMenuItem) => {
if (item && item.type === "tag") {
this.setState({ activeSelection: item.name });
}
}
render() {
const {
store: { spec, menu, options, search, marker },
@ -50,14 +62,15 @@ export class Redoc extends React.Component<RedocProps> {
marker={marker}
getItemById={menu.getItemById}
onActivate={menu.activateAndScroll}
setActiveSelection={() => this.setActiveSelection}
/>
)) ||
null}
<SideMenu menu={menu} />
<SideMenu menu={menu} setActiveSelection={this.setActiveSelection} />
</StickyResponsiveSidebar>
<ApiContentWrap className="api-content">
<ApiInfo store={store} />
<ContentItems items={menu.items as any} />
<ContentItems activeSelection={this.state.activeSelection} items={menu.items as any} />
</ApiContentWrap>
<BackgroundStub />
</RedocWrap>

View File

@ -23,6 +23,8 @@ export interface SearchBoxProps {
onActivate: (item: IMenuItem) => void;
className?: string;
setActiveSelection: () => void;
}
export interface SearchBoxState {
@ -153,6 +155,7 @@ export class SearchBox extends React.PureComponent<SearchBoxProps, SearchBoxStat
withoutChildren={true}
key={res.item.id}
data-role="search:result"
setActiveSelection={() => this.props.setActiveSelection}
/>
))}
</SearchResultsBox>

View File

@ -11,6 +11,7 @@ import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styl
export interface MenuItemProps {
item: IMenuItem;
onActivate?: (item: IMenuItem) => void;
setActiveSelection: (item: IMenuItem) => void;
withoutChildren?: boolean;
}
@ -19,6 +20,7 @@ export class MenuItem extends React.Component<MenuItemProps> {
ref = React.createRef<HTMLLabelElement>();
activate = (evt: React.MouseEvent<HTMLElement>) => {
this.props.setActiveSelection(this.props.item);
this.props.onActivate!(this.props.item);
evt.stopPropagation();
};
@ -44,22 +46,23 @@ 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} ref={this.ref}>
<MenuItemTitle title={item.name}>
{item.name}
{this.props.children}
</MenuItemTitle>
{(item.depth > 0 && item.items.length > 0 && (
<ShelfIcon float={'right'} direction={item.expanded ? 'down' : 'right'} />
)) ||
null}
</MenuItemLabel>
)}
<MenuItemLabel depth={item.depth} active={item.active} type={item.type} ref={this.ref}>
<MenuItemTitle title={item.name}>
{item.name}
{this.props.children}
</MenuItemTitle>
{(item.depth > 0 && item.items.length > 0 && (
<ShelfIcon float={'right'} direction={item.expanded ? 'down' : 'right'} />
)) ||
null}
</MenuItemLabel>
)}
{!withoutChildren && item.items && item.items.length > 0 && (
<MenuItems
expanded={item.expanded}
items={item.items}
onActivate={this.props.onActivate}
setActiveSelection={() => this.props.setActiveSelection}
/>
)}
</MenuItemLi>

View File

@ -14,6 +14,8 @@ export interface MenuItemsProps {
root?: boolean;
className?: string;
setActiveSelection: (item: IMenuItem) => void;
}
@observer
@ -29,7 +31,7 @@ export class MenuItems extends React.Component<MenuItemsProps> {
{...(root ? { role: 'navigation' } : {})}
>
{items.map((item, idx) => (
<MenuItem key={idx} item={item} onActivate={this.props.onActivate} />
<MenuItem key={idx} item={item} onActivate={this.props.onActivate} setActiveSelection={this.props.setActiveSelection} />
))}
</MenuItemUl>
);

View File

@ -9,7 +9,7 @@ import { PerfectScrollbarWrap } from '../../common-elements/perfect-scrollbar';
import { RedocAttribution } from './styled.elements';
@observer
export class SideMenu extends React.Component<{ menu: MenuStore; className?: string }> {
export class SideMenu extends React.Component<{ menu: MenuStore; className?: string; setActiveSelection: (item: IMenuItem) => void }> {
static contextType = OptionsContext;
private _updateScroll?: () => void;
@ -23,7 +23,7 @@ export class SideMenu extends React.Component<{ menu: MenuStore; className?: str
wheelPropagation: false,
}}
>
<MenuItems items={store.items} onActivate={this.activate} root={true} />
<MenuItems items={store.items} onActivate={this.activate} root={true} setActiveSelection={this.props.setActiveSelection} />
<RedocAttribution>
<a target="_blank" href="https://github.com/Redocly/redoc">
Documentation Powered by ReDoc

View File

@ -64,6 +64,8 @@ export class MenuStore {
items: IMenuItem[];
flatItems: IMenuItem[];
activeSelection?: string;
/**
* cached flattened menu items to support absolute indexing
*/