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

如何使用Elm(最好是Elm UI)制作可拖动的拆分面板?,elm,Elm,我为Elm寻找了一个拆分窗格,发现了一些似乎不容易使用的东西 doodledood/elm拆分窗格与elm 0.19.1不兼容,因此我想我要么切换到elm 0.18,要么将其转换为elm 0.19.1才能使用它。它也是根据Elm HTML而不是Elm UI定义的 我也发现了。这涉及到大量定制JavaScript,我不清楚它与应用程序其余部分的耦合有多紧密。我在elm项目的elm ui中使用了拆分窗格。我使用这个基于SplitPane-elm-html的包,将其源代码复制到我的项目中,并通过包装内

我为Elm寻找了一个拆分窗格,发现了一些似乎不容易使用的东西

doodledood/elm拆分窗格与elm 0.19.1不兼容,因此我想我要么切换到elm 0.18,要么将其转换为elm 0.19.1才能使用它。它也是根据Elm HTML而不是Elm UI定义的


我也发现了。这涉及到大量定制JavaScript,我不清楚它与应用程序其余部分的耦合有多紧密。

我在elm项目的elm ui中使用了拆分窗格。我使用这个基于SplitPane-elm-html的包,将其源代码复制到我的项目中,并通过包装内容和属性,将其内部转换为从其视图函数返回元素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
                , splitter
                , 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
                , splitter
                , el (firstChildViewStyle (State state)) firstView
                ]

        Vertical ->
            column (paneContainerStyle state.orientation)
                [ el (secondChildViewStyle (State state)) firstView
                , splitter
                , 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 "height" "100%"
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

                Vertical ->
                    [ style "display" "flex"
                    , style "width" "100%"
                    , style "height" v
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%" -- pz edit
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , 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 "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| 1 - getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute
view:ViewConfig msg->Element msg->Element msg->State->Element msg
视图(视图配置视图配置)第一视图第二视图(状态)=
让
分离器=
getConcreteSplitter viewConfig state.orientation state.dragState
在里面
案例状态
水平->
一行
(paneContainerStyle state.orientation
++[宽度填充]
)
[el(firstChildViewStyle(State))firstView
,分离器
,el(secondChildViewStyle(State-State))secondView
]
垂直->
列(paneContainerStyle状态.方向)
[el(firstChildViewStyle(State))firstView
,分离器
,el(secondChildViewStyle(State-State))secondView
]
视图反转:视图配置消息->元素消息->元素消息->状态->元素消息
视图反转(视图配置视图配置)第一视图第二视图(状态)=
让
分离器=
getConcreteSplitter viewConfig state.orientation state.dragState
在里面
案例状态
水平->
一行
(paneContainerStyle state.orientation
++[宽度填充]
)
[el(secondChildViewStyle(State))secondView
,分离器
,el(firstChildViewStyle(State-State))firstView
]
垂直->
列(paneContainerStyle状态.方向)
[el(secondChildViewStyle(State))firstView
,分离器
,el(firstChildViewStyle(State-State))firstView
]
getConcreteSplitter:
{toMsg:Msg->Msg
,拆分器:可能(CustomSplitter msg)
}
->定向
->德拉斯泰
->元素味精
getConcreteSplitter视图配置方向4 dragState=
的case viewConfig.splitter
仅(自定义拆分器拆分器)->
分离器
没有->
case createCustomSplitter viewConfig.toMsg
默认拆分器
以下是样式和功能:

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
                , splitter
                , 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
                , splitter
                , el (firstChildViewStyle (State state)) firstView
                ]

        Vertical ->
            column (paneContainerStyle state.orientation)
                [ el (secondChildViewStyle (State state)) firstView
                , splitter
                , 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 "height" "100%"
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

                Vertical ->
                    [ style "display" "flex"
                    , style "width" "100%"
                    , style "height" v
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%" -- pz edit
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , 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 "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| 1 - getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute
paneContainerStyle:Orientation->List(属性消息)
paneContainerStyle方向5=
[样式“溢出”“隐藏”
,样式为“显示”“柔性”
,样式“flexDirection”
(案例方向5)
水平->
“行”
垂直->
“栏目”
)
,样式为“justifyContent”“center”
,样式为“对齐项目”“居中”
,样式“宽度”“100%”
,样式“高度”“100%”
,样式“框大小”“边框框”
]
|>List.map Element.htmlAttribute
firstChildViewStyle:状态->列表(属性消息)
firstChildViewStyle(状态)=
case state.splitterPosition
Px px2->
让
五=
(String.fromFloat)
[样式“显示”“柔性”
,样式“宽度”v
,样式“高度”“100%”
,样式为“溢出”“隐藏”
,样式“框大小”“边框框”
,样式为“位置”“相对”
]
|>List.map Element.htmlAttribute
垂直->
[样式“显示”“柔性”
,样式“宽度”“100%”
,样式“高度”v
,样式为“溢出”“隐藏”
,样式“框大小”“边框框”
,样式为“位置”“相对”
]
|>List.map Element.htmlAttribute
百分比p->
让
五=
String.fromFloat List.map Element.htmlAttribute
secondChildViewStyle:状态->列表(属性消息)
secondChildViewStyle(状态)=
case state.splitterPosition
Px->
[样式“显示”“柔性”
,样式为“flex”“1”
,样式“宽度”“100%”
,样式“高度”“100%”
,样式为“溢出”“隐藏”
,样式“框大小”“边框框”
,样式为“位置”“相对”
]
|>List.map Element.htmlAttribute
百分比p->
让
五=
String.fromFloat List.map Element.htmlAttribute

Uri

我在elm ui的elm项目中使用了拆分窗格。我使用了这个基于拆分窗格elm html的包,将其源代码复制到我的项目中,并通过包装内容和属性将其内部转换为从其视图函数返回元素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
                , splitter
                , 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
                , splitter
                , el (firstChildViewStyle (State state)) firstView
                ]

        Vertical ->
            column (paneContainerStyle state.orientation)
                [ el (secondChildViewStyle (State state)) firstView
                , splitter
                , 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 "height" "100%"
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

                Vertical ->
                    [ style "display" "flex"
                    , style "width" "100%"
                    , style "height" v
                    , style "overflow" "hidden"
                    , style "boxSizing" "border-box"
                    , style "position" "relative"
                    ]
                        |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%" -- pz edit
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , 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 "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute

        Percentage p ->
            let
                v =
                    String.fromFloat <| 1 - getValue p
            in
            [ style "display" "flex"
            , style "flex" v
            , style "width" "100%"
            , style "height" "100%"
            , style "overflow" "hidden"
            , style "boxSizing" "border-box"
            , style "position" "relative"
            ]
                |> List.map Element.htmlAttribute
view:ViewConfig msg->Element msg->Element msg->State->Element msg
视图(视图配置视图配置)第一视图第二视图(状态)=
让
分离器=
getConcreteSplitter viewConfig state.orientation state.dragState
在里面
案例状态
水平->
一行
(paneContainerStyle state.o)