Pulls Loading out into its own module

This commit is contained in:
Tessa Kelly 2020-04-02 18:13:29 -07:00
parent 4c07849e02
commit fe864e7184
5 changed files with 243 additions and 148 deletions

93
src/Nri/Ui/Loading/V1.elm Normal file
View File

@ -0,0 +1,93 @@
module Nri.Ui.Loading.V1 exposing
( fadeInPage, page
, spinner
)
{-| Loading behaviors
@docs fadeInPage, page
@docs spinner
-}
import Css exposing (..)
import Css.Animations
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon
{-| View a full-screen loading page that fades into view.
-}
fadeInPage : Html msg
fadeInPage =
loading_
[ Css.property "animation-delay" "1s"
, Css.property "animation-duration" "1.5s"
, Css.property "animation-fill-mode" "forwards"
, Css.animationName fadeInKeyframes
, Css.property "animation-timing-function" "linear"
, Css.opacity Css.zero
]
{-| View a full-screen loading page.
-}
page : Html msg
page =
loading_ []
loading_ : List Css.Style -> Html msg
loading_ withCss =
Html.div
[ Attributes.css
([ Css.backgroundColor Colors.blueDeep
, Css.position Css.fixed
, Css.displayFlex
, Css.alignItems Css.center
, Css.justifyContent Css.center
, Css.width (Css.vw 100)
, Css.height (Css.vh 100)
, Css.top Css.zero
, Css.left Css.zero
, Css.zIndex (Css.int 10000)
]
++ withCss
)
]
[ Svg.toHtml spinner
]
{-| -}
spinner : Svg
spinner =
UiIcon.edit
|> Svg.withLabel "Loading..."
|> Svg.withColor Colors.white
|> Svg.withWidth (Css.px 100)
|> Svg.withHeight (Css.px 100)
|> Svg.withCss
[ Css.property "animation-duration" "1s"
, Css.property "animation-iteration-count" "infinite"
, Css.animationName rotateKeyframes
, Css.property "animation-timing-function" "linear"
]
rotateKeyframes : Css.Animations.Keyframes {}
rotateKeyframes =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.transform [ Css.rotate (Css.deg -360) ] ] )
]
fadeInKeyframes : Css.Animations.Keyframes {}
fadeInKeyframes =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.opacity Css.zero ] )
, ( 100, [ Css.Animations.opacity (Css.num 1) ] )
]

View File

@ -1,26 +1,20 @@
module Nri.Ui.Page.V3 exposing module Nri.Ui.Page.V3 exposing
( DefaultPage, broken, blocked, notFound, noPermission ( DefaultPage, broken, blocked, notFound, noPermission
, RecoveryText(..) , RecoveryText(..)
, loadingFadeIn, loading
) )
{-| A styled NRI page! {-| A styled NRI page!
@docs DefaultPage, broken, blocked, notFound, noPermission @docs DefaultPage, broken, blocked, notFound, noPermission
@docs RecoveryText @docs RecoveryText
@docs loadingFadeIn, loading
-} -}
import Css exposing (..) import Css exposing (..)
import Css.Animations
import Html.Styled as Html exposing (Html) import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes import Html.Styled.Attributes as Attributes
import Nri.Ui.Button.V5 as Button import Nri.Ui.Button.V5 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Text.V2 as Text import Nri.Ui.Text.V2 as Text
import Nri.Ui.UiIcon.V1 as UiIcon
{-| The default page information is for the button {-| The default page information is for the button
@ -96,75 +90,6 @@ noPermission defaultPage =
} }
{-| View a full-screen loading page that fades into view.
-}
loadingFadeIn : Html msg
loadingFadeIn =
loading_
[ Css.property "animation-delay" "1s"
, Css.property "animation-duration" "1.5s"
, Css.property "animation-fill-mode" "forwards"
, Css.animationName fadeInKeyframes
, Css.property "animation-timing-function" "linear"
, Css.opacity Css.zero
]
{-| View a full-screen loading page.
-}
loading : Html msg
loading =
loading_ []
loading_ : List Css.Style -> Html msg
loading_ withCss =
Html.div
[ Attributes.css
([ Css.backgroundColor Colors.blueDeep
, Css.position Css.fixed
, Css.displayFlex
, Css.alignItems Css.center
, Css.justifyContent Css.center
, Css.width (Css.vw 100)
, Css.height (Css.vh 100)
, Css.top Css.zero
, Css.left Css.zero
, Css.zIndex (Css.int 10000)
]
++ withCss
)
]
[ UiIcon.edit
|> Svg.withLabel "Loading..."
|> Svg.withColor Colors.white
|> Svg.withWidth (Css.px 100)
|> Svg.withHeight (Css.px 100)
|> Svg.withCss
[ Css.property "animation-duration" "1s"
, Css.property "animation-iteration-count" "infinite"
, Css.animationName rotateKeyframes
, Css.property "animation-timing-function" "linear"
]
|> Svg.toHtml
]
rotateKeyframes : Css.Animations.Keyframes {}
rotateKeyframes =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.transform [ Css.rotate (Css.deg -360) ] ] )
]
fadeInKeyframes : Css.Animations.Keyframes {}
fadeInKeyframes =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.opacity Css.zero ] )
, ( 100, [ Css.Animations.opacity (Css.num 1) ] )
]
-- INTERNAL -- INTERNAL

