~sjm/builds-character

f7a86eac04ab0dc9f9cf03ba8492fee6fd545578 — Sam Marshall 2 years ago 07b786f
feat: add basic styles for xp and level boxes
M readme.org => readme.org +18 -3
@@ 9,7 9,10 @@ Control your data, avoid hosting character sheets online, still share them with 
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-08 Sat 15:40]
:END:
*** TODO some styles
*** DONE some styles
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-09 Sun 11:18]
:END:

going to stick to something simple for now, but some structure in the UI would be nice. Ideally, it would look like the default char sheet in the SWN rule book.



@@ 28,12 31,24 @@ yarn add -D postcss-modules tailwindcss
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-08 Sat 17:02]
:END:
**** TODO Style existing components
**** DONE Style existing components
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-09 Sun 11:18]
:END:
***** DONE XP component
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-09 Sun 11:18]
:END:

*** TODO UI.XP slot should have configurable id
*** DONE UI.XP slot should have configurable id
:LOGBOOK:
- State "DONE"       from "TODO"       [2021-05-09 Sun 11:18]
:END:
*** TODO UI.Class drop-down for selecting class
*** TODO Improve use of profunctor-lenses

This one might require me to understand profunctor lenses a lot better...

**** TODO Read up on profunctor-lenses
*** TODO how many xp until level up?
*** TODO import/export json

M src/CharSheet/Level.purs => src/CharSheet/Level.purs +1 -1
@@ 5,4 5,4 @@ import Prelude
newtype Level = Level Int

instance showLevel :: Show Level where
  show (Level int) = "Level: " <> show int
  show (Level int) = show int

M src/CharSheet/XP.purs => src/CharSheet/XP.purs +8 -4
@@ 5,20 5,24 @@ import Prelude
import CharSheet.Level (Level(..))
import Data.Argonaut as A
import Data.Int as I
import Data.Lens as L

newtype XP = XP Int

instance showXP :: Show XP where
  show (XP int) = "XP: " <> show int
  show (XP int) = show int

_xp :: XP -> Int
_xp (XP i) = i
_xp ::L.Lens' XP Int
_xp = L.lens getter setter
  where
    getter (XP x) = x
    setter _ new = XP new

xp :: Int -> XP
xp = XP

inc :: XP -> XP
inc (XP i) = XP (i + 1)
inc = L.over _xp ((+) 1)

dec :: XP -> XP
dec (XP i)

M src/UI/Entry.purs => src/UI/Entry.purs +13 -4
@@ 12,6 12,7 @@ import Halogen.HTML.Properties as HP
import Type.Proxy (Proxy(..))
import UI.Class as UC
import UI.Level as UILevel
import UI.Util as Util
import UI.XP as UIXP

type State = C.Character


@@ 25,7 26,7 @@ data Query a = Load Input a
data Action =
  XPOutput UIXP.Output

