1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-19 02:27:03 +00:00

Merge branch 'feature/keybd-nav' into develop

This commit is contained in:
James Hillyerd
2019-02-17 14:05:19 -08:00
7 changed files with 276 additions and 128 deletions

View File

@@ -1,4 +1,4 @@
module Layout exposing (Page(..), frame) module Layout exposing (Model, Msg, Page(..), frame, init, reset, update)
import Data.Session as Session exposing (Session) import Data.Session as Session exposing (Session)
import Html exposing (..) import Html exposing (..)
@@ -29,56 +29,124 @@ type Page
| Status | Status
type alias FrameControls msg = type alias Model msg =
{ viewMailbox : String -> msg { mapMsg : Msg -> msg
, mailboxOnInput : String -> msg , menuVisible : Bool
, mailboxValue : String , recentVisible : Bool
, recentOptions : List String , mailboxName : String
, recentActive : String
, clearFlash : msg
, showMenu : Bool
, toggleMenu : msg
} }
frame : FrameControls msg -> Session -> Page -> Maybe (Html msg) -> List (Html msg) -> Html msg init : (Msg -> msg) -> Model msg
frame controls session activePage modal content = init mapMsg =
{ mapMsg = mapMsg
, menuVisible = False
, recentVisible = False
, mailboxName = ""
}
{-| Resets layout state, used when navigating to a new page.
-}
reset : Model msg -> Model msg
reset model =
{ model
| menuVisible = False
, recentVisible = False
, mailboxName = ""
}
type Msg
= ClearFlash
| OnMailboxNameInput String
| OpenMailbox
| ShowRecent Bool
| ToggleMenu
update : Msg -> Model msg -> Session -> ( Model msg, Session, Cmd msg )
update msg model session =
case msg of
ClearFlash ->
( model
, Session.clearFlash session
, Cmd.none
)
OnMailboxNameInput name ->
( { model | mailboxName = name }
, session
, Cmd.none
)
OpenMailbox ->
( model
, session
, Route.pushUrl session.key (Route.Mailbox model.mailboxName)
)
ShowRecent visible ->
( { model | recentVisible = visible }
, session
, Cmd.none
)
ToggleMenu ->
( { model | menuVisible = not model.menuVisible }
, session
, Cmd.none
)
type alias State msg =
{ model : Model msg
, session : Session
, activePage : Page
, activeMailbox : String
, modal : Maybe (Html msg)
, content : List (Html msg)
}
frame : State msg -> Html msg
frame { model, session, activePage, activeMailbox, modal, content } =
div [ class "app" ] div [ class "app" ]
[ header [] [ header []
[ nav [ class "navbar" ] [ nav [ class "navbar" ]
[ span [ class "navbar-toggle", Events.onClick controls.toggleMenu ] [ button [ class "navbar-toggle", Events.onClick (ToggleMenu |> model.mapMsg) ]
[ i [ class "fas fa-bars" ] [] ] [ i [ class "fas fa-bars" ] [] ]
, span [ class "navbar-brand" ] , span [ class "navbar-brand" ]
[ a [ Route.href Route.Home ] [ text "@ inbucket" ] ] [ a [ Route.href Route.Home ] [ text "@ inbucket" ] ]
, ul [ classList [ ( "main-nav", True ), ( "active", controls.showMenu ) ] ] , ul [ class "main-nav", classList [ ( "active", model.menuVisible ) ] ]
[ li [ class "navbar-mailbox" ] [ if session.config.monitorVisible then
[ form [ Events.onSubmit (controls.viewMailbox controls.mailboxValue) ]
[ input
[ type_ "text"
, placeholder "mailbox"
, value controls.mailboxValue
, Events.onInput controls.mailboxOnInput
]
[]
]
]
, if session.config.monitorVisible then
navbarLink Monitor Route.Monitor [ text "Monitor" ] activePage navbarLink Monitor Route.Monitor [ text "Monitor" ] activePage
else else
text "" text ""
, navbarLink Status Route.Status [ text "Status" ] activePage , navbarLink Status Route.Status [ text "Status" ] activePage
, navbarRecent activePage controls , navbarRecent activePage activeMailbox model session
, li [ class "navbar-mailbox" ]
[ form [ Events.onSubmit (OpenMailbox |> model.mapMsg) ]
[ input
[ type_ "text"
, placeholder "mailbox"
, value model.mailboxName
, Events.onInput (OnMailboxNameInput >> model.mapMsg)
]
[]
]
]
] ]
] ]
] ]
, div [ class "navbar-bg" ] [ text "" ] , div [ class "navbar-bg" ] [ text "" ]
, frameModal modal , frameModal modal
, div [ class "page" ] ([ errorFlash controls session.flash ] ++ content) , div [ class "page" ] ([ errorFlash model session.flash ] ++ content)
, footer [] , footer []
[ div [ class "footer" ] [ div [ class "footer" ]
[ externalLink "https://www.inbucket.org" "Inbucket" [ externalLink "https://www.inbucket.org" "Inbucket"
, text " is an open source projected hosted at " , text " is an open source project hosted on "
, externalLink "https://github.com/jhillyerd/inbucket" "GitHub" , externalLink "https://github.com/jhillyerd/inbucket" "GitHub"
, text "." , text "."
] ]
@@ -98,8 +166,8 @@ frameModal maybeModal =
text "" text ""
errorFlash : FrameControls msg -> Maybe Session.Flash -> Html msg errorFlash : Model msg -> Maybe Session.Flash -> Html msg
errorFlash controls maybeFlash = errorFlash model maybeFlash =
let let
row ( heading, message ) = row ( heading, message ) =
tr [] tr []
@@ -115,7 +183,7 @@ errorFlash controls maybeFlash =
div [ class "well well-error" ] div [ class "well well-error" ]
[ div [ class "flash-header" ] [ div [ class "flash-header" ]
[ h2 [] [ text flash.title ] [ h2 [] [ text flash.title ]
, a [ href "#", Events.onClick controls.clearFlash ] [ text "Close" ] , a [ href "#", Events.onClick (ClearFlash |> model.mapMsg) ] [ text "Close" ]
] ]
, div [ class "flash-table" ] (List.map row flash.table) , div [ class "flash-table" ] (List.map row flash.table)
] ]
@@ -129,21 +197,22 @@ externalLink url title =
navbarLink : Page -> Route -> List (Html a) -> Page -> Html a navbarLink : Page -> Route -> List (Html a) -> Page -> Html a
navbarLink page route linkContent activePage = navbarLink page route linkContent activePage =
li [ classList [ ( "navbar-active", page == activePage ) ] ] li [ classList [ ( "navbar-active", page == activePage ) ] ]
[ a [ class "navbar-active-bg", Route.href route ] linkContent ] [ a [ Route.href route ] linkContent ]
{-| Renders list of recent mailboxes, selecting the currently active mailbox. {-| Renders list of recent mailboxes, selecting the currently active mailbox.
-} -}
navbarRecent : Page -> FrameControls msg -> Html msg navbarRecent : Page -> String -> Model msg -> Session -> Html msg
navbarRecent page controls = navbarRecent page activeMailbox model session =
let let
-- Active means we are viewing a specific mailbox.
active = active =
page == Mailbox page == Mailbox
-- Recent tab title is the name of the current mailbox when active. -- Recent tab title is the name of the current mailbox when active.
title = title =
if active then if active then
controls.recentActive activeMailbox
else else
"Recent Mailboxes" "Recent Mailboxes"
@@ -151,18 +220,46 @@ navbarRecent page controls =
-- Mailboxes to show in recent list, doesn't include active mailbox. -- Mailboxes to show in recent list, doesn't include active mailbox.
recentMailboxes = recentMailboxes =
if active then if active then
List.tail controls.recentOptions |> Maybe.withDefault [] List.tail session.persistent.recentMailboxes |> Maybe.withDefault []
else else
controls.recentOptions session.persistent.recentMailboxes
dropdownExpanded =
if model.recentVisible then
"true"
else
"false"
recentLink mailbox = recentLink mailbox =
a [ Route.href (Route.Mailbox mailbox) ] [ text mailbox ] a [ Route.href (Route.Mailbox mailbox) ] [ text mailbox ]
in in
li li
[ class "navbar-recent" [ class "navbar-dropdown-container"
, classList [ ( "navbar-dropdown", True ), ( "navbar-active", active ) ] , classList [ ( "navbar-active", active ) ]
, attribute "aria-haspopup" "true"
, ariaExpanded model.recentVisible
, Events.onMouseOver (ShowRecent True |> model.mapMsg)
, Events.onMouseOut (ShowRecent False |> model.mapMsg)
] ]
[ span [ class "navbar-active-bg" ] [ text title ] [ span [ class "navbar-dropdown" ]
[ text title
, button
[ class "navbar-dropdown-button"
, Events.onClick (ShowRecent (not model.recentVisible) |> model.mapMsg)
]
[ i [ class "fas fa-chevron-down" ] [] ]
]
, div [ class "navbar-dropdown-content" ] (List.map recentLink recentMailboxes) , div [ class "navbar-dropdown-content" ] (List.map recentLink recentMailboxes)
] ]
ariaExpanded : Bool -> Attribute msg
ariaExpanded value =
attribute "aria-expanded" <|
if value then
"true"
else
"false"

View File

@@ -23,9 +23,8 @@ import Url exposing (Url)
type alias Model = type alias Model =
{ page : PageModel { layout : Layout.Model Msg
, mailboxName : String , page : PageModel
, showMenu : Bool
} }
@@ -62,9 +61,8 @@ init configValue location key =
Home.init session Home.init session
initModel = initModel =
{ page = Home subModel { layout = Layout.init LayoutMsg
, mailboxName = "" , page = Home subModel
, showMenu = False
} }
route = route =
@@ -81,10 +79,7 @@ type Msg
| LinkClicked UrlRequest | LinkClicked UrlRequest
| SessionUpdated (Result D.Error Session.Persistent) | SessionUpdated (Result D.Error Session.Persistent)
| TimeZoneLoaded Time.Zone | TimeZoneLoaded Time.Zone
| ClearFlash | LayoutMsg Layout.Msg
| OnMailboxNameInput String
| ViewMailbox String
| ToggleMenu
| HomeMsg Home.Msg | HomeMsg Home.Msg
| MailboxMsg Mailbox.Msg | MailboxMsg Mailbox.Msg
| MonitorMsg Monitor.Msg | MonitorMsg Monitor.Msg
@@ -182,11 +177,6 @@ updateMain msg model session =
, Cmd.none , Cmd.none
) )
ClearFlash ->
( applyToModelSession Session.clearFlash model
, Cmd.none
)
SessionUpdated (Ok persistent) -> SessionUpdated (Ok persistent) ->
( updateSession model { session | persistent = persistent } ( updateSession model { session | persistent = persistent }
, Cmd.none , Cmd.none
@@ -208,17 +198,15 @@ updateMain msg model session =
, Cmd.none , Cmd.none
) )
OnMailboxNameInput name -> LayoutMsg subMsg ->
( { model | mailboxName = name }, Cmd.none ) let
( layout, newSession, cmd ) =
ViewMailbox name -> Layout.update subMsg model.layout session
( applyToModelSession Session.clearFlash { model | mailboxName = "" } in
, Route.pushUrl session.key (Route.Mailbox name) ( updateSession { model | layout = layout } newSession
, cmd
) )
ToggleMenu ->
( { model | showMenu = not model.showMenu }, Cmd.none )
_ -> _ ->
updatePage msg model updatePage msg model
@@ -256,7 +244,7 @@ changeRouteTo route model =
getSession model getSession model
newModel = newModel =
{ model | showMenu = False } { model | layout = Layout.reset model.layout }
in in
case route of case route of
Route.Unknown path -> Route.Unknown path ->
@@ -372,17 +360,6 @@ view model =
_ -> _ ->
"" ""
controls =
{ viewMailbox = ViewMailbox
, mailboxOnInput = OnMailboxNameInput
, mailboxValue = model.mailboxName
, recentOptions = session.persistent.recentMailboxes
, recentActive = mailbox
, clearFlash = ClearFlash
, showMenu = model.showMenu
, toggleMenu = ToggleMenu
}
framePage : framePage :
Layout.Page Layout.Page
-> (msg -> Msg) -> (msg -> Msg)
@@ -391,11 +368,13 @@ view model =
framePage page toMsg { title, modal, content } = framePage page toMsg { title, modal, content } =
Document title Document title
[ Layout.frame [ Layout.frame
controls { model = model.layout
session , session = session
page , activePage = page
(Maybe.map (Html.map toMsg) modal) , activeMailbox = mailbox
(List.map (Html.map toMsg) content) , modal = Maybe.map (Html.map toMsg) modal
, content = List.map (Html.map toMsg) content
}
] ]
in in
case model.page of case model.page of

View File

@@ -17,15 +17,16 @@ import Html.Attributes
, id , id
, placeholder , placeholder
, property , property
, tabindex
, target , target
, type_ , type_
, value , value
) )
import Html.Events exposing (..) import Html.Events as Events
import Http exposing (Error) import Http exposing (Error)
import HttpUtil import HttpUtil
import Json.Decode as Decode exposing (Decoder) import Json.Decode as D
import Json.Encode as Encode import Json.Encode as E
import Ports import Ports
import Route import Route
import Task import Task
@@ -135,6 +136,7 @@ subscriptions model =
type Msg type Msg
= ListLoaded (Result HttpUtil.Error (List MessageHeader)) = ListLoaded (Result HttpUtil.Error (List MessageHeader))
| ClickMessage MessageID | ClickMessage MessageID
| ListKeyPress String Int
| OpenMessage MessageID | OpenMessage MessageID
| CloseMessage | CloseMessage
| MessageLoaded (Result HttpUtil.Error Message) | MessageLoaded (Result HttpUtil.Error Message)
@@ -165,7 +167,7 @@ update msg model =
) )
OpenMessage id -> OpenMessage id ->
updateOpenMessage model.session model id updateOpenMessage model id
CloseMessage -> CloseMessage ->
case model.state of case model.state of
@@ -186,6 +188,14 @@ update msg model =
, Cmd.none , Cmd.none
) )
ListKeyPress id keyCode ->
case keyCode of
13 ->
updateOpenMessage model id
_ ->
( model, Cmd.none )
ListLoaded (Ok headers) -> ListLoaded (Ok headers) ->
case model.state of case model.state of
LoadingList selection -> LoadingList selection ->
@@ -197,7 +207,7 @@ update msg model =
in in
case selection of case selection of
Just id -> Just id ->
updateOpenMessage model.session newModel id updateOpenMessage newModel id
Nothing -> Nothing ->
( { newModel ( { newModel
@@ -458,8 +468,8 @@ updateMarkMessageSeen model message =
( model, Cmd.none ) ( model, Cmd.none )
updateOpenMessage : Session -> Model -> String -> ( Model, Cmd Msg ) updateOpenMessage : Model -> String -> ( Model, Cmd Msg )
updateOpenMessage session model id = updateOpenMessage model id =
let let
newModel = newModel =
{ model | session = Session.addRecent model.mailboxName model.session } { model | session = Session.addRecent model.mailboxName model.session }
@@ -492,12 +502,12 @@ view model =
[ input [ input
[ type_ "search" [ type_ "search"
, placeholder "search" , placeholder "search"
, onInput OnSearchInput , Events.onInput OnSearchInput
, value model.searchInput , value model.searchInput
] ]
[] []
, button , button
[ onClick PurgeMailboxPrompt [ Events.onClick PurgeMailboxPrompt
, alt "Purge Mailbox" , alt "Purge Mailbox"
] ]
[ i [ class "fas fa-trash" ] [] ] [ i [ class "fas fa-trash" ] [] ]
@@ -533,8 +543,8 @@ viewModal promptPurge =
div [] div []
[ p [] [ text "Are you sure you want to delete all messages in this mailbox?" ] [ p [] [ text "Are you sure you want to delete all messages in this mailbox?" ]
, div [ class "button-bar" ] , div [ class "button-bar" ]
[ button [ onClick PurgeMailboxConfirmed, class "danger" ] [ text "Yes" ] [ button [ Events.onClick PurgeMailboxConfirmed, class "danger" ] [ text "Yes" ]
, button [ onClick PurgeMailboxCanceled ] [ text "Cancel" ] , button [ Events.onClick PurgeMailboxCanceled ] [ text "Cancel" ]
] ]
] ]
@@ -559,12 +569,14 @@ viewMessageList session model =
messageChip : Model -> Maybe MessageID -> MessageHeader -> Html Msg messageChip : Model -> Maybe MessageID -> MessageHeader -> Html Msg
messageChip model selected message = messageChip model selected message =
div div
[ classList [ class "message-list-entry"
[ ( "message-list-entry", True ) , classList
, ( "selected", selected == Just message.id ) [ ( "selected", selected == Just message.id )
, ( "unseen", not message.seen ) , ( "unseen", not message.seen )
] ]
, onClick (ClickMessage message.id) , Events.onClick (ClickMessage message.id)
, onKeyUp (ListKeyPress message.id)
, tabindex 0
] ]
[ div [ class "subject" ] [ text message.subject ] [ div [ class "subject" ] [ text message.subject ]
, div [ class "from" ] [ text message.from ] , div [ class "from" ] [ text message.from ]
@@ -586,18 +598,16 @@ viewMessage zone message bodyMode =
text "" text ""
else else
a a [ href htmlUrl, target "_blank" ]
[ href htmlUrl, target "_blank" ] [ button [ tabindex -1 ] [ text "Raw HTML" ] ]
[ button [] [ text "Raw HTML" ] ]
in in
div [] div []
[ div [ class "button-bar" ] [ div [ class "button-bar" ]
[ button [ class "message-close light", onClick CloseMessage ] [ button [ class "message-close light", Events.onClick CloseMessage ]
[ i [ class "fas fa-arrow-left" ] [] ] [ i [ class "fas fa-arrow-left" ] [] ]
, button [ class "danger", onClick (DeleteMessage message) ] [ text "Delete" ] , button [ class "danger", Events.onClick (DeleteMessage message) ] [ text "Delete" ]
, a , a [ href sourceUrl, target "_blank" ]
[ href sourceUrl, target "_blank" ] [ button [ tabindex -1 ] [ text "Source" ] ]
[ button [] [ text "Source" ] ]
, htmlButton , htmlButton
] ]
, dl [ class "message-header" ] , dl [ class "message-header" ]
@@ -644,7 +654,7 @@ messageBody message bodyMode =
bodyModeTab mode label = bodyModeTab mode label =
a a
[ classList [ ( "active", bodyMode == mode ) ] [ classList [ ( "active", bodyMode == mode ) ]
, onClick (MessageBody mode) , Events.onClick (MessageBody mode)
, href "#" , href "#"
] ]
[ text label ] [ text label ]
@@ -667,10 +677,10 @@ messageBody message bodyMode =
, article [ class "message-body" ] , article [ class "message-body" ]
[ case bodyMode of [ case bodyMode of
SafeHtmlBody -> SafeHtmlBody ->
Html.node "rendered-html" [ property "content" (Encode.string message.html) ] [] Html.node "rendered-html" [ property "content" (E.string message.html) ] []
TextBody -> TextBody ->
Html.node "rendered-html" [ property "content" (Encode.string message.text) ] [] Html.node "rendered-html" [ property "content" (E.string message.text) ] []
] ]
] ]
@@ -750,3 +760,8 @@ filterMessageList list =
|| String.contains list.searchFilter (String.toLower header.from) || String.contains list.searchFilter (String.toLower header.from)
in in
List.filter matches list.headers List.filter matches list.headers
onKeyUp : (Int -> msg) -> Attribute msg
onKeyUp tagger =
Events.on "keyup" (D.map tagger Events.keyCode)

View File

@@ -36,6 +36,7 @@ type Msg
| MessageReceived D.Value | MessageReceived D.Value
| Clear | Clear
| OpenMessage MessageHeader | OpenMessage MessageHeader
| MessageKeyPress MessageHeader Int
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> ( Model, Cmd Msg )
@@ -69,9 +70,22 @@ update msg model =
( { model | messages = [] }, Cmd.none ) ( { model | messages = [] }, Cmd.none )
OpenMessage header -> OpenMessage header ->
( model openMessage header model
, Route.pushUrl model.session.key (Route.Message header.mailbox header.id)
) MessageKeyPress header keyCode ->
case keyCode of
13 ->
openMessage header model
_ ->
( model, Cmd.none )
openMessage : MessageHeader -> Model -> ( Model, Cmd Msg )
openMessage header model =
( model
, Route.pushUrl model.session.key (Route.Message header.mailbox header.id)
)
@@ -121,7 +135,11 @@ view model =
viewMessage : Time.Zone -> MessageHeader -> Html Msg viewMessage : Time.Zone -> MessageHeader -> Html Msg
viewMessage zone message = viewMessage zone message =
tr [ Events.onClick (OpenMessage message) ] tr
[ tabindex 0
, Events.onClick (OpenMessage message)
, onKeyUp (MessageKeyPress message)
]
[ td [] [ shortDate zone message.date ] [ td [] [ shortDate zone message.date ]
, td [ class "desktop" ] [ text message.from ] , td [ class "desktop" ] [ text message.from ]
, td [] [ text message.mailbox ] , td [] [ text message.mailbox ]
@@ -147,3 +165,8 @@ shortDate zone date =
zone zone
date date
|> text |> text
onKeyUp : (Int -> msg) -> Attribute msg
onKeyUp tagger =
Events.on "keyup" (D.map tagger Events.keyCode)

View File

@@ -18,6 +18,18 @@
display: flex; display: flex;
} }
.message-list-controls button,
.message-list-controls input[type="search"] {
border: 1px solid var(--border-color);
border-radius: 3px;
}
.message-list-controls button {
color: var(--low-color);
margin-left: 1px;
padding: 0 6px;
}
.message-list-controls input[type="search"] { .message-list-controls input[type="search"] {
flex: 1 1 auto; flex: 1 1 auto;
padding: 2px 4px; padding: 2px 4px;

View File

@@ -15,7 +15,7 @@ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code, a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, small, strike, strong, sub, sup, tt, var,
b, u, i, center, b, u, i, center, button,
dl, dt, dd, ol, ul, li, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend, fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td, table, caption, tbody, tfoot, thead, tr, th, td,
@@ -44,13 +44,17 @@ body {
background-color: var(--bg-color); background-color: var(--bg-color);
} }
body, input, table { body, button, input, table {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px; font-size: 14px;
line-height: 1.43; line-height: 1.43;
color: var(--primary-color); color: var(--primary-color);
} }
button {
background: none;
}
h1, h2, h3, h4, h5, h6, p { h1, h2, h3, h4, h5, h6, p {
margin-bottom: 10px; margin-bottom: 10px;
} }

View File

@@ -30,29 +30,35 @@
.navbar-toggle { .navbar-toggle {
color: var(--navbar-color); color: var(--navbar-color);
font-size: 24px; font-size: 24px;
padding: 0 6px;
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 20px; right: 14px;
} }
.navbar a, .navbar a,
.navbar-dropdown span { .navbar-dropdown {
color: var(--navbar-color); color: var(--navbar-color);
display: block; display: block;
padding: 15px; padding: 15px;
text-decoration: none; text-decoration: none;
} }
/* This takes precendence over .navbar a above */
.navbar-brand a { .navbar-brand a {
display: inline-block; display: inline-block;
padding: 12px 15px; padding: 12px 15px;
} }
.navbar-dropdown-button {
display: none;
}
.navbar li { .navbar li {
color: var(--navbar-color); color: var(--navbar-color);
} }
li.navbar-active .navbar-active-bg { li.navbar-active > *:first-child {
background-color: #080808; background-color: #080808;
} }
@@ -83,8 +89,7 @@ li.navbar-active span,
} }
@media screen and (min-width: 1000px) { @media screen and (min-width: 1000px) {
.main-nav, .main-nav {
.navbar-bg {
height: var(--navbar-height); height: var(--navbar-height);
} }
@@ -110,16 +115,17 @@ li.navbar-active span,
background-image: var(--navbar-image); background-image: var(--navbar-image);
grid-column: 1 / 4; grid-column: 1 / 4;
grid-row: 1; grid-row: 1;
height: var(--navbar-height);
width: 100%; width: 100%;
z-index: -1; z-index: -1;
} }
.navbar-brand { .navbar-toggle {
margin-left: -15px; display: none;
} }
.navbar-recent { .navbar-brand {
margin: 0 auto; margin-left: -15px;
} }
.navbar-mailbox { .navbar-mailbox {
@@ -131,6 +137,22 @@ li.navbar-active span,
margin-top: 1px; margin-top: 1px;
} }
.navbar-dropdown-container {
margin: 0 auto;
}
.navbar-dropdown {
padding: 15px 19px 15px 25px;
}
.navbar-dropdown-button {
background: none;
border: none;
color: var(--navbar-color);
display: inline;
margin-left: 3px;
}
.navbar-dropdown-content { .navbar-dropdown-content {
background-color: var(--bg-color); background-color: var(--bg-color);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
@@ -143,7 +165,7 @@ li.navbar-active span,
z-index: 1; z-index: 1;
} }
.navbar-dropdown:hover .navbar-dropdown-content { .navbar-dropdown-container[aria-expanded="true"] .navbar-dropdown-content {
display: block; display: block;
} }
@@ -156,8 +178,4 @@ li.navbar-active span,
color: var(--primary-color) !important; color: var(--primary-color) !important;
background-color: var(--selected-color); background-color: var(--selected-color);
} }
.navbar-toggle {
display: none;
}
} }