git.iko.soy/rowtype-yoga/psfp
on master help sign in
Add close with escape
commit88d4be0f903dfcc9d6cdef7edb719aa3eb1106d8 authorMark Eibes <mark.eibes@gmail.com> dateTue 31 Mar 2020, 21:16 (7 years ago) parent3664c84
10 files changed+86−40
components/src/React/Basic/Extra/Hooks/UseAffReducer.purs+1−1 components/src/React/Basic/Extra/Hooks/UseKeyUp.js+3 components/src/React/Basic/Extra/Hooks/UseKeyUp.purs+39 components/src/React/Basic/Extra/Hooks/UseKeyUp.ts+4 components/src/Yoga/InlineCode/Component.purs+4−4 components/src/Yoga/InlineCode/Spec.purs+8−8 components/src/Yoga/InlineCode/Stories.purs+23−25 components/src/Yoga/InlineCode/Styles.purs+1−1 components/src/Yoga/Modal/Component.purs+2 components/src/Yoga/Modal/Styles.purs+1−1
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
22
33import Prelude
44import 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
22
33import Prelude
44import Data.Foldable (fold, intercalate)
@@ -14,8 +14,8 @@ import React.Basic.Hooks (ReactComponent, component, useState)
1414import React.Basic.Hooks as React
1515import Record.Extra (pick)
1616import Yoga.Helpers ((?||))
17−import Yoga.InlineCode.Styles (styles)
18−import Yoga.InlineCode.Styles as Styles
17+import Yoga.Layer.Styles (styles)
18+import Yoga.Layer.Styles as Styles
1919import Yoga.Theme.Styles (makeStylesJSS)
2020
2121type Props
@@ -37,7 +37,7 @@ type OptionalProps r
3737makeComponent ∷ Effect (ReactComponent Props)
3838makeComponent = do
3939 useStyles <- makeStylesJSS styles
40− component "InlineCode" \props@{ className, dispatch } -> React.do
40+ component "Layer" \props@{ className, dispatch } -> React.do
4141 value /\ modifyValue <- useState ""
4242 classes <- useStyles $ pick props
4343 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
22
33import Prelude
44import Data.Maybe (Maybe(..))
@@ -9,7 +9,7 @@ import Effect.Class (liftEffect)
99import Effect.Ref (Ref)
1010import Effect.Ref as Ref
1111import Justifill (justifill)
12−import React.Basic.Extra.Hooks (useAffReducer)
12+import React.Basic.Extra.Hooks.UseAffReducer (useAffReducer)
1313import React.Basic.Hooks (ReactComponent, component, element, useEffect)
1414import React.Basic.Hooks as React
1515import React.TestingLibrary (describeComponent, fireEventSubmit, renderComponent, typeText)
@@ -17,7 +17,7 @@ import Test.Spec (Spec, it)
1717import Test.Spec.Assertions (shouldEqual)
1818import Web.Event.Internal.Types (Event)
1919import Web.HTML.HTMLElement (focus)
20−import Yoga.InlineCode.Component as InlineCode
20+import Yoga.Layer.Component as Layer
2121
2222foreign import newInputEvent ∷ String -> Event
2323
@@ -26,7 +26,7 @@ foreign import newChangeEvent ∷ Event
2626spec ∷ Spec Unit
2727spec =
2828 describeComponent mkWrapper
29− "The InlineCode Component" do
29+ "The Layer Component" do
3030 it "renders without problems" \wrapper -> do
3131 strRef <- Ref.new "" # liftEffect
3232 void $ renderComponent wrapper { strRef }
@@ -41,24 +41,24 @@ spec =
4141 refContent `shouldEqual` "Heinzelmän"
4242
4343data Action
44− = InlineCodeAction InlineCode.Action
44+ = LayerAction Layer.Action
4545
4646derive instance eqAction ∷ Eq Action
4747mkReducer ∷ Ref String -> Maybe String -> Action -> Aff (Maybe String)
4848mkReducer ref state = case _ of
49− InlineCodeAction (InlineCode.CompileAndRunCode s) -> do
49+ LayerAction (Layer.CompileAndRunCode s) -> do
5050 Ref.write s ref # liftEffect
5151 pure state
5252
5353mkWrapper ∷ Effect (ReactComponent { strRef ∷ Ref String })
5454mkWrapper = do
55− inlineCode <- InlineCode.makeComponent
55+ inlineCode <- Layer.makeComponent
5656 component "Wrapper" \{ strRef } -> React.do
5757 state /\ dispatch <- useAffReducer Nothing (mkReducer strRef)
5858 useEffect state mempty
5959 pure
6060 $ element inlineCode
6161 ( justifill
62− { dispatch: dispatch <<< InlineCodeAction
62+ { dispatch: dispatch <<< LayerAction
6363 }
6464 )
components/src/Yoga/InlineCode/Stories.purs+23−25
@@ -1,13 +1,12 @@
1−module Yoga.InlineCode.Stories where
1+module Yoga.Layer.Stories where
22
33import Prelude hiding (add)
4−import Data.Array (intercalate, length)
4+import Data.Array (intercalate)
55import Data.Either (Either(..))
66import Data.Maybe (Maybe(..))
7−import Data.String (Pattern(..), split, trim)
7+import Data.String (Pattern(..), split)
88import Data.String.CodeUnits as String
99import Data.Tuple.Nested ((/\))
10−import Debug.Trace (spy)
1110import Effect (Effect)
1211import Effect.Aff (Aff)
1312import Effect.Class.Console (log)
@@ -16,46 +15,45 @@ import Milkis as M
1615import Milkis.Impl.Window (windowFetch)
1716import React.Basic (JSX, fragment)
1817import React.Basic.DOM as R
19−import React.Basic.Extra.Hooks (useAffReducer)
20−import React.Basic.Helpers (jsx)
18+import React.Basic.Extra.Hooks.UseAffReducer (useAffReducer)
2119import React.Basic.Hooks (ReactComponent, component, element)
2220import React.Basic.Hooks as React
2321import Storybook.Decorator.FullScreen (fullScreenDecorator)
2422import Storybook.React (Storybook, add, addDecorator, storiesOf)
2523import Yoga.CompileEditor.Component (compileAndRun)
26−import Yoga.InlineCode.Component (Action(..))
27−import Yoga.InlineCode.Component as InlineCode
24+import Yoga.Layer.Component (Action(..))
25+import Yoga.Layer.Component as Layer
2826import Yoga.Modal.Component as Modal
2927
3028stories ∷ Effect Storybook
3129stories = do
32− storiesOf "InlineCode" do
30+ storiesOf "Layer" do
3331 addDecorator fullScreenDecorator
34− add "The InlineCode" InlineCode.makeComponent
32+ add "The Layer" Layer.makeComponent
3533 [ ( justifill
36− { dispatch: \(_ ∷ InlineCode.Action) -> ((log "hi") ∷ Effect Unit)
34+ { dispatch: \(_ ∷ Layer.Action) -> ((log "hi") ∷ Effect Unit)
3735 }
3836 )
3937 ]
40− add "The InlineCode with some context" mkWrapper
38+ add "The Layer with some context" mkWrapper
4139 [ { inside:
4240 \inlineCode ->
4341 [ 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 })
4543 , R.text "hello again!"
4644 ]
4745 }
4846 ]
49− add "The InlineCode with some code" mkWrapper
47+ add "The Layer with some code" mkWrapper
5048 [ { inside:
5149 \inlineCode ->
5250 [ 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 })
5452 , R.code_ [ R.text "\"" ]
5553 ]
5654 }
5755 ]
58− add "The InlineCode with some real code" mkRealWrapper
56+ add "The Layer with some real code" mkRealWrapper
5957 [ {} ]
6058
6159codePrefix =
@@ -71,10 +69,10 @@ renderCode c = intercalate [ R.br {} ] (toJSX <$> lines)
7169 toJSX line = [ R.code_ [ R.text line ] ]
7270 lines = split (Pattern "\n") c
7371
74−mkWrapper ∷ Effect (ReactComponent { inside ∷ ReactComponent InlineCode.Props -> Array JSX })
72+mkWrapper ∷ Effect (ReactComponent { inside ∷ ReactComponent Layer.Props -> Array JSX })
7573mkWrapper = do
76− inlineCode <- InlineCode.makeComponent
77− component "InlineCodeWrapper" \{ inside } -> React.do
74+ inlineCode <- Layer.makeComponent
75+ component "LayerWrapper" \{ inside } -> React.do
7876 pure
7977 $ R.div_ (inside inlineCode)
8078
@@ -82,21 +80,21 @@ type State
8280 = Maybe Boolean
8381
8482data RealAction
85− = InlineCodeAction InlineCode.Action
83+ = LayerAction Layer.Action
8684 | CloseModal
8785
8886derive instance eqRealAction ∷ Eq RealAction
8987mkRealWrapper ∷ Effect (ReactComponent {})
9088mkRealWrapper = do
91− inlineCode <- InlineCode.makeComponent
89+ inlineCode <- Layer.makeComponent
9290 modal <- Modal.makeComponent
93− component "InlineCodeWrapper" \{} -> React.do
91+ component "LayerWrapper" \{} -> React.do
9492 state /\ dispatch <- useAffReducer Nothing realReducer
9593 pure
9694 $ R.div_
9795 [ R.h2_ [ R.text "Let's log some 'Magick'" ]
9896 , 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" })
10098 , fragment $ renderCode codeSuffix
10199 , R.br {}
102100 , case state of
@@ -108,9 +106,9 @@ mkRealWrapper = do
108106realReducer ∷ State -> RealAction -> Aff State
109107realReducer state = case _ of
110108 CloseModal -> pure Nothing
111− InlineCodeAction (CompileAndRunCode code) -> do
109+ LayerAction (CompileAndRunCode code) -> do
112110 res <- compileAndRun (M.fetch windowFetch) { code: codePrefix <> code <> codeSuffix }
113− (pure <<< Just) case spy "res" res of
111+ (pure <<< pure) case res of
114112 Right { stdout }
115113 | String.dropRight 1 stdout == "Magick" -> true
116114 _ -> 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
22
33import Prelude
44import 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
1111import React.Basic.DOM.Events (stopPropagation)
1212import React.Basic.DOM.SVG as SVG
1313import React.Basic.Events (EventHandler, handler, handler_)
14+import React.Basic.Extra.Hooks.UseKeyUp (useKeyUp)
1415import React.Basic.Helpers (jsx)
1516import React.Basic.Hooks (ReactComponent, component)
1617import React.Basic.Hooks as React
@@ -42,6 +43,7 @@ makeComponent = do
4243 useStyles <- makeStylesJSS Style.styles
4344 component "Modal" \props -> React.do
4445 cs <- useStyles (pick props)
46+ useKeyUp 27 $ props.onClose ?|| pure unit
4547 let
4648 darkOverlay =
4749 jsx imposter
components/src/Yoga/Modal/Styles.purs+1−1
@@ -44,7 +44,7 @@ styles =
4444 boxShadow nil nil (3.5 # rem) (Color.rgba 0 0 0 0.5)
4545 borderRadius boxBorderRadius boxBorderRadius boxBorderRadius boxBorderRadius
4646 , closeIcon:
47− { fill: toHexString theme.backgroundColour
47+ { fill: theme.textColour
4848 , width: "calc(0.8em * var(--ratio))"
4949 , height: "calc(0.8em * var(--ratio))"
5050 , margin: 0