mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-25 06:33:09 +03:00
Merge branch 'master' into extract-nri-page
This commit is contained in:
commit
d6a10d1ed4
2
Makefile
2
Makefile
@ -18,7 +18,7 @@ format: node_modules
|
||||
clean:
|
||||
rm -rf node_modules styleguide-app/elm.js $(shell find . -type d -name 'elm-stuff')
|
||||
|
||||
styleguide-app/elm.js: styleguide-app/elm-stuff styleguide-app/**/*.elm
|
||||
styleguide-app/elm.js: styleguide-app/elm-stuff $(shell find src styleguide-app -type f -name '*.elm')
|
||||
cd styleguide-app; elm-make Main.elm --output=$(@F)
|
||||
|
||||
# plumbing
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "4.10.0",
|
||||
"version": "4.13.0",
|
||||
"summary": "UI Widgets we use at NRI",
|
||||
"repository": "https://github.com/NoRedInk/noredink-ui.git",
|
||||
"license": "BSD3",
|
||||
@ -35,6 +35,7 @@
|
||||
"Nri.Ui.Select.V2",
|
||||
"Nri.Ui.Styles.V1",
|
||||
"Nri.Ui.Table.V1",
|
||||
"Nri.Ui.Table.V2",
|
||||
"Nri.Ui.Tabs.V1",
|
||||
"Nri.Ui.Text.Writing.V1",
|
||||
"Nri.Ui.Text.V1",
|
||||
@ -48,7 +49,7 @@
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0",
|
||||
"elm-lang/svg": "2.0.0 <= v < 3.0.0",
|
||||
"pablohirafuji/elm-markdown": "2.0.4 <= v < 3.0.0",
|
||||
"rtfeldman/elm-css": "13.1.1 <= v < 14.0.0",
|
||||
"rtfeldman/elm-css": "13.1.1 <= v < 15.0.0",
|
||||
"rtfeldman/elm-css-helpers": "2.1.0 <= v < 3.0.0",
|
||||
"rtfeldman/elm-css-util": "1.0.2 <= v < 2.0.0",
|
||||
"tesk9/accessible-html": "3.0.0 <= v < 4.0.0",
|
||||
|
@ -17,6 +17,7 @@ module Nri.Ui.Button.V2
|
||||
, linkExternalWithTracking
|
||||
, linkSpa
|
||||
, linkWithMethod
|
||||
, linkWithTracking
|
||||
, styles
|
||||
, submit
|
||||
, toggleButton
|
||||
@ -49,7 +50,7 @@ There will generally be a `*Button` and `*Link` version of each button style.
|
||||
|
||||
## `<a>` Buttons
|
||||
|
||||
@docs LinkConfig, link, linkSpa, linkExternal, linkWithMethod, linkExternalWithTracking
|
||||
@docs LinkConfig, link, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
|
||||
|
||||
|
||||
## `<input>` Buttons
|
||||
@ -68,6 +69,7 @@ import Html
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Html.Styled
|
||||
import Json.Decode
|
||||
import Nri.Ui.AssetPath as AssetPath exposing (Asset)
|
||||
import Nri.Ui.Colors.Extra exposing (withAlpha)
|
||||
import Nri.Ui.Colors.V1
|
||||
@ -473,6 +475,20 @@ linkWithMethod method =
|
||||
linkBase <| [ attribute "data-method" method ]
|
||||
|
||||
|
||||
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to some url.
|
||||
This should only take in messages that result in a Msg that triggers Analytics.trackAndRedirect. For buttons that trigger other effects on the page, please use Nri.Button.button instead
|
||||
-}
|
||||
linkWithTracking : msg -> LinkConfig -> Html msg
|
||||
linkWithTracking onTrack =
|
||||
linkBase <|
|
||||
[ Html.Events.onWithOptions "click"
|
||||
{ stopPropagation = False
|
||||
, preventDefault = True
|
||||
}
|
||||
(Json.Decode.succeed onTrack)
|
||||
]
|
||||
|
||||
|
||||
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to some url and have it open to an external site
|
||||
|
||||
This should only take in messages that result in tracking events. For buttons that trigger other effects on the page, please use Nri.Ui.Button.V2.button instead
|
||||
@ -630,11 +646,13 @@ styles =
|
||||
, Css.height (px config.height)
|
||||
, lineHeight (px config.lineHeight)
|
||||
, padding2 zero (px config.sidePadding)
|
||||
, boxSizing borderBox
|
||||
, minWidth (px config.minWidth)
|
||||
, borderWidth (px 1)
|
||||
, borderBottomWidth (px config.shadowHeight)
|
||||
, Css.Foreign.withClass ExplicitWidth
|
||||
[ padding2 zero (px 4)
|
||||
, boxSizing borderBox
|
||||
]
|
||||
, Css.Foreign.withClass IsLink
|
||||
[ lineHeight (px config.height)
|
||||
|
290
src/Nri/Ui/Table/V2.elm
Normal file
290
src/Nri/Ui/Table/V2.elm
Normal file
@ -0,0 +1,290 @@
|
||||
module Nri.Ui.Table.V2
|
||||
exposing
|
||||
( Column
|
||||
, custom
|
||||
, keyframeStyles
|
||||
, keyframes
|
||||
, string
|
||||
, view
|
||||
, viewLoading
|
||||
, viewLoadingWithoutHeader
|
||||
, viewWithoutHeader
|
||||
)
|
||||
|
||||
{-| Upgrading from V1:
|
||||
|
||||
- All the `width` fields in column configurations now take an elm-css length
|
||||
value rather than an Integer. Change `width = 100` to `width = px 100` to get
|
||||
the same widths as before.
|
||||
- Tables now by default take the full width of the container they are placed in.
|
||||
If this is not what you want, wrap the table in an element with a fixed width.
|
||||
- The table module now makes use of `Html.Styled` and no longer exposes a
|
||||
separate `styles` value.
|
||||
Check out the [elm-css](http://package.elm-lang.org/packages/rtfeldman/elm-css/14.0.0/Html-Styled)
|
||||
documentation on Html.Styled to see how to work with it.
|
||||
- The default cell padding has been removed and content is not vertically
|
||||
centered in its cell. If you need to overwrite this, wrap your cells in
|
||||
elements providing custom styling to the cell.
|
||||
|
||||
@docs Column, custom, string
|
||||
|
||||
@docs view, viewWithoutHeader
|
||||
|
||||
@docs viewLoading, viewLoadingWithoutHeader
|
||||
|
||||
@docs keyframes, keyframeStyles
|
||||
|
||||
-}
|
||||
|
||||
import Css exposing (..)
|
||||
import Html.Styled as Html exposing (..)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import Nri.Ui.Colors.V1 exposing (..)
|
||||
import Nri.Ui.Fonts.V1 exposing (baseFont)
|
||||
import Nri.Ui.Styles.V1
|
||||
|
||||
|
||||
{-| 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
|
||||
|
||||
|
||||
{-| A column that renders some aspect of a value as text
|
||||
-}
|
||||
string :
|
||||
{ header : String
|
||||
, value : data -> String
|
||||
, width : LengthOrAuto compatible
|
||||
}
|
||||
-> Column data msg
|
||||
string { header, value, width } =
|
||||
Column (Html.text header) (value >> Html.text) (Css.width width)
|
||||
|
||||
|
||||
{-| A column that renders however you want it to
|
||||
-}
|
||||
custom :
|
||||
{ header : Html msg
|
||||
, view : data -> Html msg
|
||||
, width : LengthOrAuto compatible
|
||||
}
|
||||
-> Column data msg
|
||||
custom { header, view, width } =
|
||||
Column header view (Css.width width)
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
{-| Displays a table of data without a header row
|
||||
-}
|
||||
viewWithoutHeader : List (Column data msg) -> List data -> Html msg
|
||||
viewWithoutHeader columns data =
|
||||
table [] <|
|
||||
List.map (viewRow columns) data
|
||||
|
||||
|
||||
{-| Displays a table of data based on the provided column definitions
|
||||
-}
|
||||
view : List (Column data msg) -> List data -> Html msg
|
||||
view columns data =
|
||||
tableWithHeader [] columns <|
|
||||
List.map (viewRow columns) data
|
||||
|
||||
|
||||
viewHeaders : List (Column data msg) -> Html msg
|
||||
viewHeaders columns =
|
||||
tr
|
||||
[ css headersStyles ]
|
||||
(List.map viewRowHeader columns)
|
||||
|
||||
|
||||
viewRowHeader : Column data msg -> Html msg
|
||||
viewRowHeader (Column header _ width) =
|
||||
th
|
||||
[ css (width :: headerStyles)
|
||||
]
|
||||
[ header ]
|
||||
|
||||
|
||||
viewRow : List (Column data msg) -> data -> Html msg
|
||||
viewRow columns data =
|
||||
tr
|
||||
[ css rowStyles ]
|
||||
(List.map (viewColumn data) columns)
|
||||
|
||||
|
||||
viewColumn : data -> Column data msg -> Html msg
|
||||
viewColumn data (Column _ renderer width) =
|
||||
td
|
||||
[ css (width :: cellStyles)
|
||||
]
|
||||
[ 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 : List (Column data msg) -> Html msg
|
||||
viewLoading columns =
|
||||
tableWithHeader loadingTableStyles columns <|
|
||||
List.map (viewLoadingRow columns) (List.range 0 8)
|
||||
|
||||
|
||||
{-| Display the loading table without a header row
|
||||
-}
|
||||
viewLoadingWithoutHeader : List (Column data msg) -> Html msg
|
||||
viewLoadingWithoutHeader columns =
|
||||
table loadingTableStyles <|
|
||||
List.map (viewLoadingRow columns) (List.range 0 8)
|
||||
|
||||
|
||||
viewLoadingRow : List (Column data msg) -> Int -> Html msg
|
||||
viewLoadingRow columns index =
|
||||
tr
|
||||
[ css rowStyles ]
|
||||
(List.indexedMap (viewLoadingColumn index) columns)
|
||||
|
||||
|
||||
viewLoadingColumn : Int -> Int -> Column data msg -> Html msg
|
||||
viewLoadingColumn rowIndex colIndex (Column _ _ width) =
|
||||
td
|
||||
[ css (stylesLoadingColumn rowIndex colIndex width ++ cellStyles ++ loadingCellStyles)
|
||||
]
|
||||
[ span [ css loadingContentStyles ] [] ]
|
||||
|
||||
|
||||
stylesLoadingColumn : Int -> Int -> Style -> List Style
|
||||
stylesLoadingColumn rowIndex colIndex width =
|
||||
[ width
|
||||
, property "animation-delay" (toString (toFloat (rowIndex + colIndex) * 0.1) ++ "s")
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- HELP
|
||||
|
||||
|
||||
table : List Style -> List (Html msg) -> Html msg
|
||||
table styles =
|
||||
Html.table [ css (styles ++ tableStyles) ]
|
||||
|
||||
|
||||
tableWithHeader : List Style -> List (Column data msg) -> List (Html msg) -> Html msg
|
||||
tableWithHeader styles columns rows =
|
||||
table styles (viewHeaders columns :: rows)
|
||||
|
||||
|
||||
|
||||
-- STYLES
|
||||
|
||||
|
||||
headersStyles : List Style
|
||||
headersStyles =
|
||||
[ borderBottom3 (px 3) solid gray75
|
||||
, height (px 45)
|
||||
, fontSize (px 15)
|
||||
]
|
||||
|
||||
|
||||
headerStyles : List Style
|
||||
headerStyles =
|
||||
[ padding4 (px 15) (px 12) (px 11) (px 12)
|
||||
, textAlign left
|
||||
, fontWeight bold
|
||||
]
|
||||
|
||||
|
||||
rowStyles : List Style
|
||||
rowStyles =
|
||||
[ height (px 45)
|
||||
, fontSize (px 14)
|
||||
, color gray45
|
||||
, pseudoClass "nth-child(odd)"
|
||||
[ backgroundColor gray96 ]
|
||||
]
|
||||
|
||||
|
||||
cellStyles : List Style
|
||||
cellStyles =
|
||||
[ verticalAlign middle
|
||||
]
|
||||
|
||||
|
||||
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 Style
|
||||
tableStyles =
|
||||
[ borderCollapse collapse
|
||||
, baseFont
|
||||
, Css.width (Css.pct 100)
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
keyframes : List Nri.Ui.Styles.V1.Keyframe
|
||||
keyframes =
|
||||
[ Nri.Ui.Styles.V1.keyframes "Nri-Ui-Table-V2-flash"
|
||||
[ ( "0%", "opacity: 0.6" )
|
||||
, ( "50%", "opacity: 0.2" )
|
||||
, ( "100%", "opacity: 0.6" )
|
||||
]
|
||||
, Nri.Ui.Styles.V1.keyframes "Nri-Ui-Table-V2-fadein"
|
||||
[ ( "from", "opacity: 0" )
|
||||
, ( "to", "opacity: 1" )
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
keyframeStyles : Html msg
|
||||
keyframeStyles =
|
||||
Html.node "style"
|
||||
[]
|
||||
(List.map (Html.text << Nri.Ui.Styles.V1.toString) keyframes)
|
||||
|
||||
|
||||
flashAnimation : List Css.Style
|
||||
flashAnimation =
|
||||
[ property "-webkit-animation" "Nri-Ui-Table-V2-flash 2s infinite"
|
||||
, property "-moz-animation" "Nri-Ui-Table-V2-flash 2s infinite"
|
||||
, property "animation" "Nri-Ui-Table-V2-flash 2s infinite"
|
||||
, opacity (num 0.6)
|
||||
]
|
||||
|
||||
|
||||
fadeInAnimation : List Css.Style
|
||||
fadeInAnimation =
|
||||
[ property "-webkit-animation" "Nri-Ui-Table-V2-fadein 0.4s 0.2s forwards"
|
||||
, property "-moz-animation" "Nri-Ui-Table-V2-fadein 0.4s 0.2s forwards"
|
||||
, property "animation" "Nri-Ui-Table-V2-fadein 0.4s 0.2s forwards"
|
||||
, opacity (num 0)
|
||||
]
|
@ -4,10 +4,12 @@ module Examples.Table exposing (Msg, State, example, init, update)
|
||||
@docs Msg, State, example, init, update
|
||||
-}
|
||||
|
||||
import Css exposing (..)
|
||||
import Html
|
||||
import Html.Styled
|
||||
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Button.V2 as Button
|
||||
import Nri.Ui.Table.V1 as Table
|
||||
import Nri.Ui.Table.V2 as Table
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -31,16 +33,18 @@ example parentMessage state =
|
||||
[ Table.string
|
||||
{ header = "First Name"
|
||||
, value = .firstName
|
||||
, width = 125
|
||||
, width = calc (pct 50) minus (px 125)
|
||||
}
|
||||
, Table.string
|
||||
{ header = "Last Name"
|
||||
, value = .lastName
|
||||
, width = 125
|
||||
, width = calc (pct 50) minus (px 125)
|
||||
}
|
||||
, Table.custom
|
||||
{ header = Html.text "Actions"
|
||||
, width = 150
|
||||
{ header =
|
||||
Html.text "Actions"
|
||||
|> Html.Styled.fromUnstyled
|
||||
, width = px 250
|
||||
, view =
|
||||
\_ ->
|
||||
Button.button
|
||||
@ -53,6 +57,7 @@ example parentMessage state =
|
||||
, state = Button.Enabled
|
||||
, icon = Nothing
|
||||
}
|
||||
|> Html.Styled.fromUnstyled
|
||||
}
|
||||
]
|
||||
|
||||
@ -64,15 +69,19 @@ example parentMessage state =
|
||||
, { firstName = "First5", lastName = "Last5" }
|
||||
]
|
||||
in
|
||||
[ Table.keyframeStyles
|
||||
[ Html.Styled.toUnstyled Table.keyframeStyles
|
||||
, Html.h4 [] [ Html.text "With header" ]
|
||||
, Table.view columns data
|
||||
|> Html.Styled.toUnstyled
|
||||
, Html.h4 [] [ Html.text "Without header" ]
|
||||
, Table.viewWithoutHeader columns data
|
||||
|> Html.Styled.toUnstyled
|
||||
, Html.h4 [] [ Html.text "Loading" ]
|
||||
, Table.viewLoading columns
|
||||
|> Html.Styled.toUnstyled
|
||||
, Html.h4 [] [ Html.text "Loading without header" ]
|
||||
, Table.viewLoadingWithoutHeader columns
|
||||
|> Html.Styled.toUnstyled
|
||||
]
|
||||
|> List.map (Html.map parentMessage)
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import Nri.Ui.Dropdown.V1
|
||||
import Nri.Ui.Icon.V2
|
||||
import Nri.Ui.SegmentedControl.V5
|
||||
import Nri.Ui.Select.V2
|
||||
import Nri.Ui.Table.V1 as Table
|
||||
import Nri.Ui.Text.V1 as Text
|
||||
import Nri.Ui.TextArea.V1 as TextArea
|
||||
import String.Extra
|
||||
@ -193,7 +192,6 @@ styles =
|
||||
, (Nri.Ui.Icon.V2.styles |> .css) ()
|
||||
, (Nri.Ui.SegmentedControl.V5.styles |> .css) ()
|
||||
, (Nri.Ui.Select.V2.styles |> .css) ()
|
||||
, (Table.styles |> .css) ()
|
||||
, (Text.styles |> .css) ()
|
||||
, (TextArea.styles |> .css) assets
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user