2021-10-22 03:20:29 +03:00
|
|
|
module Debug.Control.Extra exposing
|
2022-03-04 21:26:19 +03:00
|
|
|
( float, int
|
2022-03-05 01:49:45 +03:00
|
|
|
, list, listItem, optionalListItem, optionalListItemDefaultChecked, optionalBoolListItem
|
2022-03-04 21:42:09 +03:00
|
|
|
, css
|
2021-10-22 03:20:29 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
{-|
|
|
|
|
|
2022-03-04 21:26:19 +03:00
|
|
|
@docs float, int
|
2022-03-05 01:49:45 +03:00
|
|
|
@docs list, listItem, optionalListItem, optionalListItemDefaultChecked, optionalBoolListItem
|
2022-03-04 21:42:09 +03:00
|
|
|
@docs css
|
2021-10-22 03:20:29 +03:00
|
|
|
|
|
|
|
-}
|
|
|
|
|
2022-03-04 21:42:09 +03:00
|
|
|
import Css
|
2022-03-05 02:54:02 +03:00
|
|
|
import Css.Global
|
2021-10-22 03:20:29 +03:00
|
|
|
import Debug.Control as Control exposing (Control)
|
2022-03-05 02:54:02 +03:00
|
|
|
import Regex
|
2021-10-22 03:20:29 +03:00
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
float : Float -> Control Float
|
|
|
|
float default =
|
|
|
|
Control.map (String.toFloat >> Maybe.withDefault default)
|
|
|
|
(Control.string (String.fromFloat default))
|
|
|
|
|
|
|
|
|
2022-03-04 21:26:19 +03:00
|
|
|
{-| -}
|
|
|
|
int : Int -> Control Int
|
|
|
|
int default =
|
|
|
|
Control.map (String.toInt >> Maybe.withDefault default)
|
|
|
|
(Control.string (String.fromInt default))
|
|
|
|
|
|
|
|
|
2021-10-22 03:20:29 +03:00
|
|
|
{-| Use with `listItem` and `optionalListItem`
|
2022-03-04 21:42:00 +03:00
|
|
|
|
|
|
|
list
|
|
|
|
|> listItem "first name" string
|
|
|
|
|> listItem "last name" string
|
|
|
|
|
2021-10-22 03:20:29 +03:00
|
|
|
-}
|
|
|
|
list : Control (List a)
|
|
|
|
list =
|
|
|
|
Control.record []
|
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
listItem : String -> Control a -> Control (List a) -> Control (List a)
|
|
|
|
listItem name accessor accumulator =
|
|
|
|
Control.field name
|
|
|
|
(Control.map List.singleton accessor)
|
|
|
|
(Control.map (++) accumulator)
|
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
2021-10-22 03:27:29 +03:00
|
|
|
optionalListItem : String -> Control a -> Control (List a) -> Control (List a)
|
2022-03-05 01:49:45 +03:00
|
|
|
optionalListItem =
|
|
|
|
optionalListItem_ False
|
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
optionalListItemDefaultChecked : String -> Control a -> Control (List a) -> Control (List a)
|
|
|
|
optionalListItemDefaultChecked =
|
|
|
|
optionalListItem_ True
|
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
optionalListItem_ : Bool -> String -> Control a -> Control (List a) -> Control (List a)
|
|
|
|
optionalListItem_ default name accessor accumulator =
|
2021-10-22 03:20:29 +03:00
|
|
|
Control.field name
|
2022-03-05 01:49:45 +03:00
|
|
|
(Control.map (List.singleton >> List.filterMap identity) (Control.maybe default accessor))
|
2021-10-22 03:20:29 +03:00
|
|
|
(Control.map (++) accumulator)
|
2022-03-04 21:42:09 +03:00
|
|
|
|
|
|
|
|
2022-03-05 00:51:31 +03:00
|
|
|
{-| -}
|
|
|
|
optionalBoolListItem : String -> (Bool -> a) -> Control (List a) -> Control (List a)
|
|
|
|
optionalBoolListItem name f accumulator =
|
|
|
|
Control.field name
|
|
|
|
(Control.map
|
|
|
|
(\value ->
|
|
|
|
if value then
|
|
|
|
[ f value ]
|
|
|
|
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
)
|
|
|
|
(Control.bool False)
|
|
|
|
)
|
|
|
|
(Control.map (++) accumulator)
|
|
|
|
|
|
|
|
|
2022-03-04 21:42:09 +03:00
|
|
|
{-| -}
|
2022-03-05 01:21:02 +03:00
|
|
|
css : String -> Control ( String, List Css.Style )
|
2022-03-04 21:42:09 +03:00
|
|
|
css exampleCss =
|
|
|
|
Control.map
|
|
|
|
(\rawStr ->
|
2022-03-05 02:54:02 +03:00
|
|
|
case Regex.find selectorAndStyles rawStr of
|
|
|
|
[] ->
|
|
|
|
toCssProps rawStr
|
|
|
|
|
|
|
|
matches ->
|
|
|
|
toCss matches
|
2022-03-04 21:42:09 +03:00
|
|
|
)
|
|
|
|
(Control.stringTextarea exampleCss)
|
2022-03-05 02:54:02 +03:00
|
|
|
|
|
|
|
|
|
|
|
selectorAndStyles : Regex.Regex
|
|
|
|
selectorAndStyles =
|
|
|
|
Maybe.withDefault Regex.never
|
|
|
|
(Regex.fromString "([\\s\\S]+)\\s*{\\s*([\\s\\S]*)\\s*}\\s*")
|
|
|
|
|
|
|
|
|
|
|
|
toCss : List Regex.Match -> ( String, List Css.Style )
|
|
|
|
toCss matches =
|
|
|
|
List.concatMap
|
|
|
|
(\match ->
|
|
|
|
case Debug.log "Matches" <| List.filterMap identity match.submatches of
|
|
|
|
selector :: styles :: [] ->
|
|
|
|
let
|
|
|
|
( stylesStr, stylesVal ) =
|
|
|
|
toCssProps styles
|
|
|
|
in
|
|
|
|
[ ( "Css.Global.selector \"" ++ String.trim selector ++ "\" " ++ stylesStr
|
|
|
|
, Css.Global.selector selector stylesVal
|
|
|
|
)
|
|
|
|
]
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
[]
|
|
|
|
)
|
|
|
|
matches
|
|
|
|
|> List.unzip
|
|
|
|
|> Tuple.mapFirst (\props -> "[ Css.Global.descendants [ " ++ String.join "," props ++ " ] ]")
|
|
|
|
|> Tuple.mapSecond (\props -> [ Css.Global.descendants props ])
|
|
|
|
|
|
|
|
|
|
|
|
toCssProps : String -> ( String, List Css.Style )
|
|
|
|
toCssProps rawStr =
|
|
|
|
rawStr
|
|
|
|
|> String.split ";"
|
|
|
|
|> List.filterMap
|
|
|
|
(\segment ->
|
|
|
|
case String.split ":" segment of
|
|
|
|
name :: value :: [] ->
|
|
|
|
Just
|
|
|
|
( "Css.property \"" ++ String.trim name ++ "\" \"" ++ String.trim value ++ "\""
|
|
|
|
, Css.property name value
|
|
|
|
)
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
-- Unable to parse css
|
|
|
|
Nothing
|
|
|
|
)
|
|
|
|
|> List.unzip
|
|
|
|
|> Tuple.mapFirst (\props -> "[ " ++ String.join "," props ++ " ]")
|