{-# OPTIONS_GHC -Wno-name-shadowing #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Dashi.Components.Icon
( module Dashi.Components.Icon
, Phosphor (..)
)
where
import Clay hiding (action, span_)
import Dashi.Prelude hiding (has, none, span, (&))
import Dashi.Style.Tokens (Token (..), byTokens)
import Dashi.Style.Util ((~:))
import Data.Char (toLower)
import Miso.Html (span_)
import Miso.Html.Property (class_)
import Web.Font.Phosphor (Phosphor (..))
import Web.Font.Phosphor qualified as Phosphor
data Weight = Thin | Light | Regular | Bold | Fill | Duotone
deriving stock (Weight -> Weight -> Bool
(Weight -> Weight -> Bool)
-> (Weight -> Weight -> Bool) -> Eq Weight
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Weight -> Weight -> Bool
== :: Weight -> Weight -> Bool
$c/= :: Weight -> Weight -> Bool
/= :: Weight -> Weight -> Bool
Eq, Int -> Weight -> ShowS
[Weight] -> ShowS
Weight -> String
(Int -> Weight -> ShowS)
-> (Weight -> String) -> ([Weight] -> ShowS) -> Show Weight
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Weight -> ShowS
showsPrec :: Int -> Weight -> ShowS
$cshow :: Weight -> String
show :: Weight -> String
$cshowList :: [Weight] -> ShowS
showList :: [Weight] -> ShowS
Show, Weight
Weight -> Weight -> Bounded Weight
forall a. a -> a -> Bounded a
$cminBound :: Weight
minBound :: Weight
$cmaxBound :: Weight
maxBound :: Weight
Bounded, Int -> Weight
Weight -> Int
Weight -> [Weight]
Weight -> Weight
Weight -> Weight -> [Weight]
Weight -> Weight -> Weight -> [Weight]
(Weight -> Weight)
-> (Weight -> Weight)
-> (Int -> Weight)
-> (Weight -> Int)
-> (Weight -> [Weight])
-> (Weight -> Weight -> [Weight])
-> (Weight -> Weight -> [Weight])
-> (Weight -> Weight -> Weight -> [Weight])
-> Enum Weight
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Weight -> Weight
succ :: Weight -> Weight
$cpred :: Weight -> Weight
pred :: Weight -> Weight
$ctoEnum :: Int -> Weight
toEnum :: Int -> Weight
$cfromEnum :: Weight -> Int
fromEnum :: Weight -> Int
$cenumFrom :: Weight -> [Weight]
enumFrom :: Weight -> [Weight]
$cenumFromThen :: Weight -> Weight -> [Weight]
enumFromThen :: Weight -> Weight -> [Weight]
$cenumFromTo :: Weight -> Weight -> [Weight]
enumFromTo :: Weight -> Weight -> [Weight]
$cenumFromThenTo :: Weight -> Weight -> Weight -> [Weight]
enumFromThenTo :: Weight -> Weight -> Weight -> [Weight]
Enum)
instance Token Weight where
tokenName :: forall s. (IsString s, Semigroup s) => Weight -> s
tokenName = String -> s
forall a. IsString a => String -> a
fromString (String -> s) -> (Weight -> String) -> Weight -> s
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toLower ShowS -> (Weight -> String) -> Weight -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Weight -> String
forall a s. (Show a, IsString s) => a -> s
ishow
defaultToken :: Maybe Weight
defaultToken = Weight -> Maybe Weight
forall a. a -> Maybe a
Just Weight
Regular
fontName :: forall s. (IsString s) => Weight -> s
fontName :: forall s. IsString s => Weight -> s
fontName Weight
w
| Weight -> Maybe Weight
forall a. a -> Maybe a
Just Weight
w Maybe Weight -> Maybe Weight -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Weight
forall t. Token t => Maybe t
defaultToken = s
"Phosphor"
| Bool
otherwise = String -> s
forall a. IsString a => String -> a
fromString (String -> s) -> String -> s
forall a b. (a -> b) -> a -> b
$ String
"Phosphor-" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Weight -> String
forall a. Show a => a -> String
show Weight
w
data Icon = Icon Weight Phosphor
iconFontFamilyOverride :: Weight -> Css
iconFontFamilyOverride :: Weight -> Css
iconFontFamilyOverride Weight
Regular = () -> Css
forall a. a -> StyleM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
iconFontFamilyOverride Weight
weight =
Css -> Css
important (Css -> Css) -> Css -> Css
forall a b. (a -> b) -> a -> b
$ Key Text
"font-family" Key Text -> Value -> Css
~: Weight -> Value
forall s. IsString s => Weight -> s
fontName Weight
weight
iconStyle :: Css
iconStyle :: Css
iconStyle = do
Key Text
"font-family" Key Text -> Text -> Css
-: Weight -> Text
forall s. IsString s => Weight -> s
fontName Weight
Regular
Key Text
"speak" Key Text -> Text -> Css
-: Text
"never"
Key Text
"font-style" Key Text -> Text -> Css
-: Text
"normal"
Key Text
"font-weight" Key Text -> Text -> Css
-: Text
"normal"
Key Text
"font-variant" Key Text -> Text -> Css
-: Text
"normal"
Key Text
"text-transform" Key Text -> Text -> Css
-: Text
"none"
Size Percentage -> Css
forall a. Size a -> Css
fontSize (Size Percentage -> Css) -> Size Percentage -> Css
forall a b. (a -> b) -> a -> b
$ Number -> Size Percentage
pct Number
110
Size (ZonkAny 0) -> Css
forall a. Size a -> Css
lineHeight (Size (ZonkAny 0) -> Css) -> Size (ZonkAny 0) -> Css
forall a b. (a -> b) -> a -> b
$ Number -> Size (ZonkAny 0)
forall a. Number -> Size a
unitless Number
1
UserSelect -> Css
userSelect UserSelect
forall a. None a => a
none
TextAlign -> Css
textAlign TextAlign
forall a. Center a => a
center
Display -> Css
display Display
inlineBlock
TextRendering -> Css
textRendering TextRendering
forall a. Auto a => a
auto
Css -> Css
important (Css -> Css) -> Css -> Css
forall a b. (a -> b) -> a -> b
$ TextDecoration -> Css
textDecoration TextDecoration
forall a. None a => a
none
Position -> Css
position Position
relative
Size LengthUnit -> Css
forall a. Size a -> Css
top (Size LengthUnit -> Css) -> Size LengthUnit -> Css
forall a b. (a -> b) -> a -> b
$ Number -> Size LengthUnit
em Number
0.05
iconContent :: Phosphor -> Content
iconContent :: Phosphor -> Content
iconContent = Text -> Content
stringContent (Text -> Content) -> (Phosphor -> Text) -> Phosphor -> Content
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> (Phosphor -> String) -> Phosphor -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> String
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Char -> String) -> (Phosphor -> Char) -> Phosphor -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Phosphor -> Char
Phosphor.char
instance Widget Icon model action where
widget' :: [Attribute action] -> Icon -> View model action
widget' [Attribute action]
attrs (Icon Weight
weight Phosphor
icon) =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
span_ (Text -> Attribute action
forall action. Text -> Attribute action
class_ Text
"icon" Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: Weight -> Attribute action
forall t action. Token t => t -> Attribute action
forall action. Weight -> Attribute action
tokenAttr Weight
weight Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: [Attribute action]
attrs)
([View model action] -> View model action)
-> (Phosphor -> [View model action])
-> Phosphor
-> View model action
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. View model action -> [View model action]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(View model action -> [View model action])
-> (Phosphor -> View model action)
-> Phosphor
-> [View model action]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> View model action
forall model action. Text -> View model action
textRaw
(Text -> View model action)
-> (Phosphor -> Text) -> Phosphor -> View model action
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
forall a. IsString a => String -> a
fromString
(String -> Text) -> (Phosphor -> String) -> Phosphor -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> String
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(Char -> String) -> (Phosphor -> Char) -> Phosphor -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Phosphor -> Char
Phosphor.char
(Phosphor -> View model action) -> Phosphor -> View model action
forall a b. (a -> b) -> a -> b
$ Phosphor
icon
style :: Css
style = do
[Weight] -> (Weight -> Css) -> Css
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Weight
forall a. Bounded a => a
minBound .. Weight
forall a. Bounded a => a
maxBound] \Weight
weight ->
Css -> Css
fontFace do
[Text] -> [GenericFontFamily] -> Css
fontFamily [Weight -> Text
forall s. IsString s => Weight -> s
fontName Weight
weight] []
FontStyle -> Css
fontStyle FontStyle
forall a. Normal a => a
normal
FontWeight -> Css
fontWeight FontWeight
forall a. Normal a => a
normal
[FontFaceSrc] -> Css
fontFaceSrc
[ Text -> Maybe FontFaceFormat -> FontFaceSrc
FontFaceSrcUrl (Text
"/static/phosphor/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Weight -> Text
forall s. IsString s => Weight -> s
fontName Weight
weight Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".woff2") (FontFaceFormat -> Maybe FontFaceFormat
forall a. a -> Maybe a
Just FontFaceFormat
WOFF2)
, Text -> Maybe FontFaceFormat -> FontFaceSrc
FontFaceSrcUrl (Text
"/static/phosphor/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Weight -> Text
forall s. IsString s => Weight -> s
fontName Weight
weight Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".woff") (FontFaceFormat -> Maybe FontFaceFormat
forall a. a -> Maybe a
Just FontFaceFormat
WOFF)
, Text -> Maybe FontFaceFormat -> FontFaceSrc
FontFaceSrcUrl
(Text
"/static/phosphor/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Weight -> Text
forall s. IsString s => Weight -> s
fontName Weight
weight Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".ttf")
(FontFaceFormat -> Maybe FontFaceFormat
forall a. a -> Maybe a
Just FontFaceFormat
TrueType)
]
Selector
".icon" Selector -> Css -> Css
? do
Css
iconStyle
(Weight -> Css) -> Css
forall t. Token t => (t -> Css) -> Css
byTokens Weight -> Css
iconFontFamilyOverride
Refinement
".inline" Refinement -> Css -> Css
& Size LengthUnit -> Css
forall a. Size a -> Css
marginRight (Number -> Size LengthUnit
em Number
0.2)
inlineIcon :: Icon -> View model action
inlineIcon :: forall model action. Icon -> View model action
inlineIcon = [Attribute action] -> Icon -> View model action
forall w model action.
Widget w model action =>
[Attribute action] -> w -> View model action
widget' [Text -> Attribute action
forall action. Text -> Attribute action
class_ Text
"inline"]