@@ -50,54 +50,66 @@ export const getActionsCol = <TData extends Record<string, unknown>>(
5050 // TODO: control flow here has always confused me, would like to straighten it out
5151 const actions = makeActions ( row . original )
5252 const id = typeof row . original . id === 'string' ? row . original . id : null
53- return (
54- < DropdownMenu . Root >
55- { /* TODO: This name should not suck; future us, make it so! */ }
56- { /* stopPropagation prevents clicks from toggling row select in a single select table */ }
57- < DropdownMenu . Trigger
58- className = "flex h-full w-10 items-center justify-center"
59- aria-label = "Row actions"
60- onClick = { ( e ) => e . stopPropagation ( ) }
61- >
62- < More12Icon className = "text-tertiary" />
63- </ DropdownMenu . Trigger >
64- { /* portal fixes mysterious z-index issue where menu is behind button */ }
65- < DropdownMenu . Portal >
66- < DropdownMenu . Content align = "end" className = "-mt-3 mr-2" >
67- { id && (
53+ return < RowActions id = { id } actions = { actions } />
54+ } ,
55+ }
56+ }
57+
58+ type RowActionsProps = {
59+ /** If `id` is provided, a `Copy ID` menu item will be automatically included. */
60+ id ?: string | null
61+ /** Use `copyIdLabel` to override the default label (`Copy ID`). */
62+ copyIdLabel ?: string
63+ actions ?: MenuAction [ ]
64+ }
65+
66+ export const RowActions = ( { id, copyIdLabel = 'Copy ID' , actions } : RowActionsProps ) => {
67+ return (
68+ < DropdownMenu . Root >
69+ { /* TODO: This name should not suck; future us, make it so! */ }
70+ { /* stopPropagation prevents clicks from toggling row select in a single select table */ }
71+ < DropdownMenu . Trigger
72+ className = "flex h-full w-10 items-center justify-center"
73+ aria-label = "Row actions"
74+ onClick = { ( e ) => e . stopPropagation ( ) }
75+ >
76+ < More12Icon className = "text-tertiary" />
77+ </ DropdownMenu . Trigger >
78+ { /* portal fixes mysterious z-index issue where menu is behind button */ }
79+ < DropdownMenu . Portal >
80+ < DropdownMenu . Content align = "end" className = "-mt-3 mr-2" >
81+ { id && (
82+ < DropdownMenu . Item
83+ onSelect = { ( ) => {
84+ window . navigator . clipboard . writeText ( id )
85+ } }
86+ >
87+ { copyIdLabel }
88+ </ DropdownMenu . Item >
89+ ) }
90+ { actions ?. map ( ( action ) => {
91+ // TODO: Tooltip on disabled button broke, probably due to portal
92+ return (
93+ < Wrap
94+ when = { ! ! action . disabled }
95+ with = { < Tooltip content = { action . disabled } /> }
96+ key = { kebabCase ( `action-${ action . label } ` ) }
97+ >
6898 < DropdownMenu . Item
69- onSelect = { ( ) => {
70- window . navigator . clipboard . writeText ( id )
71- } }
99+ className = { cn ( action . className , {
100+ destructive :
101+ action . label . toLowerCase ( ) === 'delete' && ! action . disabled ,
102+ } ) }
103+ onSelect = { action . onActivate }
104+ disabled = { ! ! action . disabled }
72105 >
73- Copy ID
106+ { action . label }
74107 </ DropdownMenu . Item >
75- ) }
76- { actions . map ( ( action ) => {
77- // TODO: Tooltip on disabled button broke, probably due to portal
78- return (
79- < Wrap
80- when = { ! ! action . disabled }
81- with = { < Tooltip content = { action . disabled } /> }
82- key = { kebabCase ( `action-${ action . label } ` ) }
83- >
84- < DropdownMenu . Item
85- className = { cn ( action . className , {
86- destructive :
87- action . label . toLowerCase ( ) === 'delete' && ! action . disabled ,
88- } ) }
89- onSelect = { action . onActivate }
90- disabled = { ! ! action . disabled }
91- >
92- { action . label }
93- </ DropdownMenu . Item >
94- </ Wrap >
95- )
96- } ) }
97- </ DropdownMenu . Content >
98- </ DropdownMenu . Portal >
99- </ DropdownMenu . Root >
100- )
101- } ,
102- }
108+ </ Wrap >
109+ )
110+ } ) }
111+ </ DropdownMenu . Content >
112+ </ DropdownMenu . Portal >
113+ </ DropdownMenu . Root >
114+ )
103115}
0 commit comments