Constants
20 hours ago
Accordion.php
20 hours ago
Alert.php
20 hours ago
AttachmentCard.php
20 hours ago
Avatar.php
20 hours ago
Badge.php
20 hours ago
BaseComponent.php
20 hours ago
Button.php
20 hours ago
ConfirmationModal.php
20 hours ago
CourseFilter.php
20 hours ago
DateFilter.php
20 hours ago
DropdownFilter.php
20 hours ago
EmptyState.php
20 hours ago
FileUploader.php
20 hours ago
InputField.php
20 hours ago
Modal.php
20 hours ago
Nav.php
20 hours ago
Pagination.php
20 hours ago
Popover.php
20 hours ago
PreviewTrigger.php
20 hours ago
Progress.php
20 hours ago
SearchFilter.php
20 hours ago
Sorting.php
20 hours ago
StarRating.php
20 hours ago
StarRatingInput.php
20 hours ago
StatusSelect.php
20 hours ago
SvgIcon.php
20 hours ago
Table.php
20 hours ago
Tabs.php
20 hours ago
Tooltip.php
20 hours ago
WPEditor.php
20 hours ago
Tabs.php
234 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Tutor Component: Tabs |
| 4 | * |
| 5 | * Provides a fluent builder for rendering tabs |
| 6 | * with different orientation. |
| 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\Input; |
| 17 | |
| 18 | defined( 'ABSPATH' ) || exit; |
| 19 | |
| 20 | /** |
| 21 | * Class Tabs |
| 22 | * |
| 23 | * Responsible for rendering the tab navigation and tab content using Alpine.js (`tutorTabs`). |
| 24 | * Supports both horizontal and vertical orientations. |
| 25 | * |
| 26 | * Example usage: |
| 27 | * |
| 28 | * ```php |
| 29 | * $tabs_data = [ |
| 30 | * [ |
| 31 | * 'id' => 'lesson', |
| 32 | * 'label' => 'Lessons', |
| 33 | * 'icon' => 'book', |
| 34 | * 'content' => '<p>Lesson content goes here.</p>', |
| 35 | * ], |
| 36 | * [ |
| 37 | * 'id' => 'assignments', |
| 38 | * 'label' => 'Assignments', |
| 39 | * 'icon' => 'file', |
| 40 | * 'content' => '<p>Assignment content goes here.</p>', |
| 41 | * ], |
| 42 | * [ |
| 43 | * 'id' => 'quizzes', |
| 44 | * 'label' => 'Quizzes', |
| 45 | * 'icon' => 'check', |
| 46 | * 'content' => '<p>Quiz content goes here.</p>', |
| 47 | * ], |
| 48 | * ]; |
| 49 | * |
| 50 | * Tabs::make() |
| 51 | * ->tabs( $tabs_data ) |
| 52 | * ->default_tab( 'lesson' ) |
| 53 | * ->orientation( 'horizontal' ) |
| 54 | * ->url_params( [ 'enabled' => true ] ) |
| 55 | * ->render(); |
| 56 | * ``` |
| 57 | * |
| 58 | * @since 4.0.0 |
| 59 | */ |
| 60 | class Tabs extends BaseComponent { |
| 61 | |
| 62 | /** |
| 63 | * Tab data array. |
| 64 | * |
| 65 | * @since 4.0.0 |
| 66 | * |
| 67 | * @var array |
| 68 | */ |
| 69 | protected array $tabs = array(); |
| 70 | |
| 71 | /** |
| 72 | * Default active tab ID. |
| 73 | * |
| 74 | * @since 4.0.0 |
| 75 | * |
| 76 | * @var string |
| 77 | */ |
| 78 | protected string $default_tab = ''; |
| 79 | |
| 80 | |
| 81 | /** |
| 82 | * Tab orientation type (horizontal|vertical). |
| 83 | * |
| 84 | * @since 4.0.0 |
| 85 | * |
| 86 | * @var string |
| 87 | */ |
| 88 | public const TYPE_HORIZONTAL = 'horizontal'; |
| 89 | public const TYPE_VERTICAL = 'vertical'; |
| 90 | |
| 91 | /** |
| 92 | * Tab orientation (horizontal|vertical). |
| 93 | * |
| 94 | * @since 4.0.0 |
| 95 | * |
| 96 | * @var string |
| 97 | */ |
| 98 | protected string $orientation = 'horizontal'; |
| 99 | |
| 100 | /** |
| 101 | * URL parameters for syncing tab state. |
| 102 | * |
| 103 | * @since 4.0.0 |
| 104 | * @var array |
| 105 | */ |
| 106 | protected array $url_params = array( |
| 107 | 'enabled' => true, |
| 108 | 'paramName' => 'tab', |
| 109 | ); |
| 110 | |
| 111 | /** |
| 112 | * Set the tab data. |
| 113 | * |
| 114 | * @since 4.0.0 |
| 115 | * |
| 116 | * @param array $tabs Tabs configuration data. |
| 117 | * |
| 118 | * @return $this |
| 119 | */ |
| 120 | public function tabs( array $tabs ) { |
| 121 | $this->tabs = $tabs; |
| 122 | return $this; |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Set the default active tab. |
| 127 | * |
| 128 | * @since 4.0.0 |
| 129 | * |
| 130 | * @param string $tab_id Tab ID to activate by default. |
| 131 | * |
| 132 | * @return $this |
| 133 | */ |
| 134 | public function default_tab( string $tab_id ) { |
| 135 | $this->default_tab = Input::get( 'tab', $tab_id ); |
| 136 | return $this; |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Set the tab orientation. |
| 141 | * |
| 142 | * @since 4.0.0 |
| 143 | * |
| 144 | * @param string $orientation Either 'horizontal' or 'vertical'. |
| 145 | * |
| 146 | * @return $this |
| 147 | */ |
| 148 | public function orientation( string $orientation ) { |
| 149 | $this->orientation = in_array( $orientation, array( self::TYPE_HORIZONTAL, self::TYPE_VERTICAL ), true ) |
| 150 | ? $orientation |
| 151 | : self::TYPE_HORIZONTAL; |
| 152 | return $this; |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * Set the URL parameter configuration for tab state. |
| 157 | * |
| 158 | * @since 4.0.0 |
| 159 | * |
| 160 | * @param array $params URL parameter settings. |
| 161 | * |
| 162 | * @return $this |
| 163 | */ |
| 164 | public function url_params( array $params ) { |
| 165 | $this->url_params = wp_parse_args( |
| 166 | $params, |
| 167 | array( |
| 168 | 'enabled' => true, |
| 169 | 'paramName' => 'tab', |
| 170 | ) |
| 171 | ); |
| 172 | return $this; |
| 173 | } |
| 174 | |
| 175 | /** |
| 176 | * Get the tabs component. |
| 177 | * |
| 178 | * @since 4.0.0 |
| 179 | * |
| 180 | * @return string HTML markup for the tabs component. |
| 181 | */ |
| 182 | public function get(): string { |
| 183 | $tabs_json = wp_json_encode( $this->tabs ); |
| 184 | $default = esc_js( $this->default_tab ); |
| 185 | $orientation = esc_attr( $this->orientation ); |
| 186 | $url_params = wp_json_encode( $this->url_params ); |
| 187 | |
| 188 | ob_start(); |
| 189 | ?> |
| 190 | <div |
| 191 | x-data='tutorTabs({ |
| 192 | tabs: <?php echo $tabs_json; // phpcs:ignore ?>, |
| 193 | orientation: "<?php echo $orientation; // phpcs:ignore ?>", |
| 194 | defaultTab: "<?php echo $default; // phpcs:ignore ?>", |
| 195 | urlParams: <?php echo $url_params; // phpcs:ignore ?> |
| 196 | })' |
| 197 | > |
| 198 | <div x-ref="tablist" class="tutor-tabs-nav" role="tablist" aria-orientation="<?php echo $orientation; // phpcs:ignore ?>"> |
| 199 | <template x-for="tab in tabs" :key="tab.id"> |
| 200 | <button |
| 201 | type="button" |
| 202 | role="tab" |
| 203 | :class='getTabClass(tab)' |
| 204 | x-bind:aria-selected="isActive(tab.id)" |
| 205 | :disabled="tab.disabled ? true : false" |
| 206 | @click="selectTab(tab.id)" |
| 207 | > |
| 208 | <template x-if="tab.icon"> |
| 209 | <span x-data="tutorIcon({ name: tab.icon, width: 24, height: 24 })"></span> |
| 210 | </template> |
| 211 | <span x-text="tab.label"></span> |
| 212 | </button> |
| 213 | </template> |
| 214 | </div> |
| 215 | |
| 216 | <div class="tutor-tabs-content"> |
| 217 | <template x-for="tab in tabs" :key="tab.id"> |
| 218 | <div |
| 219 | class="tutor-tab-panel" |
| 220 | role="tabpanel" |
| 221 | x-show="activeTab === tab.id" |
| 222 | x-cloak |
| 223 | x-html="tab.content" |
| 224 | ></div> |
| 225 | </template> |
| 226 | </div> |
| 227 | </div> |
| 228 | <?php |
| 229 | $this->component_string = ob_get_clean(); |
| 230 | |
| 231 | return $this->component_string; |
| 232 | } |
| 233 | } |
| 234 |