Skip to content

Commit

Permalink
fix(scrollspy): 목차 아이템의 id 값이 중복될 때 발생하던 문제 해결 (#75)
Browse files Browse the repository at this point in the history
포스트 상세 화면에서 각 목차의 제목이 같을 경우
동시에 active 표시되는 현상이 있었고,
클로져를 이용하여 아이디 값이 이미 존재한다면
numbering된 id 값을 사용하도록 하여 문제를 해결함

Signed-off-by: chayeoi <chayeoikeem@gmail.com>
  • Loading branch information
chayeoi committed Mar 1, 2020
1 parent 9843633 commit f77d6a3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/templates/blog-post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Utterances from '../components/utterances'
import { CONTAINER_MAX_WIDTH } from '../constants'
import { Theme } from '../models/Theme'
import UnstructuredTocItem from '../models/UnstructuredTocItem'
import { getToc } from '../utils'
import { getTocCreator } from '../utils'

interface Props {
data: {
Expand Down Expand Up @@ -79,7 +79,7 @@ const BlogPost: React.FC<Props> = ({ data, location }) => {
? `${data.site.siteMetadata.siteUrl}${publicURL}`
: ''

const toc = useMemo(() => getToc(data.mdx.tableOfContents.items, 3), [data.mdx.tableOfContents.items])
const toc = useMemo(() => getTocCreator()(data.mdx.tableOfContents.items, 3), [data.mdx.tableOfContents.items])

const meta = useMemo(() => _.filter(item => Boolean(item.content), [
{
Expand Down
55 changes: 37 additions & 18 deletions src/utils/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,40 @@ export const slugger = (string: string): string => typeof string === 'string'
)(string)
: ''

// XXX: any[] 타입 수정 요망
export const getToc = (items: UnstructuredTocItem[], depth = 1, level = 2): any[] => _.map(item => {
const [, title, slug] = /^(.*?)\s*\{#([\w-]+)\}$/.exec(item.title) ?? [undefined, item.title, slugger(item.title)]

const children = _.compose(
data => _.concat(data, _.filter<UnstructuredTocItem>(item => Boolean(item.title), item.items)),
_.flatten,
_.map(item => item.items),
_.reject<UnstructuredTocItem>(item => Boolean(item.title)),
)(item.items)

return _.pickBy(_.identity, {
slug,
title,
level,
items: item.items && depth > 1 ? getToc(children, depth - 1, level + 1) : undefined,
})
}, items)
export const getTocCreator = () => {
const context: { [key: string]: boolean } = {}

const createSlug = (value: string, n = 0): string => {
const slug = n === 0 ? value : `${value}-${n}`
const isDuplicatedSlug = Boolean(context[slug])

if (isDuplicatedSlug) {
return createSlug(value, n + 1)
}

context[slug] = true

return slug
}

// XXX: any[] 타입 수정 요망
const createToc = (items: UnstructuredTocItem[], depth = 1, level = 2): any[] => _.map(item => {
const [, title, slug] = /^(.*?)\s*\{#([\w-]+)\}$/.exec(item.title) ?? [undefined, item.title, createSlug(slugger(item.title))]

const children = _.compose(
data => _.concat(data, _.filter<UnstructuredTocItem>(item => Boolean(item.title), item.items)),
_.flatten,
_.map(item => item.items),
_.reject<UnstructuredTocItem>(item => Boolean(item.title)),
)(item.items)

return _.pickBy(_.identity, {
slug,
title,
level,
items: item.items && depth > 1 ? createToc(children, depth - 1, level + 1) : undefined,
})
}, items)

return createToc
}

0 comments on commit f77d6a3

Please sign in to comment.