Skip to content

Commit

Permalink
Green column divider (#1888)
Browse files Browse the repository at this point in the history
# Pull Request

## 🀨 Rationale

Fixes #1880 

## πŸ‘©β€πŸ’» Implementation

- A hovered column divider is now `borderHoverColor`
- The column divider that is being dragged is styled using the `active`
class to be `borderHoverColor`
- The second column divider of the column being resized (assuming it
exists) is styled using the `visible` class to be visible

## πŸ§ͺ Testing

- Manually tested in storybook
- Update unit tests that check for the correct CSS classes to be applied
to dividers during a drag operation

## βœ… Checklist

<!--- Review the list and put an x in the boxes that apply or ~~strike
through~~ around items that don't (along with an explanation). -->

- [ ] I have updated the project documentation to reflect my changes or
determined no changes are needed.

---------

Co-authored-by: m-akinc <[email protected]>
Co-authored-by: Milan Raj <[email protected]>
  • Loading branch information
3 people authored Mar 4, 2024
1 parent 74a406d commit 4b05012
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Update column divider color on hover",
"packageName": "@ni/nimble-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
14 changes: 12 additions & 2 deletions packages/nimble-components/src/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ export class Table<
if (event.button === 0) {
this.layoutManager.beginColumnInteractiveSize(
event.clientX,
columnIndex * 2
this.getRightDividerIndex(columnIndex)
);
}
}
Expand All @@ -452,11 +452,21 @@ export class Table<
if (event.button === 0) {
this.layoutManager.beginColumnInteractiveSize(
event.clientX,
columnIndex * 2 - 1
this.getLeftDividerIndex(columnIndex)
);
}
}

/** @internal */
public getLeftDividerIndex(columnIndex: number): number {
return columnIndex * 2 - 1;
}

/** @internal */
public getRightDividerIndex(columnIndex: number): number {
return columnIndex * 2;
}

