Skip to content

feat: exposing col sort state as CSS class #1145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/DataTable/TableCol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,13 @@ function TableCol<T>({
<NativeSortIcon sortActive={sortActive} sortDirection={sortDirection} />
);

const renderCustomSortIcon = () => (
<span className={[sortDirection, '__rdt_custom_sort_icon__'].join(' ')}>{sortIcon}</span>
);
const renderCustomSortIcon = (sortActive: boolean) => {
const classes = [sortDirection, '__rdt_custom_sort_icon__'];
if (sortActive) {
classes.unshift('active_sort');
}
return <span className={classes.join(' ')}>{sortIcon}</span>;
};

const sortActive = !!(column.sortable && equalizeId(selectedColumn.id, column.id));
const disableSort = !column.sortable || disabled;
Expand Down Expand Up @@ -217,7 +221,7 @@ function TableCol<T>({
sortActive={!disableSort && sortActive}
disabled={disableSort}
>
{!disableSort && customSortIconRight && renderCustomSortIcon()}
{!disableSort && customSortIconRight && renderCustomSortIcon(sortActive)}
{!disableSort && nativeSortIconRight && renderNativeSortIcon(sortActive)}

{typeof column.name === 'string' ? (
Expand All @@ -228,7 +232,7 @@ function TableCol<T>({
column.name
)}

{!disableSort && customSortIconLeft && renderCustomSortIcon()}
{!disableSort && customSortIconLeft && renderCustomSortIcon(sortActive)}
{!disableSort && nativeSortIconLeft && renderNativeSortIcon(sortActive)}
</ColumnSortable>
)}
Expand Down
8 changes: 8 additions & 0 deletions src/DataTable/__tests__/DataTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,14 @@ describe('DataTable::sorting', () => {
expect(container.firstChild).toMatchSnapshot();
});

test('should render correctly with an active custom sortIcon', () => {
const mock = dataMock({ sortable: true });
const { container } = render(<DataTable data={mock.data} columns={mock.columns} sortIcon={<div>ASC</div>} />);
fireEvent.click(container.querySelector('div[data-sort-id="1"]') as HTMLElement);

expect(container.firstChild).toMatchSnapshot();
});

test('should render correctly with a defaultSortAsc = false', () => {
const mock = dataMock({ sortable: true });
const { container } = render(<DataTable data={mock.data} columns={mock.columns} defaultSortAsc={false} />);
Expand Down
305 changes: 305 additions & 0 deletions src/DataTable/__tests__/__snapshots__/DataTable.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24886,6 +24886,311 @@ exports[`DataTable::sorting should render correctly with a defaultSortAsc = fals
</div>
`;

exports[`DataTable::sorting should render correctly with an active custom sortIcon 1`] = `
.c2 {
position: relative;
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
width: 100%;
height: 100%;
max-width: 100%;
color: rgba(0,0,0,0.87);
background-color: #FFFFFF;
}

.c3 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
width: 100%;
color: rgba(0,0,0,0.87);
font-size: 12px;
font-weight: 500;
}

.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
width: 100%;
background-color: #FFFFFF;
min-height: 52px;
border-bottom-width: 1px;
border-bottom-color: rgba(0,0,0,.12);
border-bottom-style: solid;
}

.c5 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
box-sizing: border-box;
line-height: normal;
padding-left: 16px;
padding-right: 16px;
}

.c11 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
box-sizing: border-box;
line-height: normal;
padding-left: 16px;
padding-right: 16px;
word-break: break-word;
}

.c6 {
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
-webkit-flex-basis: 0;
-ms-flex-preferred-size: 0;
flex-basis: 0;
max-width: 100%;
min-width: 100px;
}

.c12 div:first-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.c10 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;
width: 100%;
box-sizing: border-box;
font-size: 13px;
font-weight: 400;
color: rgba(0,0,0,0.87);
background-color: #FFFFFF;
min-height: 48px;
}

.c10:not(:last-of-type) {
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-color: rgba(0,0,0,.12);
}

.c7 {
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: inherit;
-webkit-justify-content: inherit;
-ms-flex-pack: inherit;
justify-content: inherit;
height: 100%;
width: 100%;
outline: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow: hidden;
cursor: pointer;
}

.c7 span.__rdt_custom_sort_icon__ i,
.c7 span.__rdt_custom_sort_icon__ svg {
-webkit-transform: 'translate3d(0, 0, 0)';
-ms-transform: 'translate3d(0, 0, 0)';
transform: 'translate3d(0, 0, 0)';
opacity: 1;
color: inherit;
font-size: 18px;
height: 18px;
width: 18px;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition-duration: 95ms;
transition-duration: 95ms;
-webkit-transition-property: -webkit-transform;
-webkit-transition-property: transform;
transition-property: transform;
}

.c7 span.__rdt_custom_sort_icon__.asc i,
.c7 span.__rdt_custom_sort_icon__.asc svg {
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}

.c8 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

.c9 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}

.c0 {
position: relative;
width: 100%;
border-radius: inherit;
overflow-x: auto;
overflow-y: hidden;
min-height: 0;
}

.c1 {
position: relative;
width: 100%;
display: table;
}

<div
class="c0"
>
<div
class="c1"
>
<div
class="c2 rdt_Table"
role="table"
>
<div
class="c3 rdt_TableHead"
role="rowgroup"
>
<div
class="c4 rdt_TableHeadRow"
role="row"
>
<div
class="c5 c6 rdt_TableCol"
data-column-id="1"
>
<div
class="c7 rdt_TableCol_Sortable"
data-column-id="1"
data-sort-id="1"
role="columnheader"
tabindex="0"
>
<div
class="c8"
data-column-id="1"
>
Test
</div>
<span
class="active_sort asc __rdt_custom_sort_icon__"
>
<div>
ASC
</div>
</span>
</div>
</div>
</div>
</div>
<div
class="c9 rdt_TableBody"
role="rowgroup"
>
<div
class="c10 rdt_TableRow"
id="row-1"
role="row"
>
<div
class="c11 c6 c12 rdt_TableCell"
data-column-id="1"
data-tag="allowRowEvents"
id="cell-1-1"
role="cell"
>
<div
data-tag="allowRowEvents"
>
Apple
</div>
</div>
</div>
<div
class="c10 rdt_TableRow"
id="row-2"
role="row"
>
<div
class="c11 c6 c12 rdt_TableCell"
data-column-id="1"
data-tag="allowRowEvents"
id="cell-1-2"
role="cell"
>
<div
data-tag="allowRowEvents"
>
Zuchinni
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

exports[`DataTable::sorting should sort if the column is selected and the Enter key is pressed 1`] = `
.c2 {
position: relative;
Expand Down
4 changes: 2 additions & 2 deletions stories/props.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { Meta } from '@storybook/addon-docs';
| ------------------ | --------------------------------------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| defaultSortFieldId | string or number | no | null | The `defaultSortFieldId` sets the a column to be pre sorted and corresponds to the a column definition `id` |
| defaultSortAsc | boolean | no | true | Set this to false if you want the table data to be sorted in DESC order.<br /><br />**Note:** This will apply work when the table is initially loaded |
| sortIcon | component | no | built-in | Override the default sort icon - the icon must be a font or svg icon and it should be a "downward" icon since animation will be handled by React Data Table |
| sortIcon | component | no | built-in | Override the default sort icon - the icon must be a font or svg icon. Use `__rdt_custom_sort_icon__`, `asc`/`desc`, and `active_sort` for display/styling. |
| sortServer | boolean | no | false | Disables internal sorting for use with server-side/remote sorting or when you want to manually control the sort behavior. place your sorting logic and/or api calls in an `onSort` handler. <br /><br />**Note:** `sortFunction` is a better choice if you simply want to override the internal sorting behavior |
| sortFunction | `(rows, selector, direction) => {}` | no | null | Pass in your own custom sort function. **Your function must return an new array reference**, otherwise RDT will not re-render. For example, `Array.sort` sorts the array in place but because of JavaScript object equality it will be the same reference and will not re-render. A common pattern is to return `yourArray.slice(0)` which creates a new array |
| onSort | `(selectedColumn, sortDirection, sortedRows) => {}` | no | | callback to access the sort state when a column is clicked. returns ([column](/docs/api-columns--page), sortDirection, event) |
Expand Down Expand Up @@ -77,7 +77,7 @@ import { Meta } from '@storybook/addon-docs';
# Pagination

| Property | Type | Required | Default | Description |
| ---------------------------- | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ---------------------------- | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pagination | boolean | no | false | Enable pagination with defaults. by default the total record set will be sliced depending on the page, rows per page. if you wish to use server side pagination then use the `paginationServer` property |
| paginationServer | boolean | no | false | Changes the default pagination to work with server side pagination |
| paginationServerOptions | object | no | `{ persistSelectedOnPageChange: false, persistSelectedOnSort: false }` | When using `selectableRows` is used to make selected rows persist on page change and on sort when using server side pagination. <br /><br />**Note:** when using `persistSelectedOnPageChange` that select all checkbox will not be visible (i.e. you cannot select rows there you have to retrieved from the server) |
Expand Down
Loading