Skip to content

Commit

Permalink
Merge branch 'feature/rc-version' into fix/timeline-scale-custom-height
Browse files Browse the repository at this point in the history
  • Loading branch information
Yaroslav Kuznietsov committed Nov 7, 2024
2 parents acd8edb + 6a4592e commit 0c3a85b
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 23 deletions.
5 changes: 3 additions & 2 deletions app/src/sandbox/tables/PersonsTableDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const formatCurrency = (value: number) => {
};

export function PersonsTableDemo() {
const { personColumns, summaryColumns } = React.useMemo(() => getColumns(), []);
const { personColumns, summaryColumns, personColumnsGroups } = React.useMemo(() => getColumns(), []);

const [summary, setSummary] = React.useState<PersonsSummary & Pick<PersonsApiResponse, 'totalCount'>>({
totalCount: undefined,
Expand Down Expand Up @@ -161,7 +161,7 @@ export function PersonsTableDemo() {
[value.filter?.groupBy],
);
const { rows, listProps } = useDataRows(tree);

return (
<div className={ cx(css.container, css.uuiThemeLoveship) }>
<FlexRow spacing="12" padding="24" vPadding="12" borderBottom={ true }>
Expand Down Expand Up @@ -189,6 +189,7 @@ export function PersonsTableDemo() {
<DataTable
rows={ rows }
columns={ personColumns as DataColumnProps<PersonTableRecord, PersonTableRecordId, any>[] }
columnGroups={ personColumnsGroups }
value={ value }
onValueChange={ onValueChange }
filters={ getFilters() }
Expand Down
50 changes: 41 additions & 9 deletions app/src/sandbox/tables/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,93 @@
import * as React from 'react';
import { Text, FlexRow } from '@epam/loveship';
import { DataQueryFilter, DataColumnProps } from '@epam/uui-core';
import { DataQueryFilter, DataColumnProps, DataColumnGroupProps } from '@epam/uui-core';
import type { Person } from '@epam/uui-docs';
import type { PersonTableRecordId } from './types';
import type { PersonsSummary } from './types';

export function getColumns() {
const personColumnsGroups: DataColumnGroupProps[] = [
{
key: 'name',
caption: 'Name',
},
{
key: 'position',
caption: 'Position',
},
{
key: 'amounts',
caption: 'Amounts',
textAlign: 'right',
},
];

const personColumns: DataColumnProps<Person, PersonTableRecordId, DataQueryFilter<Person>>[] = [
{
key: 'name',
group: 'name',
caption: 'Name',
render: (p) => <Text>{p.name}</Text>,
width: 250,
grow: 1,
fix: 'left',
allowResizing: true,
isSortable: true,
}, {
key: 'name2',
group: 'name',
caption: 'Name2',
render: (p) => <Text>{p.name}</Text>,
width: 250,
fix: 'left',
allowResizing: true,
isSortable: true,
}, {
key: 'jobTitle',
group: 'position',
caption: 'Job Title',
render: (r) => <Text>{r.jobTitle}</Text>,
width: 200,
grow: 1,
allowResizing: true,
isSortable: true,
isFilterActive: (f) => !!f.jobTitle,
}, {
key: 'departmentName',
group: 'position',
caption: 'Department',
render: (p) => <Text>{p.departmentName}</Text>,
width: 200,
grow: 1,
allowResizing: true,
isSortable: true,
isFilterActive: (f) => !!f.departmentId,
}, {
key: 'birthDate',
group: 'position',
caption: 'Birth Date',
render: (p) => p?.birthDate && <Text>{new Date(p.birthDate).toLocaleDateString()}</Text>,
width: 120,
allowResizing: true,
isSortable: true,
}, {
key: 'hireDate',
caption: 'Hire Date',
render: (p) => p?.hireDate && <Text>{new Date(p.hireDate).toLocaleDateString()}</Text>,
width: 120,
allowResizing: true,
isSortable: true,
}, {
key: 'locationName',
caption: 'Location',
render: (p) => <Text>{p.locationName}</Text>,
width: 180,
grow: 1,
allowResizing: true,
isSortable: true,
}, {
key: 'salary',
group: 'amounts',
caption: 'Salary',
render: (p) => <Text color="night900">{p.salary}</Text>,
width: 150,
allowResizing: true,
isSortable: true,
textAlign: 'right',
}, {
Expand All @@ -72,7 +105,6 @@ export function getColumns() {
fix: 'left',
textAlign: 'right',
width: 250,
grow: 1,
render: (p) => (
<FlexRow background="night50">
<Text fontSize="14">
Expand All @@ -87,13 +119,13 @@ export function getColumns() {
),
}, {
key: 'jobTitle',
group: 'position',
width: 200,
grow: 1,
render: () => <Text fontSize="14">-</Text>,
}, {
key: 'departmentName',
group: 'position',
width: 200,
grow: 1,
render: () => (
<Text fontSize="14">
-
Expand All @@ -111,7 +143,6 @@ export function getColumns() {
key: 'locationName',
render: () => <Text fontSize="14">-</Text>,
width: 180,
grow: 1,
}, {
key: 'salary',
caption: 'Total Salary',
Expand All @@ -133,5 +164,6 @@ export function getColumns() {
return {
personColumns,
summaryColumns,
personColumnsGroups,
};
}
3 changes: 1 addition & 2 deletions uui-components/src/table/DataTableRowContainer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@

// Compensate negative padding of cells to overlap borders
// W/o this, we'll have additional --uui-cell-border-width pixels at the right
// We don't have access to the --uui-cell-border-width var. Hard-coded 1px for now.
border-inline-end: 1px solid transparent;
border-inline-end: var(--uui-dt-cell-border-width) solid transparent;
}

.fixed-columns-section-right {
Expand Down
42 changes: 34 additions & 8 deletions uui-components/src/table/DataTableRowContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,43 @@ const uuiDataTableRowCssMarkers = {

const CELL_BORDER_WIDTH = 1;

enum SectionType {
Fixed = 1,
Scrolling = 2,
Group = 3,
Table = 4
}

// Scrolling/Fixed sections wrappers, as well as the whole row itself, has to have matching flex-item parameters.
// This is required to have the same width, as the sum of column's width, and grow in the same proportion, as columns inside.
// E.g. for 2 columns: { width: 100, grow: 0 }, { width: 200, grow: 1 } we compute { width: 300, grow: 1 }
// For scrollingSection and for the whole table, we put at least grow=1 - to make the table occupy full width, even if there's no columns with grow > 0.
function getSectionStyle(columns: DataColumnProps[], minGrow = 0) {
function getSectionStyle(columns: DataColumnProps[], type: SectionType) {
let grow = 0;
let width = 0;

columns.forEach((column) => {
const columnWidth = typeof column.width === 'number' ? (column.fix ? column.width : column.width - CELL_BORDER_WIDTH) : column.minWidth || 0; // (column.width - CELL_BORDER_WIDTH) do not forget the negative margin of the scrolling columns in the calculation of the width
let columnWidth;
if (typeof column.width === 'number') {
// As columns border's are overlap to collapse borders, effective width of each cell is less by CELL_BORDER_WIDTH
columnWidth = column.width - CELL_BORDER_WIDTH;
} else if (typeof column.minWidth === 'number') {
columnWidth = column.minWidth;
} else {
columnWidth = 0;
}

width += columnWidth;

grow += typeof column.grow === 'number' ? column.grow : 0;
});

// For fixed sections we keep 1 border width for a transparent border on the edge, so borders on scrolling section can be visible through it
if (width > 0 && type === SectionType.Fixed) {
width += CELL_BORDER_WIDTH;
}

const minGrow = type === SectionType.Scrolling ? 1 : 0;
grow = Math.max(grow, minGrow);

return {
Expand Down Expand Up @@ -83,9 +106,9 @@ export const DataTableRowContainer = React.forwardRef(
const lastColumnIdx = props.columns?.indexOf(item.columns[item.columns.length - 1]) || 0;

return (
<div style={ getSectionStyle(item.columns) } className={ cx({ [css.section]: true, [css.groupWrapper]: true }) }>
<div>{props.renderGroupCell(item.group, index, firstColumnIdx, lastColumnIdx)}</div>
<div style={ getSectionStyle(item.columns, SectionType.Group) } className={ cx({ [css.section]: true, [css.groupWrapper]: true }) }>

{props.renderGroupCell(item.group, index, firstColumnIdx, lastColumnIdx)}
<div className={ css.groupColumnsWrapper }>
{
item.columns.map((column) => {
Expand All @@ -106,7 +129,7 @@ export const DataTableRowContainer = React.forwardRef(
function wrapFixedSection(columns: DataColumnProps<TItem, TId, TFilter>[], direction: 'left' | 'right', hasScrollingSection: boolean) {
return (
<div
style={ getSectionStyle(columns) }
style={ getSectionStyle(columns, SectionType.Fixed) }
className={ cx({
[css.section]: true,
[uuiDataTableRowCssMarkers.uuiTableFixedSection]: true,
Expand All @@ -126,7 +149,10 @@ export const DataTableRowContainer = React.forwardRef(

function wrapScrollingSection(columns: DataColumnProps<TItem, TId, TFilter>[]) {
return (
<div className={ cx(css.section, css.scrollingSection, uuiDataTableRowCssMarkers.uuiTableScrollingSection) } style={ getSectionStyle(columns, 1) }>
<div
className={ cx(css.section, css.scrollingSection, uuiDataTableRowCssMarkers.uuiTableScrollingSection) }
style={ getSectionStyle(columns, SectionType.Scrolling) }
>
{renderCells(columns)}
</div>
);
Expand Down Expand Up @@ -156,7 +182,7 @@ export const DataTableRowContainer = React.forwardRef(
}

// We use only total minWidth here, grow is not needed (rows are placed in block or vertical flex contexts)
const minWidth = getSectionStyle(props.columns, 1).minWidth;
const minWidth = getSectionStyle(props.columns, SectionType.Table).minWidth;

const rawProps = {
...restRawProps,
Expand Down
2 changes: 1 addition & 1 deletion uui/components/tables/DataTableHeaderGroupCell.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
align-items: center;
padding-inline-start: var(--uui-dt-header-group-cell-padding-start);
padding-inline-end: var(--uui-dt-header-group-cell-padding-end);
width: 0;
align-self: stretch;
background-clip: padding-box;
min-height: var(--uui-dt-header-group-cell-height);

Expand Down
1 change: 0 additions & 1 deletion uui/components/tables/DataTableHeaderGroupCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ export class DataTableHeaderGroupCell extends
const computeStyles = {
'--uui-dt-header-group-cell-padding-start': `${this.getLeftPadding()}px`,
'--uui-dt-header-group-cell-padding-end': `${this.getRightPadding()}px`,
width: '100%',
} as React.CSSProperties;

return (
Expand Down

0 comments on commit 0c3a85b

Please sign in to comment.