mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-11-27 13:02:42 +03:00
Change approach -- add new animated icon module
This commit is contained in:
parent
7b9c97b5c5
commit
38ec34dc0a
1
elm.json
1
elm.json
@ -7,6 +7,7 @@
|
||||
"exposed-modules": [
|
||||
"Nri.Ui",
|
||||
"Nri.Ui.Accordion.V3",
|
||||
"Nri.Ui.AnimatedIcon.V1",
|
||||
"Nri.Ui.AssetPath",
|
||||
"Nri.Ui.AssignmentIcon.V2",
|
||||
"Nri.Ui.Balloon.V1",
|
||||
|
81
src/Nri/Ui/AnimatedIcon/V1.elm
Normal file
81
src/Nri/Ui/AnimatedIcon/V1.elm
Normal file
@ -0,0 +1,81 @@
|
||||
module Nri.Ui.AnimatedIcon.V1 exposing (mobileOpenClose)
|
||||
|
||||
import Css
|
||||
import Css.Animations
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.MediaQuery.V1 as MediaQuery
|
||||
import Nri.Ui.Svg.V1
|
||||
import Svg.Styled as Svg
|
||||
import Svg.Styled.Attributes as Attributes
|
||||
|
||||
|
||||
animatedXHamburger : List ( List Css.Animations.Property, List Css.Animations.Property ) -> Nri.Ui.Svg.V1.Svg
|
||||
animatedXHamburger lineAnimations =
|
||||
let
|
||||
animate : ( List Css.Animations.Property, List Css.Animations.Property ) -> Svg.Attribute Never
|
||||
animate ( start, end ) =
|
||||
Attributes.css
|
||||
[ Css.animationDuration (Css.ms 300)
|
||||
, Css.property "animation-timing-function" "linear"
|
||||
, Css.property "animation-fill-mode" "forwards"
|
||||
, Css.animationName
|
||||
(Css.Animations.keyframes
|
||||
[ ( 0, start )
|
||||
, ( 20, [ Css.Animations.custom "width" "25px" ] )
|
||||
, ( 80, [ Css.Animations.custom "width" "25px" ] )
|
||||
, ( 100, end )
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
line ( x_, y ) animation =
|
||||
Svg.rect
|
||||
[ Attributes.x (String.fromFloat x_)
|
||||
, Attributes.y (String.fromFloat y)
|
||||
, Attributes.width "25"
|
||||
, Attributes.height "5"
|
||||
, Attributes.rx "2.5"
|
||||
, animate animation
|
||||
]
|
||||
[]
|
||||
in
|
||||
Nri.Ui.Svg.V1.init "0 0 25 27"
|
||||
(List.map2 identity
|
||||
[ line ( 0, 0 ), line ( 0, 10 ), line ( 0, 20 ) ]
|
||||
lineAnimations
|
||||
)
|
||||
|
||||
|
||||
topLineAsX : List Css.Animations.Property
|
||||
topLineAsX =
|
||||
[ Css.Animations.transform
|
||||
[ Css.rotate (Css.deg 45)
|
||||
, Css.translate3d (Css.px 3) (Css.px -1) Css.zero
|
||||
]
|
||||
, Css.Animations.custom "width" "32px"
|
||||
]
|
||||
|
||||
|
||||
middleLineAsX : List Css.Animations.Property
|
||||
middleLineAsX =
|
||||
[ Css.Animations.opacity (Css.num 0) ]
|
||||
|
||||
|
||||
bottomLineAsX : List Css.Animations.Property
|
||||
bottomLineAsX =
|
||||
[ Css.Animations.transform
|
||||
[ Css.translate3d (Css.px -15) (Css.px 7.5) Css.zero
|
||||
, Css.rotate (Css.deg -45)
|
||||
]
|
||||
, Css.Animations.custom "width" "32px"
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
mobileOpenClose : Bool -> Nri.Ui.Svg.V1.Svg
|
||||
mobileOpenClose isOpen =
|
||||
animatedXHamburger
|
||||
[ ( topLineAsX, [] )
|
||||
, ( middleLineAsX, [] )
|
||||
, ( bottomLineAsX, [] )
|
||||
]
|
@ -57,6 +57,7 @@ import Html.Styled
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Html.Styled.Events as Events
|
||||
import Nri.Ui
|
||||
import Nri.Ui.AnimatedIcon.V1 as AnimatedIcon
|
||||
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
|
||||
import Nri.Ui.ClickableText.V3 as ClickableText
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
@ -251,36 +252,30 @@ viewOpenCloseButton sidenavId navLabel_ { isOpen, toggle, isTooltipOpen, toggleT
|
||||
name =
|
||||
Maybe.withDefault "sidebar" navLabel_
|
||||
|
||||
( action, icon_, attributes ) =
|
||||
( action, icon_ ) =
|
||||
if isOpen then
|
||||
( "Close " ++ name
|
||||
, UiIcon.openClose
|
||||
, [ ClickableSvg.iconForMobile UiIcon.hamburgerToX
|
||||
]
|
||||
)
|
||||
|
||||
else
|
||||
( "Open " ++ name
|
||||
, UiIcon.openClose
|
||||
|> Svg.withCss [ Css.transform (rotate (deg 180)) ]
|
||||
, [ ClickableSvg.withBorder
|
||||
, ClickableSvg.iconForMobile UiIcon.xToHamburger
|
||||
]
|
||||
)
|
||||
|
||||
trigger tooltipAttributes =
|
||||
ClickableSvg.button action
|
||||
icon_
|
||||
([ ClickableSvg.custom
|
||||
[ ClickableSvg.custom
|
||||
[ Aria.controls [ sidenavId ]
|
||||
, Aria.expanded isOpen
|
||||
]
|
||||
, ClickableSvg.custom tooltipAttributes
|
||||
, ClickableSvg.onClick (toggle (not isOpen))
|
||||
, ClickableSvg.tertiary
|
||||
]
|
||||
++ attributes
|
||||
)
|
||||
, ClickableSvg.custom tooltipAttributes
|
||||
, ClickableSvg.onClick (toggle (not isOpen))
|
||||
, ClickableSvg.tertiary
|
||||
, ClickableSvg.iconForMobile (AnimatedIcon.mobileOpenClose isOpen)
|
||||
]
|
||||
in
|
||||
Tooltip.view
|
||||
{ trigger = trigger
|
||||
|
@ -1,6 +1,5 @@
|
||||
module Nri.Ui.UiIcon.V1 exposing
|
||||
( xToHamburger, hamburgerToX
|
||||
, seeMore, openClose, download, sort, gear, flipper, hamburger, kebab
|
||||
( seeMore, openClose, download, sort, gear, flipper, hamburger, kebab
|
||||
, archive, unarchive
|
||||
, playInCircle, pauseInCircle, stopInCircle
|
||||
, play, skip
|
||||
@ -37,7 +36,6 @@ module Nri.Ui.UiIcon.V1 exposing
|
||||
|
||||
{-| How to add new icons: <https://paper.dropbox.com/doc/How-to-create-a-new-SVG-icon-for-use-in-Elm--Ay9uhSLfGUAix0ERIiJ0Dm8dAg-8WNqtARdr4EgjmYEHPeYD>
|
||||
|
||||
@docs xToHamburger, hamburgerToX
|
||||
@docs seeMore, openClose, download, sort, gear, flipper, hamburger, kebab
|
||||
@docs archive, unarchive
|
||||
@docs playInCircle, pauseInCircle, stopInCircle
|
||||
@ -985,88 +983,6 @@ hamburger =
|
||||
]
|
||||
|
||||
|
||||
animatedXHamburger : List ( List Css.Animations.Property, List Css.Animations.Property ) -> Nri.Ui.Svg.V1.Svg
|
||||
animatedXHamburger lineAnimations =
|
||||
let
|
||||
animate : ( List Css.Animations.Property, List Css.Animations.Property ) -> Svg.Attribute Never
|
||||
animate ( start, end ) =
|
||||
Attributes.css
|
||||
[ Css.animationDuration (Css.ms 300)
|
||||
, Css.property "animation-timing-function" "linear"
|
||||
, Css.property "animation-fill-mode" "forwards"
|
||||
, Css.animationName
|
||||
(Css.Animations.keyframes
|
||||
[ ( 0, start )
|
||||
, ( 20, [ Css.Animations.custom "width" "25px" ] )
|
||||
, ( 80, [ Css.Animations.custom "width" "25px" ] )
|
||||
, ( 100, end )
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
line ( x_, y ) animation =
|
||||
Svg.rect
|
||||
[ Attributes.x (String.fromFloat x_)
|
||||
, Attributes.y (String.fromFloat y)
|
||||
, Attributes.width "25"
|
||||
, Attributes.height "5"
|
||||
, Attributes.rx "2.5"
|
||||
, animate animation
|
||||
]
|
||||
[]
|
||||
in
|
||||
Nri.Ui.Svg.V1.init "0 0 25 27"
|
||||
(List.map2 identity
|
||||
[ line ( 0, 0 ), line ( 0, 10 ), line ( 0, 20 ) ]
|
||||
lineAnimations
|
||||
)
|
||||
|
||||
|
||||
topLineAsX : List Css.Animations.Property
|
||||
topLineAsX =
|
||||
[ Css.Animations.transform
|
||||
[ Css.translate3d (Css.px 3) (Css.px -1) Css.zero
|
||||
, Css.rotate (Css.deg 45)
|
||||
]
|
||||
, Css.Animations.custom "width" "32px"
|
||||
]
|
||||
|
||||
|
||||
middleLineAsX : List Css.Animations.Property
|
||||
middleLineAsX =
|
||||
[ Css.Animations.opacity (Css.num 0) ]
|
||||
|
||||
|
||||
bottomLineAsX : List Css.Animations.Property
|
||||
bottomLineAsX =
|
||||
[ Css.Animations.transform
|
||||
[ Css.translate3d (Css.px -15) (Css.px 7.5) Css.zero
|
||||
, Css.rotate (Css.deg -45)
|
||||
]
|
||||
, Css.Animations.custom "width" "32px"
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
xToHamburger : Nri.Ui.Svg.V1.Svg
|
||||
xToHamburger =
|
||||
animatedXHamburger
|
||||
[ ( topLineAsX, [] )
|
||||
, ( middleLineAsX, [] )
|
||||
, ( bottomLineAsX, [] )
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
hamburgerToX : Nri.Ui.Svg.V1.Svg
|
||||
hamburgerToX =
|
||||
animatedXHamburger
|
||||
[ ( [], topLineAsX )
|
||||
, ( [], middleLineAsX )
|
||||
, ( [], bottomLineAsX )
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
kebab : Nri.Ui.Svg.V1.Svg
|
||||
kebab =
|
||||
|
@ -2,6 +2,7 @@ module Examples exposing (Msg, State, all)
|
||||
|
||||
import Example exposing (Example)
|
||||
import Examples.Accordion as Accordion
|
||||
import Examples.AnimatedIcon as AnimatedIcon
|
||||
import Examples.AssignmentIcon as AssignmentIcon
|
||||
import Examples.Balloon as Balloon
|
||||
import Examples.BreadCrumbs as BreadCrumbs
|
||||
@ -60,6 +61,25 @@ all =
|
||||
AccordionState childState ->
|
||||
Just childState
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
)
|
||||
, AnimatedIcon.example
|
||||
|> Example.wrapMsg AnimatedIconMsg
|
||||
(\msg ->
|
||||
case msg of
|
||||
AnimatedIconMsg childMsg ->
|
||||
Just childMsg
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
)
|
||||
|> Example.wrapState AnimatedIconState
|
||||
(\msg ->
|
||||
case msg of
|
||||
AnimatedIconState childState ->
|
||||
Just childState
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
)
|
||||
@ -790,6 +810,7 @@ all =
|
||||
|
||||
type State
|
||||
= AccordionState Accordion.State
|
||||
| AnimatedIconState AnimatedIcon.State
|
||||
| AssignmentIconState AssignmentIcon.State
|
||||
| BalloonState Balloon.State
|
||||
| BreadCrumbsState BreadCrumbs.State
|
||||
@ -832,6 +853,7 @@ type State
|
||||
|
||||
type Msg
|
||||
= AccordionMsg Accordion.Msg
|
||||
| AnimatedIconMsg AnimatedIcon.Msg
|
||||
| AssignmentIconMsg AssignmentIcon.Msg
|
||||
| BalloonMsg Balloon.Msg
|
||||
| BreadCrumbsMsg BreadCrumbs.Msg
|
||||
|
119
styleguide-app/Examples/AnimatedIcon.elm
Normal file
119
styleguide-app/Examples/AnimatedIcon.elm
Normal file
@ -0,0 +1,119 @@
|
||||
module Examples.AnimatedIcon exposing (example, State, Msg)
|
||||
|
||||
{-|
|
||||
|
||||
@docs example, State, Msg
|
||||
|
||||
-}
|
||||
|
||||
import Category exposing (Category(..))
|
||||
import Css
|
||||
import Debug.Control as Control exposing (Control)
|
||||
import Debug.Control.Extra as ControlExtra
|
||||
import Debug.Control.View as ControlView
|
||||
import Example exposing (Example)
|
||||
import Examples.IconExamples as IconExamples
|
||||
import Nri.Ui.AnimatedIcon.V1 as AnimatedIcon
|
||||
import Nri.Ui.Heading.V3 as Heading
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
|
||||
|
||||
moduleName : String
|
||||
moduleName =
|
||||
"AnimatedIcon"
|
||||
|
||||
|
||||
version : Int
|
||||
version =
|
||||
1
|
||||
|
||||
|
||||
{-| -}
|
||||
example : Example State Msg
|
||||
example =
|
||||
{ name = moduleName
|
||||
, version = version
|
||||
, categories = [ Icons ]
|
||||
, keyboardSupport = []
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
IconExamples.preview
|
||||
[ AnimatedIcon.mobileOpenClose False
|
||||
, AnimatedIcon.mobileOpenClose True
|
||||
]
|
||||
, view =
|
||||
\ellieLinkConfig state ->
|
||||
let
|
||||
attributes =
|
||||
Control.currentValue state.settings
|
||||
in
|
||||
[ ControlView.view
|
||||
{ ellieLinkConfig = ellieLinkConfig
|
||||
, name = moduleName
|
||||
, version = version
|
||||
, update = UpdateSettings
|
||||
, settings = state.settings
|
||||
, mainType = Just "RootHtml.Html msg"
|
||||
, extraCode = [ "import Nri.Ui.Svg.V1 as Svg" ]
|
||||
, toExampleCode =
|
||||
\settings ->
|
||||
let
|
||||
toCode viewName =
|
||||
moduleName
|
||||
++ "."
|
||||
++ viewName
|
||||
++ " "
|
||||
++ Tuple.first settings.isOpen
|
||||
++ "\n |> Svg.withCss [ Css.maxWidth (Css.px 45) ]"
|
||||
++ "\n |> Svg.toHtml"
|
||||
in
|
||||
[ { sectionName = "Code"
|
||||
, code = toCode "mobileOpenClose"
|
||||
}
|
||||
]
|
||||
}
|
||||
, Heading.h2 [ Heading.plaintext "Example" ]
|
||||
, AnimatedIcon.mobileOpenClose (Tuple.second attributes.isOpen)
|
||||
|> Svg.withCss [ Css.maxWidth (Css.px 45) ]
|
||||
|> Svg.toHtml
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias State =
|
||||
{ settings : Control Settings
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
init : State
|
||||
init =
|
||||
{ settings = initSettings
|
||||
}
|
||||
|
||||
|
||||
type alias Settings =
|
||||
{ isOpen : ( String, Bool )
|
||||
}
|
||||
|
||||
|
||||
initSettings : Control Settings
|
||||
initSettings =
|
||||
Control.record Settings
|
||||
|> Control.field "isOpen" (ControlExtra.bool False)
|
||||
|
||||
|
||||
{-| -}
|
||||
type Msg
|
||||
= UpdateSettings (Control Settings)
|
||||
|
||||
|
||||
{-| -}
|
||||
update : Msg -> State -> ( State, Cmd Msg )
|
||||
update msg state =
|
||||
case msg of
|
||||
UpdateSettings settings ->
|
||||
( { state | settings = settings }, Cmd.none )
|
@ -52,12 +52,7 @@ example =
|
||||
|
||||
all : List Group
|
||||
all =
|
||||
[ ( "Interface with transitions"
|
||||
, [ ( "xToHamburger", UiIcon.xToHamburger, [] )
|
||||
, ( "hamburgerToX", UiIcon.hamburgerToX, [] )
|
||||
]
|
||||
)
|
||||
, ( "Interface"
|
||||
[ ( "Interface"
|
||||
, [ ( "seeMore", UiIcon.seeMore, [] )
|
||||
, ( "openClose", UiIcon.openClose, [] )
|
||||
, ( "download", UiIcon.download, [] )
|
||||
|
Loading…
Reference in New Issue
Block a user