String_Prop_Type::make() ->enum( array( 'hover', 'click' ) ) ->default( 'click' ), 'mobile_mode' => String_Prop_Type::make() ->enum( array( 'drilldown', 'accordion' ) ) ->default( 'drilldown' ), 'mobile_toggle_text' => String_Prop_Type::make()->default( __( 'Menu', 'reactwoo-atomic' ) ), 'breakpoint' => String_Prop_Type::make() ->enum( array( 'mobile', 'tablet', 'none' ) ) ->default( 'tablet' ), 'aria_label' => String_Prop_Type::make()->default( __( 'Main menu', 'reactwoo-atomic' ) ), ); } /** * {@inheritdoc} */ protected function define_settings_controls(): array { return array( Select_Control::bind_to( 'desktop_mode' ) ->set_label( __( 'Desktop interaction', 'reactwoo-atomic' ) ) ->set_options( array( array( 'value' => 'hover', 'label' => __( 'Hover', 'reactwoo-atomic' ) ), array( 'value' => 'click', 'label' => __( 'Click', 'reactwoo-atomic' ) ), ) ), Select_Control_With_Helper::bind_to( 'mobile_mode' ) ->set_label( __( 'Mobile interaction', 'reactwoo-atomic' ) ) ->set_options( array( array( 'value' => 'drilldown', 'label' => __( 'Drilldown', 'reactwoo-atomic' ) ), array( 'value' => 'accordion', 'label' => __( 'Accordion', 'reactwoo-atomic' ) ), ) ) ->set_helper_text( __( 'Drilldown pushes into a submenu. Accordion expands the panel under the item. Nested panel content stays selectable in the editor.', 'reactwoo-atomic' ) ), Text_Control_With_Helper::bind_to( 'mobile_toggle_text' ) ->set_label( __( 'Mobile toggle label', 'reactwoo-atomic' ) ) ->set_helper_text( __( 'Visible on small breakpoints when the desktop nav collapses.', 'reactwoo-atomic' ) ), Select_Control::bind_to( 'breakpoint' ) ->set_label( __( 'Mobile breakpoint', 'reactwoo-atomic' ) ) ->set_options( array( array( 'value' => 'mobile', 'label' => __( 'Mobile (767px)', 'reactwoo-atomic' ) ), array( 'value' => 'tablet', 'label' => __( 'Tablet (1024px)', 'reactwoo-atomic' ) ), array( 'value' => 'none', 'label' => __( 'None', 'reactwoo-atomic' ) ), ) ), Text_Control_With_Helper::bind_to( 'aria_label' ) ->set_label( __( 'Accessible name', 'reactwoo-atomic' ) ) ->set_helper_text( __( 'Announced as the name of the navigation landmark. Keep it short.', 'reactwoo-atomic' ) ), ); } /** * {@inheritdoc} */ protected function define_base_styles(): array { return array( static::BASE_STYLE_KEY => Style_Definition::make() ->add_variant( Style_Variant::make() ->add_props( array( 'display' => String_Prop_Type::generate( 'block' ), ) ) ), ); } /** * {@inheritdoc} */ protected function define_default_children() { // Figma 17:185 — logo · Solutions (mega) · Elements · Resources · Pricing · Get started. $items = array( array( 'label' => 'R', 'url' => '#', 'role' => 'logo', 'panel' => false, ), array( 'label' => __( 'Solutions', 'reactwoo-atomic' ), 'url' => '#solutions', 'role' => 'link', 'panel' => true, 'cards' => array( array( 'title' => __( 'Conversion', 'reactwoo-atomic' ), 'body' => __( 'UX patterns', 'reactwoo-atomic' ), ), array( 'title' => __( 'Commerce', 'reactwoo-atomic' ), 'body' => __( 'Product tools', 'reactwoo-atomic' ), ), array( 'title' => __( 'Dynamic', 'reactwoo-atomic' ), 'body' => __( 'Content loops', 'reactwoo-atomic' ), ), ), ), array( 'label' => __( 'Elements', 'reactwoo-atomic' ), 'url' => '#elements', 'role' => 'link', 'panel' => false, ), array( 'label' => __( 'Resources', 'reactwoo-atomic' ), 'url' => '#resources', 'role' => 'link', 'panel' => false, ), array( 'label' => __( 'Pricing', 'reactwoo-atomic' ), 'url' => '#pricing', 'role' => 'link', 'panel' => false, ), array( 'label' => __( 'Get started', 'reactwoo-atomic' ), 'url' => '#get-started', 'role' => 'cta', 'panel' => false, ), ); $menu_items = array(); foreach ( $items as $i => $item ) { $label_class = 'rwa-smart-menu__link-label'; if ( 'logo' === $item['role'] ) { $label_class = 'rwa-smart-menu__logo'; } elseif ( 'cta' === $item['role'] ) { $label_class = 'rwa-smart-menu__cta'; } $link = Smart_Menu_Link::generate() ->settings( array( 'url' => String_Prop_Type::generate( $item['url'] ), ) ) ->children( self::default_label_children( $item['label'], $label_class ) ) ->build(); $children = array( $link ); if ( ! empty( $item['panel'] ) && ! empty( $item['cards'] ) ) { $children[] = Smart_Menu_Panel::generate() ->editor_settings( array( 'title' => $item['label'] . ' ' . __( 'panel', 'reactwoo-atomic' ), ) ) ->children( self::default_mega_panel_children( $item['cards'] ) ) ->build(); } $menu_items[] = Smart_Menu_Item::generate() ->editor_settings( array( 'title' => $item['label'], 'initial_position' => $i + 1, ) ) ->children( $children ) ->build(); } $desktop = Smart_Menu_Desktop::generate() ->children( $menu_items ) ->build(); $toggle = Smart_Menu_Toggle::generate()->build(); $mobile = Smart_Menu_Mobile::generate()->build(); return array( $toggle, $desktop, $mobile ); } /** * @param string $text Label text. * @param string $class Optional BEM class on the paragraph. * @return array */ private static function default_label_children( $text, $class = 'rwa-smart-menu__link-label' ) { $paragraph_class = '\Elementor\Modules\AtomicWidgets\Elements\Atomic_Paragraph\Atomic_Paragraph'; $html_v3 = '\Elementor\Modules\AtomicWidgets\PropTypes\Html_V3_Prop_Type'; if ( ! class_exists( $paragraph_class ) || ! class_exists( $html_v3 ) ) { return array(); } return array( $paragraph_class::generate() ->settings( array( 'paragraph' => \ReactWoo\Atomic\ElementorBridge\Atomic_Text::generate( $text ), 'tag' => String_Prop_Type::generate( 'span' ), 'classes' => self::css_classes( $class ), ) ) ->build(), ); } /** * Figma mega panel — three canvas cards in a row. * * @param list $cards Cards. * @return array */ private static function default_mega_panel_children( array $cards ) { $para_class = '\Elementor\Modules\AtomicWidgets\Elements\Atomic_Paragraph\Atomic_Paragraph'; $flex_class = '\Elementor\Modules\AtomicWidgets\Elements\Flexbox\Flexbox'; $html_v3 = '\Elementor\Modules\AtomicWidgets\PropTypes\Html_V3_Prop_Type'; if ( ! class_exists( $para_class ) || ! class_exists( $html_v3 ) ) { return array(); } $card_nodes = array(); foreach ( $cards as $card ) { $inner = array( $para_class::generate() ->settings( array( 'paragraph' => \ReactWoo\Atomic\ElementorBridge\Atomic_Text::generate( $card['title'] ), 'tag' => String_Prop_Type::generate( 'span' ), 'classes' => self::css_classes( 'rwa-smart-menu__card-title' ), ) ) ->build(), $para_class::generate() ->settings( array( 'paragraph' => \ReactWoo\Atomic\ElementorBridge\Atomic_Text::generate( $card['body'] ), 'tag' => String_Prop_Type::generate( 'span' ), 'classes' => self::css_classes( 'rwa-smart-menu__card-body' ), ) ) ->build(), ); if ( class_exists( $flex_class ) ) { $card_nodes[] = $flex_class::generate() ->settings( array( 'classes' => self::css_classes( 'rwa-smart-menu__card' ), ) ) ->children( $inner ) ->build(); } else { $card_nodes = array_merge( $card_nodes, $inner ); } } if ( class_exists( $flex_class ) && $card_nodes ) { return array( $flex_class::generate() ->settings( array( 'classes' => self::css_classes( 'rwa-smart-menu__panel-inner' ), ) ) ->children( $card_nodes ) ->build(), ); } return $card_nodes; } /** * Transformable settings.classes for default children. * * @param string ...$tokens CSS class tokens. * @return array{$$type: string, value: list}|list */ private static function css_classes( ...$tokens ) { $list = array(); foreach ( $tokens as $token ) { $token = is_string( $token ) ? trim( $token ) : ''; if ( '' !== $token ) { $list[] = $token; } } if ( class_exists( Classes_Prop_Type::class ) ) { return Classes_Prop_Type::generate( $list ); } return $list; } /** * {@inheritdoc} */ protected function define_allowed_child_types() { return array( self::TYPE_TOGGLE, self::TYPE_DESKTOP, self::TYPE_MOBILE, 'container' ); } /** * {@inheritdoc} */ protected function get_templates(): array { return array( 'reactwoo-atomic/smart-menu' => __DIR__ . '/templates/smart-menu.html.twig', ); } /** * {@inheritdoc} */ protected function define_render_context(): array { $settings = $this->get_atomic_settings(); return array( array( 'context' => array( 'desktop-mode' => isset( $settings['desktop_mode'] ) ? (string) $settings['desktop_mode'] : 'click', 'mobile-mode' => isset( $settings['mobile_mode'] ) ? (string) $settings['mobile_mode'] : 'drilldown', 'mobile-toggle-text' => isset( $settings['mobile_toggle_text'] ) ? (string) $settings['mobile_toggle_text'] : __( 'Menu', 'reactwoo-atomic' ), 'menu-id' => $this->get_id(), ), ), ); } }