View File

@ -16,6 +16,7 @@ import Examples.Dropdown as Dropdown
import Examples.Fonts as Fonts import Examples.Fonts as Fonts
import Examples.Heading as Heading import Examples.Heading as Heading
import Examples.Icon as Icon import Examples.Icon as Icon
import Examples.Loading as Loading
import Examples.Logo as Logo import Examples.Logo as Logo
import Examples.MasteryIcon as MasteryIcon import Examples.MasteryIcon as MasteryIcon
import Examples.Modal as Modal import Examples.Modal as Modal
@ -321,6 +322,25 @@ all =
IconState childState -> IconState childState ->
Just childState Just childState
_ ->
Nothing
)
, Loading.example
|> Example.wrapMsg LoadingMsg
(\msg ->
case msg of
LoadingMsg childMsg ->
Just childMsg
_ ->
Nothing
)
|> Example.wrapState LoadingState
(\msg ->
case msg of
LoadingState childState ->
Just childState
_ -> _ ->
Nothing Nothing
) )
@ -704,6 +724,7 @@ type State
| FontsState Fonts.State | FontsState Fonts.State
| HeadingState Heading.State | HeadingState Heading.State
| IconState Icon.State | IconState Icon.State
| LoadingState Loading.State
| LogoState Logo.State | LogoState Logo.State
| MasteryIconState MasteryIcon.State | MasteryIconState MasteryIcon.State
| ModalState Modal.State | ModalState Modal.State
@ -741,6 +762,7 @@ type Msg
| FontsMsg Fonts.Msg | FontsMsg Fonts.Msg
| HeadingMsg Heading.Msg | HeadingMsg Heading.Msg
| IconMsg Icon.Msg | IconMsg Icon.Msg
| LoadingMsg Loading.Msg
| LogoMsg Logo.Msg | LogoMsg Logo.Msg
| MasteryIconMsg MasteryIcon.Msg | MasteryIconMsg MasteryIcon.Msg
| ModalMsg Modal.Msg | ModalMsg Modal.Msg

View File

