diff --git a/ui/src/clockface/components/index_views/IndexList.scss b/ui/src/clockface/components/index_views/IndexList.scss index 5b6393cde2..3685eabac3 100644 --- a/ui/src/clockface/components/index_views/IndexList.scss +++ b/ui/src/clockface/components/index_views/IndexList.scss @@ -13,6 +13,8 @@ .index-list--header-cell { @include no-user-select(); + text-transform: uppercase; + letter-spacing: 0.03em; padding: 0 13px; font-size: 14px; font-weight: 600; @@ -128,4 +130,52 @@ .index-list--empty-cell { background-color: rgba($g4-onyx, 0.5); } +} + +/* + Sortable Header Styling + ------------------------------------------------------------------------------ +*/ + +.index-list--sort-arrow { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 20px; + margin-left: $ix-marg-a; + opacity: 0; + position: relative; + top: -1px; + transition: opacity 0.25s ease, transform 0.25s ease; + + > span.icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } +} + +.index-list--header-cell.index-list--sortable { + transition: color 0.25s ease; + + &:hover { + cursor: pointer; + color: $c-pool; + } +} + +.index-list--header-cell.index-list--sort-ascending, +.index-list--header-cell.index-list--sort-descending { + color: $g17-whisper; +} + +.index-list--sort-ascending .index-list--sort-arrow { + opacity: 1; + transform: rotate(180deg); +} + +.index-list--sort-descending .index-list--sort-arrow { + opacity: 1; + transform: rotate(00deg); } \ No newline at end of file diff --git a/ui/src/clockface/components/index_views/IndexListHeaderCell.tsx b/ui/src/clockface/components/index_views/IndexListHeaderCell.tsx index d766e89455..9e072bc760 100644 --- a/ui/src/clockface/components/index_views/IndexListHeaderCell.tsx +++ b/ui/src/clockface/components/index_views/IndexListHeaderCell.tsx @@ -3,15 +3,17 @@ import React, {Component} from 'react' import classnames from 'classnames' // Types -import {Alignment} from 'src/clockface/types' +import {Alignment, Sort} from 'src/clockface/types' // Decorators import {ErrorHandling} from 'src/shared/decorators/errors' interface Props { + width: string columnName?: string alignment?: Alignment - width: string + sort?: Sort + onClick?: (nextSort: Sort) => void } @ErrorHandling @@ -25,19 +27,63 @@ class IndexListHeaderCell extends Component { const {columnName, width} = this.props return ( - + {columnName} + {this.sortIndicator} ) } + private handleClick = (): void => { + const {onClick, sort} = this.props + + if (!onClick || !sort) { + return + } + + if (sort === Sort.None) { + onClick(Sort.Ascending) + } else if (sort === Sort.Ascending) { + onClick(Sort.Descending) + } else if (sort === Sort.Descending) { + onClick(Sort.None) + } + } + + private get sortIndicator(): JSX.Element { + if (this.isSortable) { + return ( + + + + ) + } + } + + private get isSortable(): boolean { + const {sort} = this.props + + if ( + sort === Sort.None || + sort === Sort.Ascending || + sort === Sort.Descending + ) { + return true + } + + return false + } + private get className(): string { - const {alignment} = this.props + const {alignment, sort} = this.props return classnames('index-list--header-cell', { 'index-list--align-left': alignment === Alignment.Left, 'index-list--align-center': alignment === Alignment.Center, 'index-list--align-right': alignment === Alignment.Right, + 'index-list--sortable': this.isSortable, + 'index-list--sort-descending': sort === Sort.Descending, + 'index-list--sort-ascending': sort === Sort.Ascending, }) } } diff --git a/ui/src/clockface/index.ts b/ui/src/clockface/index.ts index fb7aae1016..29fe640882 100644 --- a/ui/src/clockface/index.ts +++ b/ui/src/clockface/index.ts @@ -32,6 +32,7 @@ import { Columns, Alignment, ButtonType, + Sort, } from './types' // Fire de lazer @@ -68,4 +69,5 @@ export { WizardProgressHeader, ProgressBar, Spinner, + Sort, } diff --git a/ui/src/clockface/types/index.ts b/ui/src/clockface/types/index.ts index 0a462d70b8..dadb8b9d05 100644 --- a/ui/src/clockface/types/index.ts +++ b/ui/src/clockface/types/index.ts @@ -165,3 +165,9 @@ export enum Alignment { Center = 'center', Right = 'right', } + +export enum Sort { + Descending = 'desc', + Ascending = 'asc', + None = 'none', +}