<?php
/**
* Menu element
*
* @package Yuki
*/
use LottaFramework\Customizer\Controls\Border;
use LottaFramework\Customizer\Controls\BoxShadow;
use LottaFramework\Customizer\Controls\CallToAction;
use LottaFramework\Customizer\Controls\ColorPicker;
use LottaFramework\Customizer\Controls\Condition;
use LottaFramework\Customizer\Controls\Icons;
use LottaFramework\Customizer\Controls\Placeholder;
use LottaFramework\Customizer\Controls\Radio;
use LottaFramework\Customizer\Controls\Section;
use LottaFramework\Customizer\Controls\Separator;
use LottaFramework\Customizer\Controls\Slider;
use LottaFramework\Customizer\Controls\Spacing;
use LottaFramework\Customizer\Controls\Tabs;
use LottaFramework\Customizer\Controls\Toggle;
use LottaFramework\Customizer\Controls\Typography;
use LottaFramework\Customizer\GenericBuilder\Element;
use LottaFramework\Facades\AsyncCss;
use LottaFramework\Facades\Css;
use LottaFramework\Facades\CZ;
use LottaFramework\Icons\IconsManager;
use LottaFramework\Utils;
if ( !defined( 'ABSPATH' ) ) {
exit;
// Exit if accessed directly.
}
if ( !class_exists( 'Yuki_Menu_Element' ) ) {
class Yuki_Menu_Element extends Element {
/**
* After element register
*/
public function after_register() {
// Register nav menu
register_nav_menu( $this->slug, $this->getLabel() );
}
/**
* @return array
*/
protected function getTopLevelGeneralControls() {
return [
( new Slider($this->getSlug( 'top_level_height' )) )->setLabel( __( 'Items Height', 'yuki' ) )->asyncCss( ".{$this->slug}", [
'--menu-items-height' => 'value',
] )->setDefaultValue( $this->getDefaultSetting( 'top-level-height', '50%' ) )->setDefaultUnit( '%' )->setMin( 5 )->setMax( 100 ),
new Separator(),
( new Spacing($this->getSlug( 'top_level_margin' )) )->setLabel( __( 'Items Margin', 'yuki' ) )->setDisabled( ['top', 'bottom'] )->asyncCss( ".{$this->slug}", AsyncCss::dimensions( '--menu-items-margin' ) )->setDefaultValue( $this->getDefaultSetting( 'top-level-margin', [
'top' => '0px',
'bottom' => '0px',
'left' => '0px',
'right' => '0px',
'linked' => true,
] ) ),
( new Spacing($this->getSlug( 'top_level_padding' )) )->setLabel( __( 'Items Padding', 'yuki' ) )->asyncCss( ".{$this->slug}", AsyncCss::dimensions( '--menu-items-padding' ) )->setDefaultValue( $this->getDefaultSetting( 'top-level-padding', [
'top' => '4px',
'bottom' => '4px',
'left' => '8px',
'right' => '8px',
'linked' => false,
] ) ),
new Separator(),
( new Spacing($this->getSlug( 'top_level_radius' )) )->setLabel( __( 'Items Border Radius', 'yuki' ) )->asyncCss( ".{$this->slug}", AsyncCss::dimensions( '--menu-items-radius' ) )->setDefaultValue( $this->getDefaultSetting( 'top-level-radius', [
'top' => '0',
'bottom' => '0',
'left' => '0',
'right' => '0',
'linked' => true,
] ) )
];
}
/**
* @return array
*/
protected function getTopLevelStyleControls() {
$controls = [( new Typography($this->getSlug( 'top_level_typography' )) )->setLabel( __( 'Typography', 'yuki' ) )->asyncCss( ".{$this->slug} > li", AsyncCss::typography() )->setDefaultValue( $this->getDefaultSetting( 'top-level-typography', [
'family' => 'inherit',
'fontSize' => '0.8rem',
'variant' => '500',
'lineHeight' => '1',
'textTransform' => 'capitalize',
] ) )];
$controls = array_merge( $controls, [( new Placeholder($this->getSlug( 'top_level_text_color' )) )->addColor( 'initial', $this->getDefaultSetting( 'top-level-text-initial', 'var(--yuki-accent-color)' ) )->addColor( 'hover', $this->getDefaultSetting( 'top-level-text-hover', 'var(--yuki-primary-color)' ) )->addColor( 'active', $this->getDefaultSetting( 'top-level-text-active', 'var(--yuki-primary-color)' ) ), ( new Placeholder($this->getSlug( 'top_level_background_color' )) )->addColor( 'initial', $this->getDefaultSetting( 'top-level-background-initial', 'var(--yuki-transparent)' ) )->addColor( 'hover', $this->getDefaultSetting( 'top-level-background-hover', 'var(--yuki-transparent)' ) )->addColor( 'active', $this->getDefaultSetting( 'top-level-background-active', 'var(--yuki-transparent)' ) ), yuki_upsell_info_control( __( 'Fully customize your top level menu items in our %sPro Version%s', 'yuki' ) )] );
return $controls;
}
/**
* @return array
*/
protected function getDropdownGeneralControls() {
return [
( new Slider($this->getSlug( 'dropdown_width' )) )->setLabel( __( 'Min Width', 'yuki' ) )->asyncCss( ".{$this->slug}", [
'--dropdown-width' => 'value',
] )->setDefaultValue( $this->getDefaultSetting( 'dropdown-width', '200px' ) )->setMin( 100 )->setMax( 300 ),
( new Radio($this->getSlug( 'dropdown_direction' )) )->setLabel( __( 'Direction', 'yuki' ) )->selectiveRefresh( ...$this->selectiveRefresh() )->buttonsGroupView()->setDefaultValue( $this->getDefaultSetting( 'dropdown-direction', 'right' ) )->setChoices( [
'left' => __( 'Left', 'yuki' ),
'right' => __( 'Right', 'yuki' ),
] ),
new Separator(),
( new Spacing($this->getSlug( 'dropdown_item_padding' )) )->setLabel( __( 'Items Padding', 'yuki' ) )->asyncCss( ".{$this->slug}", AsyncCss::dimensions( '--dropdown-item-padding' ) )->setDefaultValue( $this->getDefaultSetting( 'dropdown-item-padding', [
'top' => '12px',
'bottom' => '12px',
'left' => '12px',
'right' => '12px',
'linked' => true,
] ) ),
( new Spacing($this->getSlug( 'dropdown_radius' )) )->setLabel( __( 'Dropdown Border Radius', 'yuki' ) )->asyncCss( ".{$this->slug}", AsyncCss::dimensions( '--dropdown-radius' ) )->setDefaultValue( $this->getDefaultSetting( 'dropdown-radius', [
'top' => '3px',
'bottom' => '3px',
'left' => '3px',
'right' => '3px',
'linked' => true,
] ) )
];
}
/**
* @return array
*/
protected function getDropdownStyleControls() {
$controls = [( new Typography($this->getSlug( 'dropdown_typography' )) )->setLabel( __( 'Typography', 'yuki' ) )->asyncCss( ".{$this->slug} > li ul", AsyncCss::typography() )->setDefaultValue( $this->getDefaultSetting( 'dropdown-typography', [
'family' => 'inherit',
'fontSize' => '0.75rem',
'variant' => '500',
'lineHeight' => '1',
] ) )];
$controls = array_merge( $controls, [
( new Placeholder($this->getSlug( 'dropdown_text_color' )) )->addColor( 'initial', $this->getDefaultSetting( 'dropdown-text-initial', 'var(--yuki-accent-color)' ) )->addColor( 'hover', $this->getDefaultSetting( 'dropdown-text-hover', 'var(--yuki-primary-color)' ) )->addColor( 'active', $this->getDefaultSetting( 'dropdown-text-active', 'var(--yuki-primary-color)' ) ),
( new Placeholder($this->getSlug( 'dropdown_background_color' )) )->addColor( 'initial', $this->getDefaultSetting( 'dropdown-background-initial', 'var(--yuki-base-color)' ) )->addColor( 'active', $this->getDefaultSetting( 'dropdown-background-active', 'var(--yuki-base-color)' ) ),
( new Placeholder($this->getSlug( 'dropdown_divider' )) )->setDefaultBorder( ...$this->getDefaultSetting( 'dropdown-divider', [1, 'none', 'var(--yuki-base-200)'] ) ),
( new Placeholder($this->getSlug( 'dropdown_shadow' )) )->setDefaultShadow( ...$this->getDefaultSetting( 'dropdown-shadow', [
'rgba(44, 62, 80, 0.2)',
'0px',
'0px',
'15px',
'0px',
true
] ) ),
yuki_upsell_info_control( __( 'Fully customize your dropdown style in our %sPro Version%s', 'yuki' ) )
] );
return $controls;
}
/**
* Get all controls
*
* @return array
*/
public function getControls() : array {
$controls = [( new CallToAction($this->getSlug( 'edit_locations' )) )->setLabel( __( 'Edit Menu Locations', 'yuki' ) )->expandCustomize( 'menu_locations' ), new Separator(), ( new Slider($this->getSlug( 'depth' )) )->setLabel( __( 'Menu Depth', 'yuki' ) )->setDescription( __( '"0" meas no limit.', 'yuki' ) )->selectiveRefresh( ...$this->selectiveRefresh() )->displayInline()->setMin( 0 )->setMax( 10 )->setDefaultUnit( false )->setDefaultValue( $this->getDefaultSetting( 'depth', 0 ) )];
$controls = array_merge( $controls, [( new Condition() )->setCondition( [
$this->getSlug( 'depth' ) => '!1',
] )->setControls( [new Separator(), ( new Toggle($this->getSlug( 'arrow' )) )->setLabel( __( 'Sub Menu Toggle Icon', 'yuki' ) )->selectiveRefresh( ...$this->selectiveRefresh() )->setDefaultValue( $this->getDefaultSetting( 'arrow', 'yes' ) ), ( new Condition() )->setCondition( [
$this->getSlug( 'arrow' ) => 'yes',
] )->setControls( [( new Icons($this->getSlug( 'arrow-icon' )) )->setLabel( __( 'Toggle Icon', 'yuki' ) )->selectiveRefresh( ...$this->selectiveRefresh() )->setDefaultValue( [
'value' => 'fas fa-angle-down',
'library' => 'fa-solid',
] )] )] )] );
$controls = array_merge( $controls, [( new Section() )->setLabel( __( 'Top Level Options', 'yuki' ) )->keepMarginBelow()->setControls( [( new Tabs() )->setActiveTab( 'general' )->addTab( 'general', __( 'General', 'yuki' ), $this->getTopLevelGeneralControls() )->addTab( 'style', __( 'Style', 'yuki' ), $this->getTopLevelStyleControls() )] ), ( new Condition() )->setCondition( [
$this->getSlug( 'depth' ) => '!1',
] )->setControls( [( new Section() )->keepMarginBelow()->setLabel( __( 'Dropdown Options', 'yuki' ) )->setControls( [( new Tabs() )->setActiveTab( 'general' )->addTab( 'general', __( 'General', 'yuki' ), $this->getDropdownGeneralControls() )->addTab( 'style', __( 'Style', 'yuki' ), $this->getDropdownStyleControls() )] )] )] );
return $controls;
}
/**
* {@inheritDoc}
*/
public function enqueue_frontend_scripts() {
add_filter( 'yuki_filter_dynamic_css', function ( $css ) {
// top level typography
$css[".{$this->slug} > li"] = Css::typography( CZ::get( $this->getSlug( 'top_level_typography' ) ) );
// dropdown typography
$css[".{$this->slug} > li ul"] = Css::typography( CZ::get( $this->getSlug( 'dropdown_typography' ) ) );
$css[".{$this->slug}"] = array_merge(
[
'--menu-items-height' => CZ::get( $this->getSlug( 'top_level_height' ) ),
'--dropdown-width' => CZ::get( $this->getSlug( 'dropdown_width' ) ),
],
Css::colors( CZ::get( $this->getSlug( 'top_level_text_color' ) ), [
'initial' => '--menu-text-initial-color',
'hover' => '--menu-text-hover-color',
'active' => '--menu-text-active-color',
] ),
Css::colors( CZ::get( $this->getSlug( 'top_level_background_color' ) ), [
'initial' => '--menu-background-initial-color',
'hover' => '--menu-background-hover-color',
'active' => '--menu-background-active-color',
] ),
Css::dimensions( CZ::get( $this->getSlug( 'top_level_margin' ) ), '--menu-items-margin' ),
Css::dimensions( CZ::get( $this->getSlug( 'top_level_padding' ) ), '--menu-items-padding' ),
Css::dimensions( CZ::get( $this->getSlug( 'top_level_radius' ) ), '--menu-items-radius' ),
// dropdown css
Css::colors( CZ::get( $this->getSlug( 'dropdown_text_color' ) ), [
'initial' => '--dropdown-text-initial-color',
'hover' => '--dropdown-text-hover-color',
'active' => '--dropdown-text-active-color',
] ),
Css::colors( CZ::get( $this->getSlug( 'dropdown_background_color' ) ), [
'initial' => '--dropdown-background-initial-color',
'active' => '--dropdown-background-active-color',
] ),
Css::dimensions( CZ::get( $this->getSlug( 'dropdown_item_padding' ) ), '--dropdown-item-padding' ),
Css::dimensions( CZ::get( $this->getSlug( 'dropdown_radius' ) ), '--dropdown-radius' ),
Css::shadow( CZ::get( $this->getSlug( 'dropdown_shadow' ) ), '--dropdown-box-shadow' ),
Css::border( CZ::get( $this->getSlug( 'dropdown_divider' ) ), '--dropdown-divider' )
);
return $css;
} );
}
/**
* Seletive refresh args
*
* @return array
*/
protected function selectiveRefresh() {
return [".{$this->getSlug( 'wrap' )}", [$this, 'build'], [
'container_inclusive' => true,
]];
}
/**
* {@inheritDoc}
*/
public function render( $attrs = [] ) {
$attrs['class'] = Utils::clsx( 'yuki-menu-wrap h-full', $this->getSlug( 'wrap' ), $attrs['class'] ?? [] );
foreach ( $attrs as $attr => $value ) {
$this->add_render_attribute( $this->slug, $attr, $value );
}
$depth = absint( CZ::get( $this->getSlug( 'depth' ) ) );
$hasArrow = $depth !== 1 && CZ::checked( $this->getSlug( 'arrow' ) );
echo '<div ' . $this->render_attribute_string( $this->slug ) . '>';
wp_nav_menu( [
'theme_location' => $this->slug,
'container' => false,
'depth' => $depth,
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'link_after' => '<span class="yuki-menu-icon">' . wp_kses_post( IconsManager::render( CZ::get( $this->getSlug( 'arrow-icon' ) ) ) ) . '</span>',
'menu_class' => Utils::clsx(
'sf-menu clearfix yuki-menu',
$this->slug,
[
'yuki-menu-has-arrow' => $hasArrow,
'sf-dropdown-left' => CZ::get( $this->getSlug( 'dropdown_direction' ) ) === 'left',
],
$menu_attrs['class'] ?? []
),
'fallback_cb' => function ( $args ) {
// for customize menu style, the default one not work.
wp_page_menu( array_merge( $args, [
'container' => 'ul',
] ) );
},
] );
echo '</div>';
}
}
} |