Skip to content

Commit 7115262

Browse files
committed
chore: edit typing for collapsible list
1 parent a2e1a61 commit 7115262

File tree

4 files changed

+71
-53
lines changed

4 files changed

+71
-53
lines changed

src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ConditionalWrap } from '@Common/Helper'
55
import { ReactComponent as ICExpand } from '@Icons/ic-expand.svg'
66

77
import { Collapse } from '../Collapse'
8-
import { CollapsibleListItem, CollapsibleListProps } from './CollapsibleList.types'
8+
import { CollapsibleListItem, CollapsibleListProps, TabOptions } from './CollapsibleList.types'
99
import './CollapsibleList.scss'
1010

1111
const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElement) => (
@@ -14,10 +14,14 @@ const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElemen
1414
</Tippy>
1515
)
1616

17-
export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListProps) => {
17+
export const CollapsibleList = <TabType extends TabOptions>({
18+
config,
19+
tabType,
20+
onCollapseBtnClick,
21+
}: CollapsibleListProps<TabType>) => {
1822
const { pathname } = useLocation()
1923

20-
const getTabContent = (item: CollapsibleListItem) => {
24+
const getTabContent = (item: CollapsibleListItem<TabOptions>) => {
2125
const { title, subtitle, iconConfig } = item
2226
return (
2327
<>
@@ -40,27 +44,8 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP
4044
)
4145
}
4246

43-
const getTabItem = (item: CollapsibleListItem) => {
44-
const { title, href, isActive, onClick, tabType } = item
45-
if (tabType === 'navLink') {
46-
return (
47-
<NavLink
48-
key={title}
49-
to={href}
50-
className="collapsible__item flexbox dc__align-items-center dc__gap-8 dc__no-decor br-4 py-6 px-8 cursor"
51-
onClick={(e) => {
52-
// Prevent navigation to the same page
53-
if (href === pathname) {
54-
e.preventDefault()
55-
}
56-
onClick?.(e)
57-
}}
58-
>
59-
{getTabContent(item)}
60-
</NavLink>
61-
)
62-
}
63-
// Since is active is boolean we need to explicitly handle for null
47+
const getButtonTabItem = (item: CollapsibleListItem<'button'>) => {
48+
const { title, isActive, onClick } = item
6449
return (
6550
<button
6651
key={title}
@@ -79,6 +64,26 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP
7964
)
8065
}
8166

67+
const getNavLinkTabItem = (item: CollapsibleListItem<'navLink'>) => {
68+
const { title, href, onClick } = item
69+
return (
70+
<NavLink
71+
key={title}
72+
to={href}
73+
className="collapsible__item flexbox dc__align-items-center dc__gap-8 dc__no-decor br-4 py-6 px-8 cursor"
74+
onClick={(e) => {
75+
// Prevent navigation to the same page
76+
if (href === pathname) {
77+
e.preventDefault()
78+
}
79+
onClick?.(e)
80+
}}
81+
>
82+
{getTabContent(item)}
83+
</NavLink>
84+
)
85+
}
86+
8287
return (
8388
<div className="mw-none bcn-0">
8489
{config.map(({ id, header, headerIconConfig, items, noItemsText, isExpanded }) => (
@@ -122,7 +127,11 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP
122127
</span>
123128
</div>
124129
) : (
125-
items.map((item) => getTabItem(item))
130+
items.map((item) =>
131+
tabType === 'button'
132+
? getButtonTabItem(item as CollapsibleListItem<'button'>)
133+
: getNavLinkTabItem(item as CollapsibleListItem<'navLink'>),
134+
)
126135
)}
127136
</div>
128137
</Collapse>

src/Shared/Components/CollapsibleList/CollapsibleList.types.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react'
22
import { TippyProps } from '@tippyjs/react'
33

44
interface ButtonTab {
5-
tabType: 'button'
65
/**
76
* Is tab active ( for button tab )
87
*/
@@ -15,7 +14,6 @@ interface ButtonTab {
1514
}
1615

1716
interface NavLinkTab {
18-
tabType: 'navLink'
1917
/**
2018
* The URL of the nav link.
2119
*/
@@ -27,9 +25,11 @@ interface NavLinkTab {
2725
isActive?: never
2826
}
2927

30-
type ConditionalTabType = ButtonTab | NavLinkTab
28+
export type TabOptions = 'button' | 'navLink'
3129

32-
export type CollapsibleListItem = ConditionalTabType & {
30+
type ConditionalTabType<TabType extends TabOptions> = TabType extends 'button' ? ButtonTab : NavLinkTab
31+
32+
export type CollapsibleListItem<TabType extends TabOptions> = ConditionalTabType<TabType> & {
3333
/**
3434
* The title of the list item.
3535
*/
@@ -57,7 +57,7 @@ export type CollapsibleListItem = ConditionalTabType & {
5757
}
5858
}
5959

60-
export interface CollapsibleListConfig {
60+
export interface CollapsibleListConfig<TabType extends 'button' | 'navLink'> {
6161
/**
6262
* The unique identifier for the collapsible list.
6363
*/
@@ -95,18 +95,22 @@ export interface CollapsibleListConfig {
9595
/**
9696
* An array of items to be displayed in the collapsible list.
9797
*/
98-
items: CollapsibleListItem[]
98+
items: CollapsibleListItem<TabType>[]
9999
/**
100100
* Boolean indicating whether the list is expanded or not.
101101
*/
102102
isExpanded?: boolean
103103
}
104104

105-
export interface CollapsibleListProps {
105+
export interface CollapsibleListProps<TabType extends TabOptions> {
106106
/**
107107
* An array of collapsible list configurations.
108108
*/
109-
config: CollapsibleListConfig[]
109+
config: CollapsibleListConfig<TabType>[]
110+
/**
111+
* Type of tab list: button or navLink
112+
*/
113+
tabType: TabType
110114
/**
111115
* Function to handle the collapse button click event.
112116
*

src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ export type DeploymentConfigDiffSelectPickerProps =
4141
selectPickerProps: SelectPickerProps
4242
}
4343

44-
export interface DeploymentConfigDiffNavigationItem extends Pick<CollapsibleListItem, 'title'> {
44+
export interface DeploymentConfigDiffNavigationItem extends Pick<CollapsibleListItem<'navLink'>, 'title'> {
4545
hasDiff?: boolean
4646
href: string
4747
onClick: (e: React.MouseEvent<HTMLAnchorElement>) => void
4848
}
4949

5050
export interface DeploymentConfigDiffNavigationCollapsibleItem
51-
extends Pick<CollapsibleListConfig, 'id' | 'header' | 'noItemsText'> {
51+
extends Pick<CollapsibleListConfig<'navLink'>, 'id' | 'header' | 'noItemsText'> {
5252
items: DeploymentConfigDiffNavigationItem[]
5353
}
5454

src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,28 @@ export const DeploymentConfigDiffNavigation = ({
3434
}, [collapsibleNavList])
3535

3636
/** Collapsible List Config. */
37-
const collapsibleListConfig: CollapsibleListConfig[] = collapsibleNavList.map(({ items, ...resListItem }) => ({
38-
...resListItem,
39-
isExpanded: expandedIds[resListItem.id],
40-
items: items.map(({ hasDiff, ...resItem }) => ({
41-
tabType: 'navLink',
42-
...resItem,
43-
...(hasDiff
44-
? {
45-
iconConfig: {
46-
Icon: ICDiffFileUpdated,
47-
props: { className: 'icon-dim-16 dc__no-shrink' },
48-
tooltipProps: { content: 'File has difference', arrow: false, placement: 'right' as const },
49-
},
50-
}
51-
: {}),
52-
})),
53-
}))
37+
const collapsibleListConfig: CollapsibleListConfig<'navLink'>[] = collapsibleNavList.map(
38+
({ items, ...resListItem }) => ({
39+
...resListItem,
40+
isExpanded: expandedIds[resListItem.id],
41+
items: items.map(({ hasDiff, ...resItem }) => ({
42+
...resItem,
43+
...(hasDiff
44+
? {
45+
iconConfig: {
46+
Icon: ICDiffFileUpdated,
47+
props: { className: 'icon-dim-16 dc__no-shrink' },
48+
tooltipProps: {
49+
content: 'File has difference',
50+
arrow: false,
51+
placement: 'right' as const,
52+
},
53+
},
54+
}
55+
: {}),
56+
})),
57+
}),
58+
)
5459

5560
// METHODS
5661
/** Handles collapse button click. */
@@ -122,7 +127,7 @@ export const DeploymentConfigDiffNavigation = ({
122127
)}
123128
</NavLink>
124129
))}
125-
<CollapsibleList config={collapsibleListConfig} onCollapseBtnClick={onCollapseBtnClick} />
130+
<CollapsibleList config={collapsibleListConfig} tabType="navLink" onCollapseBtnClick={onCollapseBtnClick} />
126131
{navHelpText && (
127132
<div className="mt-8 py-6 px-8 flexbox dc__align-items-center dc__gap-8">
128133
<span className="flex p-2 dc__align-self-start">

0 commit comments

Comments
 (0)