diff --git a/LICENSE b/LICENSE index e88cba6..b442934 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Joe +Copyright (c) 2018 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index abf15ef..c83fe99 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,4 @@ A theme component that allows you to build a header menu - with submenus - using plain text! -More information https://meta.discourse.org/ - -jquery-dropdown courtesy of Cory LaViska - MIT license +More information https://meta.discourse.org/t/header-submenus/94584 diff --git a/common/common.scss b/common/common.scss index 3416f5b..babb32e 100644 --- a/common/common.scss +++ b/common/common.scss @@ -1,183 +1,114 @@ -@import "common/foundation/variables"; - -$menu-background: null !default; -$menu-item-color: null !default; -$menu-item-active-background: null !default; -$menu-item-active-color: null !default; -$submenu-background: null !default; -$submenu-item-color: null !default; -$submenu-item-hover-background: null !default; -$submenu-item-hover-color: null !default; -$divider-color: null !default; - -@if $Menu_background != "" { - $menu-background: #{$Menu_background}; -} @else { - $menu-background: $primary; +@function fallback($setting, $color) { + @if not $setting or $setting == "" { + @return $color; + } @else { + @return $setting; + } } -@if $Menu_item_color != "" { - $menu-item-color: #{$Menu_item_color}; -} @else { - $menu-item-color: $secondary; -} - -@if $Menu_item-active_background != "" { - $menu-item-active-background: #{$Menu_item_active_background}; -} @else { - $menu-item-active-background: $primary-low; -} - -@if $Menu_item_active_color != "" { - $menu-item-active-color: #{$Menu_item_active_color}; -} @else { - $menu-item-active-color: $primary; -} - -@if $Submenu_background != "" { - $submenu-background: #{$Submenu_background}; -} @else { - $submenu-background: $secondary; -} - -@if $Submenu_item_color != "" { - $submenu-item-color: #{$Submenu_item_color}; -} @else { - $submenu-item-color: $primary; -} - -@if $Submenu_item_hover_background != "" { - $submenu-item-hover-background: #{$Submenu_item_hover_background}; -} @else { - $submenu-item-hover-background: $tertiary-low; -} - -@if $Submenu_item_hover_color != "" { - $submenu-item-hover-color: #{$Submenu_item_hover_color}; -} @else { - $submenu-item-hover-color: $primary; -} - -@if $Divider_color != "" { - $divider-color: #{$Divider_color}; -} @else { - $divider-color: $primary-low; -} +$item-height: 40px; +$icon-opacity: 0.7; .top-menu { - background: $menu-background; + background: fallback($Menu_background, $primary); + width: 100%; - .wrap { + .menu-content { display: flex; align-items: center; - - @if $Invert_position == "true" { - justify-content: flex-end; - } + justify-content: if($Invert_position == "true", flex-end, flex-start); } - .wrap > a { - color: $menu-item-color; + .menu-items { + display: flex; + height: $item-height; + } + + .menu-item { + position: relative; + color: fallback($Menu_item_color, $secondary); border: none; - padding: 10px 12px; + padding: 0 0.5em; font-size: $font-up-1; - line-height: $line-height-medium; transition: all 0.15s; display: flex; align-items: center; - white-space: nowrap; - &:first-of-type { - margin-left: -12px; - } + &:hover, + &:active, + &:focus { + background: fallback($Menu_item-active_background, $primary-low); + color: fallback($Menu-item-active-background, $primary); + cursor: default; + .d-icon-caret-right { + transform: rotate(90deg); + } + .d-header-dropdown { + display: block; + top: $item-height; + left: 0; + z-index: z("header") + 1; - .rtl & { - &:first-of-type { - margin-right: -12px; + .rtl & { + left: unset; + right: 0; + } } } - &.d-dropdown-open { - background: $menu-item-active-background; - color: $menu-item-active-color; - z-index: z("header") + 2; + .d-icon-caret-right { + margin-left: 0.25em; + transition: transform 0.15s ease-in-out; + + .rtl & { + margin-left: 0em; + margin-right: 0.25em; + } } } - .d-icon { - margin-right: 5px; - opacity: 0.7; - min-width: 16px; - text-align: center; - - &.fa-none { - min-width: unset; - } - - .rtl & { - margin-right: 0; - margin-left: 5px; - } + .d-header-dropdown { + position: absolute; + display: none; } - .d-icon-caret-down { - transform: rotate(-90deg); - transition: transform ease 0.15s; - - .rtl & { - transform: rotate(90deg); - } - } - - .d-dropdown-open .d-icon-caret-down { - transform: rotate(0); - } -} - -.d-dropdown { - position: absolute; - z-index: z("header") + 1; - display: none; - .d-dropdown-menu { min-width: 160px; - max-width: 360px; - list-style: none; - background: $submenu-background; + background: fallback($Submenu_background, $secondary); box-shadow: shadow("menu-panel"); - overflow: visible; - padding: 4px 0; margin: 0; - } - - .d-dropdown-menu li { list-style: none; - padding: 0 0; - margin: 0; - line-height: 18px; } - .d-dropdown-menu li > a { + .submenu-link { display: flex; align-items: center; - color: $submenu-item-color; - text-decoration: none; - line-height: 18px; - padding: 3px 15px; - margin: 0; + color: fallback($Submenu_item_color, $primary); + padding: 0.5em; + font-size: $font-down-1; white-space: nowrap; &:hover { - background-color: $submenu-item-hover-background; - color: inherit; - cursor: pointer; + color: fallback($Submenu_item_hover_color, $primary); + background-color: fallback($Submenu_item_hover_background, $tertiary-low); } } - .d-dropdown-menu .divider { - font-size: 1px; - border-top: solid 1px $divider-color; - padding: 0; - margin: 5px 0; + .divider { + border-top: solid 1px fallback($Divider_color, $primary-low); + margin: 0.25em auto; + } + + .d-icon { + opacity: $icon-opacity; + min-width: 1em; + &:not(.d-icon-caret-right) { + margin-right: 0.5em; + + .rtl & { + margin-right: 0; + margin-left: 0.5em; + } + } } } diff --git a/common/header.html b/common/header.html deleted file mode 100644 index 1e153ec..0000000 --- a/common/header.html +++ /dev/null @@ -1,126 +0,0 @@ -
- - - - - diff --git a/desktop/desktop.scss b/desktop/desktop.scss index e39fcda..d0b269e 100644 --- a/desktop/desktop.scss +++ b/desktop/desktop.scss @@ -1,20 +1,30 @@ +$item-height: 40px; + +@if $Fixed_mode == "true" { + .top-menu { + position: fixed; + top: 0; + z-index: z("header") + 1; + } + + .d-header { + top: $item-height; + position: fixed; + } + + #main-outlet { + padding-top: calc(5.8572em + #{$item-height}); + } +} @else { + .d-header { + top: $item-height; + + .docked & { + top: 0; + } + } +} + .vmo { display: none; } - -@if $Fixed_mode == "true" { - .d-dropdown { - top: 38.5px !important; - } - .d-header { - margin-top: 38.5px; - } - .top-menu { - position: fixed; - width: 100%; - z-index: z("header") + 1; - } - #main-outlet { - padding-top: 8.65em; - } -} diff --git a/javascripts/discourse/connectors/above-site-header/header-submenus.hbs b/javascripts/discourse/connectors/above-site-header/header-submenus.hbs new file mode 100644 index 0000000..938eca3 --- /dev/null +++ b/javascripts/discourse/connectors/above-site-header/header-submenus.hbs @@ -0,0 +1,39 @@ + \ No newline at end of file diff --git a/javascripts/discourse/connectors/above-site-header/header-submenus.js.es6 b/javascripts/discourse/connectors/above-site-header/header-submenus.js.es6 new file mode 100644 index 0000000..c01a4ea --- /dev/null +++ b/javascripts/discourse/connectors/above-site-header/header-submenus.js.es6 @@ -0,0 +1,90 @@ +// Used instead of dasherize for backwards compatibility with stable +const getClassName = text => { + return text.toLowerCase().replace(/\s/g, "-"); +}; + +export default { + setupComponent(args, component) { + try { + const splitMenuItems = settings.Menu_items.split("|").filter(Boolean); + const splitSubmenuItems = settings.Submenu_items.split("|").filter( + Boolean + ); + + const menuItemsArray = []; + const SubmenuItemsArray = []; + + splitSubmenuItems.forEach(item => { + const fragments = item.split(",").map(fragment => fragment.trim()); + const parent = fragments[0].toLowerCase(); + const text = fragments[1]; + + if (text.toLowerCase() === "divider") { + const divider = { + parent, + divider: true + }; + return SubmenuItemsArray.push(divider); + } + + const className = getClassName(text); + const icon = + fragments[2].toLowerCase() === "none" + ? "" + : fragments[2].toLowerCase(); + const href = fragments[3]; + const target = fragments[4] === "blank" ? "_blank" : ""; + const title = fragments[5]; + + const submenItem = { + parent, + text, + className, + icon, + href, + target, + title + }; + SubmenuItemsArray.push(submenItem); + }); + + splitMenuItems.forEach(item => { + const fragments = item.split(",").map(fragment => fragment.trim()); + const parentFor = fragments[0].toLowerCase(); + const text = fragments[0]; + const className = getClassName(text); + const icon = + fragments[1].toLowerCase() === "none" + ? "" + : fragments[1].toLowerCase(); + const title = fragments[2]; + const view = fragments[3]; + const childItems = SubmenuItemsArray.filter( + link => link.parent === parentFor + ); + + const menuItem = { + text, + className, + icon, + title, + view, + childItems + }; + menuItemsArray.push(menuItem); + }); + + const showCaret = settings.Show_caret; + + this.setProperties({ + menuItems: menuItemsArray, + showCaret + }); + } catch (error) { + console.error(error); + console.error( + "There's an issue in the Header Submenus Component. Check if your settings are entered correctly" + ); + } + } +}; diff --git a/mobile/mobile.scss b/mobile/mobile.scss index 2b9d699..8b9507a 100644 --- a/mobile/mobile.scss +++ b/mobile/mobile.scss @@ -1,37 +1,29 @@ -@import "common/foundation/variables"; +$item-height: 40px; -.top-menu { - .wrap > a { - font-size: $font-0; - padding: 10px 8px; +.menu-items { + display: flex; + width: 100%; + height: $item-height; +} + +.d-header { + margin-top: $item-height; + .docked & { + margin-top: 0; } } -.top-menu .wrap > a:first-of-type { - margin-left: -10px; +.menu-item-container { + overflow-x: scroll; + height: 100vh; +} - .rtl & { - margin-right: -10px; - } +.menu-placeholder { + height: $item-height; + position: relative; + width: 100%; } .vdo { display: none; } - -.top-menu .wrap { - overflow-x: scroll; - > a { - white-space: nowrap; - } -} - -// handles last menu item dropdown position -.top-menu .wrap > div:last-of-type { - left: unset !important; - right: 0 !important; - .rtl & { - left: 0 !important; - right: unset !important; - } -} diff --git a/settings.yml b/settings.yml index 1aa5934..d46b435 100644 --- a/settings.yml +++ b/settings.yml @@ -2,67 +2,63 @@ Menu_items: type: list default: "Design, magic, Get inspired!, vdm|Code, far-keyboard, Learn new things!, vdm|Business, far-money-bill-alt, Start a new career!, vdm|Shop, shopping-cart, Buy cool stuff!, vdo|More, none, Even more cool things!, vdo" description: - en: "Add menu items. One item per line in this order: Text, icon, title, view.