View.Pad
The implementation was based on the .pad block.
View Options
view : (Key -> msg) -> H.Html msg
view onClick =
-- ...
Since I only needed one option, i.e. onClick, I didn't create a ViewOptions type alias.
View Function
view : (Key -> msg) -> H.Html msg
view onClick =
H.div [ HA.class "pad" ]
[ viewPadSlot
{ position = ( 0, 0 )
, span = Just Colspan
, style = Key.Primary
, key = Key.AC
, onClick = onClick
}
, viewPadSlot
{ position = ( 0, 2 )
, span = Nothing
, style = Key.Default
, key = Key.Operator Operator.Div
, onClick = onClick
}
, viewPadSlot
{ position = ( 0, 3 )
, span = Nothing
, style = Key.Default
, key = Key.Operator Operator.Mul
, onClick = onClick
}
, viewPadSlot
{ position = ( 1, 0 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Seven
, onClick = onClick
}
, viewPadSlot
{ position = ( 1, 1 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Eight
, onClick = onClick
}
, viewPadSlot
{ position = ( 1, 2 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Nine
, onClick = onClick
}
, viewPadSlot
{ position = ( 1, 3 )
, span = Nothing
, style = Key.Default
, key = Key.Operator Operator.Sub
, onClick = onClick
}
, viewPadSlot
{ position = ( 2, 0 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Four
, onClick = onClick
}
, viewPadSlot
{ position = ( 2, 1 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Five
, onClick = onClick
}
, viewPadSlot
{ position = ( 2, 2 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Six
, onClick = onClick
}
, viewPadSlot
{ position = ( 2, 3 )
, span = Nothing
, style = Key.Default
, key = Key.Operator Operator.Add
, onClick = onClick
}
, viewPadSlot
{ position = ( 3, 0 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.One
, onClick = onClick
}
, viewPadSlot
{ position = ( 3, 1 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Two
, onClick = onClick
}
, viewPadSlot
{ position = ( 3, 2 )
, span = Nothing
, style = Key.Default
, key = Key.Digit Digit.Three
, onClick = onClick
}
, viewPadSlot
{ position = ( 3, 3 )
, span = Just Rowspan
, style = Key.Secondary
, key = Key.Equal
, onClick = onClick
}
, viewPadSlot
{ position = ( 4, 0 )
, span = Just Colspan
, style = Key.Default
, key = Key.Digit Digit.Zero
, onClick = onClick
}
, viewPadSlot
{ position = ( 4, 2 )
, span = Nothing
, style = Key.Default
, key = Key.Dot
, onClick = onClick
}
]
viewPadSlot
The viewPadSlot function abstracts over the .pad__slot element. The .pad__slot element itself can be given a row and column position via row and column classes, i.e. .r0, .r1, .r2, .r3, .r4, .c0, .c1, .c2, and .c3, and an optional spanning direction class, i.e. .rowspan2 and .colspan2. It is also the parent of the .key block so I decided to pass along the corresponding View.Key.ViewOptions, i.e. style, key, and onClick.
type Span
= Colspan
| Rowspan
viewPadSlot :
{ position : ( Int, Int )
, span : Maybe Span
, style : Key.Style
, key : Key
, onClick : Key -> msg
}
-> H.Html msg
viewPadSlot { position, span, style, key, onClick } =
let
( r, c ) =
position
in
H.div
[ HA.class "pad__slot"
, HA.class <| "r" ++ String.fromInt r
, HA.class <| "c" ++ String.fromInt c
, HA.class <|
case span of
Nothing ->
""
Just Colspan ->
"colspan2"
Just Rowspan ->
"rowspan2"
]
[ Key.view
{ style = style
, key = key
, onClick = onClick
}
]
An Alternative API
An alternative API for the viewPadSlot function could have been:
viewPadSlot :
{ position : ( Int, Int )
, span : Maybe Span
, key : Key.ViewOptions msg
}
-> H.Html msg
viewPadSlot { position, span, key } =
-- ...
This would have simplified the call to Key.view, it's just Key.view key now, but would have made the viewPadSlot calls more verbose:
viewPadSlot
{ position = ( 0, 0 )
, span = Just Colspan
, key =
{ style = Key.Primary
, key = Key.AC
, onClick = onClick
}
}
Since viewPadSlot is called more than Key.view I decided against this alternative API.