Constants
23 hours ago
Accordion.php
23 hours ago
Alert.php
23 hours ago
AttachmentCard.php
23 hours ago
Avatar.php
23 hours ago
Badge.php
23 hours ago
BaseComponent.php
23 hours ago
Button.php
23 hours ago
ConfirmationModal.php
23 hours ago
CourseFilter.php
23 hours ago
DateFilter.php
23 hours ago
DropdownFilter.php
23 hours ago
EmptyState.php
23 hours ago
FileUploader.php
23 hours ago
InputField.php
23 hours ago
Modal.php
23 hours ago
Nav.php
23 hours ago
Pagination.php
23 hours ago
Popover.php
23 hours ago
PreviewTrigger.php
23 hours ago
Progress.php
23 hours ago
SearchFilter.php
23 hours ago
Sorting.php
23 hours ago
StarRating.php
23 hours ago
StarRatingInput.php
23 hours ago
StatusSelect.php
23 hours ago
SvgIcon.php
23 hours ago
Table.php
23 hours ago
Tabs.php
23 hours ago
Tooltip.php
23 hours ago
WPEditor.php
23 hours ago
Tooltip.php
285 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Tutor Component: Tooltip |
| 4 | * |
| 5 | * Provides a fluent builder for rendering tooltips with |
| 6 | * different placements, sizes, and triggers. |
| 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 | defined( 'ABSPATH' ) || exit; |
| 17 | |
| 18 | use Tutor\Components\Constants\Size; |
| 19 | |
| 20 | /** |
| 21 | * Tooltip Component Class. |
| 22 | * |
| 23 | * Example usage: |
| 24 | * ``` |
| 25 | * Tooltip::make() |
| 26 | * ->content( 'Helpful information' ) |
| 27 | * ->placement( 'top' ) |
| 28 | * ->size( Size::SMALL ) |
| 29 | * ->trigger_element( '<button class="tutor-btn">Hover me</button>' ) |
| 30 | * ->render(); |
| 31 | * ``` |
| 32 | * |
| 33 | * @since 4.0.0 |
| 34 | */ |
| 35 | class Tooltip extends BaseComponent { |
| 36 | |
| 37 | /** |
| 38 | * Placement constants. |
| 39 | */ |
| 40 | public const PLACEMENT_TOP = 'top'; |
| 41 | public const PLACEMENT_BOTTOM = 'bottom'; |
| 42 | public const PLACEMENT_START = 'start'; |
| 43 | public const PLACEMENT_END = 'end'; |
| 44 | |
| 45 | /** |
| 46 | * Arrow alignment constants. |
| 47 | */ |
| 48 | public const ARROW_START = 'start'; |
| 49 | public const ARROW_CENTER = 'center'; |
| 50 | public const ARROW_END = 'end'; |
| 51 | |
| 52 | /** |
| 53 | * Trigger constants. |
| 54 | */ |
| 55 | public const HOVER = 'hover'; |
| 56 | public const CLICK = 'click'; |
| 57 | public const FOCUS = 'focus'; |
| 58 | |
| 59 | /** |
| 60 | * Tooltip content (HTML or text). |
| 61 | * |
| 62 | * @var string |
| 63 | */ |
| 64 | protected $content = ''; |
| 65 | |
| 66 | /** |
| 67 | * Tooltip placement (top|bottom|start|end). |
| 68 | * |
| 69 | * @var string |
| 70 | */ |
| 71 | protected $placement = self::PLACEMENT_TOP; |
| 72 | |
| 73 | /** |
| 74 | * Tooltip size (small|medium|large). |
| 75 | * |
| 76 | * @var string |
| 77 | */ |
| 78 | protected $size = Size::SMALL; |
| 79 | |
| 80 | /** |
| 81 | * Arrow alignment (start|center|end). |
| 82 | * |
| 83 | * @var string |
| 84 | */ |
| 85 | protected $arrow = self::ARROW_START; |
| 86 | |
| 87 | /** |
| 88 | * Tooltip trigger type (hover|focus|click). |
| 89 | * |
| 90 | * @var string |
| 91 | */ |
| 92 | protected $trigger = self::HOVER; |
| 93 | |
| 94 | /** |
| 95 | * The element that triggers the tooltip. |
| 96 | * |
| 97 | * @var string |
| 98 | */ |
| 99 | protected $trigger_element = ''; |
| 100 | |
| 101 | /** |
| 102 | * Distance from the trigger in pixels. |
| 103 | * |
| 104 | * @var int |
| 105 | */ |
| 106 | protected $offset = 8; |
| 107 | |
| 108 | /** |
| 109 | * Delay in milliseconds for showing/hiding. |
| 110 | * |
| 111 | * @var array |
| 112 | */ |
| 113 | protected $delay = array( |
| 114 | 'show' => 0, |
| 115 | 'hide' => 0, |
| 116 | ); |
| 117 | |
| 118 | /** |
| 119 | * Set and sanitize the tooltip content. |
| 120 | * |
| 121 | * @param string $content HTML or text content. |
| 122 | * @param array<string, array<string, bool>> $extra_tags Optional. |
| 123 | * Additional HTML tags and attributes in KSES-compatible format. |
| 124 | * |
| 125 | * @return $this |
| 126 | */ |
| 127 | public function content( string $content, $extra_tags = array() ): self { |
| 128 | |
| 129 | $this->content = wp_kses( $content, $this->get_allowed_html_tags( $extra_tags ) ); |
| 130 | return $this; |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Set the tooltip placement. |
| 135 | * |
| 136 | * @param string $placement top|bottom|start|end. |
| 137 | * |
| 138 | * @return $this |
| 139 | */ |
| 140 | public function placement( string $placement ): self { |
| 141 | $allowed = array( |
| 142 | self::PLACEMENT_TOP, |
| 143 | self::PLACEMENT_BOTTOM, |
| 144 | self::PLACEMENT_START, |
| 145 | self::PLACEMENT_END, |
| 146 | ); |
| 147 | if ( in_array( $placement, $allowed, true ) ) { |
| 148 | $this->placement = $placement; |
| 149 | } |
| 150 | return $this; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * Set the tooltip size. |
| 155 | * |
| 156 | * @param string $size small|large. |
| 157 | * |
| 158 | * @return $this |
| 159 | */ |
| 160 | public function size( string $size ): self { |
| 161 | $allowed = array( Size::SMALL, Size::MEDIUM, Size::LARGE ); |
| 162 | if ( in_array( $size, $allowed, true ) ) { |
| 163 | $this->size = $size; |
| 164 | } |
| 165 | return $this; |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * Set the arrow alignment. |
| 170 | * |
| 171 | * @param string $arrow start|center|end. |
| 172 | * |
| 173 | * @return $this |
| 174 | */ |
| 175 | public function arrow( string $arrow ): self { |
| 176 | $allowed = array( |
| 177 | self::ARROW_START, |
| 178 | self::ARROW_CENTER, |
| 179 | self::ARROW_END, |
| 180 | ); |
| 181 | if ( in_array( $arrow, $allowed, true ) ) { |
| 182 | $this->arrow = $arrow; |
| 183 | } |
| 184 | return $this; |
| 185 | } |
| 186 | |
| 187 | /** |
| 188 | * Set the trigger type. |
| 189 | * |
| 190 | * @param string $trigger hover|focus|click. |
| 191 | * |
| 192 | * @return $this |
| 193 | */ |
| 194 | public function trigger_on( string $trigger ): self { |
| 195 | $allowed = array( |
| 196 | self::HOVER, |
| 197 | self::FOCUS, |
| 198 | self::CLICK, |
| 199 | ); |
| 200 | if ( in_array( $trigger, $allowed, true ) ) { |
| 201 | $this->trigger = $trigger; |
| 202 | } |
| 203 | return $this; |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Set the element that triggers the tooltip. |
| 208 | * |
| 209 | * @param string $trigger_element HTML for the trigger element. |
| 210 | * |
| 211 | * @return $this |
| 212 | */ |
| 213 | public function trigger_element( string $trigger_element ): self { |
| 214 | $this->trigger_element = $trigger_element; |
| 215 | return $this; |
| 216 | } |
| 217 | |
| 218 | /** |
| 219 | * Set the offset. |
| 220 | * |
| 221 | * @param int $offset Distance in pixels. |
| 222 | * |
| 223 | * @return $this |
| 224 | */ |
| 225 | public function offset( int $offset ): self { |
| 226 | $this->offset = $offset; |
| 227 | return $this; |
| 228 | } |
| 229 | |
| 230 | /** |
| 231 | * Set the show and hide delay. |
| 232 | * |
| 233 | * @param int $show Show delay in ms. |
| 234 | * @param int $hide Hide delay in ms. |
| 235 | * |
| 236 | * @return $this |
| 237 | */ |
| 238 | public function delay( int $show, int $hide = 0 ): self { |
| 239 | $this->delay = array( |
| 240 | 'show' => $show, |
| 241 | 'hide' => $hide, |
| 242 | ); |
| 243 | return $this; |
| 244 | } |
| 245 | |
| 246 | /** |
| 247 | * Get the final tooltip HTML. |
| 248 | * |
| 249 | * @return string HTML output. |
| 250 | */ |
| 251 | public function get(): string { |
| 252 | $config = array( |
| 253 | 'placement' => $this->placement, |
| 254 | 'trigger' => $this->trigger, |
| 255 | 'size' => $this->size, |
| 256 | 'arrow' => $this->arrow, |
| 257 | 'offset' => $this->offset, |
| 258 | 'delay' => $this->delay, |
| 259 | ); |
| 260 | |
| 261 | // Prepare x-data dynamic config. |
| 262 | $x_data = sprintf( 'tutorTooltip(%s)', wp_json_encode( $config ) ); |
| 263 | |
| 264 | $trigger_html = $this->trigger_element; |
| 265 | |
| 266 | $this->component_string = sprintf( |
| 267 | '<div x-data="%1$s" x-ref="trigger" class="tutor-tooltip-wrap %2$s" %3$s> |
| 268 | %4$s |
| 269 | <template x-teleport="body"> |
| 270 | <div x-ref="content" x-show="open" x-cloak x-transition class="tutor-tooltip"> |
| 271 | %5$s |
| 272 | </div> |
| 273 | </template> |
| 274 | </div>', |
| 275 | esc_attr( $x_data ), |
| 276 | esc_attr( $this->attributes['class'] ?? '' ), |
| 277 | $this->get_attributes_string(), |
| 278 | $trigger_html, |
| 279 | $this->content |
| 280 | ); |
| 281 | |
| 282 | return $this->component_string; |
| 283 | } |
| 284 | } |
| 285 |