CustomHTMLElements.utils.ts108 lines · main
1// Check if heading has custom anchor first, before forming the anchor based on the title
2export const getAnchor = (text: any, { id }: { id?: string } = {}): string | undefined => {
3 if (id) {
4 // Component already defines its own id. Since the anchor must match the
5 // id, return it directly.
6 return id
7 }
8
9 if (typeof text === 'object') {
10 if (Array.isArray(text)) {
11 const customAnchor = text.find((x) => typeof x === 'string' && hasCustomAnchor(x))
12 if (customAnchor !== undefined) {
13 return parseCustomAnchor(customAnchor)
14 }
15
16 const formattedText = text
17 .map((x) => {
18 if (typeof x !== 'string') {
19 return x.props.children
20 }
21
22 return x.trim()
23 })
24 .map((x) => {
25 if (typeof x !== 'string') {
26 return x
27 }
28
29 return slugify(x)
30 })
31
32 return formattedText.join('-').toLowerCase()
33 } else {
34 const anchor = text.props.children
35 if (typeof anchor === 'string') {
36 return slugify(anchor)
37 }
38 return anchor
39 }
40 } else if (typeof text === 'string') {
41 if (hasCustomAnchor(text)) {
42 return parseCustomAnchor(text)
43 }
44 return slugify(text)
45 } else {
46 return undefined
47 }
48}
49
50const hasCustomAnchor = (value: string): boolean => value.includes('[#') && value.includes(']')
51
52const parseCustomAnchor = (value: string): string =>
53 value.slice(value.indexOf('[#') + 2, value.indexOf(']'))
54
55const slugify = (value: string): string =>
56 value
57 .toLowerCase()
58 .trim()
59 .replace(/[^a-z0-9- ]/g, '')
60 .replace(/[ ]/g, '-')
61
62export const removeAnchor = (text: any) => {
63 if (typeof text === 'object' && Array.isArray(text)) {
64 return text.filter((x) => !(typeof x === 'string' && hasCustomAnchor(x)))
65 } else if (typeof text === 'string') {
66 if (text.indexOf('[#') > 0) return text.slice(0, text.indexOf('[#'))
67 else return text
68 }
69 return text
70}
71
72export const highlightSelectedTocItem = (id: string) => {
73 const tocMenuItems = document.querySelectorAll('.toc-menu a')
74
75 // find any currently active items and remove them
76 const currentActiveItem = document.querySelector('.toc-menu .toc__menu-item--active')
77 currentActiveItem?.classList.remove('toc__menu-item--active')
78
79 // Add active class to the current item
80 tocMenuItems.forEach((item) => {
81 // @ts-ignore
82 if (item.href.split('#')[1] === id) {
83 item.classList.add('toc__menu-item--active')
84 }
85 })
86}
87
88// find any currently active items and remove them on route change
89export const unHighlightSelectedTocItems = () => {
90 const currentActiveItem = document.querySelector('.toc-menu .toc__menu-item--active')
91 currentActiveItem?.classList.remove('toc__menu-item--active')
92}
93
94export const highlightSelectedNavItem = (id: string) => {
95 const navMenuItems = document.querySelectorAll<HTMLAnchorElement>('.function-link-item a')
96
97 // find any currently active items and remove them
98 const currentActiveItems = document.querySelectorAll('.function-link-list .text-brand')
99 currentActiveItems.forEach((item) => item.classList.remove('text-brand'))
100
101 // Add active class to the current item
102 navMenuItems.forEach((item) => {
103 const parts = item.href.split('/')
104 if (parts[parts.length - 1] === id) {
105 item.classList.add('text-brand')
106 }
107 })
108}