/** @internal */
public handleGroupRowExpanded(rowIndex: number, event: Event): void {
this.toggleRowExpanded(rowIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export class TableLayoutManager<TData extends TableRecord> {
@observable
public activeColumnIndex?: number;

private activeColumnDivider?: number;
@observable
public activeColumnDivider?: number;

private gridSizedColumns?: TableColumn[];
private visibleColumns: TableColumn[] = [];
private initialTableScrollableWidth?: number;
Expand Down Expand Up @@ -111,6 +113,7 @@ export class TableLayoutManager<TData extends TableRecord> {
this.resetGridSizedColumns();
this.isColumnBeingSized = false;
this.activeColumnIndex = undefined;
this.activeColumnDivider = undefined;
};

private getTotalColumnFixedWidth(): number {
Expand Down
25 changes: 13 additions & 12 deletions packages/nimble-components/src/table/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
controlSlimHeight,
mediumPadding,
standardPadding,
tableRowBorderColor
tableRowBorderColor,
borderHoverColor
} from '../theme-provider/design-tokens';
import { Theme } from '../theme-provider/types';
import { hexToRgbaCssColor } from '../utilities/style/colors';
Expand Down Expand Up @@ -115,6 +116,17 @@ export const styles = css`
height: ${controlSlimHeight};
cursor: col-resize;
position: absolute;
z-index: ${ZIndexLevels.zIndex1};
}
.column-divider:hover,
.column-divider.divider-active {
border-color: ${borderHoverColor};
}
.column-divider.column-active,
.header-container:hover .column-divider {
display: block;
}
.column-divider::before {
Expand All @@ -131,17 +143,6 @@ export const styles = css`
);
}
.column-divider.active {
display: block;
z-index: ${ZIndexLevels.zIndex1};
}
.header-container:hover .column-divider.left,
.header-container:hover .column-divider.right {
display: block;
z-index: ${ZIndexLevels.zIndex1};
}
.column-divider.left {
left: -1px;
}
Expand Down
18 changes: 15 additions & 3 deletions packages/nimble-components/src/table/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,14 @@ export const template = html<Table>`
${repeat(x => x.visibleColumns, html<TableColumn, Table>`
<div class="header-container">
${when((_, c) => c.index > 0, html<TableColumn, Table>`
<div class="column-divider left ${(_, c) => `${c.parent.layoutManager.activeColumnIndex === c.index ? 'active' : ''}`}"
@mousedown="${(_, c) => c.parent.onLeftDividerMouseDown(c.event as MouseEvent, c.index)}">
<div
class="
column-divider
left
${(_, c) => `${c.parent.layoutManager.activeColumnIndex === c.index ? 'column-active' : ''}`}
${(_, c) => `${c.parent.layoutManager.activeColumnDivider === c.parent.getLeftDividerIndex(c.index) ? 'divider-active' : ''}`}
"
@mousedown="${(_, c) => c.parent.onLeftDividerMouseDown(c.event as MouseEvent, c.index)}">
</div>
`)}
<${tableHeaderTag}
Expand All @@ -97,7 +103,13 @@ export const template = html<Table>`
<slot name="${x => x.slot}"></slot>
</${tableHeaderTag}>
${when((_, c) => c.index < c.length - 1, html<TableColumn, Table>`
<div class="column-divider right ${(_, c) => `${c.parent.layoutManager.activeColumnIndex === c.index ? 'active' : ''}`}"
<div
class="
column-divider
right
${(_, c) => `${c.parent.layoutManager.activeColumnIndex === c.index ? 'column-active' : ''}`}
${(_, c) => `${c.parent.layoutManager.activeColumnDivider === c.parent.getRightDividerIndex(c.index) ? 'divider-active' : ''}`}
"
@mousedown="${(_, c) => c.parent.onRightDividerMouseDown(c.event as MouseEvent, c.index)}">
</div>
`)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,60 +750,74 @@ describe('Table Interactive Column Sizing', () => {
describe('active divider tests', () => {
const dividerActiveTests = [
{
name: 'click on first column right divider only results in one active divider',
name: 'click on first column right divider',
dividerClickIndex: 0,
leftDividerClick: false,
expectedActiveIndexes: [0]
expectedColumnActiveDividerIndexes: [0]
},
{
name: 'click on second column left divider results in two active dividers',
name: 'click on second column left divider',
dividerClickIndex: 1,
expectedActiveIndexes: [1, 2]
expectedColumnActiveDividerIndexes: [1, 2]
},
{
name: 'click on second column right divider results in two active dividers',
name: 'click on second column right divider',
dividerClickIndex: 2,
expectedActiveIndexes: [1, 2]
expectedColumnActiveDividerIndexes: [1, 2]
},
{
name: 'click on third column left divider results in two active dividers',
name: 'click on third column left divider',
dividerClickIndex: 3,
expectedActiveIndexes: [3, 4]
expectedColumnActiveDividerIndexes: [3, 4]
},
{
name: 'click on third column right divider results in two active dividers',
name: 'click on third column right divider',
dividerClickIndex: 4,
expectedActiveIndexes: [3, 4]
expectedColumnActiveDividerIndexes: [3, 4]
},
{
name: 'click on last column left divider only results in one active divider',
name: 'click on last column left divider',
dividerClickIndex: 5,
expectedActiveIndexes: [5]
expectedColumnActiveDividerIndexes: [5]
}
] as const;
parameterizeSpec(dividerActiveTests, (spec, name, value) => {
spec(name, async () => {
const dividers = Array.from(
element.shadowRoot!.querySelectorAll('.column-divider')
);
const divider = dividers[value.dividerClickIndex]!;
const dividerRect = divider.getBoundingClientRect();
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: (dividerRect.x + dividerRect.width) / 2,
clientY: (dividerRect.y + dividerRect.height) / 2
});
const mouseUpEvent = new MouseEvent('mouseup');
divider.dispatchEvent(mouseDownEvent);
await waitForUpdatesAsync();
const activeDividers = [];
for (let i = 0; i < dividers.length; i++) {
if (dividers[i]!.classList.contains('active')) {
activeDividers.push(i);
spec(
`${name} updates expected dividers as "divider-active" and "column-active"`,
async () => {
const dividers = Array.from(
element.shadowRoot!.querySelectorAll('.column-divider')
);
const divider = dividers[value.dividerClickIndex]!;
const dividerRect = divider.getBoundingClientRect();
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: (dividerRect.x + dividerRect.width) / 2,
clientY: (dividerRect.y + dividerRect.height) / 2
});
const mouseUpEvent = new MouseEvent('mouseup');
divider.dispatchEvent(mouseDownEvent);
await waitForUpdatesAsync();
const dividerActiveDividers = [];
const columnActiveDividers = [];
for (let i = 0; i < dividers.length; i++) {
if (dividers[i]!.classList.contains('divider-active')) {
dividerActiveDividers.push(i);
}
if (dividers[i]!.classList.contains('column-active')) {
columnActiveDividers.push(i);
}
}
document.dispatchEvent(mouseUpEvent); // clean up registered event handlers

expect(dividerActiveDividers.length).toEqual(1);
expect(dividerActiveDividers[0]).toEqual(
value.dividerClickIndex
);
expect(columnActiveDividers).toEqual(
value.expectedColumnActiveDividerIndexes
);
}
document.dispatchEvent(mouseUpEvent); // clean up registered event handlers
expect(activeDividers).toEqual(value.expectedActiveIndexes);
});
);
});

it('first column only has right divider', () => {
Expand Down Expand Up @@ -831,12 +845,12 @@ describe('Table Interactive Column Sizing', () => {
});
divider.dispatchEvent(mouseDownEvent);
await waitForUpdatesAsync();
expect(divider.classList.contains('active')).toBeTruthy();
expect(divider.classList.contains('divider-active')).toBeTruthy();

const mouseUpEvent = new MouseEvent('mouseup');
document.dispatchEvent(mouseUpEvent);
await waitForUpdatesAsync();
expect(divider.classList.contains('active')).toBeFalsy();
expect(divider.classList.contains('divider-active')).toBeFalsy();
});
});

Expand Down

0 comments on commit 4b05012

Please sign in to comment.