| 1 |
<?php |
| 2 |
namespace Elementor\Modules\NestedAccordion\Widgets; |
| 3 |
|
| 4 |
use Elementor\Controls_Manager; |
| 5 |
use Elementor\Modules\NestedElements\Base\Widget_Nested_Base; |
| 6 |
use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater; |
| 7 |
use Elementor\Plugin; |
| 8 |
use Elementor\Repeater; |
| 9 |
|
| 10 |
if ( ! defined( 'ABSPATH' ) ) { |
| 11 |
exit; // Exit if accessed directly |
| 12 |
} |
| 13 |
|
| 14 |
/** |
| 15 |
* Elementor Nested Accordion widget. |
| 16 |
* |
| 17 |
* Elementor widget that displays a collapsible display of content in an |
| 18 |
* accordion style. |
| 19 |
* |
| 20 |
* @since 3.15.0 |
| 21 |
*/ |
| 22 |
class Nested_Accordion extends Widget_Nested_Base { |
| 23 |
|
| 24 |
const NESTED_ACCORDION = 'nested-accordion'; |
| 25 |
|
| 26 |
public function get_name() { |
| 27 |
return static::NESTED_ACCORDION; |
| 28 |
} |
| 29 |
|
| 30 |
public function get_title() { |
| 31 |
return esc_html__( 'Accordion', 'elementor' ); |
| 32 |
} |
| 33 |
|
| 34 |
public function get_icon() { |
| 35 |
return 'eicon-accordion'; |
| 36 |
} |
| 37 |
|
| 38 |
public function get_keywords() { |
| 39 |
return [ 'nested', 'tabs', 'accordion', 'toggle' ]; |
| 40 |
} |
| 41 |
|
| 42 |
public function show_in_panel(): bool { |
| 43 |
return Plugin::$instance->experiments->is_feature_active( static::NESTED_ACCORDION ); |
| 44 |
} |
| 45 |
|
| 46 |
protected function item_content_container( int $index ) { |
| 47 |
return [ |
| 48 |
'elType' => 'container', |
| 49 |
'settings' => [ |
| 50 |
'_title' => sprintf( __( 'item #%s', 'elementor' ), $index ), |
| 51 |
'content_width' => 'full', |
| 52 |
], |
| 53 |
]; |
| 54 |
} |
| 55 |
|
| 56 |
protected function get_default_children_elements() { |
| 57 |
return [ |
| 58 |
$this->item_content_container( 1 ), |
| 59 |
$this->item_content_container( 2 ), |
| 60 |
$this->item_content_container( 3 ), |
| 61 |
]; |
| 62 |
} |
| 63 |
|
| 64 |
protected function get_default_repeater_title_setting_key() { |
| 65 |
return 'item_title'; |
| 66 |
} |
| 67 |
|
| 68 |
protected function get_default_children_title() { |
| 69 |
return esc_html__( 'Item #%d', 'elementor' ); |
| 70 |
} |
| 71 |
|
| 72 |
protected function get_default_children_placeholder_selector() { |
| 73 |
return '.e-n-accordion'; |
| 74 |
} |
| 75 |
|
| 76 |
protected function get_html_wrapper_class() { |
| 77 |
return 'elementor-widget-n-accordion'; |
| 78 |
} |
| 79 |
|
| 80 |
protected function register_controls() { |
| 81 |
$this->start_controls_section( 'section_items', [ |
| 82 |
'label' => esc_html__( 'Accordion', 'elementor' ), |
| 83 |
] ); |
| 84 |
|
| 85 |
$repeater = new Repeater(); |
| 86 |
|
| 87 |
$repeater->add_control( 'item_title', [ |
| 88 |
'label' => esc_html__( 'Title', 'elementor' ), |
| 89 |
'type' => Controls_Manager::TEXT, |
| 90 |
'default' => esc_html__( 'Item Title', 'elementor' ), |
| 91 |
'placeholder' => esc_html__( 'Item Title', 'elementor' ), |
| 92 |
'label_block' => true, |
| 93 |
'dynamic' => [ |
| 94 |
'active' => true, |
| 95 |
], |
| 96 |
] ); |
| 97 |
|
| 98 |
$repeater->add_control( |
| 99 |
'element_css_id', |
| 100 |
[ |
| 101 |
'label' => esc_html__( 'CSS ID', 'elementor' ), |
| 102 |
'type' => Controls_Manager::TEXT, |
| 103 |
'default' => '', |
| 104 |
'dynamic' => [ |
| 105 |
'active' => true, |
| 106 |
], |
| 107 |
'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ), |
| 108 |
'style_transfer' => false, |
| 109 |
] |
| 110 |
); |
| 111 |
|
| 112 |
$this->add_control( 'items', [ |
| 113 |
'label' => esc_html__( 'Items', 'elementor' ), |
| 114 |
'type' => Control_Nested_Repeater::CONTROL_TYPE, |
| 115 |
'fields' => $repeater->get_controls(), |
| 116 |
'default' => [ |
| 117 |
[ |
| 118 |
'item_title' => esc_html__( 'Item #1', 'elementor' ), |
| 119 |
], |
| 120 |
[ |
| 121 |
'item_title' => esc_html__( 'Item #2', 'elementor' ), |
| 122 |
], |
| 123 |
[ |
| 124 |
'item_title' => esc_html__( 'Item #3', 'elementor' ), |
| 125 |
], |
| 126 |
], |
| 127 |
'title_field' => '{{{ item_title }}}', |
| 128 |
'button_text' => 'Add Item', |
| 129 |
] ); |
| 130 |
|
| 131 |
$this->end_controls_section(); |
| 132 |
} |
| 133 |
|
| 134 |
protected function render() { |
| 135 |
$settings = $this->get_settings_for_display(); |
| 136 |
$items = $settings['items']; |
| 137 |
$id_int = substr( $this->get_id_int(), 0, 3 ); |
| 138 |
$items_title_html = ''; |
| 139 |
$this->add_render_attribute( 'elementor-accordion', 'class', 'e-n-accordion' ); |
| 140 |
|
| 141 |
foreach ( $items as $index => $item ) { |
| 142 |
$item_setting_key = $this->get_repeater_setting_key( 'item_title', 'items', $index ); |
| 143 |
$item_classes = [ 'e-n-accordion-item', 'e-normal' ]; |
| 144 |
$item_id = empty( $item['element_css_id'] ) ? 'e-n-accordion-item-' . $id_int : $item['element_css_id']; |
| 145 |
$item_title = $item['item_title']; |
| 146 |
|
| 147 |
$this->add_render_attribute( $item_setting_key, [ |
| 148 |
'id' => $item_id, |
| 149 |
'class' => $item_classes, |
| 150 |
] ); |
| 151 |
|
| 152 |
$title_render_attributes = $this->get_render_attribute_string( $item_setting_key ); |
| 153 |
|
| 154 |
// items content. |
| 155 |
ob_start(); |
| 156 |
$this->print_child( $index ); |
| 157 |
$item_content = ob_get_clean(); |
| 158 |
|
| 159 |
$items_title_html .= "\t<details {$title_render_attributes}>"; |
| 160 |
$items_title_html .= "\t\t<summary class='e-n-accordion-item-title'>{$item_title}</summary>"; |
| 161 |
$items_title_html .= "\t\t{$item_content}"; |
| 162 |
$items_title_html .= "\t</details>"; |
| 163 |
} |
| 164 |
|
| 165 |
?> |
| 166 |
<div <?php $this->print_render_attribute_string( 'elementor-accordion' ); ?>> |
| 167 |
<?php echo $items_title_html;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> |
| 168 |
</div> |
| 169 |
<?php |
| 170 |
} |
| 171 |
|
| 172 |
protected function content_template() { |
| 173 |
?> |
| 174 |
<div class="e-n-accordion" role="tablist" aria-orientation="vertical"> |
| 175 |
<# if ( settings['items'] ) { |
| 176 |
const elementUid = view.getIDInt().toString().substr( 0, 3 ); #> |
| 177 |
|
| 178 |
<# _.each( settings['items'], function( item, index ) { |
| 179 |
const itemCount = index + 1, |
| 180 |
itemUid = elementUid + itemCount, |
| 181 |
itemWrapperKey = itemUid, |
| 182 |
itemTitleKey = 'item-' + itemUid; |
| 183 |
|
| 184 |
if ( '' !== item.element_css_id ) { |
| 185 |
itemId = item.element_css_id; |
| 186 |
} else { |
| 187 |
itemId = 'e-n-accordion-item-' + itemUid; |
| 188 |
} |
| 189 |
|
| 190 |
view.addRenderAttribute( itemWrapperKey, { |
| 191 |
'id': itemId, |
| 192 |
'class': [ 'e-n-accordion-item','e-normal' ], |
| 193 |
} ); |
| 194 |
|
| 195 |
view.addRenderAttribute( itemTitleKey, { |
| 196 |
'class': [ 'e-n-accordion-item-title' ], |
| 197 |
} ); |
| 198 |
|
| 199 |
#> |
| 200 |
|
| 201 |
<details {{{ view.getRenderAttributeString( itemWrapperKey ) }}}> |
| 202 |
<summary {{{ view.getRenderAttributeString( itemTitleKey ) }}}>{{{ item.item_title }}}</summary> |
| 203 |
</details> |
| 204 |
<# } ); #> |
| 205 |
<# } #> |
| 206 |
</div> |
| 207 |
<?php |
| 208 |
} |
| 209 |
} |
| 210 |
|