Skip to content

Commit 7a91d91

Browse files
committed
feat: ActionMenu - add support for trailing item - button
1 parent 5e871a0 commit 7a91d91

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

src/Shared/Components/ActionMenu/ActionMenuItem.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'
44
import { Tooltip } from '@Common/Tooltip'
55
import { ComponentSizeType } from '@Shared/constants'
66

7+
import { Button, ButtonProps, ButtonVariantType } from '../Button'
78
import { Icon } from '../Icon'
89
import { getTooltipProps } from '../SelectPicker/common'
910
import { DTSwitch, DTSwitchProps } from '../Switch'
@@ -46,7 +47,7 @@ export const ActionMenuItem = <T extends string | number>({
4647
onClick(item, e)
4748
}
4849

49-
const handleSwitchChange =
50+
const handleTrailingSwitchChange =
5051
({ type: trailingItemType, config }: ActionMenuItemType<T>['trailingItem']): DTSwitchProps['onChange'] =>
5152
(e) => {
5253
if (trailingItemType === 'switch') {
@@ -55,6 +56,15 @@ export const ActionMenuItem = <T extends string | number>({
5556
}
5657
}
5758

59+
const handleTrailingButtonClick =
60+
({ type: trailingItemType, config }: ActionMenuItemType<T>['trailingItem']): ButtonProps['onClick'] =>
61+
(e) => {
62+
e.stopPropagation()
63+
if (trailingItemType === 'button' && config.onClick) {
64+
config.onClick(e)
65+
}
66+
}
67+
5868
// RENDERERS
5969
const renderIcon = (iconProps: typeof startIcon) =>
6070
iconProps && (
@@ -86,7 +96,20 @@ export const ActionMenuItem = <T extends string | number>({
8696
return <span className="icon-dim-20 flex px-6 bcn-1 cn-7 br-12 fs-13 lh-20 fw-6">{config.value}</span>
8797
case 'switch':
8898
return (
89-
<DTSwitch {...config} onChange={handleSwitchChange(trailingItem)} size={ComponentSizeType.small} />
99+
<DTSwitch
100+
{...config}
101+
onChange={handleTrailingSwitchChange(trailingItem)}
102+
size={ComponentSizeType.small}
103+
/>
104+
)
105+
case 'button':
106+
return (
107+
<Button
108+
{...(config as ButtonProps)}
109+
onClick={handleTrailingButtonClick(trailingItem)}
110+
variant={ButtonVariantType.borderLess}
111+
size={ComponentSizeType.xxs}
112+
/>
90113
)
91114
default:
92115
return null

src/Shared/Components/ActionMenu/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { LegacyRef, MouseEvent, Ref } from 'react'
1+
import { LegacyRef, MouseEvent, ReactElement, Ref } from 'react'
22
import { LinkProps } from 'react-router-dom'
33

4+
import { OmitNever } from '@Shared/types'
5+
6+
import { ButtonProps } from '../Button'
47
import { IconsProps } from '../Icon'
58
import { PopoverProps, UsePopoverProps } from '../Popover'
69
import { SelectPickerOptionType, SelectPickerProps } from '../SelectPicker'
@@ -66,6 +69,10 @@ type TrailingItemType =
6669
| 'tooltipContent'
6770
>
6871
}
72+
| {
73+
type: 'button'
74+
config: OmitNever<Omit<Extract<ButtonProps, { icon: ReactElement }>, 'size' | 'variant'>>
75+
}
6976

7077
export type ActionMenuItemType<T extends string | number = string | number> = Omit<
7178
SelectPickerOptionType,

src/Shared/Components/ActionMenu/useActionMenu.hook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const useActionMenu = <T extends string | number>({
2020
// MEMOIZED CONSTANTS
2121
const filteredOptions = useMemo(
2222
() => (isSearchable ? filterActionMenuOptions(options, searchTerm) : options),
23-
[isSearchable, JSON.stringify(options), searchTerm],
23+
[isSearchable, options, searchTerm],
2424
)
2525

2626
const flatOptions = useMemo(() => getActionMenuFlatOptions(filteredOptions), [filteredOptions])

src/Shared/types.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,27 @@ export type Never<T> = {
986986
[K in keyof T]?: never
987987
}
988988

989+
/**
990+
* A utility type that filters out properties from type `T` that are of type `never`. \
991+
* This is useful when you want to remove properties that have been marked as `never` from a type,
992+
* effectively creating a new type without those properties.
993+
*
994+
* @template T - The input type from which to filter out `never` properties.
995+
* @example
996+
* ```typescript
997+
* type User = {
998+
* id: number;
999+
* name: string;
1000+
* deleted: never;
1001+
* }
1002+
*
1003+
* type ActiveUser = OmitNever<User>; // { id: number; name: string; }
1004+
* ```
1005+
*/
1006+
export type OmitNever<T> = {
1007+
[K in keyof T as T[K] extends never ? never : K]: T[K]
1008+
}
1009+
9891010
export interface TargetPlatformItemDTO {
9901011
name: string
9911012
}

0 commit comments

Comments
 (0)