generated from gravity-ui/package-example
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Table): table actions column added (#61)
* feat(Table): table actions column added --------- Co-authored-by: alx-chernigin <[email protected]>
- Loading branch information
Showing
22 changed files
with
525 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
|
||
import type {Row} from '@tanstack/react-table'; | ||
|
||
import type {TableActionsSettings} from '../../types/RowActions'; | ||
import {RowActions} from '../RowActions/RowActions'; | ||
|
||
export const ACTIONS_COLUMN_ID = '_actions'; | ||
|
||
interface ActionsCellProps<TValue extends unknown> extends TableActionsSettings<TValue> { | ||
row: Row<TValue>; | ||
} | ||
|
||
export const ActionsCell = <TValue extends unknown>({ | ||
getRowActions, | ||
renderRowActions, | ||
rowActionsSize, | ||
row, | ||
}: ActionsCellProps<TValue>) => { | ||
const {original: item, index} = row; | ||
|
||
if (renderRowActions) { | ||
return renderRowActions({row}); | ||
} | ||
|
||
return ( | ||
<RowActions<TValue> | ||
item={item} | ||
index={index} | ||
getRowActions={getRowActions} | ||
rowActionsSize={rowActionsSize} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {ActionsCell} from './ActionsCell'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import {block} from '../../utils'; | ||
|
||
export const b = block('row-actions'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
@use '@gravity-ui/uikit/styles/mixins'; | ||
@use '../variables'; | ||
|
||
$block: '.#{variables.$ns}row-actions'; | ||
|
||
#{$block} { | ||
height: 18px; | ||
display: flex; | ||
align-items: center; | ||
|
||
&__popup-menu { | ||
@include mixins.max-height(200px); | ||
} | ||
|
||
&__popup-menu-item { | ||
@include mixins.max-text-width(250px); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React from 'react'; | ||
|
||
import {Ellipsis} from '@gravity-ui/icons'; | ||
import type {PopupPlacement} from '@gravity-ui/uikit'; | ||
import {Button, Icon, Popup, useUniqId} from '@gravity-ui/uikit'; | ||
|
||
import type {TableActionsSettings} from '../../types/RowActions'; | ||
import {RowActionsMenu} from '../RowActionsMenu'; | ||
|
||
import {b} from './RowActions.classname'; | ||
import i18n from './i18n'; | ||
|
||
import './RowActions.scss'; | ||
|
||
type RowActionsProps<TValue> = Pick< | ||
TableActionsSettings<TValue>, | ||
'getRowActions' | 'rowActionsSize' | ||
> & { | ||
item: TValue; | ||
index: number; | ||
}; | ||
|
||
const DEFAULT_PLACEMENT: PopupPlacement = ['bottom-end', 'top-end', 'auto']; | ||
|
||
export const RowActions = <TValue extends unknown>({ | ||
index: rowIndex, | ||
item, | ||
getRowActions, | ||
rowActionsSize, | ||
}: RowActionsProps<TValue>) => { | ||
const [isPopupOpen, setIsPopupOpen] = React.useState(false); | ||
const anchorRef = React.useRef<HTMLButtonElement>(null); | ||
const rowId = useUniqId(); | ||
|
||
const buttonExtraProps = React.useMemo( | ||
() => ({ | ||
'aria-label': i18n('label-actions'), | ||
'aria-expanded': isPopupOpen, | ||
'aria-controls': rowId, | ||
}), | ||
[isPopupOpen, rowId], | ||
); | ||
const handleButtonClick = React.useCallback( | ||
(event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>) => { | ||
setIsPopupOpen((value) => !value); | ||
event.stopPropagation(); | ||
}, | ||
[], | ||
); | ||
|
||
if (getRowActions === undefined) { | ||
return null; | ||
} | ||
|
||
const actions = getRowActions(item, rowIndex); | ||
|
||
if (actions.length === 0) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div className={b()}> | ||
<Popup | ||
open={isPopupOpen} | ||
anchorRef={anchorRef} | ||
placement={DEFAULT_PLACEMENT} | ||
onOutsideClick={() => setIsPopupOpen(false)} | ||
id={rowId} | ||
> | ||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */} | ||
<div | ||
onClick={(event) => { | ||
event.stopPropagation(); | ||
}} | ||
> | ||
<RowActionsMenu | ||
item={item} | ||
actions={actions} | ||
size={rowActionsSize} | ||
onMenuItemClick={() => setIsPopupOpen(false)} | ||
className={b('popup-menu')} | ||
itemClassName={b('popup-menu-item')} | ||
/> | ||
</div> | ||
</Popup> | ||
<Button | ||
view="flat-secondary" | ||
className={b('actions-button')} | ||
onClick={handleButtonClick} | ||
size={rowActionsSize} | ||
ref={anchorRef} | ||
extraProps={buttonExtraProps} | ||
> | ||
<Icon data={Ellipsis} /> | ||
</Button> | ||
</div> | ||
); | ||
}; |
23 changes: 23 additions & 0 deletions
23
src/components/RowActions/__stories__/RowActions.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type {Meta, StoryObj} from '@storybook/react'; | ||
|
||
import {RowActionsColumnStory} from './stories/RowActionsColumnStory'; | ||
import {RowActionsWithActionsColumnStory} from './stories/RowActionsWithActionsColumnStory'; | ||
import {RowActionsWithCustomRendering} from './stories/RowActionsWithCustomRendering'; | ||
|
||
const meta: Meta = { | ||
title: 'Table actions', | ||
}; | ||
|
||
export default meta; | ||
|
||
export const ActionsColumn: StoryObj<typeof RowActionsColumnStory> = { | ||
render: RowActionsColumnStory, | ||
}; | ||
|
||
export const CustomActions: StoryObj<typeof RowActionsWithCustomRendering> = { | ||
render: RowActionsWithCustomRendering, | ||
}; | ||
|
||
export const SettingsWithActionsColumn: StoryObj<typeof RowActionsWithActionsColumnStory> = { | ||
render: RowActionsWithActionsColumnStory, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react'; | ||
|
||
import {Pencil} from '@gravity-ui/icons'; | ||
import {Icon} from '@gravity-ui/uikit'; | ||
|
||
export {columns as baseColumns} from '../../BaseTable/__stories__/constants/columns'; | ||
import type {TableActionsSettings} from '../../../types/RowActions'; | ||
import type {Item} from '../../BaseTable/__stories__/types'; | ||
|
||
export const actionsSettings: TableActionsSettings<Item> = { | ||
getRowActions: (item, index) => [ | ||
{ | ||
text: 'default', | ||
handler: () => { | ||
alert(JSON.stringify(item)); | ||
}, | ||
}, | ||
{ | ||
text: 'with icon', | ||
icon: <Icon data={Pencil} size={14} />, | ||
handler: () => {}, | ||
}, | ||
{ | ||
text: 'disabled', | ||
disabled: true, | ||
handler: () => {}, | ||
}, | ||
{ | ||
text: 'danger theme', | ||
theme: 'danger', | ||
handler: () => { | ||
alert(index); | ||
}, | ||
}, | ||
{ | ||
text: 'with href', | ||
theme: 'normal', | ||
href: 'https://gravity-ui.com', | ||
target: '_blank', | ||
rel: 'noopener noreferrer', | ||
handler: () => {}, | ||
}, | ||
], | ||
}; |
34 changes: 34 additions & 0 deletions
34
src/components/RowActions/__stories__/stories/RowActionsColumnStory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
|
||
import type {ColumnDef, RowSelectionState} from '@tanstack/react-table'; | ||
|
||
import {ACTIONS_COLUMN_ID, getActionsColumn, selectionColumn} from '../../../../constants'; | ||
import {useTable} from '../../../../hooks'; | ||
import type {Item} from '../../../BaseTable/__stories__/types'; | ||
import {generateData} from '../../../BaseTable/__stories__/utils'; | ||
import {Table} from '../../../Table/Table'; | ||
import {actionsSettings, baseColumns} from '../constants'; | ||
|
||
const data = generateData(5); | ||
|
||
const columns: ColumnDef<Item>[] = [ | ||
selectionColumn as ColumnDef<Item>, | ||
...baseColumns, | ||
getActionsColumn<Item>(ACTIONS_COLUMN_ID, { | ||
...actionsSettings, | ||
}), | ||
]; | ||
|
||
export const RowActionsColumnStory = () => { | ||
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({}); | ||
const table = useTable({ | ||
columns, | ||
data, | ||
state: {rowSelection}, | ||
enableRowSelection: true, | ||
enableMultiRowSelection: true, | ||
onRowSelectionChange: setRowSelection, | ||
}); | ||
|
||
return <Table table={table} />; | ||
}; |
39 changes: 39 additions & 0 deletions
39
src/components/RowActions/__stories__/stories/RowActionsWithActionsColumnStory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React from 'react'; | ||
|
||
import type {ColumnDef, ColumnPinningState} from '@tanstack/react-table'; | ||
|
||
import {SETTINGS_WITH_ACTIONS_COLUMN_ID, getSettingsWithActionsColumn} from '../../../../constants'; | ||
import {useTable} from '../../../../hooks'; | ||
import type {Item} from '../../../BaseTable/__stories__/types'; | ||
import {generateData} from '../../../BaseTable/__stories__/utils'; | ||
import {Table} from '../../../Table/Table'; | ||
import {actionsSettings, baseColumns} from '../constants'; | ||
|
||
const data = generateData(5); | ||
|
||
const columns: ColumnDef<Item>[] = [ | ||
...baseColumns, | ||
getSettingsWithActionsColumn<Item>(SETTINGS_WITH_ACTIONS_COLUMN_ID, { | ||
actions: actionsSettings, | ||
settings: { | ||
sortable: true, | ||
filterable: true, | ||
}, | ||
}), | ||
]; | ||
|
||
export const RowActionsWithActionsColumnStory = () => { | ||
const [columnPinning, setColumnPinning] = React.useState<ColumnPinningState>({ | ||
left: [], | ||
right: [SETTINGS_WITH_ACTIONS_COLUMN_ID], | ||
}); | ||
const table = useTable({ | ||
columns, | ||
data, | ||
enableColumnPinning: true, | ||
state: {columnPinning}, | ||
onColumnPinningChange: setColumnPinning, | ||
}); | ||
|
||
return <Table table={table} />; | ||
}; |
53 changes: 53 additions & 0 deletions
53
src/components/RowActions/__stories__/stories/RowActionsWithCustomRendering.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from 'react'; | ||
|
||
import {Select} from '@gravity-ui/uikit'; | ||
import type {ColumnDef, RowSelectionState} from '@tanstack/react-table'; | ||
|
||
import {ACTIONS_COLUMN_ID, getActionsColumn, selectionColumn} from '../../../../constants'; | ||
import {useTable} from '../../../../hooks'; | ||
import type {Item} from '../../../BaseTable/__stories__/types'; | ||
import {generateData} from '../../../BaseTable/__stories__/utils'; | ||
import {Table} from '../../../Table/Table'; | ||
import {actionsSettings, baseColumns} from '../constants'; | ||
|
||
const data = generateData(5); | ||
|
||
const columns: ColumnDef<Item>[] = [ | ||
selectionColumn as ColumnDef<Item>, | ||
...baseColumns, | ||
getActionsColumn<Item>(ACTIONS_COLUMN_ID, { | ||
...actionsSettings, | ||
renderRowActions: ({row}) => { | ||
const {index} = row; | ||
if (index % 2) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Select | ||
options={[ | ||
{value: '1', text: 'action 1', content: 'action 1'}, | ||
{value: '2', text: 'action 2', content: 'action 2'}, | ||
{value: '3', text: 'action 3', content: 'action 3'}, | ||
]} | ||
size="s" | ||
title="Actions select example" | ||
/> | ||
); | ||
}, | ||
}), | ||
]; | ||
|
||
export const RowActionsWithCustomRendering = () => { | ||
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({}); | ||
const table = useTable({ | ||
columns, | ||
data, | ||
state: {rowSelection}, | ||
enableRowSelection: true, | ||
enableMultiRowSelection: true, | ||
onRowSelectionChange: setRowSelection, | ||
}); | ||
|
||
return <Table table={table} />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"label-actions": "Actions" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {addComponentKeysets} from '@gravity-ui/uikit/i18n'; | ||
|
||
import {NAMESPACE} from '../../../utils'; | ||
|
||
import en from './en.json'; | ||
import ru from './ru.json'; | ||
|
||
const COMPONENT = `${NAMESPACE}table-actions`; | ||
|
||
export default addComponentKeysets({en, ru}, COMPONENT); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"label-actions": "Действия" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export {RowActions} from './RowActions'; | ||
export {ActionsCell} from '../ActionsCell/ActionsCell'; |
Oops, something went wrong.