@ -0,0 +1,122 @@
module Examples.Loading exposing (example, State, Msg)
{-|
@docs example, State, Msg
-}
import Browser.Events
import Category exposing (Category(..))
import Css
import Css.Global exposing (Snippet, adjacentSiblings, children, class, descendants, each, everything, media, selector, withClass)
import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Events as Events
import Json.Decode
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Loading.V1 as Loading
{-| -}
type alias State =
{ showLoadingFadeIn : Bool
, showLoading : Bool
}
init : State
init =
{ showLoadingFadeIn = False
, showLoading = False
}
{-| -}
type Msg
= ShowLoadingFadeIn
| ShowLoading
| CloseFullScreenPage
update : Msg -> State -> ( State, Cmd Msg )
update msg model =
case msg of
ShowLoadingFadeIn ->
( { model | showLoadingFadeIn = True }
, Cmd.none
)
ShowLoading ->
( { model | showLoading = True }
, Cmd.none
)
CloseFullScreenPage ->
( { model
| showLoadingFadeIn = False
, showLoading = False
}
, Cmd.none
)
subscriptions : State -> Sub Msg
subscriptions { showLoadingFadeIn, showLoading } =
if showLoadingFadeIn || showLoading then
Browser.Events.onClick (Json.Decode.succeed CloseFullScreenPage)
else
Sub.none
{-| -}
example : Example State Msg
example =
{ name = "Nri.Ui.Loading.V1"
, categories = [ Pages ]
, state = init
, update = update
, subscriptions = subscriptions
, view =
\{ showLoadingFadeIn, showLoading } ->
[ if showLoading then
Loading.page
else
Html.text ""
, Button.button "Loading.page"
[ Button.custom
[ Events.stopPropagationOn "click"
(Json.Decode.map (\m -> ( m, True ))
(Json.Decode.succeed ShowLoading)
)
]
, if showLoadingFadeIn then
Button.disabled
else
Button.secondary
, Button.css [ Css.marginRight (Css.px 20) ]
]
, if showLoadingFadeIn then
Loading.fadeInPage
else
Html.text ""
, Button.button "Loading.fadeInPage"
[ Button.custom
[ Events.stopPropagationOn "click"
(Json.Decode.map (\m -> ( m, True ))
(Json.Decode.succeed ShowLoadingFadeIn)
)
]
, if showLoadingFadeIn then
Button.loading
else
Button.secondary
]
]
}

View File

@ -21,47 +21,22 @@ import Nri.Ui.Page.V3 as Page
{-| -} {-| -}
type alias State = type alias State =
{ showLoadingFadeIn : Bool {}
, showLoading : Bool
}
init : State init : State
init = init =
{ showLoadingFadeIn = False {}
, showLoading = False
}
{-| -} {-| -}
type Msg type Msg
= ShowLoadingFadeIn = LinkClick String
| ShowLoading
| CloseFullScreenPage
| LinkClick String
update : Msg -> State -> ( State, Cmd Msg ) update : Msg -> State -> ( State, Cmd Msg )
update msg model = update msg model =
case msg of case msg of
ShowLoadingFadeIn ->
( { model | showLoadingFadeIn = True }
, Cmd.none
)
ShowLoading ->
( { model | showLoading = True }
, Cmd.none
)
CloseFullScreenPage ->
( { model
| showLoadingFadeIn = False
, showLoading = False
}
, Cmd.none
)
LinkClick message -> LinkClick message ->
let let
_ = _ =
@ -71,12 +46,8 @@ update msg model =
subscriptions : State -> Sub Msg subscriptions : State -> Sub Msg
subscriptions { showLoadingFadeIn, showLoading } = subscriptions {} =
if showLoadingFadeIn || showLoading then Sub.none
Browser.Events.onClick (Json.Decode.succeed CloseFullScreenPage)
else
Sub.none
{-| -} {-| -}
@ -88,7 +59,7 @@ example =
, update = update , update = update
, subscriptions = subscriptions , subscriptions = subscriptions
, view = , view =
\{ showLoadingFadeIn, showLoading } -> \{} ->
[ Css.Global.global [ Css.Global.global
[ Css.Global.selector "[data-page-container]" [ Css.Global.selector "[data-page-container]"
[ Css.displayFlex [ Css.displayFlex
@ -110,43 +81,5 @@ example =
{ link = LinkClick "Custom" { link = LinkClick "Custom"
, recoveryText = Page.Custom "Hit the road, Jack" , recoveryText = Page.Custom "Hit the road, Jack"
} }
, Heading.h3 [] [ Html.text "Page.loadingFadeIn" ]
, if showLoadingFadeIn then
Page.loadingFadeIn
else
Html.text ""
, Button.button "Open loadingFadeIn"
[ Button.custom
[ Events.stopPropagationOn "click"
(Json.Decode.map (\m -> ( m, True ))
(Json.Decode.succeed ShowLoadingFadeIn)
)
]
, if showLoadingFadeIn then
Button.loading
else
Button.primary
]
, Heading.h3 [] [ Html.text "Page.loading" ]
, if showLoading then
Page.loading
else
Html.text ""
, Button.button "Open loading"
[ Button.custom
[ Events.stopPropagationOn "click"
(Json.Decode.map (\m -> ( m, True ))
(Json.Decode.succeed ShowLoading)
)
]
, if showLoadingFadeIn then
Button.disabled
else
Button.primary
]
] ]
} }