Highlight tableRows on :hover and :focus-within (#1059)
* Highlight tableRows on :hover and :focus-within Resolves #1041 The purpose of this commit is to make the pagerankTable easier to read, as it's currently difficult to distinguish which score is associated with which row because of the tight spacing of the rows and the space between the score column and the row detail column. @wchargin provided the implementation using `linearGradient()` and `backgroundImage`s. A side effect of highlighting the row on `focus-within` is that the rows will become highlighted when the expand button is clicked, which we decided was acceptable. Test plan: Yarn test passes. To test the new highlight behavior, visual/manual inspection passes. Also added the Aphrodite className to the snapshot tests. The combination of testing the className + inline style props should make these tests sensitive to UI changes in the future. Screenshots: <img width="939" alt="screenshot 2019-02-17 15 46 34" src="https://user-images.githubusercontent.com/26695477/52918955-332f5280-32cb-11e9-87d3-887c8877116a.png"> <img width="931" alt="screenshot 2019-02-17 15 45 10" src="https://user-images.githubusercontent.com/26695477/52918953-2f9bcb80-32cb-11e9-9356-82c6dccab4ae.png"> * bump CI
This commit is contained in:
parent
23f3f61e1d
commit
4adbec03c2
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import React, {type Node as ReactNode} from "react";
|
||||
import {StyleSheet, css} from "aphrodite/no-important";
|
||||
|
||||
type TableRowProps = {|
|
||||
// How many layers of nested scope we're in (changes the color)
|
||||
|
@ -49,10 +50,20 @@ export class TableRow extends React.PureComponent<
|
|||
? ""
|
||||
: (connectionProportion * 100).toFixed(2) + "%";
|
||||
const backgroundColor = `hsla(150,100%,28%,${1 - 0.9 ** depth})`;
|
||||
const makeGradient = (color) =>
|
||||
`linear-gradient(to top, ${color}, ${color})`;
|
||||
const normalBackground = makeGradient(backgroundColor);
|
||||
const highlightBackground = makeGradient("#D8E1E8");
|
||||
const backgroundImage = `${normalBackground}, ${highlightBackground}`;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{showPadding && <PaddingRow backgroundColor={backgroundColor} />}
|
||||
<tr key="self" style={{backgroundColor}}>
|
||||
<tr
|
||||
key="self"
|
||||
style={{backgroundImage}}
|
||||
className={css(styles.hoverHighlight)}
|
||||
>
|
||||
<td style={{display: "flex", alignItems: "flex-start"}}>
|
||||
<button
|
||||
style={{
|
||||
|
@ -95,3 +106,21 @@ export function PaddingRow(props: {|+backgroundColor: string|}) {
|
|||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
/* To apply 'hoverHighlight', provide a backgroundImage containing two <image>
|
||||
* data types (eg linear gradients). The first backgroundImage will be
|
||||
* the default background. The second backgroundImage will be applied on top
|
||||
* of the first background when the user hovers or tabs over the element.
|
||||
*/
|
||||
|
||||
hoverHighlight: {
|
||||
backgroundSize: "100% 100%, 0 0",
|
||||
":hover": {
|
||||
backgroundSize: "100% 100%, 100% 100%",
|
||||
},
|
||||
":focus-within": {
|
||||
backgroundSize: "100% 100%, 100% 100%",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import {TableRow, PaddingRow} from "./TableRow";
|
|||
|
||||
import {COLUMNS} from "./sharedTestUtils";
|
||||
require("../../webutil/testUtil").configureEnzyme();
|
||||
require("../../webutil/testUtil").configureAphrodite();
|
||||
|
||||
describe("explorer/pagerankTable/TableRow", () => {
|
||||
function example() {
|
||||
|
@ -34,9 +35,11 @@ describe("explorer/pagerankTable/TableRow", () => {
|
|||
children={<div data-test-children={true} />}
|
||||
/>
|
||||
);
|
||||
const trStyle = el.find("tr").props().style;
|
||||
const tr = el.find("tr");
|
||||
const trStyle = tr.props().style;
|
||||
const trClassName = tr.props().className;
|
||||
const buttonStyle = el.find("button").props().style;
|
||||
expect({depth, trStyle, buttonStyle}).toMatchSnapshot();
|
||||
expect({depth, trStyle, trClassName, buttonStyle}).toMatchSnapshot();
|
||||
}
|
||||
});
|
||||
it("indent parameter changes the button indentation", () => {
|
||||
|
@ -52,9 +55,11 @@ describe("explorer/pagerankTable/TableRow", () => {
|
|||
children={<div data-test-children={true} />}
|
||||
/>
|
||||
);
|
||||
const trStyle = el.find("tr").props().style;
|
||||
const tr = el.find("tr");
|
||||
const trStyle = tr.props().style;
|
||||
const trClassName = tr.props().className;
|
||||
const buttonStyle = el.find("button").props().style;
|
||||
expect({indent, trStyle, buttonStyle}).toMatchSnapshot();
|
||||
expect({indent, trStyle, trClassName, buttonStyle}).toMatchSnapshot();
|
||||
}
|
||||
});
|
||||
it("expand button toggles symbol based on expansion state", () => {
|
||||
|
@ -165,8 +170,9 @@ describe("explorer/pagerankTable/TableRow", () => {
|
|||
const el = paddingExample();
|
||||
const pr = el.find(PaddingRow).at(0);
|
||||
const tr = el.find("tr");
|
||||
expect(pr.props().backgroundColor).toEqual(
|
||||
tr.props().style.backgroundColor
|
||||
const prBackgroundColor = pr.props().backgroundColor;
|
||||
expect(tr.props().style.backgroundImage).toEqual(
|
||||
`linear-gradient(to top, ${prBackgroundColor}, ${prBackgroundColor}), linear-gradient(to top, #D8E1E8, #D8E1E8)`
|
||||
);
|
||||
});
|
||||
it("padding rows properly set the background color", () => {
|
||||
|
|
|
@ -7,8 +7,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"depth": 0,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0), hsla(150,100%,28%,0)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -20,8 +21,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"depth": 1,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0.09999999999999998)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0.09999999999999998), hsla(150,100%,28%,0.09999999999999998)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -33,8 +35,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"depth": 2,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0.18999999999999995)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0.18999999999999995), hsla(150,100%,28%,0.18999999999999995)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -46,8 +49,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"indent": 0,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0.2709999999999999)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0.2709999999999999), hsla(150,100%,28%,0.2709999999999999)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -59,8 +63,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"indent": 1,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0.2709999999999999)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0.2709999999999999), hsla(150,100%,28%,0.2709999999999999)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -72,8 +77,9 @@ Object {
|
|||
"marginRight": 5,
|
||||
},
|
||||
"indent": 2,
|
||||
"trClassName": "hoverHighlight_1d3gwos",
|
||||
"trStyle": Object {
|
||||
"backgroundColor": "hsla(150,100%,28%,0.2709999999999999)",
|
||||
"backgroundImage": "linear-gradient(to top, hsla(150,100%,28%,0.2709999999999999), hsla(150,100%,28%,0.2709999999999999)), linear-gradient(to top, #D8E1E8, #D8E1E8)",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
|
Loading…
Reference in New Issue