| @@ -339,8 +339,97 @@ | ||
| 339 | 339 | return BuilderFns::is_builder_preview() || $this->is_edit_mode(); |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | 342 | /** |
| 343 | + * Render a shared editor-only notice. | |
| 344 | + * | |
| 345 | + * Any widget can surface an editor placeholder (out of stock, no active | |
| 346 | + * campaign, empty result, etc.) with one consistent design. Renders only in | |
| 347 | + * edit/preview mode and prints the notice CSS inline once per request. | |
| 348 | + * | |
| 349 | + * The notice lives in the Elementor preview iframe, which loads only frontend | |
| 350 | + * styles — so the rule is printed here instead of the editor panel stylesheet, | |
| 351 | + * and kept out of the compiled frontend bundle. | |
| 352 | + * | |
| 353 | + * @param string $message Notice text (already translated). | |
| 354 | + * @param string $extra_class Optional extra class for per-widget targeting. | |
| 355 | + * @param string $title Optional hover tooltip; defaults to the editor-only hint. | |
| 356 | + * @return void | |
| 357 | + */ | |
| 358 | + public function editor_notice( $message, $extra_class = '', $title = '' ) { | |
| 359 | + if ( ! $this->is_edit_mode() || '' === $message ) { | |
| 360 | + return; | |
| 361 | + } | |
| 362 | + $this->editor_notice_style(); | |
| 363 | + $classes = trim( 'rtsb-editor-notice ' . $extra_class ); | |
| 364 | + $title = '' !== $title ? $title : esc_html__( 'This notice is only visible in the Elementor editor.', 'shopbuilder' ); | |
| 365 | + ?> | |
| 366 | + <div class="<?php echo esc_attr( $classes ); ?>" title="<?php echo esc_attr( $title ); ?>"> | |
| 367 | + <span class="rtsb-editor-notice__label"><?php echo esc_html__( 'Editor Notice:', 'shopbuilder' ); ?></span> | |
| 368 | + <?php echo esc_html( $message ); ?> | |
| 369 | + </div> | |
| 370 | + <?php | |
| 371 | + } | |
| 372 | + | |
| 373 | + /** | |
| 374 | + * Print the shared editor-notice CSS inline, once per request. | |
| 375 | + * | |
| 376 | + * @return void | |
| 377 | + */ | |
| 378 | + protected function editor_notice_style() { | |
| 379 | + static $printed = false; | |
| 380 | + if ( $printed ) { | |
| 381 | + return; | |
| 382 | + } | |
| 383 | + $printed = true; | |
| 384 | + ?> | |
| 385 | + <style> | |
| 386 | + .rtsb-editor-notice { | |
| 387 | + position: relative; | |
| 388 | + max-height: 500px; | |
| 389 | + padding: 12px 16px 12px 44px; | |
| 390 | + border: 1px solid #f0b849; | |
| 391 | + border-left: 4px solid #f0b849; | |
| 392 | + border-radius: 4px; | |
| 393 | + background: #fff8e5; | |
| 394 | + color: #8a6d3b; | |
| 395 | + font-size: 13px; | |
| 396 | + font-weight: 500; | |
| 397 | + line-height: 1.5; | |
| 398 | + box-shadow: 0 1px 4px rgba(138, 109, 59, 0.2); | |
| 399 | + cursor: help; | |
| 400 | + overflow: hidden; | |
| 401 | + opacity: 1; | |
| 402 | + transition: opacity 0.3s ease, max-height 0.3s ease, margin 0.3s ease, padding 0.3s ease, border-width 0.3s ease; | |
| 403 | + } | |
| 404 | + .rtsb-editor-notice::before { | |
| 405 | + content: "\26A0"; | |
| 406 | + position: absolute; | |
| 407 | + top: 50%; | |
| 408 | + left: 16px; | |
| 409 | + transform: translateY(-50%); | |
| 410 | + font-size: 18px; | |
| 411 | + line-height: 1; | |
| 412 | + } | |
| 413 | + .rtsb-editor-notice__label { | |
| 414 | + font-weight: 700; | |
| 415 | + margin-right: 4px; | |
| 416 | + } | |
| 417 | + /* Fade + collapse the notice when the editor panel is hidden (preview toggle). */ | |
| 418 | + .elementor-editor-preview .rtsb-editor-notice { | |
| 419 | + max-height: 0; | |
| 420 | + margin-top: 0; | |
| 421 | + padding-top: 0; | |
| 422 | + padding-bottom: 0; | |
| 423 | + border-top-width: 0; | |
| 424 | + border-bottom-width: 0; | |
| 425 | + opacity: 0; | |
| 426 | + } | |
| 427 | + </style> | |
| 428 | + <?php | |
| 429 | + } | |
| 430 | + | |
| 431 | + /** | |
| 343 | 432 | * Elementor Edit mode need some extra js for isotop reinitialize |
| 344 | 433 | * |
| 345 | 434 | * @return void |
| 346 | 435 | */ |