如何使用Elm最好是Elm-UI制作可拖动的拆分面板?

问题描述

我为Elm寻找一块隔板,发现似乎不太容易使用的东西。

doodledood / elm-split-pane与Elm 0.19.1不兼容,所以我想我要么必须切换到Elm 0.18,要么将其转换为Elm 0.19.1才能使用。也是根据Elm HTML而不是Elm UI定义的。

我还发现了https://github.com/ellie-app/ellie/blob/master/assets/src/Ellie/Ui/SplitPane.elm。这涉及到一堆自定义JavaScript,对我来说,这与应用程序的其余部分之间的紧密联系并不明显。

解决方法

我在elm项目中使用elm-ui使用拆分窗格。我将这个基于SplitPane elm-html的程序包https://github.com/doodledood/elm-split-pane复制到了我的项目中,并通过包装内容和属性将其内部信息转换为从视图函数返回Element msg的内容。

以下是转换后的函数的源代码:

view : ViewConfig msg -> Element msg -> Element msg -> State -> Element msg
view (ViewConfig viewConfig) firstView secondView (State state) =
    let
        splitter =
            getConcreteSplitter viewConfig state.orientation state.dragState
    in
    case state.orientation of
        Horizontal ->
            row
                (paneContainerStyle state.orientation
                    ++ [ width fill ]
                )
                [ el (firstChildViewStyle (State state)) firstView,splitter,el (secondChildViewStyle (State state)) secondView
                ]

        Vertical ->
            column (paneContainerStyle state.orientation)
                [ el (firstChildViewStyle (State state)) firstView,el (secondChildViewStyle (State state)) secondView
                ]


viewReversed : ViewConfig msg -> Element msg -> Element msg -> State -> Element msg
viewReversed (ViewConfig viewConfig) firstView secondView (State state) =
    let
        splitter =
            getConcreteSplitter viewConfig state.orientation state.dragState
    in
    case state.orientation of
        Horizontal ->
            row
                (paneContainerStyle state.orientation
                    ++ [ width fill ]
                )
                [ el (secondChildViewStyle (State state)) secondView,el (firstChildViewStyle (State state)) firstView
                ]

        Vertical ->
            column (paneContainerStyle state.orientation)
                [ el (secondChildViewStyle (State state)) firstView,el (firstChildViewStyle (State state)) firstView
                ]


getConcreteSplitter :
    { toMsg : Msg -> msg,splitter : Maybe (CustomSplitter msg)
    }
    -> Orientation
    -> DragState
    -> Element msg
getConcreteSplitter viewConfig orientation4 dragState =
    case viewConfig.splitter of
        Just (CustomSplitter splitter) ->
            splitter

        Nothing ->
            case createCustomSplitter viewConfig.toMsg <| createDefaultSplitterDetails orientation4 dragState of
                CustomSplitter defaultSplitter ->
                    defaultSplitter

以下是样式功能:

paneContainerStyle : Orientation -> List (Attribute msg)
paneContainerStyle orientation5 =
    [ style "overflow" "hidden",style "display" "flex",style "flexDirection"
        (case orientation5 of
            Horizontal ->
                "row"

            Vertical ->
                "column"
        ),style "justifyContent" "center",style "alignItems" "center",style "width" "100%",style "height" "100%",style "boxSizing" "border-box"
    ]
        |> List.map Element.htmlAttribute


firstChildViewStyle : State -> List (Attribute msg)
firstChildViewStyle (State state) =
    case state.splitterPosition of
        Px px2 ->
            let
                v =
                    (String.fromFloat <| toFloat (getValue px2)) ++ "px"
            in
            case state.orientation of
                Horizontal ->
                    [ style "display" "flex",style "width" v,style "overflow" "hidden",style "boxSizing" "border-box",style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

                Vertical ->
                    [ style "display" "flex",style "height" v,style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| getValue p
            in
            [ style "display" "flex",style "flex" v,style "height" "100%" -- pz edit,style "position" "relative"
            ]
                |> List.map Element.htmlAttribute


secondChildViewStyle : State -> List (Attribute msg)
secondChildViewStyle (State state) =
    case state.splitterPosition of
        Px _ ->
            [ style "display" "flex",style "flex" "1",style "position" "relative"
            ]
                |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| 1 - getValue p
            in
            [ style "display" "flex",style "position" "relative"
            ]
                |> List.map Element.htmlAttribute

乌里