Skip to content

Commit

Permalink
[DataTable]: add border for column groups in header
Browse files Browse the repository at this point in the history
  • Loading branch information
AlekseyManetov committed Nov 26, 2024
1 parent ad144c8 commit e4303cb
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 107 deletions.
183 changes: 80 additions & 103 deletions app/src/docs/_examples/tables/TableGroupedHeader.example.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import React, { ReactNode, useMemo, useState } from 'react';
import {
DataSourceState,
DataColumnProps,
useUuiContext,
useLazyDataSource,
DropdownBodyProps,
DataColumnGroupProps,
} from '@epam/uui-core';
import { Dropdown, DropdownMenuButton, DropdownMenuSplitter, DropdownMenuBody, Text, DataTable, Panel, IconButton } from '@epam/uui';
import { City } from '@epam/uui-docs';
import { ReactComponent as MoreIcon } from '@epam/assets/icons/common/navigation-more_vert-18.svg';
import { ReactComponent as PencilIcon } from '@epam/assets/icons/common/content-edit-18.svg';
import React, { useState } from 'react';
import { DataSourceState, DataColumnProps, useUuiContext, useLazyDataSource, DataColumnGroupProps } from '@epam/uui-core';
import { Text, DataTable, Panel, FlexRow, Badge, BadgeProps } from '@epam/uui';
import { Person } from '@epam/uui-docs';

import css from './TablesExamples.module.scss';
import { TApi } from '../../../data';
Expand All @@ -19,104 +10,90 @@ export default function TableGroupedHeaderExample() {
const svc = useUuiContext<TApi>();
const [tableState, setTableState] = useState<DataSourceState>({});

const renderMenu = (dropdownProps: DropdownBodyProps): ReactNode => (
<DropdownMenuBody minWidth={ 90 } { ...dropdownProps }>
<DropdownMenuButton caption="Edit" icon={ PencilIcon } iconPosition="right" />
<DropdownMenuButton caption="Remove" />
<DropdownMenuSplitter />
<DropdownMenuButton caption="Cancel" />
</DropdownMenuBody>
);

// Define columns groups array
const columnGroups: DataColumnGroupProps[] = [
{
key: 'primary',
caption: 'Primary info',
key: 'location',
caption: 'Location',
textAlign: 'center',
},
{
key: 'position',
caption: 'Position',
textAlign: 'center',
},
];

// Define columns config array
const citiesColumns: DataColumnProps<City>[] = useMemo(
() => [
{
key: 'id',
caption: 'Id',
group: 'primary', // key group from columnGroups array
render: (city) => (
<Text color="primary" fontSize="14">
{city.id}
</Text>
),
isSortable: true,
width: 120,
},
{
key: 'name',
caption: 'Name',
group: 'primary', // key group from columnGroups array
render: (city) => (
<Text color="primary" fontSize="14">
{city.name}
</Text>
),
isSortable: true,
width: 162,
grow: 1,
},
{
key: 'countryName',
caption: 'Country',
group: 'primary', // key group from columnGroups array
render: (city) => (
<Text color="primary" fontSize="14">
{city.countryName}
</Text>
),
isSortable: true,
width: 128,
isFilterActive: (filter) => filter.country && filter.country.$in && !!filter.country.$in.length,
},
{
key: 'population',
caption: 'Population',
info: 'Number of this population in the country at the time of the last census.',
render: (city) => (
<Text color="primary" fontSize="14">
{city.population}
</Text>
),
width: 136,
isSortable: true,
textAlign: 'right',
},
{
key: 'altname',
caption: 'Alt. names',
render: (city) => <Text color="primary">{city.alternativeNames.join(', ')}</Text>,
info: 'Alternative city names',
width: 1200,
},
{
key: 'actions',
render: () => (
<Dropdown
renderTarget={ (props) => <IconButton icon={ MoreIcon } color="secondary" cx={ [css.configItem, props.isOpen && css.showButton] } { ...props } /> }
renderBody={ (dropdownProps) => renderMenu(dropdownProps) }
placement="bottom-end"
/>
),
width: 54,
fix: 'right',
allowResizing: false,
},
],
[],
);
const personColumns: DataColumnProps<Person, number>[] = [
{
key: 'name',
caption: 'Name',
render: (p) => <Text>{p.name}</Text>,
width: 130,
isSortable: true,
},
{
key: 'profileStatus',
caption: 'Status',
render: (p) => (
<FlexRow>
<Badge size="24" indicator fill="outline" color={ p.profileStatus.toLowerCase() as BadgeProps['color'] } caption={ p.profileStatus } />
</FlexRow>
),
grow: 0,
width: 100,
minWidth: 90,
isSortable: true,
},
{
key: 'countryName',
caption: 'Country',
group: 'location', // Specify group key
render: (p) => <Text>{p.countryName}</Text>,
grow: 0,
width: 110,
isSortable: true,
},
{
key: 'cityName',
caption: 'City',
group: 'location', // Specify group key
render: (p) => <Text>{p.cityName}</Text>,
grow: 0,
width: 110,
isSortable: true,
},
{
key: 'officeAddress',
caption: 'Office',
group: 'location', // Specify group key
render: (p) => <Text>{p.officeAddress}</Text>,
grow: 0,
width: 150,
isSortable: true,
},
{
key: 'jobTitle',
caption: 'Title',
group: 'position', // Specify group key
render: (r) => <Text>{r.jobTitle}</Text>,
width: 180,
isSortable: true,
},
{
key: 'titleLevel',
caption: 'Track & Level',
group: 'position', // Specify group key
render: (p) => <Text>{p.titleLevel}</Text>,
grow: 1,
width: 100,
isSortable: true,
},
];

const citiesDS = useLazyDataSource<City, string, unknown>({
api: svc.api.demo.cities,
const citiesDS = useLazyDataSource<Person, number, unknown>({
api: svc.api.demo.persons,
backgroundReload: true,
}, []);

Expand All @@ -131,8 +108,8 @@ export default function TableGroupedHeaderExample() {
getRows={ view.getVisibleRows }
showColumnsConfig={ false }
columnGroups={ columnGroups }
columns={ personColumns }
headerTextCase="upper"
columns={ citiesColumns }
/>
</Panel>
);
Expand Down
32 changes: 32 additions & 0 deletions public/docs/content/examples-tables-TableGroupedHeader.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"type": "paragraph",
"children": [
{
"text": "To create column groups in the table header, provide the group configuration using the "
},
{
"text": "columnGroups",
"uui-richTextEditor-code": true
},
{
"text": " prop. For each column to be grouped, specify the "
},
{
"text": "group",
"uui-richTextEditor-code": true
},
{
"text": " field with the corresponding group key."
}
]
},
{
"type": "note-warning",
"children": [
{
"text": "This is preview version of header groups functionality with limited support of some DataTable features, like columns reordering, resizing and columns configuration via modal."
}
]
}
]
2 changes: 1 addition & 1 deletion uui-components/src/table/DataTableRowContainer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
flex-direction: row;
}

