Skip to content

Commit

Permalink
feat: tabs configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jun 17, 2020
1 parent d4e8dd2 commit bd06c05
Show file tree
Hide file tree
Showing 28 changed files with 482 additions and 218 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ There are many developments that have contributed to the creation of `component-

# Showcase sites

- [Gatsby](https://component-controls-gatsby.netlify.app)
- [Gatsby](https://component-controls.com/)

- [Storybook 6 without addon-docs](https://components-storybook-6-no-docs.netlify.app/?path=/story/storybook-starter--overview)

Expand Down
153 changes: 114 additions & 39 deletions core/core/README.md

Large diffs are not rendered by default.

44 changes: 42 additions & 2 deletions core/core/src/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import { Configuration as WebpackConfiguration } from 'webpack';
import { ComponentType } from 'react';
import { ComponentType, ReactNode } from 'react';
import { StoryRenderFn } from './utility';

/**
* story type pages can have multiple tabs with separate page configurations.
*/
export interface TabConfiguration {
/**
* tab route string
*/
route?: string;
/**
* title will be used as tab caption
*/
title: string;
/**
* page container type - a key into the component-controls/pages package
*/
type?: string;
/**
* render function, returns a react component
*/
render?: (props: any) => ReactNode;
}

export type PageTabs = TabConfiguration[];

export type PageType = 'story' | 'blog' | 'page' | 'tags' | 'author';

export interface PageConfiguration {
Expand Down Expand Up @@ -34,6 +58,11 @@ export interface PageConfiguration {
* page container react component
*/
container?: ComponentType | null;

/**
* tabs configuration for story-type pages
*/
tabs?: PageTabs;
}

export type PagesConfiguration = Record<PageType, PageConfiguration>;
Expand All @@ -44,6 +73,12 @@ type WebpackConfigFn = (
) => WebpackConfiguration;
type WebpackConfig = WebpackConfiguration | WebpackConfigFn;

export type PagesOnlyRoutes = Record<
PageType,
Pick<PageConfiguration, 'basePath'> & {
tabs?: Pick<TabConfiguration, 'route'>[];
}
>;
/**
* global configuration used at build time
* stored in a file named main.js/main.ts
Expand All @@ -58,7 +93,7 @@ export interface BuildConfiguration {
/**
* base url path for API documentation pages. Default is "docs/"
*/
pages?: Record<PageType, Pick<PageConfiguration, 'basePath'>>;
pages?: PagesOnlyRoutes;

/**
* page types that are considred as categories fields as well
Expand Down Expand Up @@ -154,6 +189,10 @@ export const defaultRunConfig: RunConfiguration = {
label: 'Docs',
sidebars: true,
topMenu: true,
tabs: [
{ title: 'Documentation', type: 'ClassicPage' },
{ title: 'Testing', type: 'TestingPage' },
],
},
blog: {
label: 'Blog',
Expand All @@ -178,6 +217,7 @@ export const defaultBuildConfig: BuildConfiguration = {
pages: {
story: {
basePath: 'docs/',
tabs: [{ route: 'page' }, { route: 'test' }],
},
blog: {
basePath: 'blogs/',
Expand Down
12 changes: 12 additions & 0 deletions core/core/src/deepMerge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,16 @@ const concatMerge = (dest: any[], src: any[]) => [...dest, ...src];
export const deepMerge = (a: any, b: any) =>
merge(a, b, { arrayMerge: concatMerge });

const mergeArrays = (dest: any[], src: any[]) => {
const result =
src.length > 0
? src.map((s, idx) =>
idx < dest.length ? deepMergeArrays(dest[idx], s) : s,
)
: src;
return result;
};
export const deepMergeArrays = (a: any, b: any) =>
merge(a, b, { arrayMerge: mergeArrays });

export { merge };
21 changes: 13 additions & 8 deletions core/core/src/stories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CodeLocation, PackageInfo, StoryRenderFn } from './utility';
import { StoryComponent } from './components';
import { ComponentControls } from './controls';
import { RunConfiguration, PageType } from './configuration';
import { RunConfiguration, PagesOnlyRoutes, PageType } from './configuration';
/**
* an identifier/variable.argument in the source code
*/
Expand Down Expand Up @@ -351,24 +351,29 @@ export interface StoriesStore {
export const getDocPath = (
pageType: PageType,
doc?: StoriesDoc,
config?: RunConfiguration,
pagesConfig?: PagesOnlyRoutes,
name: string = '',
activeTab?: string,
): string => {
const { basePath = '' } = config?.pages?.[pageType] || {};
const { basePath = '' } = pagesConfig?.[pageType] || {};
return doc
? doc.route || `/${basePath}${doc.title?.toLowerCase()}/`
: `/${basePath}${name}`;
? doc.route ||
`/${basePath}${
activeTab ? `${activeTab}/` : ''
}${doc.title?.toLowerCase()}/`
: `/${basePath}${activeTab ? `${activeTab}/` : ''}${name}/`;
};

export const getStoryPath = (
story?: Story,
doc?: StoriesDoc,
config?: RunConfiguration,
pagesConfig?: PagesOnlyRoutes,
activeTab?: string,
): string => {
if (!story) {
return '';
}

const docsPath = getDocPath('story', doc, config);
return `${docsPath}/#${story.id}`;
const docsPath = getDocPath('story', doc, pagesConfig, undefined, activeTab);
return `${docsPath}#${story.id}`;
};
56 changes: 56 additions & 0 deletions core/core/test/__snapshots__/deepmerge.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`deep merge Should append arrays 1`] = `
Object {
"a": Array [
Object {
"a": "a",
"b": "b",
},
Object {
"c": "c",
"d": "d",
},
],
}
`;

