Use flexbox instead of a table for Splits

This commit is contained in:
wooferzfg
2020-02-02 17:07:47 -06:00
parent 75130639fc
commit c316416103
4 changed files with 83 additions and 50 deletions
+62 -21
View File
@@ -1,7 +1,11 @@
@import 'Time';
@import "Time";
$split-column-width: 60px;
$split-label-height: 22px;
$split-height: 24px;
$split-icon-size: 18px;
.splits {
display: table;
width: 100%;
position: relative;
@@ -10,14 +14,22 @@
}
.split {
display: table-row;
line-height: 20px;
display: flex;
position: relative;
width: 100%;
height: $split-height;
@include time;
&.split-label {
height: $split-label-height;
}
.current-split-background {
position: absolute;
width: 100%;
height: 100%;
padding: 0;
}
@@ -26,39 +38,68 @@
padding: 0 9px;
}
.split-name {
display: flex;
align-items: center;
justify-content: flex-start;
overflow: hidden;
flex-grow: 1;
padding-left: 0px;
padding-top: 1px;
.split-name-inner {
padding: 0;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.split-time {
display: flex;
align-items: center;
justify-content: flex-end;
padding-left: 0;
&.split-time-full {
width: $split-column-width;
flex-shrink: 0;
}
&.split-label {
padding-top: 1px;
}
.split-time-inner {
padding: 0;
}
}
div {
display: table-cell;
text-align: right;
padding: 1px 6px 0px 6px;
padding: 0px 6px;
position: relative;
white-space: nowrap;
}
.split-icon-container {
padding-right: 6px;
text-align: center;
width: $split-icon-size;
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
.split-icon {
max-width: 18px;
height: 18px;
max-width: $split-icon-size;
height: $split-icon-size;
object-fit: contain;
vertical-align: middle;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, 0.3));
}
}
.split-icon-container-empty {
padding-right: 0px;
}
}
.split-name {
text-overflow: ellipsis;
width: 100%;
padding-left: 0px !important;
text-align: left !important;
max-width: 0;
white-space: nowrap;
overflow: hidden;
}
}
+19 -18
View File
@@ -2,18 +2,15 @@ import * as React from "react";
import * as LiveSplit from "../livesplit-core";
import { colorToCss, gradientToCss } from "../util/ColorUtil";
import { Option } from "../util/OptionUtil";
import { splitLabelHeight } from "./SplitLabels";
export interface Props {
splitsState: LiveSplit.SplitsComponentStateJson,
evenOdd: [Option<string>, Option<string>],
split: LiveSplit.SplitStateJson,
icon: string,
maxColumns: number,
separatorInFrontOfSplit: boolean,
layoutState: LiveSplit.LayoutStateJson,
visualSplitIndex: number,
showingLabels: boolean
}
export default class Split extends React.Component<Props> {
@@ -28,10 +25,8 @@ export default class Split extends React.Component<Props> {
const splitsHaveIcons = this.props.splitsState.has_icons;
const hasIcon = this.props.icon !== "";
const splitHeight = 24;
const innerStyle: any = {};
const outerStyle: any = { height: splitHeight };
const outerStyle: any = {};
if (this.props.split.index % 2 === 1) {
innerStyle.borderBottom = this.props.splitsState.show_thin_separators
@@ -51,11 +46,18 @@ export default class Split extends React.Component<Props> {
const currentSplitBackgroundStyle: any = {};
if (this.props.split.is_current_split) {
currentSplitBackgroundStyle.background = gradientToCss(this.props.splitsState.current_split_gradient);
currentSplitBackgroundStyle.top = this.props.visualSplitIndex * splitHeight +
(this.props.showingLabels ? splitLabelHeight : 0);
currentSplitBackgroundStyle.height = splitHeight;
}
let lastEmptyColumnIndex = this.props.split.columns.length;
for (let i = this.props.split.columns.length - 1; i >= 0; i--) {
const column = this.props.split.columns[i];
if (!column.value) {
lastEmptyColumnIndex = i;
}
}
const columns = this.props.split.columns.slice(0, lastEmptyColumnIndex);
return (
<span
className={["split", currentSplit, separator].filter((s) => s.length > 0).join(" ")}
@@ -78,27 +80,26 @@ export default class Split extends React.Component<Props> {
className="split-name"
style={innerStyle}
>
{this.props.split.name}
<div className="split-name-inner">
{this.props.split.name}
</div>
</div>
{
this.props.split.columns.map((column, i) =>
columns.map((column, i) =>
<div
key={i}
className="split-time time"
className={`split-time time ${i < columns.length - 1 ? "split-time-full" : ""}`}
style={{
...innerStyle,
color: colorToCss(column.visual_color),
}}
>
{column.value}
<div className="split-time-inner">
{column.value}
</div>
</div>,
).reverse()
}
{
Array(this.props.maxColumns - this.props.split.columns.length).fill(
<div style={innerStyle}></div>,
)
}
</span>
);
}
+2 -7
View File
@@ -4,16 +4,11 @@ export interface Props {
labels: string[],
}
export const splitLabelHeight = 22;
export default class SplitLabels extends React.Component<Props> {
public render() {
return (
<span
className="split"
style={{
height: splitLabelHeight,
}}
className="split split-label"
>
<div className="current-split-background" />
<div className="split-icon-container-empty" />
@@ -22,7 +17,7 @@ export default class SplitLabels extends React.Component<Props> {
this.props.labels.map((label, i) =>
<div
key={i}
className="split-time"
className={`split-time split-label ${i < this.props.labels.length - 1 ? "split-time-full" : ""}`}
>
{label}
</div>,
-4
View File
@@ -40,8 +40,6 @@ export default class Splits extends React.Component<Props> {
style.background = gradientToCss(background.Same);
}
const maxColumns = Math.max.apply(Math, this.props.state.splits.map((split) => split.columns.length));
return (
<div className="splits" style={style}>
{
@@ -59,14 +57,12 @@ export default class Splits extends React.Component<Props> {
layoutState={this.props.layoutState}
icon={this.iconUrls[s.index]}
key={s.index.toString()}
maxColumns={maxColumns}
separatorInFrontOfSplit={
(this.props.state.show_final_separator &&
i + 1 === this.props.state.splits.length)
|| (i === 0 && this.props.state.column_labels !== null)
}
visualSplitIndex={i}
showingLabels={this.props.state.column_labels !== null}
/>,
)
}