LoginSignup
8
2

More than 3 years have passed since last update.

Yet Another elm-css作った

Posted at

elm-origamiリリースしました🎉

elm-origamiってなに

CSS in Elmを実現するためのパッケージです
こんな感じに書けます

import Origami exposing (..)
import Origami.Html exposing (..)
import Origami.Html.Attributes exposing (css)
import Origami.Html.Events exposing (onClick)

view : Model -> Html Msg
view model =
    div
        [ css
            [ property "width" "100vw"
            , property "height" "100vh"
            , property "display" "flex"
            , property "justify-content" "center"
            , property "align-items" "center"
            ]
        ]
        [ button
            [ css
                [ property "display" "flex"
                , property "justify-content" "center"
                , property "align-items" "center"
                , property "position" "relative"
                , property "height" "50px"
                , property "width" "200px"
                , property "outline" "none"
                , property "border-width" "0"
                , property "background-color" "#f58c64"
                , property "color" "white"
                , property "font-size" "20px"
                , property "letter-spacing" "2px"
                , property "cursor" "pointer"
                , property "transition" "all 0.3s cubic-bezier(0.13, 0.99, 0.39, 1.01)"
                , property "box-shadow" "0 3px 5px rgba(0, 0, 0, 0.3)"
                , withPseudoClass "hover" [ property "background-color" "#ef794c" ]
                , case model of
                    Initial ->
                        noStyle

                    Loading ->
                        batch
                            [ property "border-radius" "50px"
                            , property "width" "50px"
                            , -- [Copyright (c) 2019 Epicmax LLC](https://epic-spinners.epicmax.co/)
                              withEach [ pseudoElement [] "after", pseudoElement [] "before" ]
                                [ property "content" <| qt ""
                                , property "position" "absolute"
                                , property "width" "60%"
                                , property "height" "60%"
                                , property "border-radius" "100%"
                                , property "border" "calc(30px / 10) solid transparent"
                                , animation
                                    [ ( ( from, [] ), [ propertyA "transform" "rotate(0deg)" ] )
                                    , ( ( to, [] ), [ propertyA "transform" "rotate(360deg)" ] )
                                    ]
                                , property "animation-duration" "1s"
                                , property "animation-iteration-count" "infinite"
                                ]
                            , withPseudoElement "after" [ property "border-top-color" "#ffe9ef" ]
                            , withPseudoElement "before"
                                [ property "border-bottom-color" "#ffe9ef"
                                , property "animation-direction" "alternate"
                                ]
                            ]

                    Completed ->
                        batch
                            [ property "border-radius" "50px"
                            , property "width" "50px"
                            , withPseudoElement "after"
                                [ property "content" <| qt ""
                                , property "position" "absolute"
                                , property "width" "60%"
                                , property "height" "30%"
                                , property "border-left" "3px solid #fff"
                                , property "border-bottom" "3px solid #fff"
                                , property "transform" "rotate(-45deg)"
                                ]
                            ]
                ]
            ]
            [ if model == Initial then
                span
                    [ css
                        [ animation
                            [ ( ( from, [] ), [ propertyA "opacity" "0" ] )
                            , ( ( to, [] ), [ propertyA "opacity" "1" ] )
                            ]
                        , property "animation-duration" "1s"
                        ]
                    ]
                    [ text "Click Me!" ]

              else
                text ""
            ]
        ]

rtfeldman/elm-cssをフォークしていて使い方はほぼ一緒です

なぜ作ったのか

elm-cssには型のついたプロパティ関数が多く用意されています
しかもCSSの柔軟性を表現するためによくわからない感じの型がついてます

CSSの書き方は結構ひとによって違うと思いますが、それらすべてを表現できるように設計するのは無理があるのではないでしょうか?
CSS in Elm的に使える部分だけでいいんじゃないだろうかと思いました

ということで作りました

なにがうれしいの?

新規性はほぼないです
型のついたプロパティ関数がないことが新規性みたいなもんです

一応Sassとかみたいにセレクターをネストさせていくのをelm-cssより柔軟に書けたりします

作ってみてなにがよかったの?

使う人には関係ない話ですが内部構造がむっちゃきれいになりました
すごい!よくなった!

elm-cssは結構古くて、当初はElmでCSSを書いてそこからcssファイルを生成する感じのライブラリでした
本当のところは知りませんがあんまりElmで書いても嬉しくないねって感じになったみたいです

今はstyled-componentsとかみたいにCSS in Elmな感じのことができるようになっています
同じようなアプローチとしてmdgriffith/elm-uiというパッケージがあってこちらがとてもいいよってreadmeにも書いてあります

そんな感じでelm-cssは内部の改善とかは全然されていません。Elmのversion up対応とPRのmergeだけって感じです

内部の型も昔のCSSを生成していたときの設計にCSS in Elmができるようにする機能を載せていてあんまり整理できていないなという感じです
elm-origamiでは参考にしつつほぼ1から作り直していてすごくきれいになったと思います
使う人には関係のない話ですが

使って欲しいというか

elm-origamiは任意のCSSを適用できますが、elm-uiのようなopinionatedなパッケージのほうがいいと思います
もしなにかしらの方法論でCSSを組んでいるのならそれを表現するパッケージを作って欲しいです。elm-uiみたいな
elm-origamiを作って思いましたがHtml型とは違うalt Html型をexposeするパッケージを作るのは結構できます
やって

おわり

よかったら使ってみてくださいね

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2