type Slots = ( xp :: UIXP.Slot
type Slots = ( xp :: (UIXP.Slot Unit)
             , lvl :: (UILevel.Slot Unit)
             , class :: (UC.Slot Unit)
             )


@@ 48,9 49,17 @@ render state = let
  xp = C.xp state
  cl = C.class' state
  in
    HH.div [ HP.classes $ HH.ClassName <$> [ "border-solid", "border-2", "border-black" ] ] [ HH.slot_ _class unit UC.component cl
            , HH.slot _xp 0 UIXP.component { xp } XPOutput
            , HH.slot_ _lvl unit UILevel.component xp ]
    HH.div
    [ Util.classes [ "border-solid"
                   , "border-2"
                   , "border-black"
                   , "p-2"
                   ]
    ]
    [ HH.slot_ _class unit UC.component cl
    , HH.slot _xp unit UIXP.component { xp } XPOutput
    , HH.slot_ _lvl unit UILevel.component xp
    ]

handleAction :: forall m. MonadEffect m => Action -> H.HalogenM State Action Slots Output m Unit
handleAction = case _ of

M src/UI/Level.purs => src/UI/Level.purs +30 -1
@@ 6,6 6,7 @@ import CharSheet.XP as CX
import Data.Maybe (Maybe(..))
import Halogen as H
import Halogen.HTML as HH
import UI.Util as Util

type Input = CX.XP
type State = CX.XP


@@ 26,7 27,35 @@ initialState :: Input -> State
initialState = identity

render :: forall a m. State -> H.ComponentHTML a () m
render s = HH.div_ [ HH.text $ show $ CX.toLevel s ]
render s = HH.div
           [ Util.classes [ "grid", "grid-cols-2", "gap-0", "w-32" ] ]
           [ HH.div
             [ Util.classes [ "px-2"
                            , "w-16"
                            , "h-8"
                            , "border-2"
                            , "border-r-0"
                            , "border-black"
                            , "justify-self-end"
                            , "flex"
                            , "justify-center"
                            , "items-center"
                            ]
             ]
             [ HH.text "level" ]
           , HH.div
             [ Util.classes [ "w-16"
                            , "h-16"
                            , "border-2"
                            , "border-black"
                            , "grid"
                            , "justify-items-center"
                            , "items-center"
                            , "justify-self-start"
                            ]
             ]
             [ HH.text $ show $ CX.toLevel s ]
           ]

handleAction :: forall o m. Action -> H.HalogenM State Action () o m Unit
handleAction = case _ of

A src/UI/Util.purs => src/UI/Util.purs +9 -0
@@ 0,0 1,9 @@
module UI.Util where

import Prelude

import Halogen.HTML as HH
import Halogen.HTML.Properties as HP

classes :: forall r i. Array String -> HH.IProp ( class :: String | r ) i
classes xs = HP.classes $ HH.ClassName <$> xs

M src/UI/XP.purs => src/UI/XP.purs +42 -5
@@ 8,6 8,7 @@ import Effect.Class (class MonadEffect)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import UI.Util as Util

type Input = { xp :: CX.XP }
type State = { xp :: CX.XP }


@@ 17,7 18,7 @@ data Output = IncXP

data Action = Inc | Dec | Update Input

type Slot = forall query. H.Slot query Output Int
type Slot s = forall query. H.Slot query Output s

component :: forall q m. MonadEffect m => H.Component q Input Output m
component = H.mkComponent { initialState


@@ 31,10 32,46 @@ initialState :: Input -> State
initialState = identity

render :: forall m. State -> H.ComponentHTML Action () m
render { xp } = HH.div_ [ HH.button [ HE.onClick \_ -> Inc  ] [ HH.text "+" ]
                        , HH.p_ [ HH.text $ show xp ]
                        , HH.button [ HE.onClick \_ -> Dec ] [ HH.text "-" ]
                        ]
render { xp } = HH.div
                [ Util.classes [ "grid"
                               , "grid-cols-2"
                               , "gap-0"
                               , "w-32"
                               , "mb-2"
                               ]
                ]
                [ HH.div
                  [ Util.classes [ "px-2"
                                 , "w-16"
                                 , "h-8"
                                 , "border-2"
                                 , "border-r-0"
                                 , "border-black"
                                 , "justify-self-end"
                                 , "flex"
                                 , "justify-center"
                                 , "items-center"
                                 ]
                  ]
                  [ HH.text "xp" ]

                , HH.div
                  [ Util.classes [ "w-16"
                                 , "h-16"
                                 , "border-2"
                                 , "border-black"
                                 , "grid"
                                 , "grid-rows-3"
                                 , "justify-items-center"
                                 , "items-center"
                                 , "justify-self-start"
                                 ]
                  ]
                  [ HH.button [ HE.onClick \_ -> Inc  ] [ HH.text "+" ]
                  , HH.p_ [ HH.text $ show xp ]
                  , HH.button [ HE.onClick \_ -> Dec ] [ HH.text "-" ]
                  ]
                ]

handleAction :: forall m. MonadEffect m => Action -> H.HalogenM State Action () Output m Unit
handleAction = case _ of