PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.1
Tutor LMS – eLearning and online course solution v4.0.1
4.0.1 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 4 days ago Accordion.php 4 days ago Alert.php 4 days ago AttachmentCard.php 4 days ago Avatar.php 4 days ago Badge.php 4 days ago BaseComponent.php 4 days ago Button.php 4 days ago ConfirmationModal.php 4 days ago CourseFilter.php 4 days ago DateFilter.php 4 days ago DropdownFilter.php 4 days ago EmptyState.php 4 days ago FileUploader.php 4 days ago InputField.php 4 days ago Modal.php 4 days ago Nav.php 4 days ago Pagination.php 4 days ago Popover.php 4 days ago PreviewTrigger.php 4 days ago Progress.php 4 days ago SearchFilter.php 4 days ago Sorting.php 4 days ago StarRating.php 4 days ago StarRatingInput.php 4 days ago StatusSelect.php 4 days ago SvgIcon.php 4 days ago Table.php 4 days ago Tabs.php 4 days ago Tooltip.php 4 days ago WPEditor.php 4 days 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