Skip to content
Snippets Groups Projects
Unverified Commit f6bf3597 authored by Kyle Doherty's avatar Kyle Doherty Committed by GitHub
Browse files

Table visual improvements (#8635)

* start table playground

* be a table

* field and column styles

* hide label

* unified fields

* init actual table vibes

* headers

* text / link color tweaks

* tokenize PK

* token tweaks

* more cleanup and tweaking

* remove table app

* handle smaller pk / fk token content

* ID > PK

* tighten up horizontal padding

* sync up styles

* Fix sort indication in table

* bubbles for simple table

* tweak table simple to better match interactive
parent 820ccd71
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ type Props = {
percentage: number,
animated: boolean,
color: string,
height: number,
};
export default class ProgressBar extends Component {
......@@ -16,17 +17,18 @@ export default class ProgressBar extends Component {
static defaultProps = {
animated: false,
color: colors["brand"],
height: 10,
};
render() {
const { percentage, animated, color } = this.props;
const { percentage, animated, color, height } = this.props;
const width = percentage * 100;
const wrapperStyles = cxs({
position: "relative",
border: `1px solid ${color}`,
height: 10,
height,
borderRadius: 99,
});
......
......@@ -3,7 +3,7 @@ import React from "react";
import colors, { alpha } from "metabase/lib/colors";
import { formatValue } from "metabase/lib/formatting";
const BAR_HEIGHT = 11;
const BAR_HEIGHT = 8;
const BAR_WIDTH = 70;
const BORDER_RADIUS = 3;
......@@ -41,10 +41,10 @@ const MiniBar = ({ value, extent: [min, max], options, cellHeight }) => {
};
return (
<div className="flex align-center justify-end relative">
<div className="flex align-center currentcolor justify-end relative">
{/* TEXT VALUE */}
<div
className="text-ellipsis text-small text-bold text-medium text-right"
className="text-ellipsis text-bold text-right flex-full"
style={{ minWidth: LABEL_MIN_WIDTH }}
>
{formatValue(value, { ...options, jsx: true })}
......
......@@ -5,7 +5,6 @@
width: 100%;
font-family: "Helvetica Neue", "Helvetica", sans-serif;
font-size: 12px;
line-height: 12px;
text-align: left;
......@@ -17,11 +16,11 @@
:local(.Table) th,
:local(.Table) td {
padding: 1em;
padding: 0.72em;
border-bottom: 1px solid color(var(--color-border) alpha(-70%));
}
:local(.TableSimple) th:first-child,
:local(.TableSimple) td:first-child {
padding-left: 2em;
padding-left: 1.44em;
}
......@@ -3,20 +3,13 @@
}
.TableInteractive {
border-radius: var(--table-border-radius);
color: #4f575d;
overflow: hidden;
}
.TableInteractive-headerCellData {
font-weight: 700;
}
.TableInteractive-headerCellData.TableInteractive-cellWrapper--firstColumn {
border-top-left-radius: var(--table-border-radius);
}
.TableInteractive-headerCellData.TableInteractive-cellWrapper--lastColumn {
border-top-right-radius: var(--table-border-radius);
.TableInteractive-headerCellData .cellData {
font-weight: 900;
font-size: 10px;
}
.TableInteractive-headerCellData .Icon {
......@@ -39,7 +32,7 @@
}
.TableInteractive .TableInteractive-cellWrapper {
padding: 1em 1.25em;
padding: 0 0.75em;
overflow: hidden;
display: flex;
align-items: center;
......@@ -50,13 +43,6 @@
border-bottom: 1px solid color(var(--color-border) alpha(-70%));
}
.TableInteractive .TableInteractive-cellWrapper--active,
.TableInteractive:not(.TableInteractive--noHover)
.TableInteractive-cellWrapper:hover {
border-color: var(--color-brand);
color: var(--color-brand);
}
.TableInteractive .TableInteractive-cellWrapper--active {
z-index: 1;
}
......@@ -78,6 +64,8 @@
white-space: nowrap;
text-overflow: ellipsis;
overflow-x: hidden;
font-weight: 700;
font-size: 12.5px;
}
/* pivot */
......@@ -94,3 +82,31 @@
background-color: var(--color-brand);
color: white !important;
}
.TableInteractive-cellWrapper:hover {
background-color: color(var(--color-brand) alpha(-90%));
}
.Table-ID .cellData {
border: 1px solid color(var(--color-brand) alpha(-86%));
background-color: color(var(--color-brand) alpha(-92%));
padding: 0.25em 0.65em;
border-radius: 99px;
min-width: 35px;
text-align: center;
}
.TableInteractive-ID.TableInteractive-cellWrapper:hover,
.TableInteractive-ID.TableInteractive-cellWrapper.tether-enabled {
background-color: transparent;
}
.TableInteractive-ID.TableInteractive-cellWrapper:hover .cellData,
.TableInteractive-ID.TableInteractive-cellWrapper.tether-enabled .cellData {
background-color: var(--color-brand);
color: white;
}
.TableInteractive-headerCellData--sorted {
color: var(--color-brand);
}
......@@ -9,12 +9,13 @@ import "./TableInteractive.css";
import Icon from "metabase/components/Icon.jsx";
import { formatValue, formatColumn } from "metabase/lib/formatting";
import { isID } from "metabase/lib/schema_metadata";
import { isID, isFK } from "metabase/lib/schema_metadata";
import {
getTableCellClickedObject,
isColumnRightAligned,
} from "metabase/visualizations/lib/table";
import { getColumnExtent } from "metabase/visualizations/lib/utils";
import Query from "metabase/lib/query";
import _ from "underscore";
import cx from "classnames";
......@@ -27,7 +28,7 @@ import { Grid, ScrollSync } from "react-virtualized";
import Draggable from "react-draggable";
const HEADER_HEIGHT = 36;
const ROW_HEIGHT = 30;
const ROW_HEIGHT = 36;
const MIN_COLUMN_WIDTH = ROW_HEIGHT;
const RESIZE_HANDLE_WIDTH = 5;
// if header is dragged fewer than than this number of pixels we consider it a click instead of a drag
......@@ -345,12 +346,15 @@ export default class TableInteractive extends Component {
transition: dragColIndex != null ? "left 200ms" : null,
backgroundColor,
}}
className={cx("TableInteractive-cellWrapper", {
className={cx("TableInteractive-cellWrapper text-dark", {
"TableInteractive-cellWrapper--firstColumn": columnIndex === 0,
"TableInteractive-cellWrapper--lastColumn":
columnIndex === cols.length - 1,
"TableInteractive-emptyCell": value == null,
"cursor-pointer": isClickable,
"justify-end": isColumnRightAligned(column),
"Table-ID": isID(column),
"Table-FK": isFK(column),
link: isClickable && isID(column),
})}
onMouseUp={
......@@ -470,9 +474,12 @@ export default class TableInteractive extends Component {
const isSortable = isClickable && column.source;
const isRightAligned = isColumnRightAligned(column);
// the column id is in `["field-id", fieldId]` format
// TODO MBQL: use query lib to get the sort field
const isSorted =
sort && sort[0] && sort[0][0] && sort[0][0][1] === column.id;
sort &&
sort[0] &&
sort[0][1] &&
Query.getFieldTargetId(sort[0][1]) === column.id;
const isAscending = sort && sort[0] && sort[0][0] === "asc";
return (
<Draggable
......@@ -532,7 +539,7 @@ export default class TableInteractive extends Component {
: this.getColumnLeft(style, columnIndex),
}}
className={cx(
"TableInteractive-cellWrapper TableInteractive-headerCellData",
"TableInteractive-cellWrapper TableInteractive-headerCellData text-medium text-brand-hover",
{
"TableInteractive-cellWrapper--firstColumn": columnIndex === 0,
"TableInteractive-cellWrapper--lastColumn":
......
......@@ -22,6 +22,8 @@ import { t } from "c-3po";
import cx from "classnames";
import _ from "underscore";
import { isID, isFK } from "metabase/lib/schema_metadata";
import type { VisualizationProps } from "metabase/meta/types/Visualization";
type Props = VisualizationProps & {
......@@ -133,7 +135,7 @@ export default class TableSimple extends Component {
<th
key={colIndex}
className={cx(
"TableInteractive-headerCellData cellData text-brand-hover",
"TableInteractive-headerCellData cellData text-brand-hover text-medium",
{
"TableInteractive-headerCellData--sorted":
sortColumn === colIndex,
......@@ -166,6 +168,7 @@ export default class TableSimple extends Component {
{rowIndexes.slice(start, end + 1).map((rowIndex, index) => (
<tr key={rowIndex} ref={index === 0 ? "firstRow" : null}>
{rows[rowIndex].map((value, columnIndex) => {
const column = cols[columnIndex];
const clicked = getTableCellClickedObject(
data,
rowIndex,
......@@ -175,7 +178,7 @@ export default class TableSimple extends Component {
const isClickable =
onVisualizationClick &&
visualizationIsClickable(clicked);
const columnSettings = settings.column(cols[columnIndex]);
const columnSettings = settings.column(column);
return (
<td
key={columnIndex}
......@@ -186,17 +189,21 @@ export default class TableSimple extends Component {
getCellBackgroundColor(
value,
rowIndex,
cols[columnIndex].name,
column.name,
),
}}
className={cx("px1 border-bottom", {
"text-right": isColumnRightAligned(
cols[columnIndex],
),
})}
className={cx(
"px1 border-bottom text-dark text-bold",
{
"text-right": isColumnRightAligned(column),
"Table-ID": isID(column),
"Table-FK": isFK(column),
link: isClickable && isID(column),
},
)}
>
<span
className={cx({
className={cx("cellData inline-block", {
"cursor-pointer text-brand-hover": isClickable,
})}
onClick={
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment