Skip to content

Commit

Permalink
[EuiDescriptionList] Add new columnWidths prop (#7146)
Browse files Browse the repository at this point in the history
  • Loading branch information
cee-chen authored Aug 31, 2023
1 parent 7b99513 commit 3aea311
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src-docs/src/views/datagrid/_snippets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ inMemory={{ level: 'sorting' }}`,
'renderFooterCellValue={({ rowIndex, columnId }) => {}}',
renderCustomGridBody: `// Optional; advanced usage only. This render function is an escape hatch for consumers who need to opt out of virtualization or otherwise need total custom control over how data grid cells are rendered.
renderCustomDataGridBody={({ visibleColumns, visibleRowData, Cell }) => (
renderCustomGridBody={({ visibleColumns, visibleRowData, Cell }) => (
<Cell colIndex={mappedFromVisibleColumns} visibleRowIndex={mappedFromVisibleRowData} />
)}`,
pagination: `pagination={{
Expand Down
28 changes: 28 additions & 0 deletions src-docs/src/views/description_list/column_widths.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';

import { EuiDescriptionList } from '../../../../src/components';

const listItems = [
{
title: '25% width',
description: '75% width',
},
{
title: 'TIE Fighter',
description:
'The sequel to XWING, join the dark side and fly for the Emperor.',
},
{
title: 'Quake 2',
description: 'The game that made me drop out of college.',
},
];

export default () => (
<EuiDescriptionList
listItems={listItems}
type="column"
columnWidths={[1, 3]} // Same as [25, 75]
style={{ maxInlineSize: '400px' }}
/>
);
72 changes: 57 additions & 15 deletions src-docs/src/views/description_list/description_list_example.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { Fragment } from 'react';
import React from 'react';

import { GuideSectionTypes } from '../../components';

import {
EuiCode,
EuiLink,
EuiDescriptionList,
EuiDescriptionListTitle,
EuiDescriptionListDescription,
Expand Down Expand Up @@ -59,6 +60,13 @@ const descriptionListResponsiveColumnSnippet = `<EuiDescriptionList
listItems={favoriteVideoGames}
/>`;

import DescriptionListColumnWidths from './column_widths';
const descriptionListColumnWidthsSource = require('!!raw-loader!./column_widths');
const descriptionListColumnWidthsSnippet = `<EuiDescriptionList
type="column"
columnWidths={[1, 3]}
/>`;

import DescriptionListStyling from './description_list_styling';
const descriptionListStylingSource = require('!!raw-loader!./description_list_styling');
const descriptionListStylingSnippet = [
Expand Down Expand Up @@ -181,13 +189,11 @@ export const DescriptionListExample = {
},
],
text: (
<Fragment>
<p>
Using the prop <EuiCode>type</EuiCode> set to{' '}
<EuiCode>column</EuiCode> description lists can be presented in an
inline, column format.
</p>
</Fragment>
<p>
Using the prop <EuiCode>type</EuiCode> set to{' '}
<EuiCode>column</EuiCode> description lists can be presented in an
inline, column format.
</p>
),
snippet: descriptionListColumnSnippet,
demo: <DescriptionListColumn />,
Expand All @@ -200,17 +206,53 @@ export const DescriptionListExample = {
},
],
text: (
<Fragment>
<p>
To return to the typical row format on smaller screens set{' '}
<EuiCode>type</EuiCode> to <EuiCode>responsiveColumn</EuiCode>. The
following list will only show the column format on larger screens.
</p>
</Fragment>
<p>
To return to the typical row format on smaller screens set{' '}
<EuiCode>type</EuiCode> to <EuiCode>responsiveColumn</EuiCode>. The
following list will only show the column format on larger screens.
</p>
),
snippet: descriptionListResponsiveColumnSnippet,
demo: <DescriptionListResponsiveColumn />,
},
{
source: [
{
type: GuideSectionTypes.TSX,
code: descriptionListColumnWidthsSource,
},
],
text: (
<>
<p>
The optional <EuiCode>columnWidths</EuiCode> prop allows customizing
specific column widths (e.g.{' '}
<EuiCode>{"['100px', '200px']"}</EuiCode>). The first array value
applies to the title column, and the second applies to the
description column.
</p>
<p>
Passing numbers instead of CSS width strings will use a ratio of
widths. For example, <EuiCode>[1, 3]</EuiCode> will render a
description column 3x the width of the title column. In other words,
titles will have a width of 25% descriptions will have a width of
75%.
</p>
<p>
For advanced usage, column width strings also accept{' '}
<EuiLink
href="https://css-tricks.com/snippets/css/complete-guide-grid/#aa-special-units-functions"
target="_blank"
>
CSS grid special units, sizing, keywords, and sizing functions
</EuiLink>
.
</p>
</>
),
snippet: descriptionListColumnWidthsSnippet,
demo: <DescriptionListColumnWidths />,
},
{
title: 'Inline',
source: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ exports[`useDataGridKeyboardShortcuts returns a popover containing a list of key
aria-labelledby="generated-id"
class="euiDescriptionList emotion-euiDescriptionList-column-center-s-s"
data-type="column"
style="grid-template-columns: 1fr 3fr;"
>
<dt
class="euiDescriptionList__title emotion-euiDescriptionList__title-column-compressed-right"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
overflow-block: auto;

.euiDescriptionList {
.euiDescriptionList__title {
width: 25%;
}

.euiDescriptionList__description {
width: 75%;
}
row-gap: 0; // Row spacing handled by default EuiText dd/dt styles
}
}
1 change: 1 addition & 0 deletions src/components/datagrid/controls/keyboard_shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const useDataGridKeyboardShortcuts = (): {
<EuiDescriptionList
aria-labelledby={titleId}
type="column"
columnWidths={[1, 3]}
align="center"
compressed
listItems={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ exports[`EuiDescriptionList props align left is rendered 1`] = `
/>
`;

exports[`EuiDescriptionList props column gap m is rendered 1`] = `
exports[`EuiDescriptionList props columnGutterSize m is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-s-m"
data-type="column"
/>
`;

exports[`EuiDescriptionList props column gap s is rendered 1`] = `
exports[`EuiDescriptionList props columnGutterSize s is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-s-s"
data-type="column"
Expand All @@ -88,20 +88,6 @@ exports[`EuiDescriptionList props compressed is rendered 1`] = `
/>
`;

exports[`EuiDescriptionList props gutter m is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-m-s"
data-type="column"
/>
`;

exports[`EuiDescriptionList props gutter s is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-s-s"
data-type="column"
/>
`;

exports[`EuiDescriptionList props listItems descriptionProps is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-row-left"
Expand Down Expand Up @@ -198,6 +184,20 @@ exports[`EuiDescriptionList props listItems titleProps is rendered 1`] = `
</dl>
`;

exports[`EuiDescriptionList props rowGutterSize m is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-m-s"
data-type="column"
/>
`;

exports[`EuiDescriptionList props rowGutterSize s is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-s-s"
data-type="column"
/>
`;

exports[`EuiDescriptionList props type column is rendered 1`] = `
<dl
class="euiDescriptionList emotion-euiDescriptionList-column-left-s-s"
Expand Down
54 changes: 52 additions & 2 deletions src/components/description_list/description_list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('EuiDescriptionList', () => {
description: 'Description 3',
},
];

describe('props', () => {
describe('listItems', () => {
const { container } = render(
Expand Down Expand Up @@ -145,7 +146,7 @@ describe('EuiDescriptionList', () => {
});
});

describe('gutter', () => {
describe('rowGutterSize', () => {
ROW_GUTTER_SIZES.forEach((gutter) => {
test(`${gutter} is rendered`, () => {
const { container } = render(
Expand All @@ -157,7 +158,7 @@ describe('EuiDescriptionList', () => {
});
});

describe('column gap', () => {
describe('columnGutterSize', () => {
COLUMN_GUTTER_SIZES.forEach((columnGutterSize) => {
test(`${columnGutterSize} is rendered`, () => {
const { container } = render(
Expand All @@ -170,6 +171,55 @@ describe('EuiDescriptionList', () => {
expect(container.firstChild).toMatchSnapshot();
});
});

describe('columnWidths', () => {
it('renders the passed values as an inline css grid style', () => {
const { container } = render(
<EuiDescriptionList
type="column"
columnWidths={['100px', 'minmax(200px, auto)']}
/>
);
expect(container.firstChild).toHaveStyle(
'grid-template-columns: 100px minmax(200px, auto)'
);
});

it('converts numbers into fr grid units', () => {
const { container } = render(
<EuiDescriptionList type="column" columnWidths={[1, 2]} />
);
expect(container.firstChild).toHaveStyle(
'grid-template-columns: 1fr 2fr'
);
});

it('respects custom styles', () => {
const { container } = render(
<EuiDescriptionList
type="column"
columnWidths={[3, 4]}
style={{ color: 'red' }}
/>
);
expect(container.firstChild).toHaveStyle('color: red');
});

it('correctly removes inline styles when responsive columns collapse to rows', () => {
const { container, rerender } = render(
<EuiDescriptionList type="responsiveColumn" columnWidths={[3, 4]} />
);
expect(container.firstChild).toHaveStyle(
'grid-template-columns: 3fr 4fr'
);

mockUseIsWithinBreakpoints.mockReturnValue(true);
rerender(
<EuiDescriptionList type="responsiveColumn" columnWidths={[3, 4]} />
);
expect(container.firstChild).toHaveAttribute('style', '');
});
});
});
});
});
26 changes: 25 additions & 1 deletion src/components/description_list/description_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const EuiDescriptionList: FunctionComponent<
align = 'left',
children,
className,
style,
compressed = false,
descriptionProps,
listItems,
Expand All @@ -32,6 +33,7 @@ export const EuiDescriptionList: FunctionComponent<
type: _type = 'row',
rowGutterSize = 's',
columnGutterSize = 's',
columnWidths,
...rest
}) => {
const showResponsiveColumns = useIsWithinBreakpoints(['xs', 's']);
Expand All @@ -54,6 +56,22 @@ export const EuiDescriptionList: FunctionComponent<
type === 'column' && styles.columnGap[columnGutterSize],
];

const inlineStyles = useMemo(() => {
if (type === 'column' && columnWidths) {
// Leave string values as is - e.g. if a consumer passes in a specific '200px' or 'minmax()'
const convertNumbersToFr = (value: number | string) =>
typeof value === 'number' ? `${value}fr` : value;

const titleWidth = convertNumbersToFr(columnWidths[0]);
const descriptionWidth = convertNumbersToFr(columnWidths[1]);
return {
gridTemplateColumns: `${titleWidth} ${descriptionWidth}`,
...style,
};
}
return style;
}, [style, type, columnWidths]);

const classes = classNames('euiDescriptionList', className);

let childrenOrListItems = null;
Expand Down Expand Up @@ -81,7 +99,13 @@ export const EuiDescriptionList: FunctionComponent<
<EuiDescriptionListContext.Provider
value={{ type, compressed, textStyle, align, rowGutterSize }}
>
<dl className={classes} css={cssStyles} {...rest} data-type={_type}>
<dl
className={classes}
css={cssStyles}
style={inlineStyles}
{...rest}
data-type={_type}
>
{childrenOrListItems}
</dl>
</EuiDescriptionListContext.Provider>
Expand Down
14 changes: 14 additions & 0 deletions src/components/description_list/description_list_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ export interface EuiDescriptionListProps {
* Only applies to `column` and `responsiveColumn` types.
*/
columnGutterSize?: EuiDescriptionListColumnGapSizes;
/**
* Allows customizing specific column widths (e.g. `['100px', '200px']`). The first
* array value applies to the title column, and the second applies to the description column.
*
* Passing numbers instead of CSS width strings will use a ratio of widths.
* For example, [1, 3] will render a description column 3x the width of the title column.
* In other words, descriptions will have a width of `75%` and titles will have a width of `25%`.
*
* Only applies to `column` and `responsiveColumn` types.
*
* _Advanced usage note:_ column width strings also accept [CSS grid special units,
* sizing, keywords, and sizing functions](https://css-tricks.com/snippets/css/complete-guide-grid/#aa-special-units-functions).
*/
columnWidths?: [number | string, number | string];
}

export const CHILD_TYPES = ['row', 'inline', 'column'] as const;
Expand Down
6 changes: 6 additions & 0 deletions upcoming_changelogs/7146.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Updated `EuiDescriptionList` with new `columnWidths` prop

**Bug fixes**

- Fixed `EuiDataGrid`'s keyboard shortcuts popover display

0 comments on commit 3aea311

Please sign in to comment.