PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.0
Tutor LMS – eLearning and online course solution v4.0.0
4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / components / Accordion.php
tutor / components Last commit date
Constants 17 hours ago Accordion.php 17 hours ago Alert.php 17 hours ago AttachmentCard.php 17 hours ago Avatar.php 17 hours ago Badge.php 17 hours ago BaseComponent.php 17 hours ago Button.php 17 hours ago ConfirmationModal.php 17 hours ago CourseFilter.php 17 hours ago DateFilter.php 17 hours ago DropdownFilter.php 17 hours ago EmptyState.php 17 hours ago FileUploader.php 17 hours ago InputField.php 17 hours ago Modal.php 17 hours ago Nav.php 17 hours ago Pagination.php 17 hours ago Popover.php 17 hours ago PreviewTrigger.php 17 hours ago Progress.php 17 hours ago SearchFilter.php 17 hours ago Sorting.php 17 hours ago StarRating.php 17 hours ago StarRatingInput.php 17 hours ago StatusSelect.php 17 hours ago SvgIcon.php 17 hours ago Table.php 17 hours ago Tabs.php 17 hours ago Tooltip.php 17 hours ago WPEditor.php 17 hours ago
Accordion.php
267 lines
1 <?php
2 /**
3 * Tutor Component: Accordion
4 *
5 * Provides a fluent builder for rendering accordion items with
6 * Alpine.js integration for expand/collapse functionality.
7 *
8 * @package Tutor\Components
9 * @author Themeum
10 * @link https://themeum.com
11 * @since 4.0.0
12 */
13
14 namespace Tutor\Components;
15
16 use TUTOR\Icon;
17
18 defined( 'ABSPATH' ) || exit;
19
20 /**
21 * Accordion Component Class.
22 *
23 * Example usage:
24 * ```
25 * // Single item accordion
26 * Accordion::make()
27 * ->add_item( 'About Course', '<p>Description...</p>' )
28 * ->render();
29 *
30 * // Multiple items
31 * Accordion::make()
32 * ->add_item( 'About Course', '<p>Description...</p>' )
33 * ->add_item( 'Requirements', '<p>Prerequisites...</p>' )
34 * ->add_item( 'Instructor', '<p>Meet your instructor...</p>' )
35 * ->default_open( array( 0 ) )
36 * ->render();
37 *
38 * // With custom icon and template
39 * Accordion::make()
40 * ->add_item( 'Details', '', 'path/to/template.php', 'custom-icon' )
41 * ->allow_multiple( false )
42 * ->render();
43 * ```
44 *
45 * @since 4.0.0
46 */
47 class Accordion extends BaseComponent {
48
49 /**
50 * Accordion items array.
51 *
52 * @since 4.0.0
53 *
54 * @var array
55 */
56 protected $items = array();
57
58 /**
59 * Whether multiple items can be open.
60 *
61 * @since 4.0.0
62 *
63 * @var bool
64 */
65 protected $multiple = true;
66
67 /**
68 * Default open item indices.
69 *
70 * @since 4.0.0
71 *
72 * @var array
73 */
74 protected $default_open = array();
75
76 /**
77 * Add accordion item.
78 *
79 * @since 4.0.0
80 *
81 * @param string $title Item title.
82 * @param string $content Item content HTML.
83 * @param string $template Optional. Template path instead of content.
84 * @param string $icon Optional. Custom icon name.
85 *
86 * @return $this
87 */
88 public function add_item( $title, $content = '', $template = '', $icon = '' ) {
89 $this->items[] = array(
90 'title' => $title,
91 'content' => $content,
92 'template' => $template,
93 'icon' => $icon,
94 );
95 return $this;
96 }
97
98 /**
99 * Set whether multiple items can be open.
100 *
101 * @since 4.0.0
102 *
103 * @param bool $multiple Whether to allow multiple open items.
104 *
105 * @return $this
106 */
107 public function allow_multiple( $multiple = true ) {
108 $this->multiple = (bool) $multiple;
109 return $this;
110 }
111
112 /**
113 * Set default open item indices.
114 *
115 * @since 4.0.0
116 *
117 * @param array $indices Array of item indices to open by default.
118 *
119 * @return $this
120 */
121 public function default_open( $indices ) {
122 $this->default_open = is_array( $indices ) ? $indices : array( $indices );
123 return $this;
124 }
125
126 /**
127 * Render accordion item content.
128 *
129 * @since 4.0.0
130 *
131 * @param array $item Item data.
132 *
133 * @return string Content HTML.
134 */
135 protected function render_item_content( $item ) {
136 // If template is provided, use it.
137 if ( ! empty( $item['template'] ) && file_exists( $item['template'] ) ) {
138 ob_start();
139 include $item['template'];
140 return ob_get_clean();
141 }
142
143 // Otherwise return content.
144 return ! empty( $item['content'] ) ? $item['content'] : '';
145 }
146
147 /**
148 * Render default chevron icon.
149 *
150 * @since 4.0.0
151 *
152 * @return string Icon SVG.
153 */
154 protected function render_default_icon() {
155 return SvgIcon::make()->name( Icon::CHEVRON_DOWN )->size( 24 )->get();
156 }
157
158 /**
159 * Render custom icon.
160 *
161 * @since 4.0.0
162 *
163 * @param string $icon Icon name.
164 *
165 * @return string Icon SVG.
166 */
167 protected function render_icon( $icon ) {
168 if ( empty( $icon ) ) {
169 return $this->render_default_icon();
170 }
171
172 return SvgIcon::make()->name( $icon )->size( 24 )->get();
173 }
174
175 /**
176 * Get the accordion HTML.
177 *
178 * @since 4.0.0
179 *
180 * @return string HTML output.
181 */
182 public function get(): string {
183 if ( empty( $this->items ) ) {
184 return '';
185 }
186
187 // Build Alpine.js config.
188 $alpine_config = array(
189 'multiple' => $this->multiple,
190 'defaultOpen' => $this->default_open,
191 );
192 $alpine_json = wp_json_encode( $alpine_config );
193
194 // Merge custom classes.
195 $wrapper_classes = 'tutor-accordion';
196 if ( ! empty( $this->attributes['class'] ) ) {
197 $wrapper_classes .= ' ' . $this->attributes['class'];
198 unset( $this->attributes['class'] );
199 }
200
201 $this->attributes['x-data'] = sprintf( 'tutorAccordion(%s)', $alpine_json );
202 $this->attributes['class'] = $wrapper_classes;
203
204 $wrapper_attrs = $this->get_attributes_string();
205
206 // Build items HTML.
207 $items_html = '';
208 foreach ( $this->items as $index => $item ) {
209 $title = isset( $item['title'] ) ? $item['title'] : '';
210 $icon = isset( $item['icon'] ) ? $item['icon'] : '';
211 $panel_id = 'tutor-acc-panel-' . $index;
212 $trigger_id = 'tutor-acc-trigger-' . $index;
213
214 $icon_html = $this->render_icon( $icon );
215 $content = $this->render_item_content( $item );
216
217 $items_html .= sprintf(
218 '<div class="tutor-accordion-item">
219 <button
220 @click="toggle(%d)"
221 @keydown="handleKeydown($event, %d)"
222 :aria-expanded="isOpen(%d)"
223 class="tutor-accordion-header tutor-accordion-trigger"
224 aria-controls="%s"
225 id="%s"
226 >
227 <span class="tutor-accordion-title">%s</span>
228 <span class="tutor-accordion-icon" aria-hidden="true">
229 %s
230 </span>
231 </button>
232 <div
233 id="%s"
234 role="region"
235 aria-labelledby="%s"
236 class="tutor-accordion-content"
237 x-show="isOpen(%d)"
238 x-collapse.duration.350ms
239 >
240 <div class="tutor-accordion-body">
241 %s
242 </div>
243 </div>
244 </div>',
245 $index,
246 $index,
247 $index,
248 esc_attr( $panel_id ),
249 esc_attr( $trigger_id ),
250 esc_html( $title ),
251 $icon_html,
252 esc_attr( $panel_id ),
253 esc_attr( $trigger_id ),
254 $index,
255 wp_kses_post( $content )
256 );
257 }
258
259 return sprintf(
260 '<div %s>%s</div>',
261 $wrapper_attrs,
262 $items_html
263 );
264 }
265
266 }
267