From dfd09ae6a5b46ed1175e8f3c240031a972c8763d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Bernardi=20Jord=C3=A3o?= Date: Fri, 1 Nov 2024 17:52:12 -0300 Subject: [PATCH] Bump table to v8 --- .../src/Examples/AnimatedIcon.elm | 2 +- component-catalog/src/Examples/Balloon.elm | 2 +- component-catalog/src/Examples/Block.elm | 2 +- .../src/Examples/BreadCrumbs.elm | 2 +- component-catalog/src/Examples/Carousel.elm | 2 +- component-catalog/src/Examples/Checkbox.elm | 2 +- .../src/Examples/ClickableText.elm | 2 +- component-catalog/src/Examples/FocusRing.elm | 2 +- component-catalog/src/Examples/Fonts.elm | 2 +- .../src/Examples/Highlighter.elm | 2 +- component-catalog/src/Examples/Menu.elm | 2 +- component-catalog/src/Examples/Message.elm | 2 +- .../src/Examples/PremiumCheckbox.elm | 2 +- .../src/Examples/QuestionBox.elm | 2 +- .../src/Examples/RadioButton.elm | 2 +- .../src/Examples/RadioButtonDotless.elm | 2 +- component-catalog/src/Examples/RingGauge.elm | 2 +- .../src/Examples/SortableTable.elm | 2 +- component-catalog/src/Examples/Spacing.elm | 2 +- component-catalog/src/Examples/Switch.elm | 2 +- component-catalog/src/Examples/Table.elm | 4 +- component-catalog/src/Examples/Tooltip.elm | 2 +- script/templates/standard-example.elm | 2 +- src/Nri/Ui/SortableTable/V4.elm | 2 +- src/Nri/Ui/Table/V7.elm | 102 ++--- src/Nri/Ui/Table/V8.elm | 367 ++++++++++++++++++ tests/Spec/Nri/Ui/SortableTable.elm | 2 +- 27 files changed, 431 insertions(+), 90 deletions(-) create mode 100644 src/Nri/Ui/Table/V8.elm diff --git a/component-catalog/src/Examples/AnimatedIcon.elm b/component-catalog/src/Examples/AnimatedIcon.elm index aa30cfe0..0d1180d7 100644 --- a/component-catalog/src/Examples/AnimatedIcon.elm +++ b/component-catalog/src/Examples/AnimatedIcon.elm @@ -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 diff --git a/component-catalog/src/Examples/Balloon.elm b/component-catalog/src/Examples/Balloon.elm index efd9a8cc..0f5c9909 100644 --- a/component-catalog/src/Examples/Balloon.elm +++ b/component-catalog/src/Examples/Balloon.elm @@ -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 diff --git a/component-catalog/src/Examples/Block.elm b/component-catalog/src/Examples/Block.elm index 0a910dae..268a7751 100644 --- a/component-catalog/src/Examples/Block.elm +++ b/component-catalog/src/Examples/Block.elm @@ -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 diff --git a/component-catalog/src/Examples/BreadCrumbs.elm b/component-catalog/src/Examples/BreadCrumbs.elm index a6db4582..1efac91c 100644 --- a/component-catalog/src/Examples/BreadCrumbs.elm +++ b/component-catalog/src/Examples/BreadCrumbs.elm @@ -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 diff --git a/component-catalog/src/Examples/Carousel.elm b/component-catalog/src/Examples/Carousel.elm index 0e760b14..cbbabbda 100644 --- a/component-catalog/src/Examples/Carousel.elm +++ b/component-catalog/src/Examples/Carousel.elm @@ -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 diff --git a/component-catalog/src/Examples/Checkbox.elm b/component-catalog/src/Examples/Checkbox.elm index d984c421..c79719c1 100644 --- a/component-catalog/src/Examples/Checkbox.elm +++ b/component-catalog/src/Examples/Checkbox.elm @@ -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 diff --git a/component-catalog/src/Examples/ClickableText.elm b/component-catalog/src/Examples/ClickableText.elm index c15fcde5..120482b2 100644 --- a/component-catalog/src/Examples/ClickableText.elm +++ b/component-catalog/src/Examples/ClickableText.elm @@ -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 diff --git a/component-catalog/src/Examples/FocusRing.elm b/component-catalog/src/Examples/FocusRing.elm index 4d1fd224..5811c2f0 100644 --- a/component-catalog/src/Examples/FocusRing.elm +++ b/component-catalog/src/Examples/FocusRing.elm @@ -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 diff --git a/component-catalog/src/Examples/Fonts.elm b/component-catalog/src/Examples/Fonts.elm index e47acb96..79188f3c 100644 --- a/component-catalog/src/Examples/Fonts.elm +++ b/component-catalog/src/Examples/Fonts.elm @@ -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 diff --git a/component-catalog/src/Examples/Highlighter.elm b/component-catalog/src/Examples/Highlighter.elm index 026ff310..1780739d 100644 --- a/component-catalog/src/Examples/Highlighter.elm +++ b/component-catalog/src/Examples/Highlighter.elm @@ -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) diff --git a/component-catalog/src/Examples/Menu.elm b/component-catalog/src/Examples/Menu.elm index 347b2b71..5b99659c 100644 --- a/component-catalog/src/Examples/Menu.elm +++ b/component-catalog/src/Examples/Menu.elm @@ -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 diff --git a/component-catalog/src/Examples/Message.elm b/component-catalog/src/Examples/Message.elm index b0864e45..642a0824 100644 --- a/component-catalog/src/Examples/Message.elm +++ b/component-catalog/src/Examples/Message.elm @@ -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) diff --git a/component-catalog/src/Examples/PremiumCheckbox.elm b/component-catalog/src/Examples/PremiumCheckbox.elm index 3b04d543..33430f5f 100644 --- a/component-catalog/src/Examples/PremiumCheckbox.elm +++ b/component-catalog/src/Examples/PremiumCheckbox.elm @@ -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) diff --git a/component-catalog/src/Examples/QuestionBox.elm b/component-catalog/src/Examples/QuestionBox.elm index d28baacb..a7ae48bb 100644 --- a/component-catalog/src/Examples/QuestionBox.elm +++ b/component-catalog/src/Examples/QuestionBox.elm @@ -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 diff --git a/component-catalog/src/Examples/RadioButton.elm b/component-catalog/src/Examples/RadioButton.elm index c0e852de..db7e7944 100644 --- a/component-catalog/src/Examples/RadioButton.elm +++ b/component-catalog/src/Examples/RadioButton.elm @@ -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 diff --git a/component-catalog/src/Examples/RadioButtonDotless.elm b/component-catalog/src/Examples/RadioButtonDotless.elm index c87372dc..172f42b4 100644 --- a/component-catalog/src/Examples/RadioButtonDotless.elm +++ b/component-catalog/src/Examples/RadioButtonDotless.elm @@ -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 diff --git a/component-catalog/src/Examples/RingGauge.elm b/component-catalog/src/Examples/RingGauge.elm index bd13b351..101b8c86 100644 --- a/component-catalog/src/Examples/RingGauge.elm +++ b/component-catalog/src/Examples/RingGauge.elm @@ -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 diff --git a/component-catalog/src/Examples/SortableTable.elm b/component-catalog/src/Examples/SortableTable.elm index d1d1688f..24e54eb0 100644 --- a/component-catalog/src/Examples/SortableTable.elm +++ b/component-catalog/src/Examples/SortableTable.elm @@ -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 diff --git a/component-catalog/src/Examples/Spacing.elm b/component-catalog/src/Examples/Spacing.elm index c90d7ce3..453f6162 100644 --- a/component-catalog/src/Examples/Spacing.elm +++ b/component-catalog/src/Examples/Spacing.elm @@ -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 diff --git a/component-catalog/src/Examples/Switch.elm b/component-catalog/src/Examples/Switch.elm index b23c7820..0f270964 100644 --- a/component-catalog/src/Examples/Switch.elm +++ b/component-catalog/src/Examples/Switch.elm @@ -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 diff --git a/component-catalog/src/Examples/Table.elm b/component-catalog/src/Examples/Table.elm index 007385ab..2e3e1517 100644 --- a/component-catalog/src/Examples/Table.elm +++ b/component-catalog/src/Examples/Table.elm @@ -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 {-| -} diff --git a/component-catalog/src/Examples/Tooltip.elm b/component-catalog/src/Examples/Tooltip.elm index 11dfced3..c13ae151 100644 --- a/component-catalog/src/Examples/Tooltip.elm +++ b/component-catalog/src/Examples/Tooltip.elm @@ -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 diff --git a/script/templates/standard-example.elm b/script/templates/standard-example.elm index 999e061d..97c77860 100644 --- a/script/templates/standard-example.elm +++ b/script/templates/standard-example.elm @@ -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 diff --git a/src/Nri/Ui/SortableTable/V4.elm b/src/Nri/Ui/SortableTable/V4.elm index 879a0c8c..b488d6b1 100644 --- a/src/Nri/Ui/SortableTable/V4.elm +++ b/src/Nri/Ui/SortableTable/V4.elm @@ -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 diff --git a/src/Nri/Ui/Table/V7.elm b/src/Nri/Ui/Table/V7.elm index a8ccaba4..864ddb8e 100644 --- a/src/Nri/Ui/Table/V7.elm +++ b/src/Nri/Ui/Table/V7.elm @@ -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 [] ] diff --git a/src/Nri/Ui/Table/V8.elm b/src/Nri/Ui/Table/V8.elm new file mode 100644 index 00000000..d8fd3e93 --- /dev/null +++ b/src/Nri/Ui/Table/V8.elm @@ -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 + -- `` 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) + ] diff --git a/tests/Spec/Nri/Ui/SortableTable.elm b/tests/Spec/Nri/Ui/SortableTable.elm index d31f37c1..55db487f 100644 --- a/tests/Spec/Nri/Ui/SortableTable.elm +++ b/tests/Spec/Nri/Ui/SortableTable.elm @@ -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