diff --git a/components/package.json b/components/package.json index 08e812f..e09592a 100644 --- a/components/package.json +++ b/components/package.json @@ -58,17 +58,14 @@ "monaco-editor": "^0.20.0", "monaco-editor-webpack-plugin": "^1.8.2", "npm-run-all": "^4.1.5", - "purescript": "^0.13.8", - "purescript-psa": "^0.7.3", - "purs-loader": "^3.6.0", - "purty": "^6.2.0", + "purescript": "^0.14.0", "react": "^16.13.1", "react-dom": "^16.13.1", "react-hot-loader": "^4.12.21", "react-monaco-editor": "^0.36.0", "react-svg-loader": "^3.0.3", "smoothscroll-polyfill": "^0.4.4", - "spago": "^0.15.2", + "spago": "^0.19.1", "typescript": "^3.7.5", "webpack": "^4.41.0", "webpack-cli": "^3.3.6", @@ -76,4 +73,4 @@ "webpack-merge": "^4.2.2", "wrappy": "^1.0.2" } -} +} \ No newline at end of file diff --git a/components/packages.dhall b/components/packages.dhall index f6b088f..bd5d151 100644 --- a/components/packages.dhall +++ b/components/packages.dhall @@ -116,20 +116,14 @@ let additions = } ------------------------------- -} - - let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20201223/packages.dhall sha256:a1a8b096175f841c4fef64c9b605fb0d691229241fd2233f6cf46e213de8a185 + https://github.com/purescript/package-sets/releases/download/psc-0.14.0-20210318/packages.dhall sha256:98bbacd65191cef354ecbafa1610be13e183ee130491ab9c0ef6e3d606f781b5 let overrides = { css = upstream.css // { repo = "https://github.com/i-am-the-slime/purescript-css.git" - , version = "8ea0bab17c268d9c62a09892d7ba231dcbe6308b" - } - , react-testing-library = - upstream.react-testing-library - // { version = "main" + , version = "39c9a9d4344e97e561eeac26eb2ce065c12bfcb1" } } @@ -153,6 +147,8 @@ let additions = } , yoga-components = ../components/spago.dhall as Location , ry-blocks = ../../ry-blocks/spago.dhall as Location + , react-testing-library = + ../../purescript-react-testing-library/spago.dhall as Location } in upstream // overrides // additions diff --git a/components/spago.dhall b/components/spago.dhall index 9ef8ca1..9723c08 100644 --- a/components/spago.dhall +++ b/components/spago.dhall @@ -18,10 +18,8 @@ You can edit this file as you like. , "react-basic-dom" , "react-basic-hooks" , "react-testing-library" - , "record-extra" , "refs" , "ry-blocks" - , "simple-json" , "spec-discovery" , "string-parsers" , "untagged-union" diff --git a/components/src/React/Basic/Hooks/Spring/Stories.purs b/components/src/React/Basic/Hooks/Spring/Stories.purs index 0e613cb..ccf5438 100644 --- a/components/src/React/Basic/Hooks/Spring/Stories.purs +++ b/components/src/React/Basic/Hooks/Spring/Stories.purs @@ -1,10 +1,7 @@ module React.Basic.Hooks.Spring.Stories where import Prelude hiding (add) - import CSS (backgroundColor, height, position, relative, vh, vw, width) -import Data.Generic.Rep (class Generic) -import Data.Generic.Rep.Eq (genericEq) import Data.Int (pow) import Data.Time.Duration (Seconds(..), convertDuration) import Data.Tuple.Nested ((/\)) @@ -143,9 +140,7 @@ data Countdown | CountdownRunning Int | CountdownFinished -derive instance genericCountdown ∷ Generic Countdown _ -instance eqCountdown ∷ Eq Countdown where - eq = genericEq +derive instance eqCountdown ∷ Eq Countdown mkCountdown ∷ Effect (ReactComponent {}) mkCountdown = do diff --git a/components/src/Simple/JSON.js b/components/src/Simple/JSON.js new file mode 100644 index 0000000..811a42c --- /dev/null +++ b/components/src/Simple/JSON.js @@ -0,0 +1,7 @@ +exports._parseJSON = JSON.parse; + +exports._undefined = undefined; + +exports.unsafeStringify = function (x) { + return JSON.stringify(x); +}; \ No newline at end of file diff --git a/components/src/Simple/JSON.purs b/components/src/Simple/JSON.purs new file mode 100644 index 0000000..f92f3f0 --- /dev/null +++ b/components/src/Simple/JSON.purs @@ -0,0 +1,421 @@ +module Simple.JSON + ( E + , readJSON + , readJSON' + , readJSON_ + , writeJSON + , write + , read + , read' + , read_ + , parseJSON + , undefined + , class ReadForeign + , readImpl + , class ReadForeignFields + , getFields + , class ReadForeignVariant + , readVariantImpl + , class WriteForeign + , writeImpl + , class WriteForeignFields + , writeImplFields + , class WriteForeignVariant + , writeVariantImpl + ) where + +import Prelude +import Control.Alt ((<|>)) +import Control.Monad.Except (ExceptT(..), except, runExcept, runExceptT, withExcept) +import Data.Array.NonEmpty (NonEmptyArray, fromArray, toArray) +import Data.Bifunctor (lmap) +import Data.Either (Either(..), hush, note) +import Data.Identity (Identity(..)) +import Data.List.NonEmpty (singleton) +import Data.Maybe (Maybe(..), maybe) +import Data.Nullable (Nullable, toMaybe, toNullable) +import Data.Symbol (class IsSymbol, reflectSymbol) +import Data.Traversable (sequence, traverse) +import Data.TraversableWithIndex (traverseWithIndex) +import Data.Variant (Variant, inj, on) +import Effect.Exception (message, try) +import Effect.Uncurried as EU +import Effect.Unsafe (unsafePerformEffect) +import Foreign (F, Foreign, ForeignError(..), MultipleErrors, fail, isNull, isUndefined, readArray, readBoolean, readChar, readInt, readNull, readNumber, readString, tagOf, unsafeFromForeign, unsafeToForeign) +import Foreign.Index (readProp) +import Foreign.Object (Object) +import Foreign.Object as Object +import Partial.Unsafe (unsafeCrashWith) +import Prim.Row as Row +import Prim.RowList (class RowToList, Cons, Nil, RowList) +import Record (get) +import Record.Builder (Builder) +import Record.Builder as Builder +import Type.Prelude (Proxy(..)) + +-- | An alias for the Either result of decoding +type E a = + Either MultipleErrors a + +-- | Read a JSON string to a type `a` while returning a `MultipleErrors` if the +-- | parsing failed. +readJSON ∷ + ∀ a. + ReadForeign a => + String -> + E a +readJSON = runExcept <<< (readImpl <=< parseJSON) + +-- | Read a JSON string to a type `a` using `F a`. Useful with record types. +readJSON' ∷ + ∀ a. + ReadForeign a => + String -> + F a +readJSON' = readImpl <=< parseJSON + +-- | Read a JSON string to a type `a` while returning `Nothing` if the parsing +-- | failed. +readJSON_ ∷ + ∀ a. + ReadForeign a => + String -> + Maybe a +readJSON_ = hush <<< readJSON + +-- | Write a JSON string from a type `a`. +writeJSON ∷ + ∀ a. + WriteForeign a => + a -> + String +writeJSON = unsafeStringify <<< writeImpl + +write ∷ + ∀ a. + WriteForeign a => + a -> + Foreign +write = writeImpl + +-- | Read a Foreign value to a type +read ∷ + ∀ a. + ReadForeign a => + Foreign -> + E a +read = runExcept <<< readImpl + +-- | Read a value of any type as Foreign to a type +readAsForeign ∷ + ∀ a b. + ReadForeign a => + b -> + E a +readAsForeign = read <<< unsafeToForeign + +read' ∷ + ∀ a. + ReadForeign a => + Foreign -> + F a +read' = readImpl + +-- | Read a Foreign value to a type, as a Maybe of type +read_ ∷ + ∀ a. + ReadForeign a => + Foreign -> + Maybe a +read_ = hush <<< read + +foreign import _parseJSON ∷ EU.EffectFn1 String Foreign + +parseJSON ∷ String -> F Foreign +parseJSON = + ExceptT + <<< Identity + <<< lmap (pure <<< ForeignError <<< message) + <<< runPure + <<< try + <<< EU.runEffectFn1 _parseJSON + where + -- Nate Faubion: "It uses unsafePerformEffect because that’s the only way to catch exceptions and still use the builtin json decoder" + runPure = unsafePerformEffect + +foreign import _undefined ∷ Foreign + +undefined ∷ Foreign +undefined = _undefined + +foreign import unsafeStringify ∷ ∀ a. a -> String + +-- | A class for reading foreign values to a type +class ReadForeign a where + readImpl ∷ Foreign -> F a + +instance readForeign ∷ ReadForeign Foreign where + readImpl = pure + +instance readChar ∷ ReadForeign Char where + readImpl = readChar + +instance readNumber ∷ ReadForeign Number where + readImpl = readNumber + +instance readInt ∷ ReadForeign Int where + readImpl = readInt + +instance readString ∷ ReadForeign String where + readImpl = readString + +instance readBoolean ∷ ReadForeign Boolean where + readImpl = readBoolean + +instance readArray ∷ ReadForeign a => ReadForeign (Array a) where + readImpl = traverseWithIndex readAtIdx <=< readArray + where + readAtIdx i f = withExcept (map (ErrorAtIndex i)) (readImpl f) + +instance readMaybe ∷ ReadForeign a => ReadForeign (Maybe a) where + readImpl = readNullOrUndefined readImpl + where + readNullOrUndefined _ value + | isNull value || isUndefined value = pure Nothing + + readNullOrUndefined f value = Just <$> f value + +instance readNullable ∷ ReadForeign a => ReadForeign (Nullable a) where + readImpl o = + withExcept (map reformat) + $ map toNullable + <$> traverse readImpl + =<< readNull o + where + reformat error = case error of + TypeMismatch inner other -> TypeMismatch ("Nullable " <> inner) other + _ -> error + +instance readObject ∷ ReadForeign a => ReadForeign (Object.Object a) where + readImpl = sequence <<< Object.mapWithKey (const readImpl) <=< readObject' + where + readObject' ∷ Foreign -> F (Object Foreign) + readObject' value + | tagOf value == "Object" = pure $ unsafeFromForeign value + | otherwise = fail $ TypeMismatch "Object" (tagOf value) + +instance readRecord ∷ + ( RowToList fields fieldList + , ReadForeignFields fieldList () fields + ) => + ReadForeign (Record fields) where + readImpl o = flip Builder.build {} <$> getFields fieldListP o + where + fieldListP = Proxy ∷ Proxy fieldList + +-- | A class for reading foreign values from properties +class ReadForeignFields (xs ∷ RowList Type) (from ∷ Row Type) (to ∷ Row Type) | xs -> from to where + getFields ∷ + Proxy xs -> + Foreign -> + F (Builder (Record from) (Record to)) + +instance readFieldsCons ∷ + ( IsSymbol name + , ReadForeign ty + , ReadForeignFields tail from from' + , Row.Lacks name from' + , Row.Cons name ty from' to + ) => + ReadForeignFields (Cons name ty tail) from to where + getFields _ obj = (compose <$> first) `exceptTApply` rest + where + first = do + value <- withExcept' (readImpl =<< readProp name obj) + pure $ Builder.insert nameP value + + rest = getFields tailP obj + + nameP = Proxy ∷ Proxy name + + tailP = Proxy ∷ Proxy tail + + name = reflectSymbol nameP + + withExcept' = withExcept <<< map $ ErrorAtProperty name + +exceptTApply ∷ ∀ a b e m. Semigroup e => Applicative m => ExceptT e m (a -> b) -> ExceptT e m a -> ExceptT e m b +exceptTApply fun a = + ExceptT $ applyEither + <$> runExceptT fun + <*> runExceptT a + +applyEither ∷ ∀ e a b. Semigroup e => Either e (a -> b) -> Either e a -> Either e b +applyEither (Left e) (Right _) = Left e + +applyEither (Left e1) (Left e2) = Left (e1 <> e2) + +applyEither (Right _) (Left e) = Left e + +applyEither (Right fun) (Right a) = Right (fun a) + +instance readFieldsNil ∷ + ReadForeignFields Nil () () where + getFields _ _ = pure identity + +instance readForeignVariant ∷ + ( RowToList variants rl + , ReadForeignVariant rl variants + ) => + ReadForeign (Variant variants) where + readImpl o = readVariantImpl (Proxy ∷ Proxy rl) o + +class ReadForeignVariant (xs ∷ RowList Type) (row ∷ Row Type) | xs -> row where + readVariantImpl ∷ + Proxy xs -> + Foreign -> + F (Variant row) + +instance readVariantNil ∷ + ReadForeignVariant Nil trash where + readVariantImpl _ _ = fail $ ForeignError "Unable to match any variant member." + +instance readVariantCons ∷ + ( IsSymbol name + , ReadForeign ty + , Row.Cons name ty trash row + , ReadForeignVariant tail row + ) => + ReadForeignVariant (Cons name ty tail) row where + readVariantImpl _ o = + do + obj ∷ { type ∷ String, value ∷ Foreign } <- readImpl o + if obj.type == name then do + value ∷ ty <- readImpl obj.value + pure $ inj namep value + else + (fail <<< ForeignError $ "Did not match variant tag " <> name) + <|> readVariantImpl (Proxy ∷ Proxy tail) o + where + namep = Proxy ∷ Proxy name + + name = reflectSymbol namep + +-- -- | A class for writing a value into JSON +-- -- | need to do this intelligently using Foreign probably, because of null and undefined whatever +class WriteForeign a where + writeImpl ∷ a -> Foreign + +instance writeForeignForeign ∷ WriteForeign Foreign where + writeImpl = identity + +instance writeForeignString ∷ WriteForeign String where + writeImpl = unsafeToForeign + +instance writeForeignInt ∷ WriteForeign Int where + writeImpl = unsafeToForeign + +instance writeForeignChar ∷ WriteForeign Char where + writeImpl = unsafeToForeign + +instance writeForeignNumber ∷ WriteForeign Number where + writeImpl = unsafeToForeign + +instance writeForeignBoolean ∷ WriteForeign Boolean where + writeImpl = unsafeToForeign + +instance writeForeignArray ∷ WriteForeign a => WriteForeign (Array a) where + writeImpl xs = unsafeToForeign $ writeImpl <$> xs + +instance writeForeignMaybe ∷ WriteForeign a => WriteForeign (Maybe a) where + writeImpl = maybe undefined writeImpl + +instance writeForeignNullable ∷ WriteForeign a => WriteForeign (Nullable a) where + writeImpl = maybe (unsafeToForeign $ toNullable Nothing) writeImpl <<< toMaybe + +instance writeForeignObject ∷ WriteForeign a => WriteForeign (Object.Object a) where + writeImpl = unsafeToForeign <<< Object.mapWithKey (const writeImpl) + +instance recordWriteForeign ∷ + ( RowToList row rl + , WriteForeignFields rl row () to + ) => + WriteForeign (Record row) where + writeImpl rec = unsafeToForeign $ Builder.build steps {} + where + rlp = Proxy ∷ Proxy rl + + steps = writeImplFields rlp rec + +class WriteForeignFields (rl ∷ RowList Type) row (from ∷ Row Type) (to ∷ Row Type) | rl -> row from to where + writeImplFields ∷ ∀ g. g rl -> Record row -> Builder (Record from) (Record to) + +instance consWriteForeignFields ∷ + ( IsSymbol name + , WriteForeign ty + , WriteForeignFields tail row from from' + , Row.Cons name ty whatever row + , Row.Lacks name from' + , Row.Cons name Foreign from' to + ) => + WriteForeignFields (Cons name ty tail) row from to where + writeImplFields _ rec = result + where + namep = Proxy ∷ Proxy name + + value = writeImpl $ get namep rec + + tailp = Proxy ∷ Proxy tail + + rest = writeImplFields tailp rec + + result = Builder.insert namep value <<< rest + +instance nilWriteForeignFields ∷ + WriteForeignFields Nil row () () where + writeImplFields _ _ = identity + +instance writeForeignVariant ∷ + ( RowToList row rl + , WriteForeignVariant rl row + ) => + WriteForeign (Variant row) where + writeImpl variant = writeVariantImpl (Proxy ∷ Proxy rl) variant + +class WriteForeignVariant (rl ∷ RowList Type) (row ∷ Row Type) | rl -> row where + writeVariantImpl ∷ ∀ g. g rl -> Variant row -> Foreign + +instance nilWriteForeignVariant ∷ + WriteForeignVariant Nil () where + -- a PureScript-defined variant cannot reach this path, but a JavaScript FFI one could. + writeVariantImpl _ _ = unsafeCrashWith "Variant was not able to be writen row WriteForeign." + +instance consWriteForeignVariant ∷ + ( IsSymbol name + , WriteForeign ty + , Row.Cons name ty subRow row + , WriteForeignVariant tail subRow + ) => + WriteForeignVariant (Cons name ty tail) row where + writeVariantImpl _ variant = + on + namep + writeVariant + (writeVariantImpl (Proxy ∷ Proxy tail)) + variant + where + namep = Proxy ∷ Proxy name + + writeVariant value = + unsafeToForeign + { type: reflectSymbol namep + , value: writeImpl value + } + +instance readForeignNEArray ∷ ReadForeign a => ReadForeign (NonEmptyArray a) where + readImpl f = do + raw ∷ Array a <- readImpl f + except $ note (singleton $ ForeignError "Nonempty array expected, got empty array") $ fromArray raw + +instance writeForeignNEArray ∷ WriteForeign a => WriteForeign (NonEmptyArray a) where + writeImpl a = writeImpl <<< toArray $ a diff --git a/components/src/Yoga/Centre/Component.purs b/components/src/Yoga/Centre/Component.purs index 39699b6..2d65ece 100644 --- a/components/src/Yoga/Centre/Component.purs +++ b/components/src/Yoga/Centre/Component.purs @@ -1,7 +1,7 @@ module Yoga.Centre.Component where import Prelude -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Maybe (Maybe) import Effect (Effect) import React.Basic (JSX) @@ -12,17 +12,17 @@ import Record.Extra (pick) import Yoga.Centre.Styles as Style import Yoga.Theme.Styles (makeStylesJSS) -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps Style.PropsR +type PropsR = + OptionalProps Style.PropsR -type OptionalProps r - = ( kids ∷ Array JSX - , className ∷ Maybe String - | r - ) +type OptionalProps r = + ( kids ∷ Array JSX + , className ∷ Maybe String + | r + ) makeComponent ∷ Effect (ReactComponent Props) makeComponent = do diff --git a/components/src/Yoga/Cluster/Component.purs b/components/src/Yoga/Cluster/Component.purs index 1a9e7a9..f85f094 100644 --- a/components/src/Yoga/Cluster/Component.purs +++ b/components/src/Yoga/Cluster/Component.purs @@ -1,8 +1,7 @@ module Yoga.Cluster.Component where import Prelude - -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Maybe (Maybe) import Effect (Effect) import React.Basic (JSX) @@ -13,17 +12,17 @@ import Record.Extra (pick) import Yoga.Cluster.Styles as Style import Yoga.Theme.Styles (makeStylesJSS) -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps Style.PropsR +type PropsR = + OptionalProps Style.PropsR -type OptionalProps r - = ( kids ∷ Array JSX - , className ∷ Maybe String - | r - ) +type OptionalProps r = + ( kids ∷ Array JSX + , className ∷ Maybe String + | r + ) makeComponent ∷ Effect (ReactComponent Props) makeComponent = do diff --git a/components/src/Yoga/Cover/Component.purs b/components/src/Yoga/Cover/Component.purs index 6877a3e..114f8ba 100644 --- a/components/src/Yoga/Cover/Component.purs +++ b/components/src/Yoga/Cover/Component.purs @@ -1,7 +1,7 @@ module Yoga.Cover.Component where import Prelude -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Array as Array import Data.Maybe (Maybe) import Effect (Effect) @@ -12,19 +12,19 @@ import React.Basic.Hooks as React import Yoga.Cover.Styles as Cover import Yoga.Theme.Styles (makeStylesJSS) -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps () +type PropsR = + OptionalProps () -type OptionalProps r - = ( header ∷ Maybe JSX - , footer ∷ Maybe JSX - , kids ∷ Array JSX - , className ∷ Maybe String - | r - ) +type OptionalProps r = + ( header ∷ Maybe JSX + , footer ∷ Maybe JSX + , kids ∷ Array JSX + , className ∷ Maybe String + | r + ) makeComponent ∷ Effect (ReactComponent Props) makeComponent = do diff --git a/components/src/Yoga/DOM/Hook.purs b/components/src/Yoga/DOM/Hook.purs index 82e5295..8f3e0e6 100644 --- a/components/src/Yoga/DOM/Hook.purs +++ b/components/src/Yoga/DOM/Hook.purs @@ -7,7 +7,6 @@ import Data.Nullable (Nullable) import Data.Nullable as Nullable import Data.Traversable (for_) import Data.Tuple.Nested (type (/\)) -import Debug.Trace (spy, traceM) import React.Basic (Ref) import React.Basic.Hooks (Hook, UseLayoutEffect, UseRef, UseState, coerceHook, readRefMaybe, useLayoutEffect, useRef, useState, (/\)) import React.Basic.Hooks as React diff --git a/components/src/Yoga/Imposter/Component.purs b/components/src/Yoga/Imposter/Component.purs index 9a91c16..bd9be35 100644 --- a/components/src/Yoga/Imposter/Component.purs +++ b/components/src/Yoga/Imposter/Component.purs @@ -1,7 +1,7 @@ module Yoga.Imposter.Component where import Prelude -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Maybe (Maybe) import Effect (Effect) import React.Basic (JSX) @@ -16,19 +16,19 @@ import Yoga.Helpers (ifJustFalse, (?||)) import Yoga.Imposter.Styles as Style import Yoga.Theme.Styles (makeStylesJSS) -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps Style.PropsR +type PropsR = + OptionalProps Style.PropsR -type OptionalProps r - = ( kids ∷ Array JSX - , className ∷ Maybe String - , onClick ∷ Maybe EventHandler - , style ∷ Maybe CSS - | r - ) +type OptionalProps r = + ( kids ∷ Array JSX + , className ∷ Maybe String + , onClick ∷ Maybe EventHandler + , style ∷ Maybe CSS + | r + ) makeComponent ∷ Effect (ReactComponent Props) makeComponent = do diff --git a/components/src/Yoga/JSS.purs b/components/src/Yoga/JSS.purs index 4566565..c72e675 100644 --- a/components/src/Yoga/JSS.purs +++ b/components/src/Yoga/JSS.purs @@ -33,19 +33,19 @@ jssClasses ∷ ({ | theme } -> { | row }) -> JSSClasses theme props to jssClasses f = JSSClasses f' where - f' theme = built - where - rec = f theme + f' theme = built + where + rec = f theme - built ∷ Record to - built = Builder.build builder {} + built ∷ Record to + built = Builder.build builder {} - rlp = RL.RLProxy ∷ RL.RLProxy rowRL + rlp = RL.RLProxy ∷ RL.RLProxy rowRL - propsy = Proxy ∷ Proxy props + propsy = Proxy ∷ Proxy props - builder ∷ Builder.Builder (Record ()) (Record to) - builder = jssifyFields propsy rlp rec + builder ∷ Builder.Builder (Record ()) (Record to) + builder = jssifyFields propsy rlp rec data JSSElem props = PrimitiveJss (String |+| Int |+| Number) @@ -93,7 +93,7 @@ instance jssAbleColor ∷ JSSAble p Color where instance jssAbleBackgroundImage ∷ JSSAble p BackgroundImage where jss v = PrimitiveJss (cast (render (value v))) where - render (Value val) = plain val + render (Value val) = plain val instance jssAbleString ∷ JSSAble p String where jss = cast >>> PrimitiveJss @@ -116,20 +116,20 @@ instance jssAbleNested ∷ JSSAble p jss => JSSAble p (Object jss) where instance jssAbleCss ∷ JSSAble p (StyleM Unit) where jss someCss = NestedJss (foldMap ruleToObject rules) where - rules = runS someCss + rules = runS someCss - ruleToObject = case _ of - Property (Key k) (Value v) -> Object.singleton (plain k) (jss (plain v)) - Nested (Sub (Selector (Refinement preds) (Elem el))) rules -> Object.singleton (el <> foldMap predicate preds) (jss (foldMap ruleToObject rules)) - Keyframe (Keyframes name frames) -> - frames - # foldMap \(Tuple pos rules) -> - Object.singleton - (show (round pos) <> "%") - (NestedJss (foldMap ruleToObject rules)) - x -> - unsafeCrashWith do - "tried to create CSS that I couldn't understand" + ruleToObject = case _ of + Property (Key k) (Value v) -> Object.singleton (plain k) (jss (plain v)) + Nested (Sub (Selector (Refinement preds) (Elem el))) rules -> Object.singleton (el <> foldMap predicate preds) (jss (foldMap ruleToObject rules)) + Keyframe (Keyframes name frames) -> + frames + # foldMap \(Tuple pos rules) -> + Object.singleton + (show (round pos) <> "%") + (NestedJss (foldMap ruleToObject rules)) + x -> + unsafeCrashWith do + "tried to create CSS that I couldn't understand" instance jssAbleRecord ∷ ( JSSAbleFields props rowRL row () to @@ -139,20 +139,20 @@ instance jssAbleRecord ∷ JSSAble props (Record row) where jss rec = NestedJss <<< Object.fromHomogeneous $ built where - built ∷ Record to - built = Builder.build builder {} + built ∷ Record to + built = Builder.build builder {} - rlp = RL.RLProxy ∷ RL.RLProxy rowRL + rlp = RL.RLProxy ∷ RL.RLProxy rowRL - propsy = Proxy ∷ Proxy props + propsy = Proxy ∷ Proxy props - builder ∷ Builder.Builder (Record ()) (Record to) - builder = jssifyFields propsy rlp rec + builder ∷ Builder.Builder (Record ()) (Record to) + builder = jssifyFields propsy rlp rec propsJss ∷ ∀ p a. JSSAble p a => (p -> a) -> JSSElem p propsJss fn = PropsJss (map jss fn) -class JSSAbleFields props (xs ∷ RowList) (row ∷ #Type) (from ∷ #Type) (to ∷ #Type) | xs -> props row from to where +class JSSAbleFields props (xs ∷ RowList Type) (row ∷ #Type) (from ∷ #Type) (to ∷ #Type) | xs -> props row from to where jssifyFields ∷ Proxy props -> RLProxy xs -> Record row -> Builder (Record from) (Record to) instance jssAbleFieldsNil ∷ JSSAbleFields props Nil row () () where @@ -169,16 +169,16 @@ instance jssAbleFieldsCons ∷ JSSAbleFields props (RL.Cons name a tail) row from to where jssifyFields _ _ r = first <<< rest where - first = Builder.insert nameP (jss val) + first = Builder.insert nameP (jss val) - val = Record.get nameP r + val = Record.get nameP r - rest = jssifyFields propsP tailP r + rest = jssifyFields propsP tailP r - nameP = SProxy ∷ SProxy name + nameP = SProxy ∷ SProxy name - tailP = RL.RLProxy ∷ RL.RLProxy tail + tailP = RL.RLProxy ∷ RL.RLProxy tail - propsP = Proxy ∷ Proxy props + propsP = Proxy ∷ Proxy props - name = reflectSymbol nameP + name = reflectSymbol nameP diff --git a/components/src/Yoga/SVG/Image.purs b/components/src/Yoga/SVG/Image.purs index ee05eb7..63be1a8 100644 --- a/components/src/Yoga/SVG/Image.purs +++ b/components/src/Yoga/SVG/Image.purs @@ -17,7 +17,7 @@ import React.Basic.DOM.SVG as SVG import React.Basic.Emotion as E import React.Basic.Hooks (ReactComponent) import React.Basic.Hooks as React -import Yoga.Block.Container.Style (colour) +import Yoga.Block.Container.Style (DarkOrLightMode(..), colour) import Yoga.DOM.Hook (useBoundingBox) import Yoga.SVG.Icon (Raw) import Yoga.Scroll.Hook (useScrollYPosition) @@ -67,7 +67,7 @@ rotateStars = mkClasses theme = { laptopBackground: E.css - { fill: E.str colour.background + { fill: E.var colour.background } , lightEllipsis: E.css @@ -82,7 +82,7 @@ mkClasses theme = } , screenText: E.css - { fontFamily: E.var "--font-mono" + { fontFamily: E.var "--mono-font" , fontSize: E.str "0.85em" , fill: E.str colour.text } @@ -134,10 +134,10 @@ mkClasses theme = } } -mkLandingPageBackground ∷ Effect (ReactComponent { className ∷ String }) +mkLandingPageBackground ∷ Effect (ReactComponent { className ∷ String, themeVariant ∷ DarkOrLightMode }) mkLandingPageBackground = do - React.reactComponent "LandingPageBackground" \{ className } -> React.do - let theme = { isLight: true } -- [TODO] + React.reactComponent "LandingPageBackground" \{ className, themeVariant } -> React.do + let theme = { isLight: themeVariant == LightMode } let classes = mkClasses theme scrollY <- useScrollYPosition bb /\ ref <- useBoundingBox diff --git a/components/src/Yoga/Switcher/Component.purs b/components/src/Yoga/Switcher/Component.purs index c6a8bcf..89b16f1 100644 --- a/components/src/Yoga/Switcher/Component.purs +++ b/components/src/Yoga/Switcher/Component.purs @@ -1,7 +1,7 @@ module Yoga.Switcher.Component where import Prelude -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Maybe (Maybe) import Effect (Effect) import React.Basic (JSX) @@ -12,17 +12,17 @@ import Record.Extra (pick) import Yoga.Switcher.Styles as Style import Yoga.Theme.Styles (makeStylesJSS) -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps Style.PropsR +type PropsR = + OptionalProps Style.PropsR -type OptionalProps r - = ( kids ∷ Array JSX - , className ∷ Maybe String - | r - ) +type OptionalProps r = + ( kids ∷ Array JSX + , className ∷ Maybe String + | r + ) makeComponent ∷ Effect (ReactComponent Props) makeComponent = do diff --git a/components/src/Yoga/WithSidebar/Component.purs b/components/src/Yoga/WithSidebar/Component.purs index 697a590..a03be1f 100644 --- a/components/src/Yoga/WithSidebar/Component.purs +++ b/components/src/Yoga/WithSidebar/Component.purs @@ -1,7 +1,7 @@ module Yoga.WithSidebar.Component where import Prelude -import Data.Array (foldMap) +import Data.Foldable (foldMap) import Data.Array as A import Data.Maybe (Maybe(..)) import Effect (Effect) @@ -12,23 +12,23 @@ import React.Basic.Hooks as React import Yoga.Theme.Styles (makeStylesJSS) import Yoga.WithSidebar.Styles as WithSidebar -type Props - = Record PropsR +type Props = + Record PropsR -type PropsR - = OptionalProps - ( sidebarChildren ∷ Array JSX - , notSidebarChildren ∷ Array JSX - ) - -type OptionalProps r - = ( className ∷ Maybe String - , sidebarClassName ∷ Maybe String - , notSidebarClassName ∷ Maybe String - , sidebarRight ∷ Maybe Boolean - | r +type PropsR = + OptionalProps + ( sidebarChildren ∷ Array JSX + , notSidebarChildren ∷ Array JSX ) +type OptionalProps r = + ( className ∷ Maybe String + , sidebarClassName ∷ Maybe String + , notSidebarClassName ∷ Maybe String + , sidebarRight ∷ Maybe Boolean + | r + ) + makeComponent ∷ Effect (ReactComponent Props) makeComponent = do useStyles <- makeStylesJSS WithSidebar.styles