exports[`deep merge Should merge arrays 1`] = `
Object {
"a": Array [
Object {
"a": "a",
"b": "b",
"c": "c",
"d": "d",
},
],
}
`;

exports[`deep merge Should merge arrays and fields 1`] = `
Object {
"a": Array [
Object {
"a": "a",
"b": "c",
},
],
}
`;

exports[`deep merge Should merge arrays mistmatched fields 1`] = `
Object {
"a": Array [
Object {
"b": "c",
},
],
"b": Array [
Object {
"a": "a",
"b": "b",
},
],
}
`;
16 changes: 0 additions & 16 deletions core/core/test/__snapshots__/randomize.test.ts.snap

This file was deleted.

55 changes: 55 additions & 0 deletions core/core/test/deepmerge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { deepMerge, deepMergeArrays } from '../src';
describe('deep merge', () => {
it('Should append arrays', () => {
expect(
deepMerge(
{
a: [{ a: 'a', b: 'b' }],
},
{
a: [{ c: 'c', d: 'd' }],
},
),
).toMatchSnapshot();
});

it('Should merge arrays', () => {
expect(
deepMergeArrays(
{
a: [{ a: 'a', b: 'b' }],
},
{
a: [{ c: 'c', d: 'd' }],
},
),
).toMatchSnapshot();
});
it('Should merge arrays and fields', () => {
expect(
deepMergeArrays(
{
a: [
{ a: 'a', b: 'b' },
{ c: 'c', d: 'd' },
],
},
{
a: [{ b: 'c' }],
},
),
).toMatchSnapshot();
});
it('Should merge arrays mistmatched fields', () => {
expect(
deepMergeArrays(
{
b: [{ a: 'a', b: 'b' }],
},
{
a: [{ b: 'c' }],
},
),
).toMatchSnapshot();
});
});
4 changes: 2 additions & 2 deletions core/store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ _defined in [@component-controls/store/src/Store/Store.ts](https://github.com/cc
| `getFirstDocument*` | **function** getFirstDocument(`pageType`\*: [PageType](#pagetype)): string \| undefined; | |
| `getNextPage*` | **function** getNextPage(`type`\*: [PageType](#pagetype) \| undefined, `docId`\*: string): [StoriesDoc](#storiesdoc) \| undefined; | returns the next page of the same type. |
| `getPageList*` | **function** getPageList(`type`\*: [PageType](#pagetype)): [Pages](#pages); | returns all the documents/pages of a certain type. |
| `getPagePath*` | **function** getPagePath(`pageType`\*: [PageType](#pagetype) \| undefined, `name`\*: string): string; | returns the url path to a document. |
| `getPagePath*` | **function** getPagePath(`pageType`\*: [PageType](#pagetype) \| undefined, `name`\*: string, `activeTab`: string): string; | returns the url path to a document. |
| `getPagesByCategory*` | **function** getPagesByCategory(`category`\*: string, `value`: any): [Pages](#pages); | returns all the documents/pages of a certain category value. |
| `getPrevPage*` | **function** getPrevPage(`type`\*: [PageType](#pagetype) \| undefined, `docId`\*: string): [StoriesDoc](#storiesdoc) \| undefined; | returns the previous page of the same type. |
| `getStore*` | **function** getStore(): [StoriesStore](#storiesstore); | returns an instance of the store |
| `getStory*` | **function** getStory(`storyId`\*: string): [Story](#story); | given a story id return a story from the store |
| `getStoryDoc*` | **function** getStoryDoc(`name`\*: string): [StoriesDoc](#storiesdoc); | given a story doc file title, return a story doc file from the store |
| `getStoryPath*` | **function** getStoryPath(`storyId`\*: string): string; | returns the url path to a story. |
| `getStoryPath*` | **function** getStoryPath(`storyId`\*: string, `activeTab`: string): string; | returns the url path to a story. |
| `getUniquesByCategory*` | **function** getUniquesByCategory(`category`\*: string): \[key: string]: number; | returns all the unique category values (and their cound) for a category field. |
| `initDocs*` | **function** initDocs(): void; | sort documents if a sortfunction is provided. separate docs and blogs |
| `removeObserver*` | **function** removeObserver(`observer`\*: [StoreObserver](#storeobserver)): **function** (`storyId`: string, `propName`: string): void;\[]; | remove installed observer callback function |
Expand Down
7 changes: 4 additions & 3 deletions core/store/src/Store/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,22 @@ export class Store implements StoryStore {
getPagePath = (
pageType: PageType | undefined = defPageType,
name: string,
activeTab?: string,
): string => {
const doc = this.getStoryDoc(name);
return getDocPath(pageType, doc, this.config, name);
return getDocPath(pageType, doc, this.config?.pages, name, activeTab);
};

/**
* returns the url path to a story.
*/
getStoryPath = (storyId: string): string => {
getStoryPath = (storyId: string, activeTab?: string): string => {
const story = this.getStory(storyId);
if (!story) {
return '';
}
const doc = this.getStoryDoc(story?.doc || '');
return getStoryPath(story, doc, this.config);
return getStoryPath(story, doc, this.config?.pages, activeTab);
};

/**
Expand Down
6 changes: 5 additions & 1 deletion core/store/src/serialization/load-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import {
StoriesStore,
Story,
deepMergeArrays,
deepMerge,
defaultRunConfig,
} from '@component-controls/core';
Expand Down Expand Up @@ -36,7 +37,10 @@ export const loadStoryStore = (
stories: {},
components: {},
packages: {},
config: deepMerge(buildConfig, deepMerge(defaultRunConfig, config)),
config: deepMergeArrays(
buildConfig,
deepMergeArrays(defaultRunConfig, config),
),
};
stores.forEach(s => {
const storeDoc = s.doc;
Expand Down
8 changes: 6 additions & 2 deletions core/store/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ export interface StoryStore {
getUniquesByCategory: (category: string) => { [key: string]: number };
config: RunConfiguration | undefined;
getFirstDocument: (pageType: PageType) => string | undefined;
getPagePath: (pageType: PageType | undefined, name: string) => string;
getStoryPath: (storyId: string) => string;
getPagePath: (
pageType: PageType | undefined,
name: string,
activeTab?: string,
) => string;
getStoryPath: (storyId: string, activeTab?: string) => string;
updateStoryProp: (
storyId: string,
propName: string,
Expand Down

This file was deleted.

Loading

0 comments on commit bd06c05

Please sign in to comment.