elm-neat-layoutを使ってみました

レイアウトに特化し見た目はcssを使っていくという、elm-neat-layoutというレイアウトライブラリを使ってみました。

作成したものはこちらです。
[github](https://github.com/GoldentTuft/layout-study2)
[demo](https://goldenttuft.github.io/layout-study2/)

前回のelm-uiから、今回はスクロールに挑戦してみようとしたのですが、けっこう敗北しました。

ウィンドウサイズを変えて要素が並び替えられても下の余白もきっちり且つスクロールも、とやってみようとしたのですが諦めてしまいました。

# メモ
なんとなく、こういうふうに使ってみたと書いてみます。
きっと間違っている部分が多々あります。

作者のarowMさんがそのうちドキュメントを書いてくださるそうです。

# フレームワーク
elm-neat-layoutはレイアウト担当でcssはcssにというものらしいので、ライブラリのようにちょっと使ってみようとしたのですがelm-uiよりもフレームワーク感覚がありました。
よく見たらframeworkと書いてありました。

### main
```elm
main : Program () Model Msg
main =
    Neat.element
        { init = \_ -> init
        , view = view
        , update = update
        , subscriptions = subscriptions
        , renderer = \_ -> defaultRenderer
        }
```
まずこのように`Browser.element`でなく`Neat.element`などで置き換えます。

### view
```elm
view : Model -> View NoGap Msg
view model =
    Layout.column
        [ menu model
        , tab
        , body |> setLayout Layout.fill
        ]
        |> setClass "main"
```
viewもこのように`Model -> View NoGap Msg`となります。

### パイプ
標準のelmならば

```elm
div
    [ class "hoge" ]
    [ text "hello" ]
```
こうですが、elm-neat-layoutでは属性はあとから追加していくみたいです。

```elm
Layout.column
    [ Neat.textBlock "hello"
    ]
    |> setClass "hoge"

```
もっと複雑になったときなど、メリットがあるんだと思います。
# きっちりした余白
余白を型で管理するようで、`View NoGap Msg`はViewにNoGapという余白がついているイメージだと思います。
余白のない余白です。

### 余白定義
```elm
type MenuGap
    = MenuGap


menuGap : Neat.IsGap MenuGap
menuGap =
    Neat.IsGap
        { width = 0.8
        , height = 0.8
        }
```
menuGapという0.8remの余白ができました。

### 仕組み
余白が0.8なら`(0.8[item1]0.8)(0.8[item2]0.8)`
このように、端は0.8で真ん中は1.6になってしまいそうですが、そのへんをうまくやってくれるみたいです。

`(0.4(0.4[item1]0.4)(0.4[item2]0.4)0.4)`
このように、item1に0.4の余白が付き、item2に0.4の余白が付き、それらを束ねるものに0.4の余白が付くのだと思います。

### 余白適用
```elm
menu : View NoGap Msg
menu =
    Layout.column
        [ Neat.textBlock "item1"
            |> fromNoGap menuGap
        , Neat.textBlock "item2"
            |> fromNoGap menuGap
        ]
        |> setBoundary menuGap
```
`fromNoGap menuGap`これによって、item1に余白が0.4付きます。
item2も同様です。

Listに異なる型を含めることができないように、item2に余白が設定されていなかったり、別の余白が設定されるとコンパイルエラーが出ます。

`setBoundary menuGap`これによって、itemを束ねるcolumnに0.4の余白が付き、外から見たら一塊の余白がないものとしてmenuは`View NoGap Msg`となります。

# クラス適用
```elm
menu : View NoGap Msg
menu =
    Layout.column
        [ Neat.textBlock "item1"
            |> setClass "menu_item"
            |> fromNoGap menuGap
        , Neat.textBlock "item2"
            |> setClass "menu_item"
            |> fromNoGap menuGap
        ]
        |> setBoundary menuGap
        |> setClass "menu"
```
`fromNoGap`によって特別なものに変わってしまうので、その前にsetClassでクラスを設定します。
もともとNoGap型にしか適用できません。

# fill
```elm
menu : View NoGap Msg
menu =
    Layout.column
        [ Neat.textBlock "item1"
            |> setClass "menu_item"
            |> fromNoGap menuGap
        , Neat.textBlock "item2"
            --|> setLayout Layout.fill
            |> setClass "menu_item"
            --|> setLayout Layout.fill
            |> fromNoGap menuGap
            |> setLayout Layout.fill
        ]
        |> setBoundary menuGap
        |> setClass "menu"
        --|> setLayout Layout.fill これは間違い
```
fillはcolumnなどの中で要素を拡大させるために使うみたいです。

elm-uiで自分は、なんだかとにかく大きくしたいから`width fill`としていたような気がしますが、なるほどと思いました。

columnの中といっても、どこに書くのがいいんだろうと思いましたが、どこでも変わらなそうです。

```
column{display: flex}
    menuGap{}
        menu_item{}
    menuGap{flex-grow: 1}
        menu_item{}
````
どこに書いても最終的にこうなるイメージだと思います。

# スクロール
row内部の要素にスクロールバーをつけてみようとしました。

```
main{height: 100vh}
    header
    body
    footer
```
まずこのように上の要素に勝手に拡大しないheightを指定しなければならないとならないみたいです。

arowMさんに聞いてしまって(ありがとうございました)その時は解決したのですが、その後rowのなかに入れたり余白を適用させたり、wrapで改行させたりすると、うまく行かなくなってしまいました。

あちらを立てればこちらが立たずといった感じで、cssなどの知識も足りずそこそこで諦めました。


```
NoGap
    NoGap{overflow-y: auto}
```
内部であってもこのようなときなら良さそうです。
それから、rowやcolumnを改行させないNoWrapでも良さそうです。

### 敗北

elm-neat-layoutの作ったdivにブラウザのdev toolで`overflow: hidden`をつけまくるとうまく動いたような気がしたのですが、どういう理屈・意味でそうなるのかはよくわかりませんでした。

```
hight: auto
    hight: 100%
```
それから、これは何がどういうことになるのかもわかりませんでした。
たぶん100%とあっても上で具体的な値が設定されていないのでautoになるのかもしれません。
トップダウンなんだか、ボトムアップなんだかややこしいです。

### 逃げ道
スクロールをつけたい要素に`max-height: 80vh`のようにしてしまいました。
というわけで、下はきっちりな余白を諦めました。

そもそもrowにwrapで改行させるようなことをせず`overflow: hidden`でなんとかなった気がします。

# まとめ
殆どの時間をcssに苦しめられていました。
たしかにきれいに見えて余白は重要そうです。