git.iko.soy/rowtype-yoga/psfp
on master help sign in
Add close with escape
88d4be0Mark Eibes
components/src/React/Basic/Extra/Hooks/UseAffReducer.purs+1−1
@@ -1,4 +1,4 @@
1−module React.Basic.Extra.Hooks where
1+module React.Basic.Extra.Hooks.UseAffReducer where
2
2
3import Prelude
3import Prelude
4import Data.Foldable (for_)
4import Data.Foldable (for_)
components/src/React/Basic/Extra/Hooks/UseKeyUp.jsnew file+3
@@ -0,0 +1,3 @@
1+exports.getKeyImpl = function (just) { return function (nothing) { return function (event) {
2+ return event.keyCode ? just(event.keyCode) : nothing;
3+}; }; };
components/src/React/Basic/Extra/Hooks/UseKeyUp.pursnew file+39
@@ -0,0 +1,39 @@
1+module React.Basic.Extra.Hooks.UseKeyUp where
2+
3+import Prelude
4+import Data.Maybe (Maybe(..))
5+import Data.Newtype (class Newtype)
6+import Debug.Trace (spy)
7+import Effect (Effect)
8+import React.Basic.Hooks (Hook, UseEffect, UseState, coerceHook, useEffect, useState, (/\))
9+import React.Basic.Hooks as React
10+import Unsafe.Coerce (unsafeCoerce)
11+import Web.Event.Event (Event, EventType(..))
12+import Web.Event.EventTarget (addEventListener, eventListener, removeEventListener)
13+import Web.HTML (window)
14+import Web.HTML.Window as Win
15+
16+newtype UseKeyUp hooks
17+ = UseKeyUp
18+ (UseEffect Unit (UseState Boolean hooks))
19+
20+derive instance ntUseKeyUp ∷ Newtype (UseKeyUp hooks) _
21+-- useScrollYPosition ∷ Hook UseScrollYPosition Number
22+useKeyUp ∷ Int -> Effect Unit -> Hook UseKeyUp Unit
23+useKeyUp targetKey doWhat = do
24+ coerceHook React.do
25+ keyPressed /\ modifyKeyPressed <- useState false
26+ useEffect unit do
27+ listener <-
28+ eventListener \event -> when (getKeyCode event == Just targetKey) doWhat
29+ win <- window
30+ addEventListener eventTypeKeyUp listener false (Win.toEventTarget win)
31+ pure (removeEventListener eventTypeKeyUp listener false (Win.toEventTarget win))
32+
33+eventTypeKeyUp ∷ EventType
34+eventTypeKeyUp = EventType "keyup"
35+
36+foreign import getKeyImpl ∷ ∀ a. (a -> Maybe a) -> Maybe a -> Event -> Maybe Int
37+
38+getKeyCode ∷ Event -> Maybe Int
39+getKeyCode = getKeyImpl Just Nothing
components/src/React/Basic/Extra/Hooks/UseKeyUp.tsnew file+4
@@ -0,0 +1,4 @@
1+exports.getKeyImpl = (just: (v: Number) => Number) => (
2+ nothing: Number
3+) => (event: { keyCode: Number }) =>
4+ event.keyCode ? just(event.keyCode) : nothing;
components/src/Yoga/InlineCode/Component.purs+4−4
@@ -1,4 +1,4 @@
1−module Yoga.InlineCode.Component where
1+module Yoga.Layer.Component where
2
2
3import Prelude
3import Prelude
4import Data.Foldable (fold, intercalate)
4import Data.Foldable (fold, intercalate)
@@ -14,8 +14,8 @@ import React.Basic.Hooks (ReactComponent, component, useState)
14import React.Basic.Hooks as React
14import React.Basic.Hooks as React
15import Record.Extra (pick)
15import Record.Extra (pick)
16import Yoga.Helpers ((?||))
16import Yoga.Helpers ((?||))
17−import Yoga.InlineCode.Styles (styles)
17+import Yoga.Layer.Styles (styles)
18−import Yoga.InlineCode.Styles as Styles
18+import Yoga.Layer.Styles as Styles
19import Yoga.Theme.Styles (makeStylesJSS)
19import Yoga.Theme.Styles (makeStylesJSS)
20
20
21type Props
21type Props
@@ -37,7 +37,7 @@ type OptionalProps r
37makeComponent ∷ Effect (ReactComponent Props)
37makeComponent ∷ Effect (ReactComponent Props)
38makeComponent = do
38makeComponent = do
39 useStyles <- makeStylesJSS styles
39 useStyles <- makeStylesJSS styles
40− component "InlineCode" \props@{ className, dispatch } -> React.do
40+ component "Layer" \props@{ className, dispatch } -> React.do
41 value /\ modifyValue <- useState ""
41 value /\ modifyValue <- useState ""
42 classes <- useStyles $ pick props
42 classes <- useStyles $ pick props
43 pure
43 pure
components/src/Yoga/InlineCode/Spec.purs+8−8
@@ -1,4 +1,4 @@
1−module Yoga.InlineCode.Spec where
1+module Yoga.Layer.Spec where
2
2
3import Prelude
3import Prelude
4import Data.Maybe (Maybe(..))
4import Data.Maybe (Maybe(..))
@@ -9,7 +9,7 @@ import Effect.Class (liftEffect)
9import Effect.Ref (Ref)
9import Effect.Ref (Ref)
10import Effect.Ref as Ref
10import Effect.Ref as Ref
11import Justifill (justifill)
11import Justifill (justifill)
12−import React.Basic.Extra.Hooks (useAffReducer)
12+import React.Basic.Extra.Hooks.UseAffReducer (useAffReducer)
13import React.Basic.Hooks (ReactComponent, component, element, useEffect)
13import React.Basic.Hooks (ReactComponent, component, element, useEffect)
14import React.Basic.Hooks as React
14import React.Basic.Hooks as React
15import React.TestingLibrary (describeComponent, fireEventSubmit, renderComponent, typeText)
15import React.TestingLibrary (describeComponent, fireEventSubmit, renderComponent, typeText)
@@ -17,7 +17,7 @@ import Test.Spec (Spec, it)
17import Test.Spec.Assertions (shouldEqual)
17import Test.Spec.Assertions (shouldEqual)
18import Web.Event.Internal.Types (Event)
18import Web.Event.Internal.Types (Event)
19import Web.HTML.HTMLElement (focus)
19import Web.HTML.HTMLElement (focus)
20−import Yoga.InlineCode.Component as InlineCode
20+import Yoga.Layer.Component as Layer
21
21
22foreign import newInputEvent ∷ String -> Event
22foreign import newInputEvent ∷ String -> Event
23
23
@@ -26,7 +26,7 @@ foreign import newChangeEvent ∷ Event
26spec ∷ Spec Unit
26spec ∷ Spec Unit
27spec =
27spec =
28 describeComponent mkWrapper
28 describeComponent mkWrapper
29− "The InlineCode Component" do
29+ "The Layer Component" do
30 it "renders without problems" \wrapper -> do
30 it "renders without problems" \wrapper -> do
31 strRef <- Ref.new "" # liftEffect
31 strRef <- Ref.new "" # liftEffect
32 void $ renderComponent wrapper { strRef }
32 void $ renderComponent wrapper { strRef }
@@ -41,24 +41,24 @@ spec =
41 refContent `shouldEqual` "Heinzelmän"
41 refContent `shouldEqual` "Heinzelmän"
42
42
43data Action
43data Action
44− = InlineCodeAction InlineCode.Action
44+ = LayerAction Layer.Action
45
45
46derive instance eqAction ∷ Eq Action
46derive instance eqAction ∷ Eq Action
47mkReducer ∷ Ref String -> Maybe String -> Action -> Aff (Maybe String)
47mkReducer ∷ Ref String -> Maybe String -> Action -> Aff (Maybe String)
48mkReducer ref state = case _ of
48mkReducer ref state = case _ of
49− InlineCodeAction (InlineCode.CompileAndRunCode s) -> do
49+ LayerAction (Layer.CompileAndRunCode s) -> do
50 Ref.write s ref # liftEffect
50 Ref.write s ref # liftEffect
51 pure state
51 pure state
52
52
53mkWrapper ∷ Effect (ReactComponent { strRef ∷ Ref String })
53mkWrapper ∷ Effect (ReactComponent { strRef ∷ Ref String })
54mkWrapper = do
54mkWrapper = do
55− inlineCode <- InlineCode.makeComponent
55+ inlineCode <- Layer.makeComponent
56 component "Wrapper" \{ strRef } -> React.do
56 component "Wrapper" \{ strRef } -> React.do
57 state /\ dispatch <- useAffReducer Nothing (mkReducer strRef)
57 state /\ dispatch <- useAffReducer Nothing (mkReducer strRef)
58 useEffect state mempty
58 useEffect state mempty
59 pure
59 pure
60 $ element inlineCode
60 $ element inlineCode
61 ( justifill
61 ( justifill
62− { dispatch: dispatch <<< InlineCodeAction
62+ { dispatch: dispatch <<< LayerAction
63 }
63 }
64 )
64 )
components/src/Yoga/InlineCode/Stories.purs+23−25
@@ -1,13 +1,12 @@
1−module Yoga.InlineCode.Stories where
1+module Yoga.Layer.Stories where
2
2
3import Prelude hiding (add)
3import Prelude hiding (add)
4−import Data.Array (intercalate, length)
4+import Data.Array (intercalate)
5import Data.Either (Either(..))
5import Data.Either (Either(..))
6import Data.Maybe (Maybe(..))
6import Data.Maybe (Maybe(..))
7−import Data.String (Pattern(..), split, trim)
7+import Data.String (Pattern(..), split)
8import Data.String.CodeUnits as String
8import Data.String.CodeUnits as String
9import Data.Tuple.Nested ((/\))
9import Data.Tuple.Nested ((/\))
10−import Debug.Trace (spy)
11import Effect (Effect)
10import Effect (Effect)
12import Effect.Aff (Aff)
11import Effect.Aff (Aff)
13import Effect.Class.Console (log)
12import Effect.Class.Console (log)
@@ -16,46 +15,45 @@ import Milkis as M
16import Milkis.Impl.Window (windowFetch)
15import Milkis.Impl.Window (windowFetch)
17import React.Basic (JSX, fragment)
16import React.Basic (JSX, fragment)
18import React.Basic.DOM as R
17import React.Basic.DOM as R
19−import React.Basic.Extra.Hooks (useAffReducer)
18+import React.Basic.Extra.Hooks.UseAffReducer (useAffReducer)
20−import React.Basic.Helpers (jsx)
21import React.Basic.Hooks (ReactComponent, component, element)
19import React.Basic.Hooks (ReactComponent, component, element)
22import React.Basic.Hooks as React
20import React.Basic.Hooks as React
23import Storybook.Decorator.FullScreen (fullScreenDecorator)
21import Storybook.Decorator.FullScreen (fullScreenDecorator)
24import Storybook.React (Storybook, add, addDecorator, storiesOf)
22import Storybook.React (Storybook, add, addDecorator, storiesOf)
25import Yoga.CompileEditor.Component (compileAndRun)
23import Yoga.CompileEditor.Component (compileAndRun)
26−import Yoga.InlineCode.Component (Action(..))
24+import Yoga.Layer.Component (Action(..))
27−import Yoga.InlineCode.Component as InlineCode
25+import Yoga.Layer.Component as Layer
28import Yoga.Modal.Component as Modal
26import Yoga.Modal.Component as Modal
29
27
30stories ∷ Effect Storybook
28stories ∷ Effect Storybook
31stories = do
29stories = do
32− storiesOf "InlineCode" do
30+ storiesOf "Layer" do
33 addDecorator fullScreenDecorator
31 addDecorator fullScreenDecorator
34− add "The InlineCode" InlineCode.makeComponent
32+ add "The Layer" Layer.makeComponent
35 [ ( justifill
33 [ ( justifill
36− { dispatch: \(_ ∷ InlineCode.Action) -> ((log "hi") ∷ Effect Unit)
34+ { dispatch: \(_ ∷ Layer.Action) -> ((log "hi") ∷ Effect Unit)
37 }
35 }
38 )
36 )
39 ]
37 ]
40− add "The InlineCode with some context" mkWrapper
38+ add "The Layer with some context" mkWrapper
41 [ { inside:
39 [ { inside:
42 \inlineCode ->
40 \inlineCode ->
43 [ R.text "hi!"
41 [ R.text "hi!"
44− , element inlineCode (justifill { dispatch: \(_ ∷ InlineCode.Action) -> (log "Hi") ∷ Effect Unit })
42+ , element inlineCode (justifill { dispatch: \(_ ∷ Layer.Action) -> (log "Hi") ∷ Effect Unit })
45 , R.text "hello again!"
43 , R.text "hello again!"
46 ]
44 ]
47 }
45 }
48 ]
46 ]
49− add "The InlineCode with some code" mkWrapper
47+ add "The Layer with some code" mkWrapper
50 [ { inside:
48 [ { inside:
51 \inlineCode ->
49 \inlineCode ->
52 [ R.code_ [ R.text "main = logShow \"" ]
50 [ R.code_ [ R.text "main = logShow \"" ]
53− , element inlineCode (justifill { dispatch: \(_ ∷ InlineCode.Action) -> (log "Hi") ∷ Effect Unit })
51+ , element inlineCode (justifill { dispatch: \(_ ∷ Layer.Action) -> (log "Hi") ∷ Effect Unit })
54 , R.code_ [ R.text "\"" ]
52 , R.code_ [ R.text "\"" ]
55 ]
53 ]
56 }
54 }
57 ]
55 ]
58− add "The InlineCode with some real code" mkRealWrapper
56+ add "The Layer with some real code" mkRealWrapper
59 [ {} ]
57 [ {} ]
60
58
61codePrefix =
59codePrefix =
@@ -71,10 +69,10 @@ renderCode c = intercalate [ R.br {} ] (toJSX <$> lines)
71 toJSX line = [ R.code_ [ R.text line ] ]
69 toJSX line = [ R.code_ [ R.text line ] ]
72 lines = split (Pattern "\n") c
70 lines = split (Pattern "\n") c
73
71
74−mkWrapper ∷ Effect (ReactComponent { inside ∷ ReactComponent InlineCode.Props -> Array JSX })
72+mkWrapper ∷ Effect (ReactComponent { inside ∷ ReactComponent Layer.Props -> Array JSX })
75mkWrapper = do
73mkWrapper = do
76− inlineCode <- InlineCode.makeComponent
74+ inlineCode <- Layer.makeComponent
77− component "InlineCodeWrapper" \{ inside } -> React.do
75+ component "LayerWrapper" \{ inside } -> React.do
78 pure
76 pure
79 $ R.div_ (inside inlineCode)
77 $ R.div_ (inside inlineCode)
80
78
@@ -82,21 +80,21 @@ type State
82 = Maybe Boolean
80 = Maybe Boolean
83
81
84data RealAction
82data RealAction
85− = InlineCodeAction InlineCode.Action
83+ = LayerAction Layer.Action
86 | CloseModal
84 | CloseModal
87
85
88derive instance eqRealAction ∷ Eq RealAction
86derive instance eqRealAction ∷ Eq RealAction
89mkRealWrapper ∷ Effect (ReactComponent {})
87mkRealWrapper ∷ Effect (ReactComponent {})
90mkRealWrapper = do
88mkRealWrapper = do
91− inlineCode <- InlineCode.makeComponent
89+ inlineCode <- Layer.makeComponent
92 modal <- Modal.makeComponent
90 modal <- Modal.makeComponent
93− component "InlineCodeWrapper" \{} -> React.do
91+ component "LayerWrapper" \{} -> React.do
94 state /\ dispatch <- useAffReducer Nothing realReducer
92 state /\ dispatch <- useAffReducer Nothing realReducer
95 pure
93 pure
96 $ R.div_
94 $ R.div_
97 [ R.h2_ [ R.text "Let's log some 'Magick'" ]
95 [ R.h2_ [ R.text "Let's log some 'Magick'" ]
98 , fragment $ renderCode codePrefix
96 , fragment $ renderCode codePrefix
99− , element inlineCode (justifill { dispatch: dispatch <<< InlineCodeAction, width: String.length "Magick" })
97+ , element inlineCode (justifill { dispatch: dispatch <<< LayerAction, width: String.length "Magick" })
100 , fragment $ renderCode codeSuffix
98 , fragment $ renderCode codeSuffix
101 , R.br {}
99 , R.br {}
102 , case state of
100 , case state of
@@ -108,9 +106,9 @@ mkRealWrapper = do
108realReducer ∷ State -> RealAction -> Aff State
106realReducer ∷ State -> RealAction -> Aff State
109realReducer state = case _ of
107realReducer state = case _ of
110 CloseModal -> pure Nothing
108 CloseModal -> pure Nothing
111− InlineCodeAction (CompileAndRunCode code) -> do
109+ LayerAction (CompileAndRunCode code) -> do
112 res <- compileAndRun (M.fetch windowFetch) { code: codePrefix <> code <> codeSuffix }
110 res <- compileAndRun (M.fetch windowFetch) { code: codePrefix <> code <> codeSuffix }
113− (pure <<< Just) case spy "res" res of
111+ (pure <<< pure) case res of
114 Right { stdout }
112 Right { stdout }
115 | String.dropRight 1 stdout == "Magick" -> true
113 | String.dropRight 1 stdout == "Magick" -> true
116 _ -> false
114 _ -> false
components/src/Yoga/InlineCode/Styles.purs+1−1
@@ -1,4 +1,4 @@
1−module Yoga.InlineCode.Styles where
1+module Yoga.Layer.Styles where
2
2
3import Prelude
3import Prelude
4import CSS (GenericFontFamily(..), Selector, TimingFunction(..), animation, background, border, borderBottom, borderBox, borderRadius, boxSizing, color, darken, display, element, focus, fontFamily, fontSize, fromString, inlineBlock, iterationCount, keyframes, lighten, lineHeight, nil, padding, sec, solid, transform, transition, unitless, width, (!*), (!+), (&), (?))
4import CSS (GenericFontFamily(..), Selector, TimingFunction(..), animation, background, border, borderBottom, borderBox, borderRadius, boxSizing, color, darken, display, element, focus, fontFamily, fontSize, fromString, inlineBlock, iterationCount, keyframes, lighten, lineHeight, nil, padding, sec, solid, transform, transition, unitless, width, (!*), (!+), (&), (?))
components/src/Yoga/Modal/Component.purs+2
@@ -11,6 +11,7 @@ import React.Basic.DOM as R
11import React.Basic.DOM.Events (stopPropagation)
11import React.Basic.DOM.Events (stopPropagation)
12import React.Basic.DOM.SVG as SVG
12import React.Basic.DOM.SVG as SVG
13import React.Basic.Events (EventHandler, handler, handler_)
13import React.Basic.Events (EventHandler, handler, handler_)
14+import React.Basic.Extra.Hooks.UseKeyUp (useKeyUp)
14import React.Basic.Helpers (jsx)
15import React.Basic.Helpers (jsx)
15import React.Basic.Hooks (ReactComponent, component)
16import React.Basic.Hooks (ReactComponent, component)
16import React.Basic.Hooks as React
17import React.Basic.Hooks as React
@@ -42,6 +43,7 @@ makeComponent = do
42 useStyles <- makeStylesJSS Style.styles
43 useStyles <- makeStylesJSS Style.styles
43 component "Modal" \props -> React.do
44 component "Modal" \props -> React.do
44 cs <- useStyles (pick props)
45 cs <- useStyles (pick props)
46+ useKeyUp 27 $ props.onClose ?|| pure unit
45 let
47 let
46 darkOverlay =
48 darkOverlay =
47 jsx imposter
49 jsx imposter
components/src/Yoga/Modal/Styles.purs+1−1
@@ -44,7 +44,7 @@ styles =
44 boxShadow nil nil (3.5 # rem) (Color.rgba 0 0 0 0.5)
44 boxShadow nil nil (3.5 # rem) (Color.rgba 0 0 0 0.5)
45 borderRadius boxBorderRadius boxBorderRadius boxBorderRadius boxBorderRadius
45 borderRadius boxBorderRadius boxBorderRadius boxBorderRadius boxBorderRadius
46 , closeIcon:
46 , closeIcon:
47− { fill: toHexString theme.backgroundColour
47+ { fill: theme.textColour
48 , width: "calc(0.8em * var(--ratio))"
48 , width: "calc(0.8em * var(--ratio))"
49 , height: "calc(0.8em * var(--ratio))"
49 , height: "calc(0.8em * var(--ratio))"
50 , margin: 0
50 , margin: 0