Place_Picker.php
123 lines
| 1 | <?php |
| 2 | |
| 3 | namespace EmbedPress\Elementor\Controls; |
| 4 | |
| 5 | use Elementor\Base_Data_Control; |
| 6 | |
| 7 | (defined('ABSPATH')) or die("No direct script access allowed."); |
| 8 | |
| 9 | /** |
| 10 | * Custom Elementor control: searchable Google Places picker. |
| 11 | * |
| 12 | * Stores a single object value: { place_id, place_name, place_address }. |
| 13 | * The Backbone view that drives the search/dropdown UI lives in |
| 14 | * static/js/ep-gr-elementor-control.js. |
| 15 | * |
| 16 | * The template uses Elementor's CSS design tokens (var(--e-a-...)) so the |
| 17 | * control follows the editor's light/dark theme automatically — no |
| 18 | * hard-coded background or border colors. |
| 19 | */ |
| 20 | class Place_Picker extends Base_Data_Control |
| 21 | { |
| 22 | const CONTROL_TYPE = 'ep_gr_place_picker'; |
| 23 | |
| 24 | public function get_type() |
| 25 | { |
| 26 | return self::CONTROL_TYPE; |
| 27 | } |
| 28 | |
| 29 | protected function get_default_settings() |
| 30 | { |
| 31 | return [ |
| 32 | 'label_block' => true, |
| 33 | 'placeholder' => __('e.g. Sydney Opera House', 'embedpress'), |
| 34 | 'description' => __('Type a business name and pick a result. Reviews load automatically through the EmbedPress API — no keys needed.', 'embedpress'), |
| 35 | ]; |
| 36 | } |
| 37 | |
| 38 | public function get_default_value() |
| 39 | { |
| 40 | return [ |
| 41 | 'place_id' => '', |
| 42 | 'place_name' => '', |
| 43 | 'place_address' => '', |
| 44 | ]; |
| 45 | } |
| 46 | |
| 47 | public function content_template() |
| 48 | { |
| 49 | $control_uid = $this->get_control_uid(); |
| 50 | ?> |
| 51 | <div class="elementor-control-field ep-gr-picker"> |
| 52 | <label for="<?php echo esc_attr($control_uid); ?>" class="elementor-control-title">{{{ data.label }}}</label> |
| 53 | <div class="elementor-control-input-wrapper"> |
| 54 | <div class="ep-gr-picker__selected" data-state="empty"> |
| 55 | <span class="ep-gr-picker__selected-pin" aria-hidden="true"> |
| 56 | <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> |
| 57 | </span> |
| 58 | <div class="ep-gr-picker__selected-info"> |
| 59 | <strong class="ep-gr-picker__selected-name"></strong> |
| 60 | <span class="ep-gr-picker__selected-address" hidden></span> |
| 61 | <span class="ep-gr-picker__selected-id"></span> |
| 62 | </div> |
| 63 | <button type="button" class="ep-gr-picker__clear"> |
| 64 | <?php esc_html_e('Change', 'embedpress'); ?> |
| 65 | </button> |
| 66 | </div> |
| 67 | <div class="ep-gr-picker__search-wrap"> |
| 68 | <div class="ep-gr-picker__search"> |
| 69 | <span class="ep-gr-picker__search-icon" aria-hidden="true"> |
| 70 | <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="7" cy="7" r="4.5"/><path d="M10.5 10.5 L14 14"/></svg> |
| 71 | </span> |
| 72 | <input |
| 73 | id="<?php echo esc_attr($control_uid); ?>" |
| 74 | type="text" |
| 75 | class="ep-gr-picker__input" |
| 76 | placeholder="{{ data.placeholder }}" |
| 77 | autocomplete="off" |
| 78 | > |
| 79 | <span class="ep-gr-picker__spinner" hidden> |
| 80 | <span class="ep-gr-picker__spinner-dot"></span> |
| 81 | </span> |
| 82 | </div> |
| 83 | <div class="ep-gr-picker__results-panel" hidden> |
| 84 | <ul class="ep-gr-picker__results" role="listbox"></ul> |
| 85 | <p class="ep-gr-picker__results-note" hidden></p> |
| 86 | </div> |
| 87 | </div> |
| 88 | <div class="ep-gr-picker__status" role="status" aria-live="polite"></div> |
| 89 | <div class="ep-gr-picker__lists" hidden> |
| 90 | <div class="ep-gr-picker__list" data-kind="saved" hidden> |
| 91 | <div class="ep-gr-picker__list-heading"><?php esc_html_e('Saved', 'embedpress'); ?></div> |
| 92 | <ul class="ep-gr-picker__list-items"></ul> |
| 93 | </div> |
| 94 | <div class="ep-gr-picker__list" data-kind="recent" hidden> |
| 95 | <div class="ep-gr-picker__list-heading"><?php esc_html_e('Recent', 'embedpress'); ?></div> |
| 96 | <ul class="ep-gr-picker__list-items"></ul> |
| 97 | </div> |
| 98 | </div> |
| 99 | <div class="ep-gr-picker__manual"> |
| 100 | <button type="button" class="ep-gr-picker__manual-toggle" aria-expanded="false"> |
| 101 | <?php esc_html_e('Have a Place ID? Enter manually', 'embedpress'); ?> |
| 102 | </button> |
| 103 | <div class="ep-gr-picker__manual-row" hidden> |
| 104 | <input |
| 105 | type="text" |
| 106 | class="ep-gr-picker__manual-input" |
| 107 | placeholder="ChIJ…" |
| 108 | autocomplete="off" |
| 109 | > |
| 110 | <button type="button" class="ep-gr-picker__manual-apply"> |
| 111 | <?php esc_html_e('Use', 'embedpress'); ?> |
| 112 | </button> |
| 113 | </div> |
| 114 | </div> |
| 115 | </div> |
| 116 | </div> |
| 117 | <# if ( data.description ) { #> |
| 118 | <div class="elementor-control-field-description">{{{ data.description }}}</div> |
| 119 | <# } #> |
| 120 | <?php |
| 121 | } |
| 122 | } |
| 123 |