Skip to content

Commit

Permalink
Fix exampleMode
Browse files Browse the repository at this point in the history
  • Loading branch information
sapegin committed May 11, 2021
1 parent 2c9eade commit d06cb34
Show file tree
Hide file tree
Showing 20 changed files with 171 additions and 68 deletions.
2 changes: 1 addition & 1 deletion src/client/rsg-components/Components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as Rsg from '../../../typings';
interface ComponentsProps {
components: Rsg.Component[];
depth: number;
exampleMode?: string;
exampleMode: string;
usageMode?: string;
}

Expand Down
17 changes: 9 additions & 8 deletions src/client/rsg-components/ComponentsList/ComponentsList.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import { render } from '@testing-library/react';
import ComponentsList from './ComponentsList';
import Context from '../Context';
import * as Rsg from '../../../typings';

const context = {
config: {
Expand All @@ -24,7 +25,7 @@ it('should not render any links when the list is empty', () => {
});

it('should ignore items without visibleName', () => {
const components = [
const components: Rsg.TOCItem[] = [
{
visibleName: 'Button',
slug: 'button',
Expand All @@ -42,13 +43,13 @@ it('should ignore items without visibleName', () => {
</Provider>
);

expect(Array.from(getAllByRole('link')).map(node => (node as HTMLAnchorElement).href)).toEqual([
expect(Array.from(getAllByRole('link')).map((node) => (node as HTMLAnchorElement).href)).toEqual([
'http://localhost/#button',
]);
});

it('should show content of items that are open and not what is closed', () => {
const components = [
const components: Rsg.TOCItem[] = [
{
visibleName: 'Button',
name: 'Button',
Expand All @@ -74,12 +75,12 @@ it('should show content of items that are open and not what is closed', () => {
getByText('Button').click();

expect(
Array.from(getAllByTestId('content')).map(node => (node as HTMLDivElement).innerHTML)
Array.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)
).toEqual(['Content for Button']);
});

it('should show content of initialOpen items even if they are not active', () => {
const components = [
const components: Rsg.TOCItem[] = [
{
visibleName: 'Button',
name: 'Button',
Expand All @@ -106,12 +107,12 @@ it('should show content of initialOpen items even if they are not active', () =>
getByText('Button').click();

expect(
Array.from(getAllByTestId('content')).map(node => (node as HTMLDivElement).innerHTML)
Array.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)
).toEqual(['Content for Button', 'Content for Input']);
});

it('should show content of forcedOpen items even if they are initially collapsed', () => {
const components = [
const components: Rsg.TOCItem[] = [
{
visibleName: 'Button',
name: 'Button',
Expand Down Expand Up @@ -140,6 +141,6 @@ it('should show content of forcedOpen items even if they are initially collapsed
getByText('Input').click();

expect(
Array.from(getAllByTestId('content')).map(node => (node as HTMLDivElement).innerHTML)
Array.from(getAllByTestId('content')).map((node) => (node as HTMLDivElement).innerHTML)
).toEqual(['Content for Button', 'Content for Input']);
});
12 changes: 8 additions & 4 deletions src/client/rsg-components/Examples/Examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,25 @@ import * as Rsg from '../../../typings';
export interface ExamplesRenderer {
content: Rsg.ExamplesModule;
componentName?: string;
exampleMode?: string;
exampleMode: string;
}

const Examples: React.FunctionComponent<ExamplesRenderer> = ({ content, componentName }) => {
const Examples: React.FunctionComponent<ExamplesRenderer> = ({
content,
componentName,
exampleMode,
}) => {
const ExampleComponent = content.default;
return (
<ExamplesRenderer componentName={componentName}>
<ExampleComponent componentName={componentName} />
<ExampleComponent componentName={componentName} exampleMode={exampleMode} />
</ExamplesRenderer>
);
};

Examples.propTypes = {
content: PropTypes.any.isRequired,
componentName: PropTypes.string.isRequired,
componentName: PropTypes.string,
exampleMode: PropTypes.string.isRequired,
};

Expand Down
2 changes: 1 addition & 1 deletion src/client/rsg-components/Playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as Rsg from '../../../typings';

interface PlaygroundProps {
componentName: string;
exampleMode?: string;
exampleMode: string;
code: string;
documentScope: Record<string, unknown>;
exampleScope: Record<string, unknown>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ExamplePlaceholder =
interface ReactComponentProps {
component: Rsg.Component;
depth: number;
exampleMode?: string;
exampleMode: string;
usageMode?: string;
}

Expand Down
51 changes: 47 additions & 4 deletions src/client/rsg-components/TableOfContents/TableOfContents.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ const components = [

const sections: Rsg.Section[] = [
{
exampleMode: 'collapse',
visibleName: 'Introduction',
name: 'Introduction',
href: '#introduction',
slug: 'introduction',
content: module,
},
{
exampleMode: 'collapse',
visibleName: 'Buttons',
name: 'Buttons',
href: '#buttons',
Expand All @@ -63,6 +65,7 @@ const sections: Rsg.Section[] = [
],
},
{
exampleMode: 'collapse',
visibleName: 'Forms',
name: 'Forms',
href: '#forms',
Expand Down Expand Up @@ -90,6 +93,7 @@ it('should filter list when search field contains a query', () => {
<TableOfContents
sections={[
{
exampleMode: 'collapse',
visibleName: 'Input',
href: '#input',
components,
Expand Down Expand Up @@ -144,15 +148,18 @@ it('should render components with useRouterLinks', () => {
useRouterLinks
sections={[
{
exampleMode: 'collapse',
sections: [
{
exampleMode: 'collapse',
visibleName: '1',
name: 'Components',
href: '#/Components',
slug: 'components',
content: module,
},
{
exampleMode: 'collapse',
visibleName: '2',
content: module,
href: '#/Chap',
Expand Down Expand Up @@ -186,21 +193,39 @@ it('should detect sections containing current selection when tocMode is collapse
tocMode="collapse"
sections={[
{
exampleMode: 'collapse',
sections: [
{
exampleMode: 'collapse',
visibleName: '1',
href: '#/components',
slug: 'components',
sections: [{ visibleName: '1.1', href: '#/button', slug: 'button' }],
sections: [
{
exampleMode: 'collapse',
visibleName: '1.1',
href: '#/button',
slug: 'button',
},
],
},
{
exampleMode: 'collapse',
visibleName: '2',
href: '#/chap',
slug: 'chap',
content: module,
sections: [{ visibleName: '2.1', href: '#/chapter-1', slug: 'chapter-1' }],
sections: [
{
exampleMode: 'collapse',
visibleName: '2.1',
href: '#/chapter-1',
slug: 'chapter-1',
},
],
},
{
exampleMode: 'collapse',
visibleName: '3',
href: 'http://react-styleguidist.com',
slug: 'react-styleguidist',
Expand All @@ -222,22 +247,40 @@ it('should show sections with expand: true when tocMode is collapse', () => {
tocMode="collapse"
sections={[
{
exampleMode: 'collapse',
sections: [
{
exampleMode: 'collapse',
visibleName: '1',
expand: true,
href: '#/components',
slug: 'components',
sections: [{ visibleName: '1.1', href: '#/button', slug: 'button' }],
sections: [
{
exampleMode: 'collapse',
visibleName: '1.1',
href: '#/button',
slug: 'button',
},
],
},
{
exampleMode: 'collapse',
visibleName: '2',
href: '#/chap',
slug: 'chap',
content: module,
sections: [{ visibleName: '2.1', href: '#/chapter-1', slug: 'chapter-1' }],
sections: [
{
exampleMode: 'collapse',
visibleName: '2.1',
href: '#/chapter-1',
slug: 'chapter-1',
},
],
},
{
exampleMode: 'collapse',
visibleName: '3',
href: 'http://react-styleguidist.com',
slug: 'react-styleguidist',
Expand Down
41 changes: 25 additions & 16 deletions src/client/rsg-components/TableOfContents/TableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import ComponentsList from 'rsg-components/ComponentsList';
import TableOfContentsRenderer from 'rsg-components/TableOfContents/TableOfContentsRenderer';
import filterSectionsByName from '../../utils/filterSectionsByName';
import filterComponentsByName from '../../utils/filterComponentsByName';
import { getHash } from '../../utils/handleHash';
import * as Rsg from '../../../typings';

Expand Down Expand Up @@ -30,7 +31,7 @@ export default class TableOfContents extends Component<TableOfContentsProps> {
};

private renderLevel(
sections: Rsg.TOCItem[],
sections: (Rsg.Section | Rsg.Component)[],
useRouterLinks = false,
hashPath: string[] = [],
useHashId = false
Expand All @@ -40,33 +41,41 @@ export default class TableOfContents extends Component<TableOfContentsProps> {
const windowHash = pathname + (useRouterLinks ? hash : getHash(hash));

let childrenContainSelected = false;
const processedItems = sections.map((section) => {
const children = [...(section.sections || []), ...(section.components || [])];
const sectionDepth = section.sectionDepth || 0;
const processedItems: Rsg.TOCItem[] = sections.map((tocItem) => {
const children = [
...('sections' in tocItem ? tocItem.sections || [] : []),
...('components' in tocItem ? tocItem.components || [] : []),
];
const sectionDepth = 'sectionDepth' in tocItem ? tocItem.sectionDepth || 0 : 0;
const childHashPath =
sectionDepth === 0 && useHashId
? hashPath
: [...hashPath, section.name ? section.name : '-'];
: [...hashPath, tocItem.name ? tocItem.name : '-'];

const { content, containsSelected } =
children.length > 0
? this.renderLevel(children, useRouterLinks, childHashPath, sectionDepth === 0)
: { content: undefined, containsSelected: false };

const selected =
(!useRouterLinks && section.href ? getHash(section.href) : section.href) === windowHash;
(!useRouterLinks && tocItem.href ? getHash(tocItem.href) : tocItem.href) === windowHash;

if (containsSelected || selected) {
childrenContainSelected = true;
}

return {
...section,
heading: !!section.name && children.length > 0,
...tocItem,
heading: !!tocItem.name && children.length > 0,
content,
selected,
shouldOpenInNewTab: !!section.external && !!section.externalLink,
initialOpen: this.props.tocMode !== 'collapse' || containsSelected || section.expand,
shouldOpenInNewTab:
!!('external' in tocItem && tocItem.external) &&
!!('externalLink' in tocItem && tocItem.externalLink),
initialOpen:
this.props.tocMode !== 'collapse' ||
containsSelected ||
('expand' in tocItem && tocItem.expand),
forcedOpen: !!this.state.searchTerm.length,
};
});
Expand All @@ -84,14 +93,14 @@ export default class TableOfContents extends Component<TableOfContentsProps> {
// Since a section can contain only other sections,
// we need to make sure not to loose the subsections.
// We will treat those subsections as the new roots.
const firstLevel =
// TODO: Extract into a function
const filtered =
sections.length === 1
? // only use subsections if there actually are subsections
sections[0].sections && sections[0].sections.length
? sections[0].sections
: sections[0].components
: sections;
const filtered = firstLevel ? filterSectionsByName(firstLevel, searchTerm) : firstLevel || [];
sections[0].sections && sections[0].sections.length > 0
? filterSectionsByName(sections[0].sections, searchTerm)
: filterComponentsByName(sections[0].components || [], searchTerm)
: filterSectionsByName(sections, searchTerm);

return this.renderLevel(filtered, useRouterLinks).content;
}
Expand Down
4 changes: 3 additions & 1 deletion src/client/rsg-components/mdx/MdxContext.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { createContext } from 'react';
import { ExampleModes } from '../../consts';

interface MdxContextContents {
/** Name of the React component */
componentName?: string;
/** How to render an editor: expanded or not */
exampleMode?: string;
exampleMode: string;
/** Modules imported inside Mdx file */
documentScope: Record<string, unknown>;
/** Modules imported inside examples */
Expand All @@ -14,6 +15,7 @@ interface MdxContextContents {
}

const MdxContext = createContext<MdxContextContents>({
exampleMode: ExampleModes.collapse,
documentScope: {},
exampleScope: {},
namedExamples: {},
Expand Down
2 changes: 1 addition & 1 deletion src/client/rsg-components/mdx/MdxWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as Rsg from '../../../typings';
interface Props extends Rsg.MdxExtras {
children?: ReactNode;
componentName?: string;
exampleMode?: string;
exampleMode: string;
}

export default function MdxWrapper({
Expand Down
Loading

0 comments on commit d06cb34

Please sign in to comment.