diff --git a/src/UI/PageLayout.elm b/src/UI/PageLayout.elm index 271e48f..1f4e568 100644 --- a/src/UI/PageLayout.elm +++ b/src/UI/PageLayout.elm @@ -2,7 +2,6 @@ module UI.PageLayout exposing (..) import Html exposing (Html, div, header, section) import Html.Attributes exposing (class, classList) -import UI.AppHeader as AppHeader exposing (AppHeader) import UI.Sidebar as Sidebar @@ -16,18 +15,16 @@ type PageContent msg type PageLayout msg = HeroLayout - { header : AppHeader msg - , hero : PageHero msg + { hero : PageHero msg , content : PageContent msg } | SidebarLayout - { header : AppHeader msg - , sidebar : List (Html msg) + { sidebar : List (Html msg) , sidebarToggled : Bool , content : PageContent msg } - | FullLayout { header : AppHeader msg, content : PageContent msg } + | FullLayout { content : PageContent msg } @@ -47,25 +44,22 @@ viewContent (PageContent content) = view : PageLayout msg -> Html msg view page = case page of - HeroLayout { header, hero, content } -> + HeroLayout { hero, content } -> div [ class "page hero-layout" ] - [ AppHeader.view header - , viewHero hero + [ viewHero hero , viewContent content ] - SidebarLayout { header, sidebar, sidebarToggled, content } -> + SidebarLayout { sidebar, sidebarToggled, content } -> div [ class "page sidebar-layout" , classList [ ( "sidebar-toggled", sidebarToggled ) ] ] - [ AppHeader.view header - , Sidebar.view sidebar + [ Sidebar.view sidebar , viewContent content ] - FullLayout { header, content } -> + FullLayout { content } -> div [ class "page full-layout" ] - [ AppHeader.view header - , viewContent content + [ viewContent content ] diff --git a/src/UnisonLocal/App.elm b/src/UnisonLocal/App.elm index 3060fcf..0a3188d 100644 --- a/src/UnisonLocal/App.elm +++ b/src/UnisonLocal/App.elm @@ -754,33 +754,37 @@ viewModal model = viewAppLoading : Html msg viewAppLoading = - PageLayout.view - (PageLayout.SidebarLayout - { header = AppHeader.appHeader (appTitle Nothing) - , sidebar = [] - , sidebarToggled = False - , content = PageLayout.PageContent [] - } - ) + div [ id "app" ] + [ AppHeader.view (AppHeader.appHeader (appTitle Nothing)) + , PageLayout.view + (PageLayout.SidebarLayout + { sidebar = [] + , sidebarToggled = False + , content = PageLayout.PageContent [] + } + ) + ] viewAppError : Http.Error -> Html msg viewAppError error = - PageLayout.view - (PageLayout.SidebarLayout - { header = AppHeader.appHeader (appTitle Nothing) - , sidebar = [] - , sidebarToggled = False - , content = - PageLayout.PageContent - [ div [ class "app-error" ] - [ Icon.view Icon.warn - , p [ title (Api.errorToString error) ] - [ text "Unison Local could not be started." ] + div [ id "app" ] + [ AppHeader.view (AppHeader.appHeader (appTitle Nothing)) + , PageLayout.view + (PageLayout.SidebarLayout + { sidebar = [] + , sidebarToggled = False + , content = + PageLayout.PageContent + [ div [ class "app-error" ] + [ Icon.view Icon.warn + , p [ title (Api.errorToString error) ] + [ text "Unison Local could not be started." ] + ] ] - ] - } - ) + } + ) + ] view : Model -> Browser.Document Msg @@ -800,12 +804,11 @@ view model = page = PageLayout.SidebarLayout - { header = viewAppHeader model - , sidebar = viewMainSidebar model + { sidebar = viewMainSidebar model , sidebarToggled = model.sidebarToggled , content = PageLayout.PageContent [ pageContent ] } in { title = "Unison Local" - , body = [ div [ id "app" ] [ PageLayout.view page, viewModal model ] ] + , body = [ div [ id "app" ] [ AppHeader.view (viewAppHeader model), PageLayout.view page, viewModal model ] ] } diff --git a/src/UnisonShare/App.elm b/src/UnisonShare/App.elm index fdc7e1b..f8794a0 100644 --- a/src/UnisonShare/App.elm +++ b/src/UnisonShare/App.elm @@ -646,41 +646,43 @@ viewMainSidebar model = viewAppLoading : Html msg viewAppLoading = - PageLayout.view - (PageLayout.FullLayout - { header = AppHeader.appHeader (appTitle Nothing) - , content = PageLayout.PageContent [] - } - ) + div [ id "app" ] + [ AppHeader.view (AppHeader.appHeader (appTitle Nothing)) + , PageLayout.view + (PageLayout.FullLayout + { content = PageLayout.PageContent [] } + ) + ] viewAppError : Http.Error -> Html msg viewAppError error = - PageLayout.view - (PageLayout.FullLayout - { header = AppHeader.appHeader (appTitle Nothing) - , content = - PageLayout.PageContent - [ div [ class "app-error" ] - [ Icon.view Icon.warn - , p [ title (Api.errorToString error) ] - [ text "Unison Share could not be started." ] + div [ id "app" ] + [ AppHeader.view (AppHeader.appHeader (appTitle Nothing)) + , PageLayout.view + (PageLayout.FullLayout + { content = + PageLayout.PageContent + [ div [ class "app-error" ] + [ Icon.view Icon.warn + , p [ title (Api.errorToString error) ] + [ text "Unison Share could not be started." ] + ] ] - ] - } - ) + } + ) + ] view : Model -> Browser.Document Msg view model = let appHeader = - viewAppHeader model + AppHeader.view (viewAppHeader model) withSidebar pageContent = PageLayout.SidebarLayout - { header = viewAppHeader model - , sidebar = viewMainSidebar model + { sidebar = viewMainSidebar model , sidebarToggled = model.sidebarToggled , content = PageLayout.PageContent [ pageContent ] } @@ -688,12 +690,7 @@ view model = page = case model.route of Route.Catalog -> - let - ( m, _ ) = - Catalog.init model.env - in - -- Html.map CatalogMsg (Catalog.view appHeader m) - Catalog.view appHeader m + Html.map CatalogMsg (Catalog.view model.catalog) Route.Perspective _ -> Html.map PerspectiveLandingMsg @@ -712,7 +709,8 @@ view model = { title = "Unison Share" , body = [ div [ id "app" ] - [ page + [ appHeader + , page , Html.map AppModalMsg (AppModal.view model.env model.appModal) ] ] diff --git a/src/UnisonShare/Page/Catalog.elm b/src/UnisonShare/Page/Catalog.elm index 5ade928..0b9ea8b 100644 --- a/src/UnisonShare/Page/Catalog.elm +++ b/src/UnisonShare/Page/Catalog.elm @@ -6,12 +6,12 @@ import Env exposing (Env) import FullyQualifiedName as FQN import Html exposing (Html, a, div, h1, input, strong, text) import Html.Attributes exposing (class, href, placeholder) +import Html.Events exposing (onInput) import Http import Project exposing (ProjectListing) import RemoteData exposing (RemoteData(..), WebData) import Set exposing (Set) import UI -import UI.AppHeader exposing (AppHeader) import UI.Card as Card import UI.Icon as Icon import UI.PageLayout as PageLayout exposing (PageLayout) @@ -133,8 +133,8 @@ viewCategory (Category category projects) = |> Card.view -viewLoaded : AppHeader msg -> LoadedModel -> PageLayout msg -viewLoaded appHeader _ = +viewLoaded : LoadedModel -> PageLayout Msg +viewLoaded model = let content = [ div [ class "categories" ] @@ -165,8 +165,7 @@ viewLoaded appHeader _ = ] in PageLayout.HeroLayout - { header = appHeader - , hero = + { hero = PageLayout.PageHero (div [ class "catalog-hero" ] [ h1 [] @@ -180,37 +179,43 @@ viewLoaded appHeader _ = ] , div [] [ text "Projects, libraries, documention, terms, and types" ] ] - , div [ class "catalog-search" ] [ Icon.view Icon.search, input [ placeholder "Search for projects" ] [] ] + , div [ class "catalog-search" ] + [ Icon.view Icon.search + , input + [ placeholder "Search for projects" + , onInput UpdateQuery + ] + [] + ] ] ) , content = PageLayout.PageContent content } -disabledPage : AppHeader msg -> Html msg -> PageLayout msg -disabledPage appHeader content = +disabledPage : Html Msg -> PageLayout Msg +disabledPage content = PageLayout.HeroLayout - { header = appHeader - , hero = PageLayout.PageHero UI.nothing + { hero = PageLayout.PageHero UI.nothing , content = PageLayout.PageContent [ content ] } -view : AppHeader msg -> Model -> Html msg -view appHeader model = +view : Model -> Html Msg +view model = let page = case model of NotAsked -> - disabledPage appHeader (div [] []) + disabledPage (div [] []) Loading -> - disabledPage appHeader (div [] []) + disabledPage (div [] []) Failure _ -> - disabledPage appHeader (div [] []) + disabledPage (div [] []) Success m -> - viewLoaded appHeader m + viewLoaded m in PageLayout.view page diff --git a/src/css/app.css b/src/css/app.css index 1a96768..f1b1aaa 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1,3 +1,12 @@ +#app { + display: grid; + grid-template-rows: var(--app-header-height) auto; + grid-template-columns: auto; + grid-template-areas: + "app-header" + "page-layout"; +} + /* -- App Error ---------------------------------------------------------- */ .app-error { @@ -15,416 +24,6 @@ color: var(--color-main-alert); } -/* -- Main Sidebar --------------------------------------------------------- */ - -#main-sidebar { - grid-area: main-sidebar; - display: flex; - flex-direction: column; - position: relative; - overflow: visible; - height: calc(100vh - var(--app-header-height)); - background: var(--color-sidebar-bg); - color: var(--color-sidebar-fg); - border-right: 1px solid var(--color-sidebar-border); - font-size: var(--font-size-medium); - z-index: var(--layer-popover); - - box-shadow: 0 -1px 0 var(--color-sidebar-border); - - --color-main-fg: var(--color-sidebar-fg); - --color-main-subtle-fg: var(--color-sidebar-subtle-fg); - - --color-button-default-fg: var(--color-sidebar-button-default-fg); - --color-button-default-bg: var(--color-sidebar-button-default-bg); - --color-button-default-hover-fg: var(--color-sidebar-button-default-hover-fg); - --color-button-default-hover-bg: var(--color-sidebar-button-default-hover-bg); - - --color-tooltip-fg: var(--color-sidebar-tooltip-fg); - --color-tooltip-bg: var(--color-sidebar-tooltip-bg); - --color-tooltip-border: var(--color-sidebar-tooltip-border); - - --color-main-divider: var(--color-sidebar-divider); -} - -#main-sidebar a:hover { - text-decoration: none; -} - -#main-sidebar .expanded-content { - display: flex; - flex-direction: column; - height: calc(100vh - var(--app-header-height)); - opacity: 1; - transition: all var(--transition-sidebar-collapse-time); - transition-delay: var(--transition-sidebar-collapse-time); -} - -#main-sidebar .sidebar-scroll-area { - display: flex; - flex-direction: column; - overflow-y: auto; - overflow-x: hidden; - height: calc(100vh - var(--app-header-height)); - scrollbar-width: thin; - scrollbar-color: var(--color-sidebar-subtle-fg) var(--color-sidebar-bg); - padding: 0rem 1rem 1rem 1.5rem; -} - -#main-sidebar .sidebar-scroll-area::-webkit-scrollbar { - width: 0.4rem; - height: 0.4rem; -} - -#main-sidebar .sidebar-scroll-area::-webkit-scrollbar-track { - background: var(--color-sidebar-bg); -} - -#main-sidebar .sidebar-scroll-area::-webkit-scrollbar-thumb { - background-color: var(--color-sidebar-subtle-fg); - border-radius: 0.2rem; -} - -#main-sidebar .loading-placeholder { - background: var(--color-sidebar-subtle-fg); - opacity: 0.5; -} - -#main-sidebar .sidebar-section { - margin-top: 1.5rem; -} - -#main-sidebar .sidebar-section:first-child { - margin-top: 1rem; -} - -#main-sidebar .sidebar-section-title { - font-size: var(--font-size-medium); - font-weight: normal; - color: var(--color-sidebar-subtle-fg); - text-transform: uppercase; - font-size: 0.75rem; - height: 1.875rem; - display: flex; - align-items: center; - white-space: nowrap; -} - -/* TODO: Consolidate with codebase-tree .node */ - -#main-sidebar .sidebar-item { - margin-left: -0.5rem; - display: flex; - user-select: none; - align-items: center; - border-radius: var(--border-radius-base); - padding-left: 0.5rem; - margin-bottom: 0.125rem; - height: 1.875rem; -} - -#main-sidebar .sidebar-item > label { - color: var(--color-sidebar-fg); - transition: all 0.2s; - cursor: pointer; - overflow: hidden; - text-overflow: ellipsis; - line-height: 1.875; -} - -#main-sidebar .sidebar-item:hover { - background: var(--color-sidebar-focus-bg); - text-decoration: none; -} - -#main-sidebar .divider { - margin: 0; -} - -/* -- Collapsing ----------------------------------------------------------- */ - -#main-sidebar .collapse-sidebar-button { - position: absolute; - left: var(--main-sidebar-width); - top: 1rem; - z-index: var(--layer-popover); - opacity: 0; - transition: opacity 0.2s !important; -} - -#app:not(.sidebar-toggled) .collapse-sidebar-button .button { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - padding-left: 0.2rem; - background: var(--color-sidebar-bg); -} - -#main-sidebar:not(.sidebar-toggled):hover .collapse-sidebar-button { - opacity: 1; -} - -#main-sidebar .collapsed-content { - transform: translateX(-17rem); - width: var(--main-sidebar-collapsed-width); - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - opacity: 0; - transition: all var(--transition-sidebar-collapse-time) ease-in-out; - position: absolute; - bottom: 1rem; - gap: 1.5rem; -} - -#main-sidebar .collapsed-content .keyboard-shortcut:hover .key { - color: var(--color-sidebar-keyboard-shortcut-hover-key-fg); -} - -#main-sidebar .sidebar-header { - padding: 1rem 1.5rem 0 1.5rem; - display: flex; - flex-direction: column; - position: relative; - gap: 1.5rem; - margin-bottom: 0.5rem; -} - -#main-sidebar .sidebar-header:after { - position: absolute; - left: 1.5rem; - right: 1.5rem; - bottom: -2rem; - height: 1.75rem; - content: ""; - background: linear-gradient( - var(--color-sidebar-bg), - var(--color-sidebar-bg), - var(--color-sidebar-bg-transparent) - ); -} - -#main-sidebar .sidebar-header .namespace-slug { - position: relative; -} - -#main-sidebar .sidebar-header .is-overflowing .namespace-slug:after { - position: absolute; - top: 0; - right: -1.5rem; - bottom: 0; - content: ""; - width: 1.5rem; - background: linear-gradient( - 90deg, - var(--color-sidebar-bg), - var(--color-sidebar-bg), - var(--color-sidebar-bg-transparent) - ); -} - -#main-sidebar .sidebar-header .namespace { - display: inline-flex; - color: var(--color-sidebar-fg-em); - font-size: 1rem; - font-weight: 500; - height: 1.5rem; - overflow: hidden; - white-space: nowrap; - text-align: right; - flex-direction: row-reverse; -} - -#main-sidebar .sidebar-header-item { - display: flex; - flex: 1; - flex-direction: row; - user-select: none; - align-items: center; - border-radius: var(--border-radius-base); - height: 1.875rem; - gap: 0.75rem; -} - -#main-sidebar .sidebar-header-item .button { - width: 100%; -} - -#main-sidebar . { - margin-bottom: 0; -} - -/* -- Main Sidebar Unison Submenu ----------------------------------------------------- */ - -#main-sidebar .sidebar-unison-submenu { - color: var(--color-sidebar-subtle-fg); - width: 1.5rem; - height: 1.5rem; -} - -#main-sidebar .sidebar-unison-submenu:hover { - color: var(--color-sidebar-focus-fg); -} - -#main-sidebar nav a.tooltip-menu-item { - margin-left: 0; -} - -/* -- Main Sidebar Nav ----------------------------------------------------- */ - -#main-sidebar nav { - display: flex; - flex-direction: column; - justify-self: flex-end; - flex: none; - margin-top: auto; - padding-top: 1.5rem; -} - -#main-sidebar nav a { - height: 1.5rem; - display: flex; - align-items: center; - transition: all 0.2s; - padding-left: 0.5rem; - margin-left: -0.5rem; - border-radius: var(--border-radius-base); - white-space: nowrap; -} - -#main-sidebar nav a, -#main-sidebar nav .icon { - color: var(--color-sidebar-subtle-fg); -} - -#main-sidebar nav a:hover, -#main-sidebar nav a:hover .icon { - color: var(--color-sidebar-fg); - text-decoration: none; -} - -#main-sidebar .show-keyboard-shortcuts { - position: relative; - line-height: 1; - display: flex; - align-items: center; - font-weight: bold; - color: var(--color-sidebar-fg); - cursor: pointer; - height: 1.875rem; - margin-top: 1.5rem; -} - -#main-sidebar .show-keyboard-shortcuts:hover { - text-decoration: none; -} - -#main-sidebar .show-keyboard-shortcuts .keyboard-shortcut { - justify-self: flex-end; - margin-left: auto; - margin-right: 0.1875rem; -} - -#main-sidebar .keyboard-shortcut .key { - color: var(--color-sidebar-keyboard-shortcut-key-fg); - background: var(--color-sidebar-keyboard-shortcut-key-bg); - font-weight: normal; -} - -#main-sidebar .show-keyboard-shortcuts:hover { - background: var(--color-sidebar-focus-bg); -} -#main-sidebar .show-keyboard-shortcuts:hover .key { - color: var(--color-sidebar-keyboard-shortcut-hover-key-fg); -} - -/* -- Responsive ----------------------------------------------------------- */ - -@media only screen and (min-width: 1025px) { - .page.sidebar-toggled { - --main-sidebar-width: var(--main-sidebar-collapsed-width); - } - - .page.sidebar-toggled .collapse-sidebar-button { - animation: collapse-sidebar-button var(--transition-sidebar-collapse-time) - ease-in-out; - transition: none; - animation-fill-mode: forwards; - } - - .page.sidebar-toggled #main-sidebar { - overflow: visible; - } - - .page.sidebar-toggled #main-sidebar .collapsed-content { - opacity: 1; - transform: translateX(0); - } - - .page.sidebar-toggled #main-sidebar .expanded-content { - transition: opacity; - transition-duration: var(--transition-sidebar-collapse-time) * 1.1; - transition-delay: 0; - opacity: 0; - overflow: hidden; - } - - .page.sidebar-toggled .sidebar-scroll-area { - overflow: hidden; - } -} - -@media only screen and (max-width: 1024px) { - #app { - grid-template-rows: 3.5rem auto; - grid-template-columns: auto auto; - grid-template-areas: - "app-header app-header" - "page-content page-content"; - } - - #main-sidebar { - display: none; - } - - .page-content { - width: 100vw; - } - - .page.sidebar-toggled { - grid-template-rows: 3.5rem auto; - grid-template-columns: auto auto; - grid-template-areas: - "app-header app-header" - "main-sidebar main-sidebar"; - } - - .page.sidebar-toggled #main-sidebar { - display: flex; - width: 100vw; - } - - .page.sidebar-toggled .collapse-sidebar-button, - .page.sidebar-toggled .page-content { - display: none; - } -} - -/* collapse animations */ -@keyframes collapse-sidebar-button { - 0% { - opacity: 0; - transform: translateX(-17rem); - } - 50% { - opacity: 0.5; - } - 100% { - opacity: 1; - transform: translateX(-3.15rem); - } -} - @import "./help-modal.css"; @import "./publish-modal.css"; @import "./report-bug-modal.css"; diff --git a/src/css/ui/page-layout.css b/src/css/ui/page-layout.css index 16385cd..657118d 100644 --- a/src/css/ui/page-layout.css +++ b/src/css/ui/page-layout.css @@ -1,30 +1,26 @@ .page { + grid-area: page-layout; display: grid; transition: grid-template-columns var(--transition-sidebar-collapse-time); --transition-sidebar-collapse-time: 0.3s; } .page.sidebar-layout { - grid-template-rows: var(--app-header-height) auto; + grid-template-rows: auto; grid-template-columns: var(--main-sidebar-width) auto; - grid-template-areas: - "app-header app-header" - "main-sidebar page-content"; + grid-template-areas: "main-sidebar page-content"; } .page.full-layout { - grid-template-rows: var(--app-header-height) auto; + grid-template-rows: auto; grid-template-columns: auto; - grid-template-areas: - "app-header" - "page-content"; + grid-template-areas: "page-content"; } .page.hero-layout { - grid-template-rows: var(--app-header-height) var(page-hero-height) auto; + grid-template-rows: var(--page-hero-height) auto; grid-template-columns: auto; grid-template-areas: - "app-header" "page-hero" "page-content"; } @@ -58,6 +54,326 @@ overflow: auto; } +#main-sidebar { + grid-area: main-sidebar; + display: flex; + flex-direction: column; + position: relative; + overflow: visible; + height: calc(100vh - var(--app-header-height)); + background: var(--color-sidebar-bg); + color: var(--color-sidebar-fg); + border-right: 1px solid var(--color-sidebar-border); + box-shadow: 0 -1px 0 var(--color-sidebar-border); + font-size: var(--font-size-medium); + z-index: var(--layer-popover); + + --color-main-fg: var(--color-sidebar-fg); + --color-main-subtle-fg: var(--color-sidebar-subtle-fg); + + --color-button-default-fg: var(--color-sidebar-button-default-fg); + --color-button-default-bg: var(--color-sidebar-button-default-bg); + --color-button-default-hover-fg: var(--color-sidebar-button-default-hover-fg); + --color-button-default-hover-bg: var(--color-sidebar-button-default-hover-bg); + + --color-tooltip-fg: var(--color-sidebar-tooltip-fg); + --color-tooltip-bg: var(--color-sidebar-tooltip-bg); + --color-tooltip-border: var(--color-sidebar-tooltip-border); + + --color-main-divider: var(--color-sidebar-divider); +} + +#main-sidebar a:hover { + text-decoration: none; +} + +#main-sidebar .expanded-content { + display: flex; + flex-direction: column; + height: calc(100vh - var(--app-header-height)); + opacity: 1; + transition: all var(--transition-sidebar-collapse-time); + transition-delay: var(--transition-sidebar-collapse-time); +} + +#main-sidebar .sidebar-scroll-area { + display: flex; + flex-direction: column; + overflow-y: auto; + overflow-x: hidden; + height: calc(100vh - var(--app-header-height)); + scrollbar-width: thin; + scrollbar-color: var(--color-sidebar-subtle-fg) var(--color-sidebar-bg); + padding: 0rem 1rem 1rem 1.5rem; +} + +#main-sidebar .sidebar-scroll-area::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; +} + +#main-sidebar .sidebar-scroll-area::-webkit-scrollbar-track { + background: var(--color-sidebar-bg); +} + +#main-sidebar .sidebar-scroll-area::-webkit-scrollbar-thumb { + background-color: var(--color-sidebar-subtle-fg); + border-radius: 0.2rem; +} + +#main-sidebar .loading-placeholder { + background: var(--color-sidebar-subtle-fg); + opacity: 0.5; +} + +#main-sidebar .sidebar-section { + margin-top: 1.5rem; +} + +#main-sidebar .sidebar-section:first-child { + margin-top: 1rem; +} + +#main-sidebar .sidebar-section-title { + font-size: var(--font-size-medium); + font-weight: normal; + color: var(--color-sidebar-subtle-fg); + text-transform: uppercase; + font-size: 0.75rem; + height: 1.875rem; + display: flex; + align-items: center; + white-space: nowrap; +} + +/* TODO: Consolidate with codebase-tree .node */ + +#main-sidebar .sidebar-item { + margin-left: -0.5rem; + display: flex; + user-select: none; + align-items: center; + border-radius: var(--border-radius-base); + padding-left: 0.5rem; + margin-bottom: 0.125rem; + height: 1.875rem; +} + +#main-sidebar .sidebar-item > label { + color: var(--color-sidebar-fg); + transition: all 0.2s; + cursor: pointer; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1.875; +} + +#main-sidebar .sidebar-item:hover { + background: var(--color-sidebar-focus-bg); + text-decoration: none; +} + +#main-sidebar .divider { + margin: 0; +} + +/* -- Collapsing ----------------------------------------------------------- */ + +#main-sidebar .collapse-sidebar-button { + position: absolute; + left: var(--main-sidebar-width); + top: 1rem; + z-index: var(--layer-popover); + opacity: 0; + transition: opacity 0.2s !important; +} + +#app:not(.sidebar-toggled) .collapse-sidebar-button .button { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + padding-left: 0.2rem; + background: var(--color-sidebar-bg); +} + +#main-sidebar:not(.sidebar-toggled):hover .collapse-sidebar-button { + opacity: 1; +} + +#main-sidebar .collapsed-content { + transform: translateX(-17rem); + width: var(--main-sidebar-collapsed-width); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + opacity: 0; + transition: all var(--transition-sidebar-collapse-time) ease-in-out; + position: absolute; + bottom: 1rem; + gap: 1.5rem; +} + +#main-sidebar .collapsed-content .keyboard-shortcut:hover .key { + color: var(--color-sidebar-keyboard-shortcut-hover-key-fg); +} + +#main-sidebar .sidebar-header { + padding: 1rem 1.5rem 0 1.5rem; + display: flex; + flex-direction: column; + position: relative; + gap: 1.5rem; + margin-bottom: 0.5rem; +} + +#main-sidebar .sidebar-header:after { + position: absolute; + left: 1.5rem; + right: 1.5rem; + bottom: -2rem; + height: 1.75rem; + content: ""; + background: linear-gradient( + var(--color-sidebar-bg), + var(--color-sidebar-bg), + var(--color-sidebar-bg-transparent) + ); +} + +#main-sidebar .sidebar-header .namespace-slug { + position: relative; +} + +#main-sidebar .sidebar-header .is-overflowing .namespace-slug:after { + position: absolute; + top: 0; + right: -1.5rem; + bottom: 0; + content: ""; + width: 1.5rem; + background: linear-gradient( + 90deg, + var(--color-sidebar-bg), + var(--color-sidebar-bg), + var(--color-sidebar-bg-transparent) + ); +} + +#main-sidebar .sidebar-header .namespace { + display: inline-flex; + color: var(--color-sidebar-fg-em); + font-size: 1rem; + font-weight: 500; + height: 1.5rem; + overflow: hidden; + white-space: nowrap; + text-align: right; + flex-direction: row-reverse; +} + +#main-sidebar .sidebar-header-item { + display: flex; + flex: 1; + flex-direction: row; + user-select: none; + align-items: center; + border-radius: var(--border-radius-base); + height: 1.875rem; + gap: 0.75rem; +} + +#main-sidebar .sidebar-header-item .button { + width: 100%; +} + +#main-sidebar . { + margin-bottom: 0; +} + +/* -- Main Sidebar Unison Submenu ----------------------------------------------------- */ + +#main-sidebar .sidebar-unison-submenu { + color: var(--color-sidebar-subtle-fg); + width: 1.5rem; + height: 1.5rem; +} + +#main-sidebar .sidebar-unison-submenu:hover { + color: var(--color-sidebar-focus-fg); +} + +#main-sidebar nav a.tooltip-menu-item { + margin-left: 0; +} + +/* -- Main Sidebar Nav ----------------------------------------------------- */ + +#main-sidebar nav { + display: flex; + flex-direction: column; + justify-self: flex-end; + flex: none; + margin-top: auto; + padding-top: 1.5rem; +} + +#main-sidebar nav a { + height: 1.5rem; + display: flex; + align-items: center; + transition: all 0.2s; + padding-left: 0.5rem; + margin-left: -0.5rem; + border-radius: var(--border-radius-base); + white-space: nowrap; +} + +#main-sidebar nav a, +#main-sidebar nav .icon { + color: var(--color-sidebar-subtle-fg); +} + +#main-sidebar nav a:hover, +#main-sidebar nav a:hover .icon { + color: var(--color-sidebar-fg); + text-decoration: none; +} + +#main-sidebar .show-keyboard-shortcuts { + position: relative; + line-height: 1; + display: flex; + align-items: center; + font-weight: bold; + color: var(--color-sidebar-fg); + cursor: pointer; + height: 1.875rem; + margin-top: 1.5rem; +} + +#main-sidebar .show-keyboard-shortcuts:hover { + text-decoration: none; +} + +#main-sidebar .show-keyboard-shortcuts .keyboard-shortcut { + justify-self: flex-end; + margin-left: auto; + margin-right: 0.1875rem; +} + +#main-sidebar .keyboard-shortcut .key { + color: var(--color-sidebar-keyboard-shortcut-key-fg); + background: var(--color-sidebar-keyboard-shortcut-key-bg); + font-weight: normal; +} + +#main-sidebar .show-keyboard-shortcuts:hover { + background: var(--color-sidebar-focus-bg); +} +#main-sidebar .show-keyboard-shortcuts:hover .key { + color: var(--color-sidebar-keyboard-shortcut-hover-key-fg); +} + /* -- Hero ----------------------------------------------------------------- */ .page.hero-layout .page-hero { @@ -74,3 +390,86 @@ width: 62.5rem; margin: auto; } + +/* -- Responsive ----------------------------------------------------------- */ + +@media only screen and (min-width: 1025px) { + .page.sidebar-toggled { + --main-sidebar-width: var(--main-sidebar-collapsed-width); + } + + .page.sidebar-toggled .collapse-sidebar-button { + animation: collapse-sidebar-button var(--transition-sidebar-collapse-time) + ease-in-out; + transition: none; + animation-fill-mode: forwards; + } + + .page.sidebar-toggled #main-sidebar { + overflow: visible; + } + + .page.sidebar-toggled #main-sidebar .collapsed-content { + opacity: 1; + transform: translateX(0); + } + + .page.sidebar-toggled #main-sidebar .expanded-content { + transition: opacity; + transition-duration: var(--transition-sidebar-collapse-time) * 1.1; + transition-delay: 0; + opacity: 0; + overflow: hidden; + } + + .page.sidebar-toggled .sidebar-scroll-area { + overflow: hidden; + } +} + +/* collapse animations */ +@keyframes collapse-sidebar-button { + 0% { + opacity: 0; + transform: translateX(-17rem); + } + 50% { + opacity: 0.5; + } + 100% { + opacity: 1; + transform: translateX(-3.15rem); + } +} + +@media only screen and (max-width: 1024px) { + .page.sidebar-layout { + grid-template-rows: auto; + grid-template-columns: auto; + grid-template-areas: "page-content"; + } + + #main-sidebar { + display: none; + } + + .page-content { + width: 100vw; + } + + .page.sidebar-layout.sidebar-toggled { + grid-template-rows: auto; + grid-template-columns: auto auto; + grid-template-areas: "main-sidebar main-sidebar"; + } + + .page.sidebar-toggled #main-sidebar { + display: flex; + width: 100vw; + } + + .page.sidebar-toggled .collapse-sidebar-button, + .page.sidebar-toggled .page-content { + display: none; + } +}