Skip to content

Commit

Permalink
feat: ordering menu on doczrc (#322)
Browse files Browse the repository at this point in the history
* feat(docz): ordering-menu-through-doczrc

* chore: change unknown pos to infinity

* chore: change config interface so it will not break when we need to add
more options
  • Loading branch information
mpivaa authored and pedronauck committed Sep 12, 2018
1 parent fa4a649 commit 0efb905
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 6 deletions.
5 changes: 5 additions & 0 deletions packages/docz-core/src/commands/args.ts
Expand Up @@ -24,6 +24,10 @@ const getInitialDescription = (pkg: any): string =>
export type Env = 'production' | 'development'
export type ThemeConfig = Record<string, any>

type SubMenuConfig = string[]
export interface MenuConfig { name: string, docs: SubMenuConfig }
export type RootMenuConfig = Array<string | MenuConfig> | null

export interface HtmlContext {
lang: string
favicon?: string
Expand Down Expand Up @@ -75,6 +79,7 @@ export interface Config extends Argv {
hastPlugins: any[]
themeConfig: ThemeConfig
htmlContext: HtmlContext
menu: RootMenuConfig
modifyBundlerConfig<C>(config: C, dev: boolean, args: Config): C
modifyBabelRc(babelrc: BabelRC, args: Config): BabelRC
}
Expand Down
4 changes: 3 additions & 1 deletion packages/docz-core/src/states/config.ts
Expand Up @@ -5,14 +5,15 @@ import equal from 'fast-deep-equal'
import get from 'lodash.get'

import { Params, State } from '../DataServer'
import { Config, ThemeConfig } from '../commands/args'
import { Config, RootMenuConfig, ThemeConfig } from '../commands/args'
import { getRepoUrl } from '../utils/repo-info'
import * as paths from '../config/paths'

interface Payload {
title: string
description: string
ordering: string
menu: RootMenuConfig
themeConfig: ThemeConfig
version: string | null
repository: string | null
Expand All @@ -27,6 +28,7 @@ const getInitialConfig = (config: Config): Payload => {
title: config.title,
description: config.description,
themeConfig: config.themeConfig,
menu: config.menu,
ordering: config.ordering,
version: get(pkg, 'version'),
repository: repoUrl,
Expand Down
1 change: 1 addition & 0 deletions packages/docz-core/src/utils/load-config.ts
Expand Up @@ -22,6 +22,7 @@ export const loadConfig = (args: Config): Config => {
hastPlugins: [],
themeConfig: {},
htmlContext: defaultHtmlContext,
menu: null,
modifyBundlerConfig: (config: any) => config,
modifyBabelRc: (babelrc: BabelRC) => babelrc,
})
Expand Down
66 changes: 61 additions & 5 deletions packages/docz/src/components/Docs.tsx
Expand Up @@ -2,18 +2,69 @@ import * as React from 'react'
import { Children } from 'react'
import sort from 'array-sort'

import { state, Entry, EntryMap, Config } from '../state'
import { state, Entry, EntryMap, Config, MenuConfig } from '../state'
import { entriesSelector } from './DocPreview'
import { configSelector } from './ThemeConfig'

export const isFn = (value: any): boolean => typeof value === 'function'

const sortBy = (a: any, b: any, reverse?: boolean) => {
const compare = (a: any, b: any, reverse?: boolean) => {
if (a < b) return reverse ? 1 : -1
if (a > b) return reverse ? -1 : 1
return 0
}

const UNKNOWN_POS = Infinity

const comparePositionInConfig = (
a: string,
b: string,
menu: string | null,
config: Config
) => {

if(config.menu) {
const orderedMenuList = config.menu.map(m => {
return typeof m === 'string' ? m : m.name
})

if(menu) {
const menuPos = findPos(menu, orderedMenuList)

if(menuPos !== UNKNOWN_POS && typeof config.menu[menuPos] === 'object') {
const menuConfig = config.menu[menuPos] as MenuConfig
const orderedList = menuConfig.docs

return compare(
findPos(a, orderedList),
findPos(b, orderedList)
)
}
} else {
return compare(
findPos(a, orderedMenuList),
findPos(b, orderedMenuList)
)
}
}
return 0
}

const compareEntryPositionInConfig = (a: Entry, b: Entry, config: Config) => {
if(a.menu === b.menu) {
return comparePositionInConfig(a.name, b.name, a.menu, config)
}
return 0
}

const findPos = (name: string, orderedList: string[] | null) => {
if(!orderedList) {
return UNKNOWN_POS
}
const pos = orderedList.findIndex(item => item === name)
return pos !== -1 ? pos : UNKNOWN_POS
}

const menuFromEntries = (entries: Entry[]) =>
Array.from(
new Set(
Expand Down Expand Up @@ -49,13 +100,18 @@ export const Docs: React.SFC<DocsProps> = ({ children }) => {

const arr = Object.values(entries)
const menusArr = menuFromEntries(arr)
const menus = sort(menusArr, (a: Entry, b: Entry) => sortBy(a, b))
const menus = sort(
menusArr,
(a: string, b: string) => comparePositionInConfig(a, b, null, config),
(a: string, b: string) => compare(a, b)
)
const descending = config.ordering === 'descending'

const docs: Entry[] = sort(
arr,
(a: Entry, b: Entry) => sortBy(a.order, b.order, descending),
(a: Entry, b: Entry) => sortBy(a.name, b.name)
(a: Entry, b: Entry) => compareEntryPositionInConfig(a, b, config),
(a: Entry, b: Entry) => compare(a.order, b.order, descending),
(a: Entry, b: Entry) => compare(a.name, b.name)
)

return Children.only(
Expand Down
5 changes: 5 additions & 0 deletions packages/docz/src/state.ts
Expand Up @@ -34,11 +34,16 @@ export interface ThemeConfig {
[key: string]: any
}

type SubMenuConfig = string[]
export interface MenuConfig { name: string, docs: SubMenuConfig }
export type RootMenuConfig = Array<string | MenuConfig> | null

export interface Config {
title: string
description: string
ordering: string
themeConfig: ThemeConfig
menu: RootMenuConfig
version: string | null
repository: string | null
native: boolean
Expand Down

0 comments on commit 0efb905

Please sign in to comment.