mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-10-21 21:00:11 +00:00
318 lines
7.1 KiB
Elm
318 lines
7.1 KiB
Elm
{-
|
|
Copyright 2020 Docspell Contributors
|
|
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
-}
|
|
|
|
|
|
module Comp.MenuBar exposing
|
|
( ButtonData
|
|
, CheckboxData
|
|
, Item(..)
|
|
, MenuBar
|
|
, TextInputData
|
|
, view
|
|
, viewItem
|
|
, viewSide
|
|
)
|
|
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (onCheck, onClick, onInput)
|
|
import Styles as S
|
|
|
|
|
|
type Item msg
|
|
= TextInput (TextInputData msg)
|
|
| Checkbox (CheckboxData msg)
|
|
| PrimaryButton (ButtonData msg)
|
|
| SecondaryButton (ButtonData msg)
|
|
| DeleteButton (ButtonData msg)
|
|
| BasicButton (ButtonData msg)
|
|
| CustomButton (CustomButtonData msg)
|
|
| TextLabel LabelData
|
|
| CustomElement (Html msg)
|
|
| Dropdown (DropdownData msg)
|
|
|
|
|
|
type alias MenuBar msg =
|
|
{ start : List (Item msg)
|
|
, end : List (Item msg)
|
|
, rootClasses : String
|
|
}
|
|
|
|
|
|
type alias TextInputData msg =
|
|
{ tagger : String -> msg
|
|
, value : String
|
|
, placeholder : String
|
|
, icon : Maybe String
|
|
}
|
|
|
|
|
|
type alias CheckboxData msg =
|
|
{ tagger : Bool -> msg
|
|
, label : String
|
|
, value : Bool
|
|
, id : String
|
|
}
|
|
|
|
|
|
type alias ButtonData msg =
|
|
{ tagger : msg
|
|
, title : String
|
|
, icon : Maybe String
|
|
, label : String
|
|
}
|
|
|
|
|
|
type alias CustomButtonData msg =
|
|
{ tagger : msg
|
|
, title : String
|
|
, icon : Maybe String
|
|
, label : String
|
|
, inputClass : List ( String, Bool )
|
|
}
|
|
|
|
|
|
type alias LabelData =
|
|
{ icon : String
|
|
, label : String
|
|
, class : String
|
|
}
|
|
|
|
|
|
type alias DropdownData msg =
|
|
{ linkIcon : String
|
|
, linkClass : List ( String, Bool )
|
|
, toggleMenu : msg
|
|
, menuOpen : Bool
|
|
, items : List (DropdownMenu msg)
|
|
}
|
|
|
|
|
|
type alias DropdownMenu msg =
|
|
{ icon : String
|
|
, label : String
|
|
, attrs : List (Attribute msg)
|
|
}
|
|
|
|
|
|
view : MenuBar msg -> Html msg
|
|
view =
|
|
view1 "bg-white dark:bg-bluegray-800"
|
|
|
|
|
|
viewSide : MenuBar msg -> Html msg
|
|
viewSide =
|
|
view1 "bg-blue-50 dark:bg-bluegray-700"
|
|
|
|
|
|
view1 : String -> MenuBar msg -> Html msg
|
|
view1 classes mb =
|
|
let
|
|
left =
|
|
div [ class "flex flex-row items-center space-x-2 w-full" ]
|
|
(List.map viewItem mb.start)
|
|
|
|
right =
|
|
div [ class "flex-grow flex-row flex justify-end space-x-2 w-full" ]
|
|
(List.map viewItem mb.end)
|
|
in
|
|
div
|
|
[ class mb.rootClasses
|
|
, class "flex flex-col sm:flex-row space-y-1 sm:space-y-0 sticky top-0 z-40"
|
|
, class classes
|
|
]
|
|
[ left
|
|
, right
|
|
]
|
|
|
|
|
|
viewItem : Item msg -> Html msg
|
|
viewItem item =
|
|
case item of
|
|
TextInput model ->
|
|
makeInput model
|
|
|
|
Checkbox model ->
|
|
makeCheckbox model
|
|
|
|
PrimaryButton model ->
|
|
makeButton [ ( S.primaryButton, True ) ] model
|
|
|
|
SecondaryButton model ->
|
|
makeButton [ ( S.secondaryButton, True ) ] model
|
|
|
|
DeleteButton model ->
|
|
makeButton [ ( S.deleteButton, True ) ] model
|
|
|
|
BasicButton model ->
|
|
makeButton [ ( S.secondaryBasicButton, True ) ] model
|
|
|
|
CustomButton model ->
|
|
makeButton model.inputClass model
|
|
|
|
TextLabel model ->
|
|
makeLabel model
|
|
|
|
CustomElement v ->
|
|
v
|
|
|
|
Dropdown model ->
|
|
makeDropdown model
|
|
|
|
|
|
makeDropdown : DropdownData msg -> Html msg
|
|
makeDropdown model =
|
|
let
|
|
menuStyle =
|
|
"absolute right-0 bg-white dark:bg-bluegray-800 border dark:border-bluegray-700 z-50 dark:text-bluegray-300 shadow-lg transition duration-200 min-w-max "
|
|
|
|
itemStyle =
|
|
"transition-colors duration-200 items-center block px-4 py-2 text-normal hover:bg-gray-200 dark:hover:bg-bluegray-700 dark:hover:text-bluegray-50"
|
|
|
|
menuItem m =
|
|
a
|
|
(class itemStyle :: m.attrs)
|
|
[ i
|
|
[ class m.icon
|
|
, classList [ ( "hidden", m.icon == "" ) ]
|
|
]
|
|
[]
|
|
, span
|
|
[ class "ml-2"
|
|
, classList [ ( "hidden", m.label == "" ) ]
|
|
]
|
|
[ text m.label
|
|
]
|
|
]
|
|
in
|
|
div [ class "relative" ]
|
|
[ a
|
|
[ classList model.linkClass
|
|
, class "block"
|
|
, href "#"
|
|
, onClick model.toggleMenu
|
|
]
|
|
[ i [ class model.linkIcon ] []
|
|
]
|
|
, div
|
|
[ class menuStyle
|
|
, classList [ ( "hidden", not model.menuOpen ) ]
|
|
]
|
|
(List.map menuItem model.items)
|
|
]
|
|
|
|
|
|
makeLabel : LabelData -> Html msg
|
|
makeLabel model =
|
|
div
|
|
[ class "flex items-center justify-center "
|
|
, class model.class
|
|
]
|
|
[ i
|
|
[ class model.icon
|
|
, classList [ ( "hidden", model.icon == "" ) ]
|
|
]
|
|
[]
|
|
, text model.label
|
|
]
|
|
|
|
|
|
makeButton :
|
|
List ( String, Bool )
|
|
->
|
|
{ e
|
|
| tagger : msg
|
|
, title : String
|
|
, icon : Maybe String
|
|
, label : String
|
|
}
|
|
-> Html msg
|
|
makeButton btnType model =
|
|
let
|
|
( icon, iconMargin ) =
|
|
case model.icon of
|
|
Just cls ->
|
|
( [ i [ class cls ] []
|
|
]
|
|
, if model.label == "" then
|
|
""
|
|
|
|
else
|
|
"ml-2"
|
|
)
|
|
|
|
Nothing ->
|
|
( [], "" )
|
|
|
|
label =
|
|
if model.label == "" then
|
|
[]
|
|
|
|
else
|
|
[ span [ class (iconMargin ++ " hidden sm:inline") ]
|
|
[ text model.label
|
|
]
|
|
]
|
|
in
|
|
a
|
|
[ classList btnType
|
|
, href "#"
|
|
, onClick model.tagger
|
|
, title model.title
|
|
]
|
|
(icon ++ label)
|
|
|
|
|
|
makeCheckbox : CheckboxData msg -> Html msg
|
|
makeCheckbox model =
|
|
div [ class "" ]
|
|
[ label
|
|
[ class "inline-flex space-x-2 items-center"
|
|
, for model.id
|
|
]
|
|
[ input
|
|
[ type_ "checkbox"
|
|
, onCheck model.tagger
|
|
, checked model.value
|
|
, class S.checkboxInput
|
|
, id model.id
|
|
]
|
|
[]
|
|
, span [ class "truncate" ]
|
|
[ text model.label
|
|
]
|
|
]
|
|
]
|
|
|
|
|
|
makeInput : TextInputData msg -> Html msg
|
|
makeInput model =
|
|
let
|
|
( icon, iconPad ) =
|
|
case model.icon of
|
|
Just cls ->
|
|
( [ div [ class S.inputIcon ]
|
|
[ i [ class cls ] []
|
|
]
|
|
]
|
|
, "pl-10"
|
|
)
|
|
|
|
Nothing ->
|
|
( [], "" )
|
|
in
|
|
div [ class "relative pr-2" ]
|
|
(input
|
|
[ type_ "text"
|
|
, onInput model.tagger
|
|
, value model.value
|
|
, placeholder model.placeholder
|
|
, class (iconPad ++ " pr-4 py-1 rounded" ++ S.textInput)
|
|
]
|
|
[]
|
|
:: icon
|
|
)
|