Skip to content

Commit

Permalink
feat(core): menu hierarchy helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Yuferev committed Mar 20, 2019
1 parent 39c3bd5 commit 6b07bb5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ export * from './overlays'
export * from './block'
export * from './recaptcha'
export * from './recaptcha-field'
export * from './menu'
67 changes: 67 additions & 0 deletions packages/core/src/menu/MenuLevelBuilder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {ReactNode} from 'react'

export interface BaseMenuItem {
id: string
title: ReactNode
}

export type MenuTree<Item extends BaseMenuItem> = Item & {
sub?: MenuTree<Item>[]
}

export class MenuLevel<Item extends BaseMenuItem> {
constructor(public items: Item[] = [], public activeId: string = '') {}
}

export class MenuLevelBuilder<Item extends BaseMenuItem> {
constructor(protected items: MenuTree<Item>[]) {}

protected buildLevels(
activeId: string,
items: MenuTree<Item>[],
levels: MenuLevel<Item>[],
depth = 0,
parentActive = false
): boolean {
if (levels.length <= depth) levels[depth] = new MenuLevel()
const level = levels[depth]
let activeItem: MenuTree<Item> | undefined
for (let item of items) {
const currentActive = item.id === activeId
const sub = item.sub
const childActive =
sub && sub.length > 0
? this.buildLevels(
activeId,
sub,
levels,
depth + 1,
currentActive || parentActive
)
: false
if (currentActive) activeItem = item
if (childActive && !activeItem) activeItem = item
}

if (activeItem) {
level.items = items
level.activeId = activeItem.id
} else if (parentActive) {
level.items = items
level.activeId = items[0].id
}

return !!activeItem
}

/**
* Split MenuTree structure to levels.
*
* @param activeId current menu item id
*/
levels(activeId: string): MenuLevel<Item>[] {
const result: MenuLevel<Item>[] = []
this.buildLevels(activeId, this.items, result)
return result
}
}
1 change: 1 addition & 0 deletions packages/core/src/menu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './MenuLevelBuilder'

0 comments on commit 6b07bb5

Please sign in to comment.