mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-04 04:10:19 +03:00
fix: simplified section spliting and added side menu top margin to side menu item if tag groups
This commit is contained in:
parent
2996e947e9
commit
01910e0622
|
@ -40,7 +40,12 @@ export class MenuItem extends React.Component<MenuItemProps> {
|
||||||
render() {
|
render() {
|
||||||
const { item, withoutChildren } = this.props;
|
const { item, withoutChildren } = this.props;
|
||||||
return (
|
return (
|
||||||
<MenuItemLi onClick={this.activate} depth={item.depth} data-item-id={item.id}>
|
<MenuItemLi
|
||||||
|
onClick={this.activate}
|
||||||
|
depth={item.depth}
|
||||||
|
data-item-id={item.id}
|
||||||
|
topMargin={item.topMargin}
|
||||||
|
>
|
||||||
{item.type === 'operation' ? (
|
{item.type === 'operation' ? (
|
||||||
<OperationMenuItemContent {...this.props} item={item as OperationModel} />
|
<OperationMenuItemContent {...this.props} item={item as OperationModel} />
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -83,12 +83,12 @@ export const MenuItemUl = styled.ul<{ expanded: boolean }>`
|
||||||
${props => (props.expanded ? '' : 'display: none;')};
|
${props => (props.expanded ? '' : 'display: none;')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const MenuItemLi = styled.li<{ depth: number }>`
|
export const MenuItemLi = styled.li<{ depth: number; topMargin?: boolean }>`
|
||||||
list-style: none inside none;
|
list-style: none inside none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
${props => (props.depth === 0 ? 'margin-top: 15px' : '')};
|
${props => (props.depth === 0 || props.topMargin ? 'margin-top: 15px' : '')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const menuItemDepth = {
|
export const menuItemDepth = {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
setSecuritySchemePrefix,
|
setSecuritySchemePrefix,
|
||||||
JsonPointer,
|
JsonPointer,
|
||||||
extractContent,
|
extractContent,
|
||||||
removeContent,
|
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { MarkdownRenderer } from './MarkdownRenderer';
|
import { MarkdownRenderer } from './MarkdownRenderer';
|
||||||
import { GroupModel, OperationModel } from './models';
|
import { GroupModel, OperationModel } from './models';
|
||||||
|
@ -55,14 +54,18 @@ export class MenuBuilder {
|
||||||
const items: ContentItemModel[] = [];
|
const items: ContentItemModel[] = [];
|
||||||
const tagsMap = MenuBuilder.getTagsWithOperations(spec);
|
const tagsMap = MenuBuilder.getTagsWithOperations(spec);
|
||||||
|
|
||||||
let setionToTheEnd = '';
|
let sectionsBefore = '';
|
||||||
|
let sectionsAfter = '';
|
||||||
|
|
||||||
options.sectionsAtTheEnd.forEach(function(s) {
|
new MarkdownRenderer(options).extractHeadings(spec.info.description || '').forEach(function(h) {
|
||||||
setionToTheEnd += extractContent(spec.info.description || '', s);
|
if (options.sectionsAtTheEnd.includes(h.name)) {
|
||||||
spec.info.description = removeContent(spec.info.description || '', s);
|
sectionsAfter += extractContent(spec.info.description || '', h.name);
|
||||||
|
} else {
|
||||||
|
sectionsBefore += extractContent(spec.info.description || '', h.name);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
items.push(...MenuBuilder.addMarkdownItems(spec.info.description || '', undefined, 1, options));
|
items.push(...MenuBuilder.addMarkdownItems(sectionsBefore, undefined, 1, options));
|
||||||
if (spec['x-tagGroups'] && spec['x-tagGroups'].length > 0) {
|
if (spec['x-tagGroups'] && spec['x-tagGroups'].length > 0) {
|
||||||
items.push(
|
items.push(
|
||||||
...MenuBuilder.getTagGroupsItems(parser, undefined, spec['x-tagGroups'], tagsMap, options),
|
...MenuBuilder.getTagGroupsItems(parser, undefined, spec['x-tagGroups'], tagsMap, options),
|
||||||
|
@ -71,7 +74,15 @@ export class MenuBuilder {
|
||||||
items.push(...MenuBuilder.getTagsItems(parser, tagsMap, undefined, undefined, options));
|
items.push(...MenuBuilder.getTagsItems(parser, tagsMap, undefined, undefined, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push(...MenuBuilder.addMarkdownItems(setionToTheEnd, undefined, 1, options));
|
items.push(
|
||||||
|
...MenuBuilder.addMarkdownItems(
|
||||||
|
sectionsAfter,
|
||||||
|
undefined,
|
||||||
|
1,
|
||||||
|
options,
|
||||||
|
spec['x-tagGroups'] && spec['x-tagGroups'].length > 0, // If tagGroups, add topMargin to side menu item
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +96,7 @@ export class MenuBuilder {
|
||||||
parent: GroupModel | undefined,
|
parent: GroupModel | undefined,
|
||||||
initialDepth: number,
|
initialDepth: number,
|
||||||
options: RedocNormalizedOptions,
|
options: RedocNormalizedOptions,
|
||||||
|
topMargin: boolean = false,
|
||||||
): ContentItemModel[] {
|
): ContentItemModel[] {
|
||||||
const renderer = new MarkdownRenderer(options);
|
const renderer = new MarkdownRenderer(options);
|
||||||
const headings = renderer.extractHeadings(description || '');
|
const headings = renderer.extractHeadings(description || '');
|
||||||
|
@ -99,6 +111,10 @@ export class MenuBuilder {
|
||||||
const mapHeadingsDeep = (_parent, items, depth = 1) =>
|
const mapHeadingsDeep = (_parent, items, depth = 1) =>
|
||||||
items.map(heading => {
|
items.map(heading => {
|
||||||
const group = new GroupModel('section', heading, _parent);
|
const group = new GroupModel('section', heading, _parent);
|
||||||
|
if (topMargin) {
|
||||||
|
group.topMargin = true;
|
||||||
|
topMargin = false;
|
||||||
|
}
|
||||||
group.depth = depth;
|
group.depth = depth;
|
||||||
if (heading.items) {
|
if (heading.items) {
|
||||||
group.items = mapHeadingsDeep(group, heading.items, depth + 1);
|
group.items = mapHeadingsDeep(group, heading.items, depth + 1);
|
||||||
|
|
|
@ -24,6 +24,7 @@ export interface IMenuItem {
|
||||||
parent?: IMenuItem;
|
parent?: IMenuItem;
|
||||||
deprecated?: boolean;
|
deprecated?: boolean;
|
||||||
type: MenuItemType;
|
type: MenuItemType;
|
||||||
|
topMargin?: boolean;
|
||||||
|
|
||||||
deactivate(): void;
|
deactivate(): void;
|
||||||
activate(): void;
|
activate(): void;
|
||||||
|
|
|
@ -28,6 +28,7 @@ export class GroupModel implements IMenuItem {
|
||||||
|
|
||||||
depth: number;
|
depth: number;
|
||||||
level: number;
|
level: number;
|
||||||
|
topMargin: boolean;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -94,17 +94,6 @@ export function extractContent(md: string, heading: string): string {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeContent(md: string, heading: string): string {
|
|
||||||
// remove the content of section with given heading
|
|
||||||
const testRegex = new RegExp(`(^|\\n)#\\s?${heading}\\s*\\n`, 'i');
|
|
||||||
const replaceRegex = new RegExp(`((\\n|^)#\\s*${heading}\\s*(\\n|$)(?:.|\\n)*?)(?=\\n#|$)`, 'i');
|
|
||||||
if (testRegex.test(md)) {
|
|
||||||
return md.replace(replaceRegex, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return md;
|
|
||||||
}
|
|
||||||
|
|
||||||
// credits https://stackoverflow.com/a/46973278/1749888
|
// credits https://stackoverflow.com/a/46973278/1749888
|
||||||
export const mergeObjects = (target: any, ...sources: any[]): any => {
|
export const mergeObjects = (target: any, ...sources: any[]): any => {
|
||||||
if (!sources.length) {
|
if (!sources.length) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user