-
Notifications
You must be signed in to change notification settings - Fork 843
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…5640) * [types] Set up interface for new `renderCellPopover` API - which replaces `popoverContents` and shares some common props with `renderCellValue` * [types] Replace component popoverContents prop with renderCellPopover + improve prop documentation for renderCellValue, renderFooterCellValue * [parents] Remove passed popoverContents for renderCellPopover - in grid parent components * [cell] Remove popoverContent for renderCellPopover * Convert DefaultColumnFormatter to DefaultCellPopover + move to data_grid_cell_popover instead of popover_utils * Pass cellActions to popover renderers as JSX * Pass schema info to both renderCellValue and renderCellPopover - the popover needs this to conditionally change formatting based on schema, and renderCellValue seems like it could use this info as well * Convert default JSON popover formatter * Delete popover_utils * Add defaultPopoverRender prop to renderCellPopover - which will allow custom renderers to pass back the default renderer if they only want custom rendering for certain popovers * [misc] fix Typescript complaints in data_grid.spec file - likely created by recent Cypress reference/ts PRs * Add Cypress E2E tests for cell popover customization/rendering * [docs] Add new cell popover documentation page and examples * [docs] Remove cell popover example/logic from schema page + remove props unrelated to schema + schema.js misc cleanup: - Remove unnecessary pagination state/props - there's only 5 items - Remove unnecessary conditional JSON - Make Star Wars vs Star Trek alternating, so sorting does more - Fix aria-label - (lint) fragment, export default * [docs] Update main datagrid documentation page - remove popoverContents, add renderCellPopover - improve documentation on rendercellValue * [docs] Misc fixes/improvements to main datagrid snippet - Fix several incorrect instances of `optional` vs `required` notation - move inMemory down to sorting/pagination instead of being at the top, since it's an optional prop - misc indentation/lint fixes * Add changelog entry * [PR feedback] Change `defaultPopoverRender` to `DefaultCellPopover` - the component usage is cleaner than a render fn * [PR feedback] Documentation copy * [PR feedback] Emphasize that leaving out the cell actions is not recommended
- Loading branch information
Constance
authored
Feb 16, 2022
1 parent
327adcf
commit 93b70f9
Showing
24 changed files
with
1,011 additions
and
419 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
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
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,96 @@ | ||
import React, { useState, ReactNode } from 'react'; | ||
// @ts-ignore - faker does not have type declarations | ||
import { fake } from 'faker'; | ||
|
||
import { | ||
EuiDataGrid, | ||
EuiDataGridCellValueElementProps, | ||
EuiDataGridColumnCellAction, | ||
EuiDataGridColumn, | ||
EuiTitle, | ||
} from '../../../../src/components'; | ||
|
||
const cellActions: EuiDataGridColumnCellAction[] = [ | ||
({ Component }) => ( | ||
<Component iconType="plusInCircle" aria-label="Filter in"> | ||
Filter in | ||
</Component> | ||
), | ||
({ Component }) => ( | ||
<Component iconType="minusInCircle" aria-label="Filter out"> | ||
Filter out | ||
</Component> | ||
), | ||
]; | ||
|
||
const columns: EuiDataGridColumn[] = [ | ||
{ | ||
id: 'default', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'datetime', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'json', | ||
schema: 'json', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'custom', | ||
schema: 'favoriteFranchise', | ||
cellActions, | ||
}, | ||
]; | ||
|
||
const data: Array<{ [key: string]: ReactNode }> = []; | ||
for (let i = 1; i < 5; i++) { | ||
data.push({ | ||
default: fake('{{name.lastName}}, {{name.firstName}} {{name.suffix}}'), | ||
datetime: fake('{{date.past}}'), | ||
json: JSON.stringify([ | ||
{ | ||
numeric: fake('{{finance.account}}'), | ||
currency: fake('${{finance.amount}}'), | ||
date: fake('{{date.past}}'), | ||
}, | ||
]), | ||
custom: i % 2 === 0 ? 'Star Wars' : 'Star Trek', | ||
}); | ||
} | ||
|
||
const RenderCellValue = ({ | ||
rowIndex, | ||
columnId, | ||
schema, | ||
isDetails, | ||
}: EuiDataGridCellValueElementProps) => { | ||
let value = data[rowIndex][columnId]; | ||
|
||
if (schema === 'favoriteFranchise' && isDetails) { | ||
value = ( | ||
<EuiTitle size="xs"> | ||
<h3>{value} is the best!</h3> | ||
</EuiTitle> | ||
); | ||
} | ||
|
||
return value; | ||
}; | ||
|
||
export default () => { | ||
const [visibleColumns, setVisibleColumns] = useState( | ||
columns.map(({ id }) => id) | ||
); | ||
|
||
return ( | ||
<EuiDataGrid | ||
aria-label="Data grid example of renderCellValue.isDetails" | ||
columns={columns} | ||
columnVisibility={{ visibleColumns, setVisibleColumns }} | ||
rowCount={data.length} | ||
renderCellValue={RenderCellValue} | ||
/> | ||
); | ||
}; |
68 changes: 68 additions & 0 deletions
68
src-docs/src/views/datagrid/cell_popover_is_expandable.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,68 @@ | ||
import React, { useState, ReactNode } from 'react'; | ||
// @ts-ignore - faker does not have type declarations | ||
import { fake } from 'faker'; | ||
|
||
import { | ||
EuiDataGrid, | ||
EuiDataGridColumnCellAction, | ||
EuiDataGridColumn, | ||
} from '../../../../src/components'; | ||
|
||
const cellActions: EuiDataGridColumnCellAction[] = [ | ||
({ Component }) => ( | ||
<Component iconType="plusInCircle" aria-label="Filter in"> | ||
Filter in | ||
</Component> | ||
), | ||
({ Component }) => ( | ||
<Component iconType="minusInCircle" aria-label="Filter out"> | ||
Filter out | ||
</Component> | ||
), | ||
]; | ||
|
||
const columns: EuiDataGridColumn[] = [ | ||
{ | ||
id: 'firstName', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'lastName', | ||
isExpandable: false, | ||
cellActions, | ||
}, | ||
{ | ||
id: 'suffix', | ||
isExpandable: false, | ||
}, | ||
{ | ||
id: 'boolean', | ||
isExpandable: false, | ||
}, | ||
]; | ||
|
||
const data: Array<{ [key: string]: ReactNode }> = []; | ||
for (let i = 1; i < 5; i++) { | ||
data.push({ | ||
firstName: fake('{{name.firstName}}'), | ||
lastName: fake('{{name.lastName}}'), | ||
suffix: fake('{{name.suffix}}'), | ||
boolean: fake('{{random.boolean}}'), | ||
}); | ||
} | ||
|
||
export default () => { | ||
const [visibleColumns, setVisibleColumns] = useState( | ||
columns.map(({ id }) => id) | ||
); | ||
|
||
return ( | ||
<EuiDataGrid | ||
aria-label="Data grid example of columns.isExpandable" | ||
columns={columns} | ||
columnVisibility={{ visibleColumns, setVisibleColumns }} | ||
rowCount={data.length} | ||
renderCellValue={({ rowIndex, columnId }) => data[rowIndex][columnId]} | ||
/> | ||
); | ||
}; |
176 changes: 176 additions & 0 deletions
176
src-docs/src/views/datagrid/cell_popover_rendercellpopover.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,176 @@ | ||
import React, { useState, ReactNode } from 'react'; | ||
// @ts-ignore - faker does not have type declarations | ||
import { fake } from 'faker'; | ||
|
||
import { | ||
EuiDataGrid, | ||
EuiDataGridCellPopoverElementProps, | ||
EuiDataGridColumnCellAction, | ||
EuiDataGridColumn, | ||
EuiPopoverTitle, | ||
EuiPopoverFooter, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiButtonEmpty, | ||
EuiCopy, | ||
EuiText, | ||
EuiImage, | ||
} from '../../../../src/components'; | ||
|
||
const cellActions: EuiDataGridColumnCellAction[] = [ | ||
({ Component }) => ( | ||
<Component iconType="plusInCircle" aria-label="Filter in"> | ||
Filter in | ||
</Component> | ||
), | ||
({ Component }) => ( | ||
<Component iconType="minusInCircle" aria-label="Filter out"> | ||
Filter out | ||
</Component> | ||
), | ||
]; | ||
|
||
const columns: EuiDataGridColumn[] = [ | ||
{ | ||
id: 'default', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'datetime', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'json', | ||
cellActions, | ||
}, | ||
{ | ||
id: 'custom', | ||
schema: 'favoriteFranchise', | ||
cellActions, | ||
}, | ||
]; | ||
|
||
const data: Array<{ [key: string]: ReactNode }> = []; | ||
for (let i = 1; i < 5; i++) { | ||
data.push({ | ||
default: fake('{{name.lastName}}, {{name.firstName}} {{name.suffix}}'), | ||
datetime: fake('{{date.past}}'), | ||
json: JSON.stringify([ | ||
{ | ||
numeric: fake('{{finance.account}}'), | ||
currency: fake('${{finance.amount}}'), | ||
date: fake('{{date.past}}'), | ||
}, | ||
]), | ||
custom: i % 2 === 0 ? 'Star Wars' : 'Star Trek', | ||
}); | ||
} | ||
|
||
const RenderCellPopover = (props: EuiDataGridCellPopoverElementProps) => { | ||
const { | ||
columnId, | ||
schema, | ||
children, | ||
cellActions, | ||
cellContentsElement, | ||
DefaultCellPopover, | ||
} = props; | ||
|
||
let title: ReactNode = 'Custom popover'; | ||
let content: ReactNode = <EuiText size="s">{children}</EuiText>; | ||
let footer: ReactNode = cellActions; | ||
|
||
// An example of custom popover content | ||
if (schema === 'favoriteFranchise') { | ||
title = 'Custom popover with custom content'; | ||
const franchise = cellContentsElement.innerText; | ||
const caption = `${franchise} is the best!`; | ||
content = ( | ||
<> | ||
{franchise === 'Star Wars' ? ( | ||
<EuiImage | ||
allowFullScreen | ||
size="m" | ||
hasShadow | ||
caption={caption} | ||
alt="Random Star Wars image" | ||
url="https://source.unsplash.com/600x600/?starwars" | ||
/> | ||
) : ( | ||
<EuiImage | ||
allowFullScreen | ||
size="m" | ||
hasShadow | ||
caption={caption} | ||
alt="Random Star Trek image" | ||
url="https://source.unsplash.com/600x600/?startrek" | ||
/> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
// An example of a custom cell actions footer, and of using | ||
// `cellContentsElement` to directly access a cell's raw text | ||
if (columnId === 'datetime') { | ||
title = 'Custom popover with custom actions'; | ||
footer = ( | ||
<EuiPopoverFooter> | ||
<EuiFlexGroup | ||
justifyContent="spaceBetween" | ||
gutterSize="none" | ||
responsive={false} | ||
> | ||
<EuiFlexItem className="eui-displayBlock"> | ||
{/* When not using the default cellActions, be sure to replace them | ||
with your own action buttons to ensure a consistent user experience */} | ||
<EuiButtonEmpty size="xs">Filter in</EuiButtonEmpty> | ||
<EuiButtonEmpty size="xs">Filter out</EuiButtonEmpty> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiCopy textToCopy={cellContentsElement.innerText}> | ||
{(copy) => ( | ||
<EuiButtonEmpty size="xs" onClick={copy} color="success"> | ||
Click to copy | ||
</EuiButtonEmpty> | ||
)} | ||
</EuiCopy> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiPopoverFooter> | ||
); | ||
} | ||
|
||
// An example of conditionally falling back back to the default cell popover render. | ||
// Note that JSON schemas have automatic EuiCodeBlock and isCopyable formatting | ||
// which can be nice to keep intact. For cells that have non-JSON content but | ||
// JSON popovers, you can also manually pass a `json` schema to force this formatting. | ||
if (columnId === 'json') { | ||
return <DefaultCellPopover {...props} schema="json" />; | ||
} | ||
|
||
return ( | ||
<> | ||
<EuiPopoverTitle>{title}</EuiPopoverTitle> | ||
{content} | ||
{footer} | ||
</> | ||
); | ||
}; | ||
|
||
export default () => { | ||
const [visibleColumns, setVisibleColumns] = useState( | ||
columns.map(({ id }) => id) | ||
); | ||
|
||
return ( | ||
<EuiDataGrid | ||
aria-label="Data grid renderCellPopover example" | ||
columns={columns} | ||
columnVisibility={{ visibleColumns, setVisibleColumns }} | ||
rowCount={data.length} | ||
renderCellValue={({ rowIndex, columnId }) => data[rowIndex][columnId]} | ||
renderCellPopover={RenderCellPopover} | ||
/> | ||
); | ||
}; |
Oops, something went wrong.