diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7b6563bcc..928838e57 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -14,6 +14,24 @@ module ApplicationHelper render "diff_list", diff: diff end + def decorated_nav_link_to(text, icon, url, **options) + klass = options.delete(:class) + + if nav_link_match(params[:controller], url) + klass = "#{klass} current" + end + + id = "nav-#{text.downcase.gsub(/[^a-z ]/, '').parameterize}" + + tag.li(id: id, class: klass) do + link_to(url, id: "#{id}-link", **options) do + concat tag.i(class: icon) + concat " " + concat tag.span(text) + end + end + end + def nav_link_to(text, url, **options) klass = options.delete(:class) diff --git a/app/javascript/src/javascripts/navigation.js b/app/javascript/src/javascripts/navigation.js new file mode 100644 index 000000000..d2f2fe5d3 --- /dev/null +++ b/app/javascript/src/javascripts/navigation.js @@ -0,0 +1,17 @@ +const Navigation = {}; + +Navigation.init = function () { + const wrapper = $("body"); + $("#nav-toggle").on("click", (event) => { + event.preventDefault(); + + wrapper.toggleClass("nav-toggled"); + }); +}; + +$(() => { + if (!$("nav.navigation").length) return; + Navigation.init(); +}); + +export default Navigation; diff --git a/app/javascript/src/javascripts/responsive.js b/app/javascript/src/javascripts/responsive.js deleted file mode 100644 index 3f821d3fe..000000000 --- a/app/javascript/src/javascripts/responsive.js +++ /dev/null @@ -1,8 +0,0 @@ -$(function () { - $("#maintoggle").on("click.danbooru", function (e) { - e.preventDefault(); - $("#nav").toggle(); - $("#maintoggle-on").toggle(); - $("#maintoggle-off").toggle(); - }); -}); diff --git a/app/javascript/src/styles/base.scss b/app/javascript/src/styles/base.scss index 07847ae48..68379cbe6 100644 --- a/app/javascript/src/styles/base.scss +++ b/app/javascript/src/styles/base.scss @@ -24,9 +24,9 @@ @import "common/jquery_ui_custom.scss"; @import "common/link_decorator.scss"; @import "common/main_layout.scss"; +@import "common/navigation.scss"; @import "common/news.scss"; @import "common/notices.scss"; -@import "common/page_header.scss"; @import "common/paginator.scss"; @import "common/scores"; @import "common/simple_form.scss"; diff --git a/app/javascript/src/styles/common/navigation.scss b/app/javascript/src/styles/common/navigation.scss new file mode 100644 index 000000000..3c7496d43 --- /dev/null +++ b/app/javascript/src/styles/common/navigation.scss @@ -0,0 +1,328 @@ +nav.navigation { + display: grid; + grid-template-areas: "logo logo controls"; + grid-template-columns: min-content auto; + grid-template-rows: min-content auto min-content min-content; + + width: 100%; // otherwise narrow when fixed + z-index: 10; // otherwise post labels layered above + + pointer-events: none; // allow clicking through offset + & > menu { pointer-events: auto; } + + + /* Top bar, always visible */ + .nav-logo { + grid-area: logo; + + a.nav-logo-link { + display: flex; + + height: 3rem; + width: 3rem; + margin: 0.5rem; + + background-image: url("main-logo.png"); + background-repeat: no-repeat; + background-size: contain; + background-position-y: center; + } + } + + .nav-controls { + grid-area: controls; + + display: flex; + flex-flow: row-reverse; + align-items: center; + gap: 0.5em; + + font-size: 1.15rem; + padding-right: 0.5em; + + & > a { + display: flex; + gap: 0.25em; + + padding: 0.25rem 0.5rem; + background: themed("color-foreground"); + border-radius: 6px; + + & > i { + font-size: 1.5rem; + color: themed("color-link-active"); + } + } + } + + /* Prevent toggled menus from being too wide */ + .nav-offset { + grid-area: offset; + pointer-events: none; + display: none; // flex + } + + /* Toggled menus, hidden by default */ + .nav-primary { + grid-area: primary; + display: none; // flex + flex-flow: column; + + background-color: themed("color-section"); + font-size: 1.5em; + + li { + padding: 0; + a { + display: block; + border-bottom: 1px solid themed("color-foreground"); + padding: 0.5em; + + i { + width: 1.5rem; + color: themed("color-link-active"); + text-align: center; + } + } + + &.current a { background-color: themed("color-foreground"); } + } + } + + .nav-secondary { + grid-area: secondary; + display: none; // flex + flex-flow: column; + + background-color: themed("color-foreground"); + font-size: 1.35em; + + li { + padding: 0; + a { + display: block; + border-bottom: 1px solid themed("color-section"); + padding: 0.5em; + } + + &.divider { + border-bottom: 1px solid themed("color-section"); + height: 0.25em; + } + + form input[type="text"] { width: 100%; } + } + } + + .nav-tools { + grid-area: tools; + + display: none; // grid + grid-template-columns: 1fr 1fr; + grid-template-rows: min-content; + + padding: 1rem; + gap: 1rem; + + background-color: themed("color-section"); + border-top: 1px solid themed("color-foreground"); + + li { + padding: 0; + + &.nav-tools-login { grid-column: 1 / -1; } + + & > a { + display: block; + + background: themed("color-section-lighten-5"); + border-radius: 6px; + + font-size: 125%; + padding: 0.5rem 1rem; + text-align: center; + + i { color: themed("color-link-active"); } + } + } + + &.anonymous li.nav-tools-themes { + grid-column: 1 / -1; + } + } + + .nav-help { + grid-area: help; + + display: none; // grid + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: min-content; + + padding: 1rem; + gap: 1rem; + + background: themed("color-section"); + + li { + padding: 0; + + &.nav-help-discord { grid-column: 1 / -1; } + + & > a { + display: block; + + background: themed("color-section-darken-5"); + border-radius: 6px; + + font-size: 125%; + padding: 0.5rem 1rem; + text-align: center; + + i { color: themed("color-link-active"); } + } + } + } +} + + +// Mobile toggle +body.nav-toggled { + padding-top: 4rem; + + nav.navigation { + grid-template-areas: + "logo logo controls" + "offset primary secondary " + "offset tools tools " + "offset help help "; + grid-template-columns: auto minmax(auto, 180px) minmax(auto, 180px); + position: fixed; + top: 0; + height: 100vh; + max-height: 800px; + max-width: 100vw; // prevent bug when page overflows viewport + + // Allow scrolling when the menu is too long + overflow-y: scroll; + + .nav-logo, .nav-controls { + background-color: themed("color-background"); + } + + .nav-primary, .nav-secondary, .nav-offset { + display: flex; + } + .nav-tools, .nav-help { + display: grid; + } + } +} + + +// Desktop +nav.navigation, body.nav-toggled nav.navigation { + @include window-larger-than(800px) { + grid-template-areas: + "logo primary help tools " + "logo secondary secondary secondary" + ; + grid-template-columns: min-content min-content 1fr min-content; + grid-template-rows: 1fr 1fr; + + padding: 0 1em 1em; + box-sizing: border-box; + height: unset; + + .nav-logo { + a.nav-logo-link { margin: 0.5em 0.25em 0 0; } + } + + .nav-offset, .nav-controls { display: none; } + + .nav-primary { + display: flex; + flex-flow: row; + + background: unset; + font-size: 1.05em; + padding: 0 0.25em; + + li { + display: flex; + + a { + align-content: center; + + border-bottom: 0; + padding: 0 0.75em; + i { display: none; } + } + } + } + + .nav-secondary { + display: flex; + flex-flow: row; + align-items: center; + + padding: 0 0.25em; + font-size: 1.05em; + border-radius: 6px; + + // Silly fix for too many links + overflow: hidden; + + li { + a { + border-bottom: 0; + padding: 0 0.75em; + white-space: nowrap; + } + + &.divider { + display: flex; + align-items: center; + &::after { content: "|"; } + } + } + } + + .nav-tools, .nav-help { + display: flex; + + padding: 0; + background: unset; + border: none; + gap: 0; + + li { + display: flex; + + a { + align-content: center; + + background: unset; + font-size: 1.05em; + padding: 0 0.75em; + text-align: unset; + white-space: nowrap; + border-radius: 0; + } + } + } + + .nav-tools { + li a { + span { display: none; } + i { color: themed("color-link"); } + &:hover i { color: themed("color-link-hover"); } + } + } + .nav-help { + li.current a { + background-color: themed("color-foreground"); + i { display: none; } + } + } + } +} \ No newline at end of file diff --git a/app/javascript/src/styles/common/page_header.scss b/app/javascript/src/styles/common/page_header.scss deleted file mode 100644 index 30556071e..000000000 --- a/app/javascript/src/styles/common/page_header.scss +++ /dev/null @@ -1,92 +0,0 @@ - -#maintoggle { - display: none; -} - -#nav { - display: grid; - grid-template-columns: 3.75em 1fr; - grid-template-areas: "logo main" "logo secondary"; - - .logo { - grid-area: logo; - - margin-top: 6px; - background-image: url("main-logo.png"); - background-repeat: no-repeat; - background-size: contain; - background-position-y: center; - } - - .mobile-logo { - display: none; - } - - .main { - grid-area: main; - } - - .secondary { - grid-area: secondary; - } -} - -header#top { - font-size: 1.05em; - margin: 0 $base-padding 0.8rem; - color: themed("color-text"); - background-color: themed("color-background"); - background-image: themed("image-background"); - - #subnav-height-placeholder { - visibility: hidden; - } - - menu { - margin-top: -2px; - background-color: themed("color-foreground"); - border-radius: $border-radius-full; - padding: 6px; - - form { - display: inline-block; - - input { - width: 9.5em; - vertical-align: baseline; - font-size: revert; - padding-top: 0; - padding-bottom: 0; - } - } - - li { - margin: 0; - padding: 0; - white-space: nowrap; - } - - li a { - padding: 6px 10px; - } - } - - menu.main { - margin-top: 0; - background-color: themed("color-background"); - - li.current a { - background-color: themed("color-foreground"); - font-weight: bold; - } - - li#nav-sign-in a { - font-weight: bold; - color: $page-header-sign-in-link-color; - } - - li.forum-updated a { - font-style: italic; - } - } -} diff --git a/app/javascript/src/styles/common/z_responsive.scss b/app/javascript/src/styles/common/z_responsive.scss index 9c41084d7..df11223a5 100644 --- a/app/javascript/src/styles/common/z_responsive.scss +++ b/app/javascript/src/styles/common/z_responsive.scss @@ -130,12 +130,6 @@ } } - #maintoggle { - display: block; - font-weight: bold; - font-size: 2em; - } - /* Make the quick search box in the navbar full width. */ header#top menu form input { width: auto; @@ -216,47 +210,6 @@ } } - #nav { - font-size: 2em; - line-height: 2em; - display: none; - } - - header#top { - input { - font-size: 18pt; - } - - menu.main { - padding: 5px 10px; - - .mobile-logo { - display: inline-block; - width: 1.5em; - box-sizing: border-box; - - a { - display: inline-block; - padding: 6px 10px; - - background-image: url("main-logo.png"); - background-repeat: no-repeat; - background-size: contain; - - // Gives the link height - &::after { - content: "Placeholder"; - visibility: hidden; - } - } - } - } - - menu.secondary.empty { - display: none; - } - } - header { text-align: center; line-height: 2em; diff --git a/app/views/artists/_secondary_links.html.erb b/app/views/artists/_secondary_links.html.erb index 3b2894b27..6f5400b0c 100644 --- a/app/views/artists/_secondary_links.html.erb +++ b/app/views/artists/_secondary_links.html.erb @@ -8,7 +8,7 @@ <%= subnav_link_to "Recent changes", artist_versions_path %> <%= subnav_link_to "URLs", artist_urls_path %> <% if @artist && !@artist.new_record? %> -