PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.3
Tutor LMS – eLearning and online course solution v4.0.3
4.0.3 4.0.2 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 / Button.php
tutor / components Last commit date
Constants 3 weeks ago Accordion.php 1 week ago Alert.php 1 week ago AttachmentCard.php 1 week ago Avatar.php 1 week ago Badge.php 1 week ago BaseComponent.php 3 weeks ago Button.php 1 week ago ConfirmationModal.php 1 week ago CourseFilter.php 1 week ago DateFilter.php 1 week ago DropdownFilter.php 1 week ago EmptyState.php 1 week ago FileUploader.php 1 week ago InputField.php 1 week ago Modal.php 1 week ago Nav.php 1 week ago Pagination.php 1 week ago Popover.php 1 week ago PreviewTrigger.php 1 week ago Progress.php 1 week ago SearchFilter.php 1 week ago Sorting.php 1 week ago StarRating.php 1 week ago StarRatingInput.php 1 week ago StatusSelect.php 1 week ago SvgIcon.php 1 week ago Table.php 1 week ago Tabs.php 1 week ago Tooltip.php 1 week ago WPEditor.php 1 week ago
Button.php
480 lines
1 <?php
2 /**
3 * Tutor Component: Button
4 *
5 * Provides a fluent builder for rendering buttons with
6 * different sizes, variants, and styles.
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\Components\Constants\Size;
17 use Tutor\Components\Constants\Variant;
18
19 defined( 'ABSPATH' ) || exit;
20
21 /**
22 * Button Component Class.
23 *
24 * Example usage:
25 * ```
26 * // Primary button (default)
27 * Button::make()
28 * ->label( 'Enroll Now' )
29 * ->render();
30 *
31 * // Button with size and variant
32 * Button::make()
33 * ->label( 'Save Changes' )
34 * ->size( Size::LARGE )
35 * ->variant( Variant::PRIMARY )
36 * ->render();
37 *
38 * // Button with left icon
39 * Button::make()
40 * ->label( 'Add Course' )
41 * ->icon( Icon::PLUS )
42 * ->size( Size::MEDIUM )
43 * ->variant( Variant::PRIMARY )
44 * ->render();
45 *
46 * // Button with right icon and custom icon size/color
47 * Button::make()
48 * ->label( 'Download' )
49 * ->icon( Icon::DOWNLOAD_2, 'right', 18, Color::BRAND )
50 * ->variant( Variant::OUTLINE )
51 * ->render();
52 *
53 * // Icon-only button (no visible label, uses aria-label)
54 * Button::make()
55 * ->label( 'Delete' )
56 * ->icon( Icon::DELETE_2 )
57 * ->icon_only()
58 * ->variant( Variant::GHOST )
59 * ->size( Size::SMALL )
60 * ->render();
61 *
62 * // Disabled button
63 * Button::make()
64 * ->label( 'Submit' )
65 * ->variant( Variant::PRIMARY )
66 * ->disabled()
67 * ->render();
68 *
69 * // Block (full-width) button
70 * Button::make()
71 * ->label( 'Continue' )
72 * ->variant( Variant::PRIMARY )
73 * ->block()
74 * ->render();
75 *
76 * // Link-styled button rendered as <a> tag
77 * Button::make()
78 * ->label( 'View Course' )
79 * ->variant( Variant::LINK )
80 * ->tag( 'a' )
81 * ->attr( 'href', get_permalink( $course_id ) )
82 * ->render();
83 *
84 * // Destructive button
85 * Button::make()
86 * ->label( 'Delete Course' )
87 * ->variant( Variant::DESTRUCTIVE )
88 * ->size( Size::SMALL )
89 * ->render();
90 *
91 * // Secondary/outline button with data attribute
92 * Button::make()
93 * ->label( 'Cancel' )
94 * ->variant( Variant::SECONDARY )
95 * ->attr( 'data-id', $course_id )
96 * ->render();
97 *
98 * // Button with RTL-flippable directional icon
99 * Button::make()
100 * ->label( 'Next' )
101 * ->icon( Icon::CHEVRON_RIGHT, 'right' )
102 * ->flip_rtl()
103 * ->render();
104 *
105 * // Retrieve HTML string without echoing
106 * $html = Button::make()->label( 'Get Started' )->variant( Variant::PRIMARY )->get();
107 * ```
108 *
109 * @since 4.0.0
110 */
111 class Button extends BaseComponent {
112
113 /**
114 * Button label text.
115 *
116 * @since 4.0.0
117 *
118 * @var string
119 */
120 protected $label = '';
121
122 /**
123 * Button size (small|medium|large).
124 *
125 * @since 4.0.0
126 *
127 * @see Size constants
128 *
129 * @var string
130 */
131 protected $size = Size::MEDIUM;
132
133 /**
134 * Button variant style (primary|secondary, etc).
135 *
136 * @since 4.0.0
137 *
138 * @see Size constants
139 *
140 * @var string
141 */
142 protected $variant = Variant::PRIMARY;
143
144 /**
145 * Button HTML tag (button|a).
146 *
147 * @since 4.0.0
148 *
149 * @var string
150 */
151 protected $tag = 'button';
152
153 /**
154 * Button attributes.
155 *
156 * @since 4.0.0
157 *
158 * @var array
159 */
160 protected $attributes = array();
161
162 /**
163 * The SVG icon name or markup.
164 *
165 * @since 4.0.0
166 *
167 * @var string
168 */
169 protected $icon = '';
170
171 /**
172 * Icon width.
173 *
174 * @var int
175 */
176 protected $icon_size = 16;
177
178 /**
179 * Icon color.
180 *
181 * @var string
182 */
183 protected $icon_color = '';
184
185 /**
186 * Button icon position
187 *
188 * @since 4.0.0
189 *
190 * @var string
191 */
192 private const POSITION_LEFT = 'left';
193 private const POSITION_RIGHT = 'right';
194
195 /**
196 * The icon position relative to label. Accepts 'left' or 'right'.
197 *
198 * @since 4.0.0
199 *
200 * @var string
201 */
202 protected $icon_position = 'left';
203
204 /**
205 * Icon attributes.
206 *
207 * @var array
208 */
209 protected $icon_attributes = array();
210
211 /**
212 * Whether to flip the button icon in RTL.
213 *
214 * @since 4.0.0
215 *
216 * @var bool
217 */
218 protected $flip_rtl = false;
219
220 /**
221 * Whether button is disabled.
222 *
223 * @since 4.0.0
224 *
225 * @var bool
226 */
227 protected $disabled = false;
228
229 /**
230 * Whether button is an icon-only button.
231 *
232 * @since 4.0.0
233 *
234 * @var bool
235 */
236 protected $icon_only = false;
237
238 /**
239 * Whether button is a block button.
240 *
241 * @since 4.0.0
242 *
243 * @var bool
244 */
245 protected $block = false;
246
247 /**
248 * Set button label text.
249 *
250 * @since 4.0.0
251 *
252 * @param string $label Button label text.
253 *
254 * @return $this
255 */
256 public function label( $label ) {
257 $this->label = esc_html( $label );
258 return $this;
259 }
260
261 /**
262 * Set button size.
263 *
264 * @since 4.0.0
265 *
266 * @param string $size Button size (small|medium|large).
267 *
268 * @return $this
269 */
270 public function size( $size ) {
271 $allowed = $this->get_allowed_sizes();
272 if ( in_array( $size, $allowed, true ) ) {
273 $this->size = $size;
274 }
275 return $this;
276 }
277
278 /**
279 * Set button block state.
280 *
281 * @since 4.0.0
282 *
283 * @param bool $block Whether the button is a block button.
284 *
285 * @return $this
286 */
287 public function block( bool $block = true ): self {
288 $this->block = $block;
289 return $this;
290 }
291
292 /**
293 * Set button variant style.
294 *
295 * @since 4.0.0
296 *
297 * @param string $variant Button variant (primary|secondary|success|danger|link).
298 *
299 * @return $this
300 */
301 public function variant( $variant ) {
302 $this->variant = sanitize_html_class( $variant );
303 return $this;
304 }
305
306 /**
307 * Set the SVG icon for the button.
308 *
309 * @since 4.0.0
310 *
311 * @param string $icon SVG icon name or markup.
312 * @param string $position Optional. Icon position: 'left' or 'right'.
313 * @param int $size Optional. Icon size (width and height).
314 * @param string $color Optional. Icon color (use \Tutor\Components\Constants\Color).
315 * @param array $attributes Optional. Icon attributes.
316 *
317 * @return $this
318 */
319 public function icon( string $icon, string $position = 'left', int $size = 16, string $color = '', array $attributes = array() ): self {
320 $this->icon = $icon;
321 $this->icon_position = in_array( $position, array( self::POSITION_LEFT, self::POSITION_RIGHT ), true ) ? $position : 'left';
322 $this->icon_size = $size;
323 $this->icon_color = $color;
324 $this->icon_attributes = $attributes;
325 return $this;
326 }
327
328 /**
329 * Set the HTML tag for rendering.
330 *
331 * @since 4.0.0
332 *
333 * @param bool $icon_only Whether the button is icon-only.
334 *
335 * @return $this
336 */
337 public function icon_only( bool $icon_only = true ): self {
338 $this->icon_only = $icon_only;
339 return $this;
340 }
341
342 /**
343 * Flip the button icon in RTL.
344 *
345 * Use this only for directional icons such as arrows,
346 * chevrons and pagination controls.
347 *
348 * @since 4.0.0
349 *
350 * @return $this
351 */
352 public function flip_rtl(): self {
353 $this->flip_rtl = true;
354 return $this;
355 }
356
357 /**
358 * Set the HTML tag for rendering.
359 *
360 * @since 4.0.0
361 *
362 * @param string $tag HTML tag (button|a).
363 *
364 * @return $this
365 */
366 public function tag( $tag ) {
367 if ( in_array( $tag, array( 'a', 'button' ), true ) ) {
368 $this->tag = $tag;
369 }
370 return $this;
371 }
372
373 /**
374 * Set button disabled state.
375 *
376 * @since 4.0.0
377 *
378 * @param bool $disabled Whether the button is disabled.
379 *
380 * @return $this
381 */
382 public function disabled( $disabled = true ) {
383 $this->disabled = (bool) $disabled;
384 return $this;
385 }
386
387 /**
388 * Allowed sizes
389 *
390 * @since 4.0.0
391 *
392 * @return array
393 */
394 public function get_allowed_sizes() {
395 return array(
396 Size::SMALL,
397 Size::MEDIUM,
398 Size::LARGE,
399 Size::X_SMALL,
400 );
401 }
402
403 /**
404 * Get the final button HTML.
405 *
406 * @since 4.0.0
407 *
408 * @return string HTML output.
409 */
410 public function get(): string {
411 $classes = sprintf(
412 'tutor-btn tutor-btn-%1$s tutor-btn-%2$s',
413 esc_attr( $this->variant ),
414 esc_attr( $this->size )
415 );
416
417 if ( $this->disabled ) {
418 $this->attributes['disabled'] = 'disabled';
419 $classes .= ' disabled';
420 }
421
422 if ( $this->block ) {
423 $classes .= ' tutor-btn-block';
424 }
425
426 if ( $this->icon_only ) {
427 $classes .= ' tutor-btn-icon';
428 if ( ! empty( $this->label ) && empty( $this->attributes['aria-label'] ) ) {
429 $this->attributes['aria-label'] = $this->label;
430 }
431 }
432
433 $this->attributes['class'] = trim( "{$classes} " . ( $this->attributes['class'] ?? '' ) );
434
435 $attributes = $this->get_attributes_string();
436
437 // Prepare icon HTML if exists.
438 $icon_html = '';
439 if ( ! empty( $this->icon ) ) {
440 if ( false !== strpos( $this->icon, '<svg' ) ) {
441 $icon_html = $this->icon;
442 } else {
443 ob_start();
444 SvgIcon::make()
445 ->name( $this->icon )
446 ->size( $this->icon_size )
447 ->color( $this->icon_color )
448 ->flip_rtl( $this->flip_rtl )
449 ->attrs( $this->icon_attributes )
450 ->render();
451 $icon_html = ob_get_clean();
452 }
453 }
454
455 if ( ! empty( $icon_html ) && empty( $this->label ) ) {
456 $this->attributes['class'] .= ' tutor-btn-icon';
457 // Re-render attributes to include updated class.
458 $attributes = $this->get_attributes_string();
459 }
460
461 // Build button inner HTML depending on icon position.
462 if ( $this->icon_only ) {
463 $content = $icon_html;
464 } else {
465 $content = self::POSITION_RIGHT === ( $this->icon_position ? $this->icon_position : self::POSITION_LEFT )
466 ? sprintf( '%1$s%2$s', esc_html( $this->label ), $icon_html )
467 : sprintf( '%1$s%2$s', $icon_html, esc_html( $this->label ) );
468 }
469
470 $this->component_string = sprintf(
471 '<%1$s %2$s>%3$s</%1$s>',
472 esc_attr( $this->tag ),
473 $attributes,
474 $content
475 );
476
477 return $this->component_string;
478 }
479 }
480