.groupWrapper {
:global(.uui-table-column-group-wrapper) {
display: flex;
flex-direction: column;
}
2 changes: 1 addition & 1 deletion uui-components/src/table/DataTableRowContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const DataTableRowContainer = React.forwardRef(
const lastColumnIdx = props.columns?.indexOf(item.columns[item.columns.length - 1]) || 0;

return (
<div style={ getSectionStyle(item.columns, SectionType.Group) } className={ cx({ [css.section]: true, [css.groupWrapper]: true }) }>
<div style={ getSectionStyle(item.columns, SectionType.Group) } className={ cx(css.section, 'uui-table-column-group-wrapper') }>

{props.renderGroupCell(item.group, index, firstColumnIdx, lastColumnIdx)}
<div className={ css.groupColumnsWrapper }>
Expand Down
6 changes: 4 additions & 2 deletions uui/components/tables/DataTableHeaderCell.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
--uui-dt-header-cell-height: var(--uui-size);
--uui-dt-header-cell-caption-column-gap: 3px;
--uui-dt-header-cell-truncate-caption-line-height: 18px;
--uui-dt-header-cell-border: transparent;
//
color: var(--uui-text-primary);
align-items: center;
Expand All @@ -21,6 +22,7 @@
width: 0;
background-clip: padding-box;
min-height: var(--uui-dt-header-cell-height);
border-color: var(--uui-dt-header-cell-border);

.caption-wrapper {
column-gap: var(--uui-dt-header-cell-caption-column-gap);
Expand All @@ -38,7 +40,7 @@

&:hover {
background: var(--uui-dt-row-bg-hover);
box-shadow: inset 1px 0 0 var(--uui-dt-border), inset -1px 0 0 var(--uui-dt-border);
border-color: var(--uui-dt-border);
}

&:hover:not(:has(:global(.-clickable):hover)) {
Expand All @@ -50,7 +52,7 @@

&.resizable {
&:hover {
box-shadow: inset 1px 0 0 var(--uui-dt-border), inset -1px 0 0 var(--uui-dt-border);
border-color: var(--uui-dt-border);
}
}

Expand Down
2 changes: 2 additions & 0 deletions uui/components/tables/DataTableHeaderGroupCell.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
align-self: stretch;
background-clip: padding-box;
min-height: var(--uui-dt-header-group-cell-height);
border-bottom: 1px solid;
border-color: var(--uui-dt-border);

.caption-wrapper {
column-gap: var(--uui-dt-header-group-cell-caption-column-gap);
Expand Down
5 changes: 5 additions & 0 deletions uui/components/tables/DataTableHeaderRow.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

.root {
--uui-dt-header-row-config-icon-padding: 24px;


:global(.uui-table-column-group-wrapper) :global(.uui-table-header-cell) {
--uui-dt-header-cell-border: var(--uui-dt-border);
}
}

:global(.config-icon) {
Expand Down

0 comments on commit e4303cb

Please sign in to comment.