mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2025-01-03 03:46:37 +03:00
Bump table to v8
This commit is contained in:
parent
bb2a236f91
commit
dfd09ae6a5
@ -20,7 +20,7 @@ import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
|
||||
|
||||
moduleName : String
|
||||
|
@ -23,7 +23,7 @@ import Nri.Ui.Balloon.V2 as Balloon
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
|
||||
|
||||
moduleName : String
|
||||
|
@ -26,7 +26,7 @@ import Nri.Ui.ClickableText.V4 as ClickableText
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Task
|
||||
|
||||
|
@ -25,7 +25,7 @@ import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Html.V3 exposing (viewJust)
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
||||
|
@ -33,7 +33,7 @@ import Nri.Ui.FocusRing.V1 as FocusRing
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Html.Attributes.V2 as Attributes
|
||||
import Nri.Ui.Html.V3 exposing (viewJust)
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Routes
|
||||
|
@ -26,7 +26,7 @@ import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Html.Attributes.V2 exposing (safeIdWithPrefix)
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ import Html.Styled.Attributes exposing (css)
|
||||
import Nri.Ui.ClickableText.V4 as ClickableText
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
||||
|
@ -27,7 +27,7 @@ import Nri.Ui.SegmentedControl.V14 as SegmentedControl
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Switch.V3 as Switch
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Routes
|
||||
|
@ -15,7 +15,7 @@ import Nri.Ui.ClickableText.V4 as ClickableText
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ import Nri.Ui.Highlightable.V3 as Highlightable exposing (Highlightable)
|
||||
import Nri.Ui.Highlighter.V6 as Highlighter
|
||||
import Nri.Ui.HighlighterTool.V1 as Tool
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Sort exposing (Sorter)
|
||||
|
||||
|
@ -37,7 +37,7 @@ import Nri.Ui.Menu.V4 as Menu
|
||||
import Nri.Ui.RadioButton.V4 as RadioButton
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Switch.V3 as Switch
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.TextInput.V8 as TextInput
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
|
@ -16,7 +16,7 @@ import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Message.V4 as Message
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import ViewHelpers exposing (viewExamples)
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ import Nri.Ui.Pennant.V3 as Pennant
|
||||
import Nri.Ui.PremiumCheckbox.V8 as PremiumCheckbox
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Set exposing (Set)
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.QuestionBox.V7 as QuestionBox
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ import Nri.Ui.Modal.V12 as Modal
|
||||
import Nri.Ui.RadioButton.V4 as RadioButton
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
@ -19,7 +19,7 @@ import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.RadioButtonDotless.V1 as RadioButtonDotless
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Platform.Sub as Sub
|
||||
|
||||
|
@ -20,7 +20,7 @@ import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.RingGauge.V1 as RingGauge
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Round
|
||||
import SolidColor.Accessibility
|
||||
|
||||
|
@ -20,7 +20,7 @@ import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.SortableTable.V4 as SortableTable exposing (Column)
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ import Nri.Ui.Container.V2 as Container
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Svg.Styled
|
||||
import Svg.Styled.Attributes
|
||||
|
@ -20,7 +20,7 @@ import KeyboardSupport exposing (Key(..))
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Switch.V3 as Switch
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ import Html.Attributes exposing (alt)
|
||||
import Nri.Ui.Button.V10 as Button
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table exposing (Column)
|
||||
import Nri.Ui.Table.V8 as Table exposing (Column)
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -32,7 +32,7 @@ moduleName =
|
||||
|
||||
version : Int
|
||||
version =
|
||||
7
|
||||
8
|
||||
|
||||
|
||||
{-| -}
|
||||
|
@ -26,7 +26,7 @@ import Nri.Ui.ClickableText.V4 as ClickableText
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Routes
|
||||
|
@ -21,7 +21,7 @@ import KeyboardSupport exposing (Key(..))
|
||||
import Nri.Ui.COMPONENT_NAME.V1 as COMPONENT_NAME
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Spacing.V1 as Spacing
|
||||
import Nri.Ui.Table.V7 as Table
|
||||
import Nri.Ui.Table.V8 as Table
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ import Nri.Ui.Html.Attributes.V2 exposing (maybe)
|
||||
import Nri.Ui.Html.V3 exposing (viewJust)
|
||||
import Nri.Ui.MediaQuery.V1 as MediaQuery
|
||||
import Nri.Ui.Svg.V1
|
||||
import Nri.Ui.Table.V7 as Table exposing (SortDirection(..))
|
||||
import Nri.Ui.Table.V8 as Table exposing (SortDirection(..))
|
||||
import Nri.Ui.UiIcon.V1
|
||||
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
module Nri.Ui.Table.V7 exposing
|
||||
module Nri.Ui.Table.V8 exposing
|
||||
( Column, SortDirection(..), custom, string, rowHeader
|
||||
, view, viewWithoutHeader
|
||||
, viewLoading, viewLoadingWithoutHeader
|
||||
, placeholderColumn
|
||||
)
|
||||
|
||||
{-| Upgrading from V6:
|
||||
@ -35,7 +34,7 @@ import Nri.Ui.Fonts.V1 exposing (baseFont)
|
||||
in the table
|
||||
-}
|
||||
type Column data msg
|
||||
= Column (Html msg) (data -> Html msg) Style (data -> List Style) (Maybe SortDirection) CellType Bool
|
||||
= Column (Html msg) (data -> Html msg) Style (data -> List Style) (Maybe SortDirection) CellType
|
||||
|
||||
|
||||
{-| Which direction is a table column sorted? Only set these on columns that
|
||||
@ -74,19 +73,7 @@ string :
|
||||
}
|
||||
-> Column data msg
|
||||
string { header, value, width, cellStyles, sort } =
|
||||
Column (Html.text header) (value >> Html.text) (Css.width width) cellStyles sort DataCell False
|
||||
|
||||
|
||||
{-| Creates a placeholder column which will reserve the space for the column,
|
||||
this can be used when multiple tables have similar data and we want to keep
|
||||
the size consistent.
|
||||
-}
|
||||
placeholderColumn :
|
||||
{ width : LengthOrAuto compatible
|
||||
}
|
||||
-> Column data msg
|
||||
placeholderColumn options =
|
||||
Column (Html.text "") (always (Html.text "")) (Css.width options.width) (always []) Nothing DataCell False
|
||||
Column (Html.text header) (value >> Html.text) (Css.width width) cellStyles sort DataCell
|
||||
|
||||
|
||||
{-| A column that renders however you want it to
|
||||
@ -100,7 +87,7 @@ custom :
|
||||
}
|
||||
-> Column data msg
|
||||
custom options =
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort DataCell True
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort DataCell
|
||||
|
||||
|
||||
{-| A column whose cells are row headers
|
||||
@ -114,7 +101,7 @@ rowHeader :
|
||||
}
|
||||
-> Column data msg
|
||||
rowHeader options =
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort RowHeaderCell False
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort RowHeaderCell
|
||||
|
||||
|
||||
|
||||
@ -123,29 +110,29 @@ rowHeader options =
|
||||
|
||||
{-| Displays a table of data without a header row
|
||||
-}
|
||||
viewWithoutHeader : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> List data -> Html msg
|
||||
viewWithoutHeader { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithoutHeader additionalStyles columns (viewRow columns alternatingRowColors)
|
||||
viewWithoutHeader : List Style -> List (Column data msg) -> List data -> Html msg
|
||||
viewWithoutHeader additionalStyles columns =
|
||||
tableWithoutHeader additionalStyles columns (viewRow columns)
|
||||
|
||||
|
||||
{-| Displays a table of data based on the provided column definitions
|
||||
-}
|
||||
view : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> List data -> Html msg
|
||||
view { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithHeader additionalStyles columns (viewRow columns alternatingRowColors)
|
||||
view : List Style -> List (Column data msg) -> List data -> Html msg
|
||||
view additionalStyles columns =
|
||||
tableWithHeader additionalStyles columns (viewRow columns)
|
||||
|
||||
|
||||
viewRow : List (Column data msg) -> Bool -> data -> Html msg
|
||||
viewRow columns alternatingRowColors data =
|
||||
viewRow : List (Column data msg) -> data -> Html msg
|
||||
viewRow columns data =
|
||||
tr
|
||||
[ css (rowStyles alternatingRowColors) ]
|
||||
[ css rowStyles ]
|
||||
(List.map (viewColumn data) columns)
|
||||
|
||||
|
||||
viewColumn : data -> Column data msg -> Html msg
|
||||
viewColumn data (Column _ renderer width cellStyles _ cellType _) =
|
||||
viewColumn data (Column _ renderer width cellStyles _ cellType) =
|
||||
cell cellType
|
||||
[ css ([ width, verticalAlign middle, padding4 (px 11) (px 12) (px 14) (px 12), textAlign left ] ++ cellStyles data)
|
||||
[ css ([ width, verticalAlign middle ] ++ cellStyles data)
|
||||
]
|
||||
[ renderer data ]
|
||||
|
||||
@ -158,27 +145,27 @@ viewColumn data (Column _ renderer width cellStyles _ cellType _) =
|
||||
out text with an interesting animation. This view lets the user know that
|
||||
data is on its way and what it will look like when it arrives.
|
||||
-}
|
||||
viewLoading : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> Html msg
|
||||
viewLoading { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns alternatingRowColors) (List.range 0 8)
|
||||
viewLoading : List Style -> List (Column data msg) -> Html msg
|
||||
viewLoading additionalStyles columns =
|
||||
tableWithHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns) (List.range 0 8)
|
||||
|
||||
|
||||
{-| Display the loading table without a header row
|
||||
-}
|
||||
viewLoadingWithoutHeader : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> Html msg
|
||||
viewLoadingWithoutHeader { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithoutHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns alternatingRowColors) (List.range 0 8)
|
||||
viewLoadingWithoutHeader : List Style -> List (Column data msg) -> Html msg
|
||||
viewLoadingWithoutHeader additionalStyles columns =
|
||||
tableWithoutHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns) (List.range 0 8)
|
||||
|
||||
|
||||
viewLoadingRow : List (Column data msg) -> Bool -> Int -> Html msg
|
||||
viewLoadingRow columns alternatingRowColors index =
|
||||
viewLoadingRow : List (Column data msg) -> Int -> Html msg
|
||||
viewLoadingRow columns index =
|
||||
tr
|
||||
[ css (rowStyles alternatingRowColors) ]
|
||||
[ css rowStyles ]
|
||||
(List.indexedMap (viewLoadingColumn index) columns)
|
||||
|
||||
|
||||
viewLoadingColumn : Int -> Int -> Column data msg -> Html msg
|
||||
viewLoadingColumn rowIndex colIndex (Column _ _ width _ _ cellType _) =
|
||||
viewLoadingColumn rowIndex colIndex (Column _ _ width _ _ cellType) =
|
||||
cell cellType
|
||||
[ css (stylesLoadingColumn rowIndex colIndex width ++ [ verticalAlign middle ] ++ loadingCellStyles)
|
||||
]
|
||||
@ -198,7 +185,7 @@ stylesLoadingColumn rowIndex colIndex width =
|
||||
|
||||
tableWithoutHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
|
||||
tableWithoutHeader styles columns toRow data =
|
||||
table styles columns
|
||||
table styles
|
||||
[ thead [] [ tr Style.invisible (List.map tableColHeader columns) ]
|
||||
, tableBody toRow data
|
||||
]
|
||||
@ -206,15 +193,15 @@ tableWithoutHeader styles columns toRow data =
|
||||
|
||||
tableWithHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
|
||||
tableWithHeader styles columns toRow data =
|
||||
table styles columns
|
||||
table styles
|
||||
[ tableHeader columns
|
||||
, tableBody toRow data
|
||||
]
|
||||
|
||||
|
||||
table : List Style -> List (Column data msg) -> List (Html msg) -> Html msg
|
||||
table styles columns =
|
||||
Html.table [ css (styles ++ tableStyles columns) ]
|
||||
table : List Style -> List (Html msg) -> Html msg
|
||||
table styles =
|
||||
Html.table [ css (styles ++ tableStyles) ]
|
||||
|
||||
|
||||
tableHeader : List (Column data msg) -> Html msg
|
||||
@ -226,7 +213,7 @@ tableHeader columns =
|
||||
|
||||
|
||||
tableColHeader : Column data msg -> Html msg
|
||||
tableColHeader (Column header _ width _ sort _ _) =
|
||||
tableColHeader (Column header _ width _ sort _) =
|
||||
th
|
||||
[ Attributes.scope "col"
|
||||
, css (width :: headerStyles)
|
||||
@ -278,17 +265,13 @@ headerStyles =
|
||||
]
|
||||
|
||||
|
||||
rowStyles : Bool -> List Style
|
||||
rowStyles alternatingRowColors =
|
||||
rowStyles : List Style
|
||||
rowStyles =
|
||||
[ height (px 45)
|
||||
, fontSize (px 14)
|
||||
, color gray20
|
||||
, if alternatingRowColors then
|
||||
pseudoClass "nth-child(odd)"
|
||||
[ backgroundColor gray96 ]
|
||||
|
||||
else
|
||||
Css.batch []
|
||||
, pseudoClass "nth-child(odd)"
|
||||
[ backgroundColor gray96 ]
|
||||
]
|
||||
|
||||
|
||||
@ -314,20 +297,11 @@ loadingTableStyles =
|
||||
fadeInAnimation
|
||||
|
||||
|
||||
tableStyles : List (Column data msg) -> List Style
|
||||
tableStyles columns =
|
||||
let
|
||||
hasPlaceholderColumns =
|
||||
List.any (\(Column _ _ _ _ _ _ h) -> h) columns
|
||||
in
|
||||
tableStyles : List Style
|
||||
tableStyles =
|
||||
[ borderCollapse collapse
|
||||
, baseFont
|
||||
, Css.width (Css.pct 100)
|
||||
, if hasPlaceholderColumns then
|
||||
Css.tableLayout Css.fixed
|
||||
|
||||
else
|
||||
Css.batch []
|
||||
]
|
||||
|
||||
|
||||
|
367
src/Nri/Ui/Table/V8.elm
Normal file
367
src/Nri/Ui/Table/V8.elm
Normal file
@ -0,0 +1,367 @@
|
||||
module Nri.Ui.Table.V8 exposing
|
||||
( Column, SortDirection(..), custom, string, rowHeader
|
||||
, view, viewWithoutHeader
|
||||
, viewLoading, viewLoadingWithoutHeader
|
||||
, placeholderColumn
|
||||
)
|
||||
|
||||
{-| Upgrading from V7:
|
||||
|
||||
- New attribute added to define `alternatingRowColors`, set it to true to get default behavior.
|
||||
- Consider moving to `SortableTable`, as in V4 a non-interactive table renders
|
||||
just the same but has additional flexibility in the API and will make future
|
||||
upgrades easier.
|
||||
|
||||
@docs Column, SortDirection, custom, string, rowHeader
|
||||
|
||||
@docs view, viewWithoutHeader
|
||||
|
||||
@docs viewLoading, viewLoadingWithoutHeader
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Style as Style
|
||||
import Css exposing (..)
|
||||
import Css.Animations
|
||||
import Css.Global
|
||||
import Html.Styled as Html exposing (..)
|
||||
import Html.Styled.Attributes as Attributes exposing (css)
|
||||
import Nri.Ui.Colors.V1 exposing (..)
|
||||
import Nri.Ui.Fonts.V1 exposing (baseFont)
|
||||
|
||||
|
||||
{-| Closed representation of how to render the header and cells of a column
|
||||
in the table
|
||||
-}
|
||||
type Column data msg
|
||||
= Column (Html msg) (data -> Html msg) Style (data -> List Style) (Maybe SortDirection) CellType Bool
|
||||
|
||||
|
||||
{-| Which direction is a table column sorted? Only set these on columns that
|
||||
actually have an explicit sort!
|
||||
-}
|
||||
type SortDirection
|
||||
= Ascending
|
||||
| Descending
|
||||
|
||||
|
||||
{-| Is this cell a data cell or header cell?
|
||||
-}
|
||||
type CellType
|
||||
= RowHeaderCell
|
||||
| DataCell
|
||||
|
||||
|
||||
cell : CellType -> List (Attribute msg) -> List (Html msg) -> Html msg
|
||||
cell cellType attrs =
|
||||
case cellType of
|
||||
RowHeaderCell ->
|
||||
th (Attributes.scope "row" :: attrs)
|
||||
|
||||
DataCell ->
|
||||
td attrs
|
||||
|
||||
|
||||
{-| A column that renders some aspect of a value as text
|
||||
-}
|
||||
string :
|
||||
{ header : String
|
||||
, value : data -> String
|
||||
, width : LengthOrAuto compatible
|
||||
, cellStyles : data -> List Style
|
||||
, sort : Maybe SortDirection
|
||||
}
|
||||
-> Column data msg
|
||||
string { header, value, width, cellStyles, sort } =
|
||||
Column (Html.text header) (value >> Html.text) (Css.width width) cellStyles sort DataCell False
|
||||
|
||||
|
||||
{-| Creates a placeholder column which will reserve the space for the column,
|
||||
this can be used when multiple tables have similar data and we want to keep
|
||||
the size consistent.
|
||||
-}
|
||||
placeholderColumn :
|
||||
{ width : LengthOrAuto compatible
|
||||
}
|
||||
-> Column data msg
|
||||
placeholderColumn options =
|
||||
Column (Html.text "") (always (Html.text "")) (Css.width options.width) (always []) Nothing DataCell False
|
||||
|
||||
|
||||
{-| A column that renders however you want it to
|
||||
-}
|
||||
custom :
|
||||
{ header : Html msg
|
||||
, view : data -> Html msg
|
||||
, width : LengthOrAuto compatible
|
||||
, cellStyles : data -> List Style
|
||||
, sort : Maybe SortDirection
|
||||
}
|
||||
-> Column data msg
|
||||
custom options =
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort DataCell True
|
||||
|
||||
|
||||
{-| A column whose cells are row headers
|
||||
-}
|
||||
rowHeader :
|
||||
{ header : Html msg
|
||||
, view : data -> Html msg
|
||||
, width : LengthOrAuto compatible
|
||||
, cellStyles : data -> List Style
|
||||
, sort : Maybe SortDirection
|
||||
}
|
||||
-> Column data msg
|
||||
rowHeader options =
|
||||
Column options.header options.view (Css.width options.width) options.cellStyles options.sort RowHeaderCell False
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
{-| Displays a table of data without a header row
|
||||
-}
|
||||
viewWithoutHeader : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> List data -> Html msg
|
||||
viewWithoutHeader { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithoutHeader additionalStyles columns (viewRow columns alternatingRowColors)
|
||||
|
||||
|
||||
{-| Displays a table of data based on the provided column definitions
|
||||
-}
|
||||
view : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> List data -> Html msg
|
||||
view { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithHeader additionalStyles columns (viewRow columns alternatingRowColors)
|
||||
|
||||
|
||||
viewRow : List (Column data msg) -> Bool -> data -> Html msg
|
||||
viewRow columns alternatingRowColors data =
|
||||
tr
|
||||
[ css (rowStyles alternatingRowColors) ]
|
||||
(List.map (viewColumn data) columns)
|
||||
|
||||
|
||||
viewColumn : data -> Column data msg -> Html msg
|
||||
viewColumn data (Column _ renderer width cellStyles _ cellType _) =
|
||||
cell cellType
|
||||
[ css ([ width, verticalAlign middle, padding4 (px 11) (px 12) (px 14) (px 12), textAlign left ] ++ cellStyles data)
|
||||
]
|
||||
[ renderer data ]
|
||||
|
||||
|
||||
|
||||
-- VIEW LOADING
|
||||
|
||||
|
||||
{-| Display a table with the given columns but instead of data, show blocked
|
||||
out text with an interesting animation. This view lets the user know that
|
||||
data is on its way and what it will look like when it arrives.
|
||||
-}
|
||||
viewLoading : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> Html msg
|
||||
viewLoading { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns alternatingRowColors) (List.range 0 8)
|
||||
|
||||
|
||||
{-| Display the loading table without a header row
|
||||
-}
|
||||
viewLoadingWithoutHeader : { additionalStyles : List Style, alternatingRowColors : Bool } -> List (Column data msg) -> Html msg
|
||||
viewLoadingWithoutHeader { additionalStyles, alternatingRowColors } columns =
|
||||
tableWithoutHeader (loadingTableStyles ++ additionalStyles) columns (viewLoadingRow columns alternatingRowColors) (List.range 0 8)
|
||||
|
||||
|
||||
viewLoadingRow : List (Column data msg) -> Bool -> Int -> Html msg
|
||||
viewLoadingRow columns alternatingRowColors index =
|
||||
tr
|
||||
[ css (rowStyles alternatingRowColors) ]
|
||||
(List.indexedMap (viewLoadingColumn index) columns)
|
||||
|
||||
|
||||
viewLoadingColumn : Int -> Int -> Column data msg -> Html msg
|
||||
viewLoadingColumn rowIndex colIndex (Column _ _ width _ _ cellType _) =
|
||||
cell cellType
|
||||
[ css (stylesLoadingColumn rowIndex colIndex width ++ [ verticalAlign middle ] ++ loadingCellStyles)
|
||||
]
|
||||
[ span [ css loadingContentStyles ] [] ]
|
||||
|
||||
|
||||
stylesLoadingColumn : Int -> Int -> Style -> List Style
|
||||
stylesLoadingColumn rowIndex colIndex width =
|
||||
[ width
|
||||
, property "animation-delay" (String.fromFloat (toFloat (rowIndex + colIndex) * 0.1) ++ "s")
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- HELP
|
||||
|
||||
|
||||
tableWithoutHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
|
||||
tableWithoutHeader styles columns toRow data =
|
||||
table styles columns
|
||||
[ thead [] [ tr Style.invisible (List.map tableColHeader columns) ]
|
||||
, tableBody toRow data
|
||||
]
|
||||
|
||||
|
||||
tableWithHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
|
||||
tableWithHeader styles columns toRow data =
|
||||
table styles columns
|
||||
[ tableHeader columns
|
||||
, tableBody toRow data
|
||||
]
|
||||
|
||||
|
||||
table : List Style -> List (Column data msg) -> List (Html msg) -> Html msg
|
||||
table styles columns =
|
||||
Html.table [ css (styles ++ tableStyles columns) ]
|
||||
|
||||
|
||||
tableHeader : List (Column data msg) -> Html msg
|
||||
tableHeader columns =
|
||||
thead []
|
||||
[ tr [ css headersStyles ]
|
||||
(List.map tableColHeader columns)
|
||||
]
|
||||
|
||||
|
||||
tableColHeader : Column data msg -> Html msg
|
||||
tableColHeader (Column header _ width _ sort _ _) =
|
||||
th
|
||||
[ Attributes.scope "col"
|
||||
, css (width :: headerStyles)
|
||||
, Attributes.attribute "aria-sort" <|
|
||||
case sort of
|
||||
Nothing ->
|
||||
"none"
|
||||
|
||||
Just Ascending ->
|
||||
"ascending"
|
||||
|
||||
Just Descending ->
|
||||
"descending"
|
||||
]
|
||||
[ header ]
|
||||
|
||||
|
||||
tableBody : (a -> Html msg) -> List a -> Html msg
|
||||
tableBody toRow items =
|
||||
tbody [] (List.map toRow items)
|
||||
|
||||
|
||||
|
||||
-- STYLES
|
||||
|
||||
|
||||
headersStyles : List Style
|
||||
headersStyles =
|
||||
[ -- We use a inset box shadow for a bottom border instead of an actual
|
||||
-- border because with our use of `border-collapse: collapse`, the bottom
|
||||
-- gray border sticks to the table instead of traveling with the header
|
||||
-- when the header has `position: sticky` applied.
|
||||
--
|
||||
-- We add the style on the children instead of on the parent because
|
||||
-- `<tr>` tags do not display box shadows in Safari (although by the time
|
||||
-- you read this, they may have fixed it. Feel free to try again!)
|
||||
Css.Global.children [ Css.Global.th [ boxShadow4 inset (px 0) (px -3) gray75 ] ]
|
||||
, height (px 45)
|
||||
, fontSize (px 15)
|
||||
]
|
||||
|
||||
|
||||
headerStyles : List Style
|
||||
headerStyles =
|
||||
[ padding4 (px 11) (px 12) (px 14) (px 12)
|
||||
, textAlign left
|
||||
, fontWeight bold
|
||||
, color gray20
|
||||
]
|
||||
|
||||
|
||||
rowStyles : Bool -> List Style
|
||||
rowStyles alternatingRowColors =
|
||||
[ height (px 45)
|
||||
, fontSize (px 14)
|
||||
, color gray20
|
||||
, if alternatingRowColors then
|
||||
pseudoClass "nth-child(odd)"
|
||||
[ backgroundColor gray96 ]
|
||||
|
||||
else
|
||||
Css.batch []
|
||||
]
|
||||
|
||||
|
||||
loadingContentStyles : List Style
|
||||
loadingContentStyles =
|
||||
[ width (pct 100)
|
||||
, display inlineBlock
|
||||
, height (Css.em 1)
|
||||
, borderRadius (Css.em 1)
|
||||
, backgroundColor gray75
|
||||
]
|
||||
|
||||
|
||||
loadingCellStyles : List Style
|
||||
loadingCellStyles =
|
||||
[ batch flashAnimation
|
||||
, padding2 (px 14) (px 10)
|
||||
]
|
||||
|
||||
|
||||
loadingTableStyles : List Style
|
||||
loadingTableStyles =
|
||||
fadeInAnimation
|
||||
|
||||
|
||||
tableStyles : List (Column data msg) -> List Style
|
||||
tableStyles columns =
|
||||
let
|
||||
hasPlaceholderColumns =
|
||||
List.any (\(Column _ _ _ _ _ _ h) -> h) columns
|
||||
in
|
||||
[ borderCollapse collapse
|
||||
, baseFont
|
||||
, Css.width (Css.pct 100)
|
||||
, if hasPlaceholderColumns then
|
||||
Css.tableLayout Css.fixed
|
||||
|
||||
else
|
||||
Css.batch []
|
||||
]
|
||||
|
||||
|
||||
flash : Css.Animations.Keyframes {}
|
||||
flash =
|
||||
Css.Animations.keyframes
|
||||
[ ( 0, [ Css.Animations.opacity (Css.num 0.6) ] )
|
||||
, ( 50, [ Css.Animations.opacity (Css.num 0.2) ] )
|
||||
, ( 100, [ Css.Animations.opacity (Css.num 0.6) ] )
|
||||
]
|
||||
|
||||
|
||||
fadeIn : Css.Animations.Keyframes {}
|
||||
fadeIn =
|
||||
Css.Animations.keyframes
|
||||
[ ( 0, [ Css.Animations.opacity (Css.num 0) ] )
|
||||
, ( 100, [ Css.Animations.opacity (Css.num 1) ] )
|
||||
]
|
||||
|
||||
|
||||
flashAnimation : List Css.Style
|
||||
flashAnimation =
|
||||
[ animationName flash
|
||||
, property "animation-duration" "2s"
|
||||
, property "animation-iteration-count" "infinite"
|
||||
, opacity (num 0.6)
|
||||
]
|
||||
|
||||
|
||||
fadeInAnimation : List Css.Style
|
||||
fadeInAnimation =
|
||||
[ animationName fadeIn
|
||||
, property "animation-duration" "0.4s"
|
||||
, property "animation-delay" "0.2s"
|
||||
, property "animation-fill-mode" "forwards"
|
||||
, animationIterationCount (int 1)
|
||||
, opacity (num 0)
|
||||
]
|
@ -3,7 +3,7 @@ module Spec.Nri.Ui.SortableTable exposing (spec)
|
||||
import Expect
|
||||
import Html.Styled
|
||||
import Nri.Ui.SortableTable.V4 as SortableTable
|
||||
import Nri.Ui.Table.V7 exposing (SortDirection)
|
||||
import Nri.Ui.Table.V8 exposing (SortDirection)
|
||||
import Test exposing (..)
|
||||
import Test.Html.Query as Query
|
||||
import Test.Html.Selector as Selector
|
||||
|
Loading…
Reference in New Issue
Block a user