diff --git a/modules/template-parts/assets/js/hello-plus-header.js b/modules/template-parts/assets/js/hello-plus-header.js new file mode 100644 index 00000000..fab98cd3 --- /dev/null +++ b/modules/template-parts/assets/js/hello-plus-header.js @@ -0,0 +1,211 @@ +class elementorHelloPlusHeaderHandler { + constructor() { + this.initSettings(); + this.initElements(); + this.bindEvents(); + this.lastScrollY = window.scrollY; + } + + initSettings() { + this.settings = { + selectors: { + main: '.ehp-header', + navigationToggle: '.ehp-header__button-toggle', + dropdownToggle: '.ehp-header__dropdown-toggle', + navigation: '.ehp-header__navigation', + dropdown: '.ehp-header__dropdown', + wpAdminBar: '#wpadminbar', + }, + constants: { + mobilePortrait: 767, + tabletPortrait: 1024, + mobile: 'mobile', + tablet: 'tablet', + desktop: 'desktop', + dataScrollBehavior: 'data-scroll-behavior', + dataBehaviorFloat: 'data-behavior-float', + scrollUp: 'scroll-up', + always: 'always', + none: 'none', + no: 'no', + }, + }; + } + + initElements() { + this.elements = { + window, + main: document.querySelector( this.settings.selectors.main ), + navigationToggle: document.querySelector( this.settings.selectors.navigationToggle ), + dropdownToggle: document.querySelectorAll( this.settings.selectors.dropdownToggle ), + navigation: document.querySelector( this.settings.selectors.navigation ), + dropdown: document.querySelector( this.settings.selectors.dropdown ), + wpAdminBar: document.querySelector( this.settings.selectors.wpAdminBar ), + }; + } + + bindEvents() { + if ( this.elements.navigationToggle ) { + this.elements.navigationToggle.addEventListener( 'click', () => this.toggleNavigation() ); + } + + if ( this.elements.dropdownToggle.length > 0 ) { + this.elements.dropdownToggle.forEach( ( menuItem ) => { + menuItem.addEventListener( 'click', ( event ) => this.toggleSubMenu( event ) ); + } ); + } + + if ( this.elements.main ) { + window.addEventListener( 'resize', () => this.onResize() ); + window.addEventListener( 'scroll', () => this.onScroll() ); + + this.onInit(); + } + } + + onInit() { + const { none, no } = this.settings.constants; + + this.handleAriaAttributesMenu(); + this.handleAriaAttributesDropdown(); + this.handleOffsetTop(); + + if ( none === this.getDataScrollBehavior() && no === this.getBehaviorFloat() ) { + this.setupInnerContainer(); + } + } + + getBehaviorFloat() { + const { dataBehaviorFloat } = this.settings.constants; + return this.elements.main.getAttribute( dataBehaviorFloat ); + } + + getDataScrollBehavior() { + const { dataScrollBehavior } = this.settings.constants; + return this.elements.main.getAttribute( dataScrollBehavior ); + } + + setupInnerContainer() { + this.elements.main.closest( '.e-con-inner' ).classList.add( 'e-con-inner--ehp-header' ); + this.elements.main.closest( '.e-con' ).classList.add( 'e-con--ehp-header' ); + } + + onResize() { + this.handleAriaAttributesMenu(); + } + + onScroll() { + const { scrollUp, always } = this.settings.constants; + + if ( scrollUp === this.getDataScrollBehavior() || always === this.getDataScrollBehavior() ) { + this.handleScrollDown( this.getDataScrollBehavior() ); + } + + if ( always === this.getDataScrollBehavior() ) { + this.applyBodyPadding(); + } + } + + handleOffsetTop() { + const wpAdminBarOffsetHeight = this.elements.wpAdminBar?.offsetHeight || 0; + this.elements.main.style.setProperty( '--header-wp-admin-bar-height', `${ wpAdminBarOffsetHeight }px` ); + } + + applyBodyPadding() { + const mainHeight = this.elements.main.offsetHeight; + document.body.style.paddingTop = `${ mainHeight }px`; + } + + handleAriaAttributesDropdown() { + this.elements.dropdownToggle.forEach( ( item ) => { + item.nextElementSibling.setAttribute( 'aria-hidden', 'true' ); + } ); + } + + handleAriaAttributesMenu() { + if ( this.isResponsiveBreakpoint() ) { + this.elements.navigationToggle.setAttribute( 'aria-expanded', 'false' ); + this.elements.navigation.setAttribute( 'aria-hidden', 'true' ); + } + } + + toggleSubMenu( event ) { + event.preventDefault(); + const subMenu = event.target.nextElementSibling; + const itemTarget = event.target; + const ariaHidden = subMenu.getAttribute( 'aria-hidden' ); + + if ( 'true' === ariaHidden ) { + this.openSubMenu( itemTarget, subMenu ); + } else { + this.closeSubMenu( itemTarget, subMenu ); + } + } + + openSubMenu( itemTarget, subMenu ) { + itemTarget.setAttribute( 'aria-expanded', 'true' ); + subMenu.setAttribute( 'aria-hidden', 'false' ); + } + + closeSubMenu( itemTarget, subMenu ) { + itemTarget.setAttribute( 'aria-expanded', 'false' ); + subMenu.setAttribute( 'aria-hidden', 'true' ); + } + + handleScrollDown( behaviorOnScroll ) { + const { scrollUp } = this.settings.constants; + + const currentScrollY = window.scrollY; + const headerHeight = this.elements.main.offsetHeight; + const wpAdminBarOffsetHeight = this.elements.wpAdminBar?.offsetHeight || 0; + const headerFloatOffsetProperty = getComputedStyle( this.elements.main ).getPropertyValue( '--header-float-offset' ); + const headerFloatOffset = parseInt( headerFloatOffsetProperty, 10 ) || 0; + const totalOffset = headerHeight + wpAdminBarOffsetHeight + headerFloatOffset; + + if ( currentScrollY > this.lastScrollY ) { + this.elements.main.classList.add( 'scroll-down' ); + + if ( scrollUp === behaviorOnScroll ) { + this.elements.main.style.setProperty( '--header-scroll-down', `${ totalOffset }px` ); + } + } else { + this.elements.main.classList.remove( 'scroll-down' ); + } + this.lastScrollY = currentScrollY; + } + + isResponsiveBreakpoint() { + const device = this.getCurrentDevice(); + return this.elements.main.classList.contains( `has-navigation-breakpoint-${ device }-portrait` ); + } + + getCurrentDevice() { + const { mobilePortrait, tabletPortrait, mobile, tablet, desktop } = this.settings.constants; + + const isMobile = this.elements.window.innerWidth <= mobilePortrait; + const isTablet = this.elements.window.innerWidth <= tabletPortrait; + + if ( isMobile ) { + return mobile; + } else if ( isTablet ) { + return tablet; + } + return desktop; + } + + toggleNavigation() { + const isNavigationHidden = this.elements.navigation.getAttribute( 'aria-hidden' ); + + if ( 'true' === isNavigationHidden ) { + this.elements.navigation.setAttribute( 'aria-hidden', 'false' ); + this.elements.navigationToggle.setAttribute( 'aria-expanded', 'true' ); + } else { + this.elements.navigation.setAttribute( 'aria-hidden', 'true' ); + this.elements.navigationToggle.setAttribute( 'aria-expanded', 'false' ); + } + } +} + +document.addEventListener( 'DOMContentLoaded', () => { + new elementorHelloPlusHeaderHandler(); +} ); diff --git a/modules/template-parts/assets/scss/breakpoints.scss b/modules/template-parts/assets/scss/breakpoints.scss new file mode 100644 index 00000000..32c02cfa --- /dev/null +++ b/modules/template-parts/assets/scss/breakpoints.scss @@ -0,0 +1,27 @@ +$breakpoints: ( + sm: 480px, // Mobile landscape + md: 768px, // Tablet + lg: 1025px, // Desktop + xl: 1440px, // Larger devices + xxl: 1600px // Largest devices +); + +$screen-mobile-min: map_get($breakpoints, sm); +$screen-mobile-max: map_get($breakpoints, md) - 1; +$screen-tablet-min: map_get($breakpoints, md); +$screen-mobile-next: map_get($breakpoints, md); +$screen-tablet-max: map_get($breakpoints, lg) - 1; +$screen-desktop-min: map_get($breakpoints, lg); +$screen-desktop-max: 99999px; +$screen-tablet-next: map_get($breakpoints, lg); + +// Additional Custom Breakpoints - SCSS placeholders +$screen-mobile-extra-min: -1; +$screen-mobile-extra-max: -1; +$screen-mobile-extra-next: -1; +$screen-tablet-extra-min: -1; +$screen-tablet-extra-max: -1; +$screen-tablet-extra-next: -1; +$screen-laptop-min: -1; +$screen-laptop-max: -1; +$screen-widescreen-min: -1; diff --git a/modules/template-parts/assets/scss/hello-plus-header.scss b/modules/template-parts/assets/scss/hello-plus-header.scss index 1b3d1570..a29a8ad5 100644 --- a/modules/template-parts/assets/scss/hello-plus-header.scss +++ b/modules/template-parts/assets/scss/hello-plus-header.scss @@ -1,3 +1,671 @@ +@import "./breakpoints"; +@import "./variables"; + .ehp-header { - // TODO: Header styles + $submenu-shape-default: 8px; + $submenu-shape-sharp: 0; + $submenu-shape-rounded: 32px; + $submenu-shape-round: 52px; + + --header-logo-width: 68px; + --header-logo-width-sticky: 34px; + --header-site-title-color: #0052FF; + --header-buttons-space-between: 16px; + --header-logo-order: 0; + --header-navigation-breakpoint: 767px; + --header-menu-item-spacing: 32px; + --header-title-size-sticky: 20px; + --header-title-weight-sticky: 800; + + --header-wp-admin-bar-height: 0; + --header-float-offset: 0px; + --header-float-height: calc(var(--header-wp-admin-bar-height) + var(--header-float-offset)); + --header-float-width: 100%; + --header-scroll-down: 0; + + --header-button-primary-background-color: #0052FF; + --header-button-primary-icon-spacing: 10px; + --header-button-primary-icon-size: 16px; + --header-button-primary-text-color: #FFFFFF; + --header-button-primary-text-color-hover: #FFFFFF; + --header-button-primary-border-width: 0; + --header-button-primary-border-color: transparent; + --header-button-primary-padding-block-end: 8px; + --header-button-primary-padding-block-start: 8px; + --header-button-primary-padding-inline-end: 16px; + --header-button-primary-padding-inline-start: 16px; + --header-button-primary-border-radius: 0; + + --header-button-secondary-background-color: transparent; + --header-button-secondary-icon-spacing: 10px; + --header-button-secondary-icon-size: 16px; + --header-button-secondary-text-color: #555963; + --header-button-secondary-text-color-hover: #555963; + --header-button-secondary-border-width: 2px; + --header-button-secondary-border-color: #555963; + --header-button-secondary-padding-block-end: 8px; + --header-button-secondary-padding-block-start: 8px; + --header-button-secondary-padding-inline-end: 16px; + --header-button-secondary-padding-inline-start: 16px; + --header-button-secondary-border-radius: #{$corners-shape-default}; + + --header-button-text-color: var(--header-button-primary-text-color); + --header-button-text-color-hover: var(--header-button-primary-text-color-hover); + --header-button-border-color: var(--header-button-primary-border-color); + --header-button-background-color: var(--header-button-primary-background-color); + --header-button-padding-block-end: var(--header-button-primary-padding-block-end); + --header-button-padding-block-start: var(--header-button-primary-padding-block-start); + --header-button-padding-inline-end: var(--header-button-primary-padding-inline-end); + --header-button-padding-inline-start: var(--header-button-primary-padding-inline-start); + --header-button-border-width: var(--header-button-primary-border-width); + --header-button-border-radius: var(--header-button-primary-border-radius); + --header-button-icon-spacing: var(--header-button-primary-icon-spacing); + --header-button-icon-size: var(--header-button-primary-icon-size); + + --header-toggle-icon-color: #555963; + --header-toggle-icon-size: 22px; + + --header-menu-item-color: #555963; + --header-menu-item-color-hover: #555963; + --header-menu-item-color-active: #555963; + + --header-pointer-hover-underline-width: 2px; + --header-pointer-hover-underline-color: #0052FF; + --header-pointer-hover-highlight-bg-color: #E0EAFF; + --header-pointer-hover-highlight-padding-inline-default: 8px; + --header-pointer-hover-highlight-padding-block-default: 4px;--header-pointer-hover-highlight-padding-inline-thin: 6px; + --header-pointer-hover-highlight-padding-block-thin: 2px; + --header-pointer-hover-highlight-padding-inline-thick: 8px; + --header-pointer-hover-highlight-padding-block-thick: 8px; + + --header-pointer-hover-highlight-padding-inline: var(--header-pointer-hover-highlight-padding-inline-default); + --header-pointer-hover-highlight-padding-block: var(--header-pointer-hover-highlight-padding-block-default); + + --header-focus-active-underline-width: 2px; + --header-focus-active-underline-color: #0052FF; + --header-focus-active-highlight-bg-color: #E0EAFF; + --header-focus-active-highlight-padding-inline-default: 8px; + --header-focus-active-highlight-padding-block-default: 4px;--header-focus-active-highlight-padding-inline-thin: 6px; + --header-focus-active-highlight-padding-block-thin: 2px; + --header-focus-active-highlight-padding-inline-thick: 8px; + --header-focus-active-highlight-padding-block-thick: 8px; + + --header-focus-active-highlight-padding-inline: var(--header-focus-active-highlight-padding-inline-default); + --header-focus-active-highlight-padding-block: var(--header-focus-active-highlight-padding-block-default); + + --header-dropdown-text-align: flex-start; + --header-dropdown-divider-color: #E0E1E2; + + --header-box-padding-block-start: 16px; + --header-box-padding-block-end: 16px; + --header-box-padding-inline-start: 32px; + --header-box-padding-inline-end: 32px; + --header-box-border-width: 1px; + --header-box-border-color: #555963; + + display: flex; + max-width: var(--header-float-width); + padding-block-start: var(--header-box-padding-block-start); + padding-block-end: var(--header-box-padding-block-end); + padding-inline-start: var(--header-box-padding-inline-start); + padding-inline-end: var(--header-box-padding-inline-end); + + &.has-box-border { + border-bottom: var(--header-box-border-width) solid var(--header-box-border-color); + } + + &.has-behavior-float { + --header-float-offset: 16px; + --header-float-width: 1140px; + } + + &.has-behavior-onscroll-always, + &.has-behavior-onscroll-scroll-up { + left: 0; + margin: 0 auto; + position: fixed; + right: 0; + top: var(--header-float-height); + transition: top 0.5s ease-in-out; + width: 100%; + z-index: 999; + } + + &.has-behavior-onscroll-scroll-up { + + &.scroll-down { + top: calc(-1 * var(--header-scroll-down)); + transition: top 0.5s ease-in-out; + } + } + + & .has-shape, + &.has-shape { + + &-sharp { + border-radius: $corners-shape-sharp; + } + + &-rounded { + border-radius: $corners-shape-rounded; + } + + &-round { + border-radius: $corners-shape-round; + } + + &-default { + border-radius: $corners-shape-default; + } + } + + &__elements-container { + display: flex; + flex-grow: 1; + justify-content: space-between; + position: relative; + + & > .ehp-header__ctas-container { + grid-area: end; + justify-content: flex-end; + } + } + + &__site-link { + align-items: center; + display: flex; + order: var(--header-logo-order); + justify-content: var(--header-logo-order); + + img { + width: var(--header-logo-width); + } + } + + &__site-title { + color: var(--header-site-title-color); + font-weight: 600; + margin: 0; + } + + &__ctas-container { + align-items: center; + display: flex; + gap: var(--header-buttons-space-between); + order: 3; + } + + &__button { + align-items: center; + display: flex; + font-weight: 500; + font-size: 16px; + gap: var(--header-button-icon-spacing); + text-decoration: none; + transition: $transition; + + &:hover, + &:focus { + transition: $transition; + } + + &.has-border { + border-color: var(--header-button-border-color); + border-style: solid; + border-width: var(--header-button-border-width); + border-radius: var(--header-button-border-radius); + } + + &.is-type { + + &-button { + background-color: var(--header-button-background-color); + padding-block-end: var(--header-button-padding-block-end); + padding-block-start: var(--header-button-padding-block-start); + padding-inline-end: var(--header-button-padding-inline-end); + padding-inline-start: var(--header-button-padding-inline-start); + } + + &-link, + &-link:not([href]):not([tabindex]) { + text-decoration: underline; + } + + &-button, + &-link, + &-button:not([href]):not([tabindex]), + &-link:not([href]):not([tabindex]) { + color: var(--header-button-text-color); + + &:hover, + &:focus { + color: var(--header-button-text-color-hover); + } + } + } + + &--secondary { + --header-button-text-color: var(--header-button-secondary-text-color); + --header-button-text-color-hover: var(--header-button-secondary-text-color-hover); + --header-button-border-color: var(--header-button-secondary-border-color); + --header-button-background-color: var(--header-button-secondary-background-color); + --header-button-padding-block-end: var(--header-button-secondary-padding-block-end); + --header-button-padding-block-start: var(--header-button-secondary-padding-block-start); + --header-button-padding-inline-end: var(--header-button-secondary-padding-inline-end); + --header-button-padding-inline-start: var(--header-button-secondary-padding-inline-start); + --header-button-border-width: var(--header-button-secondary-border-width); + --header-button-border-radius: var(--header-button-secondary-border-radius); + --header-button-icon-spacing: var(--header-button-secondary-icon-spacing); + } + } + + &__navigation { + order: 1; + + &[aria-hidden="true"] { + display: none; + } + } + + &__toggle-icon { + + &--open { + display: block; + } + + &--close { + display: none; + } + } + + &__button-toggle { + align-items: center; + background: none; + border: none; + cursor: pointer; + display: none; + grid-area: end; + order: 3; + padding: 0; + + &:hover, + &:focus { + background: none; + } + + svg { + fill: var(--header-toggle-icon-color); + height: var(--header-toggle-icon-size); + width: var(--header-toggle-icon-size); + } + + i { + color: var(--header-toggle-icon-color); + font-size: var(--header-toggle-icon-size); + } + + &[aria-expanded="true"] { + + .ehp-header__toggle-icon--open { + display: none; + } + + .ehp-header__toggle-icon--close { + display: block; + } + } + + &[aria-expanded="false"] { + + .ehp-header__toggle-icon--open { + display: block; + } + + .ehp-header__toggle-icon--close { + display: none; + } + } + } + + &__dropdown { + display: flex; + gap: var(--header-menu-item-spacing); + left: -16px; + list-style: none; + padding: 0; + position: absolute; + top: calc(100% + var(--header-box-padding-block-end)); + width: auto; + z-index: 9; + + .menu-item { + flex-grow: 1; + } + + &.has-shape { + + &-default { + border-radius: $submenu-shape-default; + } + + &-sharp { + border-radius: $submenu-shape-sharp; + } + + &-rounded { + border-radius: $submenu-shape-rounded; + } + + &-round { + border-radius: $submenu-shape-round; + } + } + + &[aria-hidden="true"] { + display: none; + } + } + + &__item--sub-level { + white-space: nowrap; + } + + &__item { + color: var(--header-menu-item-color); + transition: $transition; + + &:hover, + &:focus { + color: var(--header-menu-item-color-hover); + transition: $transition; + } + + &[aria-expanded="true"] { + + .ehp-header__submenu-toggle-icon { + transform: rotate(180deg); + transition: $transition; + } + } + } + + &__dropdown-toggle { + border: unset; + border-radius: unset; + padding: unset; + + &:hover, + &:focus { + background: unset; + } + } + + .menu-item { + align-items: center; + display: flex; + height: 100%; + position: relative; + + &.current-menu-item { + + .ehp-header__item { + color: var(--header-menu-item-color-active); + } + } + } + + &__menu { + align-items: center; + display: flex; + gap: var(--header-menu-item-spacing); + list-style-type: none; + padding: 0; + + &.has-focus-active { + + &-underline { + + .menu-item.current-menu-item { + + .ehp-header__item { + position: relative; + + &:after { + background-color: var(--header-focus-active-underline-color); + bottom: -5px; + height: var(--header-focus-active-underline-width); + content: ""; + left: 0; + position: absolute; + width: 100%; + } + } + } + } + + &-highlight { + + .menu-item.current-menu-item { + + .ehp-header__item { + border-radius: 8px; + padding-inline: var(--header-focus-active-highlight-padding-inline); + padding-block: var(--header-focus-active-highlight-padding-block); + + &:hover, + &:focus { + background-color: var(--header-focus-active-highlight-bg-color); + } + } + } + } + } + } + + &__submenu-toggle-icon { + margin-left: 8px; + height: 10px; + transition: $transition; + width: 10px; + } + + &.has-behavior-onscroll-always { + transition: $transition; + + .ehp-header__site-link img, + .ehp-header__site-title { + transition: $transition; + } + + &.scroll-down { + transition: $transition; + + .ehp-header__site-link img { + width: var(--header-logo-width-sticky); + transition: $transition; + } + + .ehp-header__site-title { + font-size: var(--header-title-size-sticky); + font-weight: var(--header-title-weight-sticky); + transition: $transition; + } + } + } + + @mixin responsive_styles_mobile() { + .ehp-header { + + &__elements-container > .ehp-header__ctas-container { + display: none; + } + + &__dropdown { + align-items: var(--header-dropdown-text-align); + border-radius: unset; + flex-direction: column; + left: unset; + top: unset; + position: relative; + width: 100%; + } + + &__navigation { + left: calc(-1 * var(--header-box-padding-inline-start)); + padding-block-start: var(--header-box-padding-block-start); + padding-block-end: var(--header-box-padding-block-end); + padding-inline-start: var(--header-box-padding-inline-start); + padding-inline-end: var(--header-box-padding-inline-end); + position: absolute; + top: 100%; + width: calc(100% + var(--header-box-padding-inline-start) + var(--header-box-padding-inline-end)); + + .ehp-header__ctas-container { + align-items: stretch; + display: flex; + flex-direction: column; + } + } + + &__button { + justify-content: center; + } + + &__button-toggle { + display: flex; + } + + &__menu { + align-items: var(--header-dropdown-text-align); + display: flex; + flex-direction: column; + + &.has-responsive-divider { + + & > .menu-item { + border-bottom: 1px solid var(--header-dropdown-divider-color); + padding-block-end: var(--header-menu-item-spacing); + width: 100%; + + &:last-child { + border-bottom: none; + padding-bottom: 0; + } + } + } + } + } + + .menu-item.menu-item-has-children { + align-items: var(--header-dropdown-text-align); + display: flex; + flex-direction: column; + margin-bottom: var(--header-menu-item-spacing); + width: 100%; + + & .ehp-header__dropdown-toggle[aria-expanded="true"] { + margin-bottom: var(--header-menu-item-spacing); + } + } + } + + @mixin responsive_styles_desktop { + + .ehp-header { + &__navigation { + align-items: center; + display: flex; + + & > .ehp-header__ctas-container { + display: none; + } + } + + &__ghost-element { + display: none; + } + + &__dropdown { + padding: 16px 32px; + + &.has-layout-horizontal { + flex-direction: row; + } + + &.has-layout-vertical { + flex-direction: column; + } + } + + &__menu { + + &.has-pointer-hover { + + &-underline { + + .ehp-header__item:hover { + position: relative; + + &:after { + background-color: var(--header-pointer-hover-underline-color); + bottom: -5px; + height: var(--header-pointer-hover-underline-width); + content: ""; + left: 0; + position: absolute; + width: 100%; + } + } + } + + &-highlight { + + .ehp-header__item { + border-radius: 8px; + padding-inline: var(--header-pointer-hover-highlight-padding-inline); + padding-block: var(--header-pointer-hover-highlight-padding-block); + + &:hover { + background-color: var(--header-pointer-hover-highlight-bg-color); + } + } + } + } + } + } + } + + &.has-navigation-breakpoint-mobile-portrait { + + @media screen and (max-width: $screen-mobile-max) { + @include responsive_styles_mobile(); + } + + @media screen and (min-width: $screen-tablet-min) { + @include responsive_styles_desktop(); + } + } + + &.has-navigation-breakpoint-tablet-portrait { + + @media screen and (max-width: $screen-tablet-max) { + @include responsive_styles_mobile(); + } + + @media screen and (min-width: $screen-desktop-min) { + @include responsive_styles_desktop(); + } + } +} + +.e-con.e-con--ehp-header, +.e-con:has(.ehp-header:is(.has-behavior-onscroll-none):not(.has-behavior-float)) { + padding: 0; + + & > .e-con-inner.e-con-inner--ehp-header, + & > .e-con-inner { + max-width: unset; + padding-block-end: 0; + padding-block-start: 0; + } } diff --git a/modules/template-parts/assets/scss/variables.scss b/modules/template-parts/assets/scss/variables.scss new file mode 100644 index 00000000..8d64c4f8 --- /dev/null +++ b/modules/template-parts/assets/scss/variables.scss @@ -0,0 +1,5 @@ +$transition: all .3s; +$corners-shape-default: 8px; +$corners-shape-sharp: 0; +$corners-shape-rounded: 12px; +$corners-shape-round: 32px; diff --git a/modules/template-parts/classes/render/widget-header-render.php b/modules/template-parts/classes/render/widget-header-render.php index bf927d5d..d0873993 100644 --- a/modules/template-parts/classes/render/widget-header-render.php +++ b/modules/template-parts/classes/render/widget-header-render.php @@ -2,11 +2,20 @@ namespace HelloPlus\Modules\TemplateParts\Classes\Render; +use Elementor\Group_Control_Image_Size; +use Elementor\Icons_Manager; +use Elementor\Utils; + use HelloPlus\Modules\TemplateParts\Widgets\Header; class Widget_Header_Render { + protected Header $widget; + const LAYOUT_CLASSNAME = 'ehp-header'; + const SITE_LINK_CLASSNAME = 'ehp-header__site-link'; + const CTAS_CONTAINER_CLASSNAME = 'ehp-header__ctas-container'; + const BUTTON_CLASSNAME = 'ehp-header__button'; protected array $settings; @@ -17,20 +26,311 @@ public function __construct( Header $widget ) { public function render(): void { $layout_classnames = self::LAYOUT_CLASSNAME; - $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + $navigation_breakpoint = $this->settings['navigation_breakpoint'] ?? ''; + $box_border = $this->settings['show_box_border'] ?? ''; + $behavior_float = $this->settings['behavior_float']; + $behavior_float_shape = $this->settings['behavior_float_shape']; + $behavior_on_scroll = $this->settings['behavior_onscroll_select']; + + if ( ! empty( $navigation_breakpoint ) ) { + $layout_classnames .= ' has-navigation-breakpoint-' . $navigation_breakpoint; + } + + if ( 'yes' === $box_border ) { + $layout_classnames .= ' has-box-border'; + } - if ( '' !== $custom_classes ) { - $layout_classnames .= ' ' . $custom_classes; + if ( 'yes' === $behavior_float ) { + $layout_classnames .= ' has-behavior-float'; + } + + if ( ! empty( $behavior_float_shape ) ) { + $layout_classnames .= ' has-shape-' . $behavior_float_shape; + } + + if ( ! empty( $behavior_on_scroll ) ) { + $layout_classnames .= ' has-behavior-onscroll-' . $behavior_on_scroll; } $this->widget->add_render_attribute( 'layout', [ - 'id' => $this->settings['advanced_custom_css_id'], 'class' => $layout_classnames, + 'data-scroll-behavior' => $behavior_on_scroll, + 'data-behavior-float' => $behavior_float, ] ); ?>
widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> - Header +
+ render_site_link(); + $this->render_navigation(); + $this->render_ctas_container(); + ?> +
settings['site_logo_image']; + $site_title_text = $this->widget->get_site_title(); + $site_title_tag = $this->settings['site_logo_title_tag'] ?? 'h2'; + $site_link_classnames = self::SITE_LINK_CLASSNAME; + + $this->widget->add_render_attribute( 'site-link', [ + 'class' => $site_link_classnames, + ] ); + + $site_link = $this->get_link_url(); + + if ( $site_link ) { + $this->widget->add_link_attributes( 'site-link', $site_link ); + } + ?> + widget->get_render_attribute_string( 'site-link' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + + settings, 'site_logo_image' ); ?> + %4$s', Utils::validate_html_tag( $site_title_tag ), $this->widget->get_render_attribute_string( 'heading' ), 'class="ehp-header__site-title"', esc_html( $site_title_text ) ); + // Escaped above + Utils::print_unescaped_internal_string( $site_title_output ); + } ?> + + widget->get_available_menus(); + $menu_classname = 'ehp-header__menu'; + + if ( ! $available_menus ) { + return; + } + + $pointer_hover_type = $this->settings['style_navigation_pointer_hover'] ?? ''; + $focus_active_type = $this->settings['style_navigation_focus_active'] ?? ''; + $has_responsive_divider = $this->settings['style_responsive_menu_divider']; + + if ( 'none' !== $pointer_hover_type ) { + $menu_classname .= ' has-pointer-hover-' . $pointer_hover_type; + } + + if ( 'none' !== $focus_active_type ) { + $menu_classname .= ' has-focus-active-' . $focus_active_type; + } + + if ( 'yes' === $has_responsive_divider ) { + $menu_classname .= ' has-responsive-divider'; + } + + $settings = $this->settings; + $submenu_layout = $this->settings['style_submenu_layout'] ?? 'horizontal'; + + $args = [ + 'echo' => false, + 'menu' => $settings['navigation_menu'], + 'menu_class' => $menu_classname, + 'menu_id' => 'menu-' . $this->widget->get_and_advance_nav_menu_index() . '-' . $this->widget->get_id(), + 'fallback_cb' => '__return_empty_string', + 'container' => '', + ]; + + // Add custom filter to handle Nav Menu HTML output. + add_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_classes' ], 10, 4 ); + add_filter( 'nav_menu_submenu_css_class', [ $this, 'handle_sub_menu_classes' ] ); + add_filter( 'walker_nav_menu_start_el', [ $this, 'handle_walker_menu_start_el' ], 10, 4 ); + add_filter( 'nav_menu_item_id', '__return_empty_string' ); + + // General Menu. + $menu_html = wp_nav_menu( $args ); + + // Remove all our custom filters. + remove_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_classes' ] ); + remove_filter( 'nav_menu_submenu_css_class', [ $this, 'handle_sub_menu_classes' ] ); + remove_filter( 'walker_nav_menu_start_el', [ $this, 'handle_walker_menu_start_el' ] ); + remove_filter( 'nav_menu_item_id', '__return_empty_string' ); + + if ( empty( $menu_html ) ) { + return; + } + + if ( $settings['navigation_menu_name'] ) { + $this->widget->add_render_attribute( 'main-menu', 'aria-label', $settings['navigation_menu_name'] ); + } + + $this->widget->add_render_attribute( 'main-menu', 'class', [ + ' has-submenu-layout-' . $submenu_layout, + 'ehp-header__navigation', + ] ); + ?> + + + + render_menu_toggle(); + } + + private function render_menu_toggle() { + $toggle_icon = $this->settings['navigation_menu_icon']; + $toggle_classname = 'ehp-header__button-toggle'; + + $this->widget->add_render_attribute( 'button-toggle', [ + 'class' => $toggle_classname, + 'role' => 'button', + 'tabindex' => '0', + 'aria-label' => esc_html__( 'Menu Toggle', 'hello-plus' ), + 'aria-expanded' => 'false', + ] ); + + ?> + + settings['primary_cta_button_text']; + $secondary_cta_button_text = $this->settings['secondary_cta_button_text']; + $has_primary_button = ! empty( $primary_cta_button_text ); + $has_secondary_button = ! empty( $secondary_cta_button_text ); + + $ctas_container_classnames = self::CTAS_CONTAINER_CLASSNAME; + + $this->widget->add_render_attribute( 'ctas-container', [ + 'class' => $ctas_container_classnames, + ] ); + ?> +
widget->get_render_attribute_string( 'ctas-container' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_button( 'primary' ); + } ?> + render_button( 'secondary' ); + } ?> +
+ settings[ $type . '_cta_button_text' ]; + $button_link = $this->settings[ $type . '_cta_button_link' ]; + $button_icon = $this->settings[ $type . '_cta_button_icon' ]; + $button_hover_animation = $this->settings[ $type . '_button_hover_animation' ] ?? ''; + $button_has_border = $this->settings[ $type . '_show_button_border' ]; + $button_corner_shape = $this->settings[ $type . '_button_shape' ] ?? ''; + $button_type = $this->settings[ $type . '_button_type' ] ?? ''; + $button_classnames = self::BUTTON_CLASSNAME; + + $button_classnames .= ' ehp-header__button--' . $type; + + if ( ! empty( $button_type ) ) { + $button_classnames .= ' is-type-' . $button_type; + } + + if ( $button_hover_animation ) { + $button_classnames .= ' elementor-animation-' . $button_hover_animation; + } + + if ( 'yes' === $button_has_border ) { + $button_classnames .= ' has-border'; + } + + if ( ! empty( $button_corner_shape ) ) { + $button_classnames .= ' has-shape-' . $button_corner_shape; + } + + $this->widget->add_render_attribute( $type . '-button', [ + 'class' => $button_classnames, + ] ); + + if ( ! empty( $button_link ) ) { + $this->widget->add_link_attributes( $type . '-button', $button_link ); + } + + ?> + widget->get_render_attribute_string( $type . '-button' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + 'true', + 'class' => 'ehp-header__button-icon', + ] + ); + ?> + + + $this->widget->get_site_url() ]; + } + + public function handle_link_classes( $atts, $item, $args, $depth ) { + $classes = $depth ? 'ehp-header__item ehp-header__item--sub-level' : 'ehp-header__item ehp-header__item--top-level'; + $is_anchor = false !== strpos( $atts['href'], '#' ); + + if ( ! $is_anchor && in_array( 'current-menu-item', $item->classes, true ) ) { + $classes .= ' is-item-active'; + } + + if ( $is_anchor ) { + $classes .= ' is-item-anchor'; + } + + if ( empty( $atts['class'] ) ) { + $atts['class'] = $classes; + } else { + $atts['class'] .= ' ' . $classes; + } + + return $atts; + } + + public function handle_sub_menu_classes( $classes ) { + $submenu_layout = $this->settings['style_submenu_layout'] ?? 'horizontal'; + $submenu_shape = $this->settings['style_submenu_shape'] ?? 'default'; + + $dropdown_classnames = 'ehp-header__dropdown'; + $dropdown_classnames .= ' has-layout-' . $submenu_layout; + $dropdown_classnames .= ' has-shape-' . $submenu_shape; + + $classes[] = $dropdown_classnames; + + return $classes; + } + + public function handle_walker_menu_start_el( $item_output, $item ) { + + if ( in_array( 'menu-item-has-children', $item->classes, true ) ) { + $submenu_icon = $this->settings['navigation_menu_submenu_icon']; + + $svg_icon = Icons_Manager::try_get_icon_html( $submenu_icon, + [ + 'aria-hidden' => 'true', + 'class' => 'ehp-header__submenu-toggle-icon', + ] + ); + + $item_output = ''; + } + + return $item_output; + } } diff --git a/modules/template-parts/classes/traits/shared-header-traits.php b/modules/template-parts/classes/traits/shared-header-traits.php new file mode 100644 index 00000000..eba2c5d7 --- /dev/null +++ b/modules/template-parts/classes/traits/shared-header-traits.php @@ -0,0 +1,47 @@ +slug ] = $menu->name; + } + + return $options; + } + + public function get_and_advance_nav_menu_index(): int { + return $this->nav_menu_index++; + } +} diff --git a/modules/template-parts/module.php b/modules/template-parts/module.php index 64a69c2b..e3702964 100644 --- a/modules/template-parts/module.php +++ b/modules/template-parts/module.php @@ -46,6 +46,18 @@ public function enqueue(): void { [], HELLO_PLUS_ELEMENTOR_VERSION ); + + wp_enqueue_script( + 'hello-plus-header', + HELLO_PLUS_SCRIPTS_URL . 'hello-plus-header.js', + [ 'jquery' ], + HELLO_PLUS_ELEMENTOR_VERSION, + true + ); + } + + public function get_script_depends(): array { + return [ 'hello-plus-header' ]; } /** diff --git a/modules/template-parts/widgets/header.php b/modules/template-parts/widgets/header.php index 830366ca..8370c8d9 100644 --- a/modules/template-parts/widgets/header.php +++ b/modules/template-parts/widgets/header.php @@ -6,22 +6,24 @@ exit; // Exit if accessed directly. } -use Elementor\Controls_Manager; -use Elementor\Group_Control_Background; -use Elementor\Group_Control_Box_Shadow; -use Elementor\Group_Control_Typography; -use Elementor\Utils; -use Elementor\Widget_Base; +use Elementor\{ + Widget_Base, + Controls_Manager, + Group_Control_Background, + Group_Control_Box_Shadow, + Group_Control_Typography +}; use Elementor\Core\Kits\Documents\Tabs\Global_Typography; -use HelloPlus\Includes\Utils as Theme_Utils; -use HelloPlus\Modules\TemplateParts\Classes\Render\Widget_Header_Render; -use HelloPlus\Modules\Theme\Classes\Control_Media_Preview; +use HelloPlus\Modules\TemplateParts\Classes\{ + Traits\Shared_Header_Traits, + Render\Widget_Header_Render +}; use HelloPlus\Modules\Theme\Module as Theme_Module; class Header extends Widget_Base { - const TAB_ADVANCED = 'advanced-tab-header'; + use Shared_Header_Traits; public function get_name(): string { return 'header'; @@ -54,32 +56,22 @@ protected function render(): void { } protected function register_controls() { - $this->add_content_section(); - $this->add_style_section(); - $this->add_advanced_section(); + $this->add_content_tab(); + $this->add_style_tab(); } - protected function add_content_section() { + protected function add_content_tab() { $this->add_content_site_logo_section(); $this->add_content_navigation_section(); $this->add_content_cta_section(); } - protected function add_style_section() { + protected function add_style_tab() { $this->add_style_site_identity_section(); $this->add_style_navigation_section(); $this->add_style_cta_section(); $this->add_style_box_section(); - } - - protected function add_advanced_section() { - Controls_Manager::add_tab( - static::TAB_ADVANCED, - esc_html__( 'Advanced', 'hello-plus' ) - ); - - $this->add_advanced_behavior_section(); - $this->add_advanced_custom_section(); + $this->add_style_behavior_section(); } protected function add_content_site_logo_section() { @@ -91,14 +83,14 @@ protected function add_content_site_logo_section() { ] ); - $this->add_responsive_control( + $this->add_control( 'site_logo_brand_select', [ 'label' => esc_html__( 'Brand', 'hello-plus' ), 'type' => Controls_Manager::SELECT, 'options' => [ - 'logo' => 'Site Logo', - 'title' => 'Site Title', + 'logo' => esc_html__( 'Site Logo', 'hello-plus' ), + 'title' => esc_html__( 'Site Title', 'hello-plus' ), ], 'default' => 'logo', 'tablet_default' => 'logo', @@ -109,15 +101,14 @@ protected function add_content_site_logo_section() { $this->add_control( 'site_logo_image', [ - 'label' => esc_html__( 'Site Logo', 'hello-plus' ), - 'type' => Control_Media_Preview::CONTROL_TYPE, - 'src' => $this->get_site_logo(), + 'label' => esc_html__( 'Choose Image', 'hello-plus' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => $this->get_site_logo_url(), + ], 'condition' => [ 'site_logo_brand_select' => 'logo', ], - ], - [ - 'recursive' => true, ] ); @@ -129,7 +120,7 @@ protected function add_content_site_logo_section() { 'show_label' => false, 'button_type' => 'default elementor-button-center', 'text' => esc_html__( 'Change Site Logo', 'hello-plus' ), - 'event' => 'elementorProSiteLogo:change', + 'event' => 'helloPlusLogo:change', 'condition' => [ 'site_logo_brand_select' => 'logo', ], @@ -243,21 +234,6 @@ protected function add_content_navigation_section() { ] ); - $this->add_control( - 'navigation_menu_close_button', - [ - 'label' => esc_html__( 'Close Button', 'hello-plus' ), - 'type' => Controls_Manager::ICONS, - 'skin' => 'inline', - 'label_block' => false, - 'default' => [ - 'value' => 'fa fa-close', - 'library' => 'fa-solid', - ], - 'exclude_inline_options' => [ 'none' ], - ] - ); - $this->add_control( 'navigation_breakpoint', [ @@ -270,9 +246,6 @@ protected function add_content_navigation_section() { ], 'default' => 'mobile-portrait', 'separator' => 'after', - 'selectors' => [ - '{{WRAPPER}} .ehp-zigzag' => '--zigzag-image-width: {{VALUE}};', - ], ] ); @@ -373,9 +346,9 @@ protected function add_content_cta_section() { $this->add_control( 'secondary_cta_button_text', [ - 'label' => esc_html__( 'Primary CTA', 'hello-plus' ), + 'label' => esc_html__( 'Secondary CTA', 'hello-plus' ), 'type' => Controls_Manager::TEXT, - 'default' => esc_html__( 'Schedule Now', 'hello-plus' ), + 'default' => esc_html__( 'Contact Us', 'hello-plus' ), 'dynamic' => [ 'active' => true, ], @@ -434,20 +407,20 @@ protected function add_style_site_identity_section() { 'label' => esc_html__( 'Align Logo', 'hello-plus' ), 'type' => Controls_Manager::CHOOSE, 'options' => [ - 'flex-start' => [ + '0' => [ 'title' => esc_html__( 'Start', 'hello-plus' ), 'icon' => 'eicon-align-start-h', ], - 'center' => [ - 'title' => esc_html__( 'End', 'hello-plus' ), + '2' => [ + 'title' => esc_html__( 'Center', 'hello-plus' ), 'icon' => 'eicon-align-center-h', ], ], - 'default' => 'flex-start', - 'tablet_default' => 'flex-start', - 'mobile_default' => 'flex-start', + 'default' => '0', + 'tablet_default' => '0', + 'mobile_default' => '0', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-buttons-position: {{VALUE}};', + '{{WRAPPER}} .ehp-header' => '--header-logo-order: {{VALUE}};', ], 'condition' => [ 'site_logo_brand_select' => 'logo', @@ -455,7 +428,7 @@ protected function add_style_site_identity_section() { ] ); - $this->add_control( + $this->add_responsive_control( 'style_logo_width', [ 'label' => __( 'Logo Width', 'hello-plus' ), @@ -472,8 +445,16 @@ protected function add_style_site_identity_section() { 'size' => 68, 'unit' => 'px', ], + 'tablet_default' => [ + 'size' => 68, + 'unit' => 'px', + ], + 'mobile_default' => [ + 'size' => 68, + 'unit' => 'px', + ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button--border-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-logo-width: {{SIZE}}{{UNIT}};', ], 'condition' => [ 'site_logo_brand_select' => 'logo', @@ -487,20 +468,20 @@ protected function add_style_site_identity_section() { 'label' => esc_html__( 'Align Site Title', 'hello-plus' ), 'type' => Controls_Manager::CHOOSE, 'options' => [ - 'flex-start' => [ + '0' => [ 'title' => esc_html__( 'Start', 'hello-plus' ), 'icon' => 'eicon-align-start-h', ], - 'center' => [ + '2' => [ 'title' => esc_html__( 'End', 'hello-plus' ), 'icon' => 'eicon-align-center-h', ], ], - 'default' => 'flex-start', - 'tablet_default' => 'flex-start', - 'mobile_default' => 'flex-start', + 'default' => '0', + 'tablet_default' => '0', + 'mobile_default' => '0', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-buttons-position: {{VALUE}};', + '{{WRAPPER}} .ehp-header' => '--header-logo-order: {{VALUE}};', ], 'condition' => [ 'site_logo_brand_select' => 'title', @@ -515,7 +496,7 @@ protected function add_style_site_identity_section() { 'type' => Controls_Manager::COLOR, 'default' => '#0052FF', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button--border-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-site-title-color: {{VALUE}}', ], 'condition' => [ 'site_logo_brand_select' => 'title', @@ -527,10 +508,13 @@ protected function add_style_site_identity_section() { Group_Control_Typography::get_type(), [ 'name' => 'style_title_typography', - 'selector' => '{{WRAPPER}} .ehp-cta__heading', + 'selector' => '{{WRAPPER}} .ehp-header__site-title', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, ], + 'condition' => [ + 'site_logo_brand_select' => 'title', + ], ] ); @@ -550,7 +534,7 @@ protected function add_style_navigation_section() { Group_Control_Typography::get_type(), [ 'name' => 'style_navigation_typography', - 'selector' => '{{WRAPPER}} .ehp-cta__heading', + 'selector' => '{{WRAPPER}} .ehp-header__item', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_ACCENT, ], @@ -575,7 +559,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-menu-item-color: {{VALUE}}', ], ] ); @@ -596,7 +580,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-menu-item-color-hover: {{VALUE}}', ], ] ); @@ -622,7 +606,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-pointer-hover-underline-color: {{VALUE}}', ], 'condition' => [ 'style_navigation_pointer_hover' => 'underline', @@ -635,11 +619,14 @@ protected function add_style_navigation_section() { [ 'label' => esc_html__( 'Underline Width', 'hello-plus' ), 'type' => Controls_Manager::SELECT, - 'default' => 'default', + 'default' => '3px', 'options' => [ - 'default' => esc_html__( 'Default', 'hello-plus' ), - 'thin' => esc_html__( 'Thin', 'hello-plus' ), - 'thick' => esc_html__( 'Thick', 'hello-plus' ), + '3px' => esc_html__( 'Default', 'hello-plus' ), + '1px' => esc_html__( 'Thin', 'hello-plus' ), + '5px' => esc_html__( 'Thick', 'hello-plus' ), + ], + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-pointer-hover-underline-width: {{VALUE}}', ], 'condition' => [ 'style_navigation_pointer_hover' => 'underline', @@ -652,9 +639,9 @@ protected function add_style_navigation_section() { [ 'label' => esc_html__( 'Highlight Color', 'hello-plus' ), 'type' => Controls_Manager::COLOR, - 'default' => '#555963', + 'default' => '#E0EAFF', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-pointer-hover-highlight-bg-color: {{VALUE}}', ], 'condition' => [ 'style_navigation_pointer_hover' => 'highlight', @@ -673,6 +660,9 @@ protected function add_style_navigation_section() { 'thin' => esc_html__( 'Thin', 'hello-plus' ), 'thick' => esc_html__( 'Thick', 'hello-plus' ), ], + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-pointer-hover-highlight-padding-inline: var(--header-pointer-hover-highlight-padding-inline-{{VALUE}}); --header-pointer-hover-highlight-padding-block: var(--header-pointer-hover-highlight-padding-block-{{VALUE}});', + ], 'condition' => [ 'style_navigation_pointer_hover' => 'highlight', ], @@ -695,7 +685,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-menu-item-color-active: {{VALUE}}', ], ] ); @@ -721,7 +711,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-focus-active-underline-color: {{VALUE}}', ], 'condition' => [ 'style_navigation_focus_active' => 'underline', @@ -734,11 +724,14 @@ protected function add_style_navigation_section() { [ 'label' => esc_html__( 'Underline Width', 'hello-plus' ), 'type' => Controls_Manager::SELECT, - 'default' => 'default', + 'default' => '3px', 'options' => [ - 'default' => esc_html__( 'Default', 'hello-plus' ), - 'thin' => esc_html__( 'Thin', 'hello-plus' ), - 'thick' => esc_html__( 'Thick', 'hello-plus' ), + '3px' => esc_html__( 'Default', 'hello-plus' ), + '1px' => esc_html__( 'Thin', 'hello-plus' ), + '5px' => esc_html__( 'Thick', 'hello-plus' ), + ], + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-focus-active-underline-width: {{VALUE}}', ], 'condition' => [ 'style_navigation_focus_active' => 'underline', @@ -753,7 +746,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-focus-active-highlight-bg-color: {{VALUE}}', ], 'condition' => [ 'style_navigation_focus_active' => 'highlight', @@ -772,6 +765,9 @@ protected function add_style_navigation_section() { 'thin' => esc_html__( 'Thin', 'hello-plus' ), 'thick' => esc_html__( 'Thick', 'hello-plus' ), ], + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-focus-active-highlight-padding-inline: var(--header-focus-active-highlight-padding-inline-{{VALUE}}); --header-focus-active-highlight-padding-block: var(--header-focus-active-highlight-padding-block-{{VALUE}});', + ], 'condition' => [ 'style_navigation_focus_active' => 'highlight', ], @@ -782,6 +778,37 @@ protected function add_style_navigation_section() { $this->end_controls_tabs(); + $this->add_responsive_control( + 'menu_item_spacing', + [ + 'label' => __( 'Menu Item Spacing', 'hello-plus' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', '%', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + 'step' => 1, + ], + ], + 'default' => [ + 'size' => 32, + 'unit' => 'px', + ], + 'tablet_default' => [ + 'size' => 32, + 'unit' => 'px', + ], + 'mobile_default' => [ + 'size' => 32, + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-menu-item-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + $this->add_control( 'style_submenu_label', [ @@ -852,7 +879,7 @@ protected function add_style_navigation_section() { ], 'default' => 'flex-start', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-buttons-position: {{VALUE}};', + '{{WRAPPER}} .ehp-header' => '--header-dropdown-text-align: {{VALUE}};', ], ] ); @@ -877,7 +904,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#E0E1E2', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-dropdown-divider-color: {{VALUE}}', ], 'condition' => [ 'style_responsive_menu_divider' => 'yes', @@ -922,10 +949,21 @@ protected function add_style_navigation_section() { 'max' => 100, ], ], + 'default' => [ + 'size' => 22, + 'unit' => 'px', + ], + 'tablet_default' => [ + 'size' => 22, + 'unit' => 'px', + ], + 'mobile_default' => [ + 'size' => 22, + 'unit' => 'px', + ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-content-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-toggle-icon-size: {{SIZE}}{{UNIT}};', ], - 'separator' => 'before', ] ); @@ -947,7 +985,7 @@ protected function add_style_navigation_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-toggle-icon-color: {{VALUE}}', ], ] ); @@ -1019,7 +1057,7 @@ protected function add_style_box_section() { 'name' => 'background', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], - 'selector' => '{{WRAPPER}} .ehp-cta', + 'selector' => '{{WRAPPER}} .ehp-header, {{WRAPPER}} .ehp-header .ehp-header__dropdown', 'fields_options' => [ 'background' => [ 'default' => 'classic', @@ -1062,7 +1100,7 @@ protected function add_style_box_section() { 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-button-border-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-box-border-width: {{SIZE}}{{UNIT}};', ], 'condition' => [ 'show_box_border' => 'yes', @@ -1077,7 +1115,7 @@ protected function add_style_box_section() { 'type' => Controls_Manager::COLOR, 'default' => '#555963', 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-button-border-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-box-border-color: {{VALUE}}', ], 'condition' => [ 'show_box_border' => 'yes', @@ -1089,7 +1127,7 @@ protected function add_style_box_section() { Group_Control_Box_Shadow::get_type(), [ 'name' => 'box_box_shadow', - 'selector' => '{{WRAPPER}} .ehp-hero__button', + 'selector' => '{{WRAPPER}} .ehp-header', ] ); @@ -1099,8 +1137,15 @@ protected function add_style_box_section() { 'label' => esc_html__( 'Padding', 'hello-plus' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem' ], + 'default' => [ + 'top' => 16, + 'right' => 32, + 'bottom' => 16, + 'left' => 32, + 'unit' => 'px', + ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-button-padding-block-end: {{BOTTOM}}{{UNIT}}; --hero-button-padding-block-start: {{TOP}}{{UNIT}}; --hero-button-padding-inline-end: {{RIGHT}}{{UNIT}}; --hero-button-padding-inline-start: {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-box-padding-block-end: {{BOTTOM}}{{UNIT}}; --header-box-padding-block-start: {{TOP}}{{UNIT}}; --header-box-padding-inline-end: {{RIGHT}}{{UNIT}}; --header-box-padding-inline-start: {{LEFT}}{{UNIT}};', ], ] ); @@ -1109,8 +1154,11 @@ protected function add_style_box_section() { } protected function add_cta_button_controls( string $type, bool $add_condition = false ) { - $label = 'primary' === $type ? esc_html__( 'Primary CTA', 'hello-plus' ) : esc_html__( 'Secondary CTA', 'hello-plus' ); - $show_button_border_default = 'primary' === $type ? 'no' : 'yes'; + $is_primary = 'primary' === $type; + $label = $is_primary ? esc_html__( 'Primary CTA', 'hello-plus' ) : esc_html__( 'Secondary CTA', 'hello-plus' ); + $show_button_border_default = $is_primary ? 'no' : 'yes'; + $text_color_default = $is_primary ? '#ffffff' : '#555963'; + $background_color_default = $is_primary ? '#0052FF' : '#F6F7F8'; $add_type_condition = $add_condition ? [ $type . '_cta_show' => 'yes', @@ -1143,7 +1191,10 @@ protected function add_cta_button_controls( string $type, bool $add_condition = Group_Control_Typography::get_type(), [ 'name' => $type . '_button_typography', - 'selector' => '{{WRAPPER}} .ehp-cta__button--' . $type, + 'selector' => '{{WRAPPER}} .ehp-header__button--' . $type, + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], 'condition' => $add_type_condition, ] ); @@ -1170,7 +1221,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'right' => is_rtl() ? 'row' : 'row-reverse', ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta__button--' . $type => 'flex-direction: {{VALUE}};', + '{{WRAPPER}} .ehp-header__button--' . $type => 'flex-direction: {{VALUE}};', ], 'condition' => array_merge([ $type . '_cta_button_icon[value]!' => '', @@ -1199,7 +1250,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = ], ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-icon-spacing: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-icon-spacing: {{SIZE}}{{UNIT}};', ], 'condition' => array_merge([ $type . '_cta_button_icon[value]!' => '', @@ -1224,8 +1275,9 @@ protected function add_cta_button_controls( string $type, bool $add_condition = [ 'label' => esc_html__( 'Text Color', 'hello-plus' ), 'type' => Controls_Manager::COLOR, + 'default' => $text_color_default, 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-text-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-text-color: {{VALUE}}', ], 'condition' => $add_type_condition, ] @@ -1237,11 +1289,14 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'name' => $type . '_button_background', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], - 'selector' => '{{WRAPPER}} .ehp-cta__button--' . $type, + 'selector' => '{{WRAPPER}} .ehp-header__button--' . $type, 'fields_options' => [ 'background' => [ 'default' => 'classic', ], + 'color' => [ + 'default' => $background_color_default, + ], ], 'condition' => array_merge([ $type . '_button_type' => 'button', @@ -1264,8 +1319,9 @@ protected function add_cta_button_controls( string $type, bool $add_condition = [ 'label' => esc_html__( 'Text Color', 'hello-plus' ), 'type' => Controls_Manager::COLOR, + 'default' => $text_color_default, 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-text-color-hover: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-text-color-hover: {{VALUE}}', ], 'condition' => $add_type_condition, ] @@ -1277,11 +1333,14 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'name' => $type . '_button_background_hover', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], - 'selector' => '{{WRAPPER}} .ehp-cta__button--' . $type . ':hover, {{WRAPPER}} .ehp-cta__button--' . $type . ':focus', + 'selector' => '{{WRAPPER}} .ehp-header__button--' . $type . ':hover, {{WRAPPER}} .ehp-header__button--' . $type . ':focus', 'fields_options' => [ 'background' => [ 'default' => 'classic', ], + 'color' => [ + 'default' => $background_color_default, + ], ], 'condition' => array_merge([ $type . '_button_type' => 'button', @@ -1336,7 +1395,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-border-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-border-width: {{SIZE}}{{UNIT}};', ], 'condition' => array_merge([ $type . '_show_button_border' => 'yes', @@ -1350,7 +1409,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'label' => esc_html__( 'Color', 'hello-plus' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-border-color: {{VALUE}}', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-border-color: {{VALUE}}', ], 'condition' => array_merge([ $type . '_show_button_border' => 'yes', @@ -1380,7 +1439,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = Group_Control_Box_Shadow::get_type(), [ 'name' => $type . '_button_box_shadow', - 'selector' => '{{WRAPPER}} .ehp-cta__button--' . $type, + 'selector' => '{{WRAPPER}} .ehp-header__button--' . $type, 'condition' => array_merge([ $type . '_button_type' => 'button', ], $add_type_condition), @@ -1394,7 +1453,7 @@ protected function add_cta_button_controls( string $type, bool $add_condition = 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem' ], 'selectors' => [ - '{{WRAPPER}} .ehp-cta' => '--cta-button-' . $type . '-padding-block-end: {{BOTTOM}}{{UNIT}}; --cta-button-' . $type . '-padding-block-start: {{TOP}}{{UNIT}}; --cta-button-' . $type . '-padding-inline-end: {{RIGHT}}{{UNIT}}; --cta-button-' . $type . '-padding-inline-start: {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-button-' . $type . '-padding-block-end: {{BOTTOM}}{{UNIT}}; --header-button-' . $type . '-padding-block-start: {{TOP}}{{UNIT}}; --header-button-' . $type . '-padding-inline-end: {{RIGHT}}{{UNIT}}; --header-button-' . $type . '-padding-inline-start: {{LEFT}}{{UNIT}};', ], 'separator' => 'before', 'condition' => array_merge([ @@ -1404,12 +1463,12 @@ protected function add_cta_button_controls( string $type, bool $add_condition = ); } - private function add_advanced_behavior_section(): void { + private function add_style_behavior_section(): void { $this->start_controls_section( 'advanced_behavior_section', [ 'label' => esc_html__( 'Behavior', 'hello-plus' ), - 'tab' => static::TAB_ADVANCED, + 'tab' => Controls_Manager::TAB_STYLE, ] ); @@ -1441,7 +1500,7 @@ private function add_advanced_behavior_section(): void { 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-image-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-float-offset: {{SIZE}}{{UNIT}};', ], 'condition' => [ 'behavior_float' => 'yes', @@ -1466,7 +1525,7 @@ private function add_advanced_behavior_section(): void { 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-image-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .ehp-header' => '--header-float-width: {{SIZE}}{{UNIT}};', ], 'condition' => [ 'behavior_float' => 'yes', @@ -1501,7 +1560,8 @@ private function add_advanced_behavior_section(): void { ] ); - $this->add_responsive_control( + // TODO: check if this needs to be responsive + $this->add_control( 'behavior_onscroll_select', [ 'label' => esc_html__( 'Sticky', 'hello-plus' ), @@ -1524,9 +1584,20 @@ private function add_advanced_behavior_section(): void { 'label_off' => esc_html__( 'No', 'hello-plus' ), 'return_value' => 'yes', 'default' => 'yes', - 'condition' => [ - 'behavior_onscroll_select' => 'always', - 'site_logo_brand_select' => 'site-logo', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'behavior_onscroll_select', + 'operator' => '==', + 'value' => 'always', + ], + [ + 'name' => 'site_logo_brand_select', + 'operator' => '==', + 'value' => 'logo', + ], + ], ], ] ); @@ -1558,11 +1629,27 @@ private function add_advanced_behavior_section(): void { 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-image-height: {{SIZE}}{{UNIT}};', - ], - 'condition' => [ - 'behavior_sticky_scale_logo' => 'yes', - 'site_logo_brand_select' => 'site-logo', + '{{WRAPPER}} .ehp-header' => '--header-logo-width-sticky: {{SIZE}}{{UNIT}};', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'behavior_onscroll_select', + 'operator' => '==', + 'value' => 'always', + ], + [ + 'name' => 'behavior_sticky_scale_logo', + 'operator' => '==', + 'value' => 'yes', + ], + [ + 'name' => 'site_logo_brand_select', + 'operator' => '==', + 'value' => 'logo', + ], + ], ], ] ); @@ -1576,9 +1663,20 @@ private function add_advanced_behavior_section(): void { 'label_off' => esc_html__( 'No', 'hello-plus' ), 'return_value' => 'yes', 'default' => 'yes', - 'condition' => [ - 'behavior_onscroll_select' => 'always', - 'site_logo_brand_select' => 'site-title', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'behavior_onscroll_select', + 'operator' => '==', + 'value' => 'always', + ], + [ + 'name' => 'site_logo_brand_select', + 'operator' => '==', + 'value' => 'title', + ], + ], ], ] ); @@ -1607,11 +1705,27 @@ private function add_advanced_behavior_section(): void { 'unit' => 'px', ], 'selectors' => [ - '{{WRAPPER}} .ehp-hero' => '--hero-content-text-gap: {{SIZE}}{{UNIT}};', - ], - 'condition' => [ - 'behavior_sticky_scale_title' => 'yes', - 'site_logo_brand_select' => 'site-title', + '{{WRAPPER}} .ehp-header' => '--header-title-size-sticky: {{SIZE}}{{UNIT}};', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'behavior_onscroll_select', + 'operator' => '==', + 'value' => 'always', + ], + [ + 'name' => 'behavior_sticky_scale_title', + 'operator' => '==', + 'value' => 'yes', + ], + [ + 'name' => 'site_logo_brand_select', + 'operator' => '==', + 'value' => 'title', + ], + ], ], ] ); @@ -1633,9 +1747,28 @@ private function add_advanced_behavior_section(): void { '800' => esc_html__( '800', 'hello-plus' ), '900' => esc_html__( '900', 'hello-plus' ), ], - 'condition' => [ - 'behavior_sticky_scale_title' => 'yes', - 'site_logo_brand_select' => 'site-title', + 'selectors' => [ + '{{WRAPPER}} .ehp-header' => '--header-title-weight-sticky: {{VALUE}};', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'behavior_onscroll_select', + 'operator' => '==', + 'value' => 'always', + ], + [ + 'name' => 'behavior_sticky_scale_title', + 'operator' => '==', + 'value' => 'yes', + ], + [ + 'name' => 'site_logo_brand_select', + 'operator' => '==', + 'value' => 'title', + ], + ], ], ] ); @@ -1661,7 +1794,7 @@ private function add_advanced_behavior_section(): void { 'name' => 'behavior_sticky_bg', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], - 'selector' => '{{WRAPPER}} .ehp-hero__button', + 'selector' => '{{WRAPPER}} .ehp-header.scroll-down, {{WRAPPER}} .ehp-header.scroll-down .ehp-header__dropdown', 'fields_options' => [ 'background' => [ 'default' => 'classic', @@ -1678,91 +1811,4 @@ private function add_advanced_behavior_section(): void { $this->end_controls_section(); } - - private function add_advanced_custom_section(): void { - $this->start_controls_section( - 'advanced_responsive_section', - [ - 'label' => esc_html__( 'Responsive', 'hello-plus' ), - 'tab' => static::TAB_ADVANCED, - ] - ); - - $this->add_control( - 'responsive_description', - [ - 'raw' => __( 'Responsive visibility will take effect only on preview mode or live page, and not while editing in Elementor.', 'hello-plus' ), - 'type' => Controls_Manager::RAW_HTML, - 'content_classes' => 'elementor-descriptor', - ] - ); - - $this->add_hidden_device_controls(); - - $this->end_controls_section(); - - $this->start_controls_section( - 'advanced_custom_controls_section', - [ - 'label' => esc_html__( 'CSS', 'hello-plus' ), - 'tab' => static::TAB_ADVANCED, - ] - ); - - $this->add_control( - 'advanced_custom_css_id', - [ - 'label' => esc_html__( 'CSS ID', 'hello-plus' ), - 'type' => Controls_Manager::TEXT, - 'default' => '', - 'ai' => [ - 'active' => false, - ], - 'dynamic' => [ - 'active' => true, - ], - 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'hello-plus' ), - 'style_transfer' => false, - ] - ); - - $this->add_control( - 'advanced_custom_css_classes', - [ - 'label' => esc_html__( 'CSS Classes', 'hello-plus' ), - 'type' => Controls_Manager::TEXT, - 'default' => '', - 'ai' => [ - 'active' => false, - ], - 'dynamic' => [ - 'active' => true, - ], - 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'hello-plus' ), - ] - ); - - $this->end_controls_section(); - - Theme_Utils::elementor()->controls_manager->add_custom_css_controls( $this, static::TAB_ADVANCED ); - - Theme_Utils::elementor()->controls_manager->add_custom_attributes_controls( $this, static::TAB_ADVANCED ); - } - - private function get_site_logo(): string { - $site_logo = Theme_Utils::elementor()->dynamic_tags->get_tag_data_content( null, 'site-logo' ); - return $site_logo['url'] ?? Utils::get_placeholder_image_src(); - } - - private function get_available_menus() { - $menus = wp_get_nav_menus(); - - $options = []; - - foreach ( $menus as $menu ) { - $options[ $menu->slug ] = $menu->name; - } - - return $options; - } } diff --git a/webpack.config.js b/webpack.config.js index fa65fe03..c47e31b6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -32,6 +32,7 @@ const entryPoints = { // Template Parts module 'css/hello-plus-header': path.resolve( modulesDir, 'template-parts/assets/scss', 'hello-plus-header.scss' ), + 'js/hello-plus-header': path.resolve( modulesDir, 'template-parts/assets/js', 'hello-plus-header.js' ), // Theme module 'css/theme': path.resolve( modulesDir, 'theme/assets/scss', 'theme.scss' ),