feat: implement WooCommerce AJAX product search
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX Search — reusable, accessible, combobox-like (without over-engineered ARIA).
|
||||
*
|
||||
* Reusable by: desktop header, mobile header, future overlay.
|
||||
* JS: assets/js/search.js handles fetch, debounce, stale protection, keyboard.
|
||||
*
|
||||
* Args: ['placeholder'=>string, 'action'=>string, 'id'=>string|null]
|
||||
*
|
||||
* @package XShop
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$uid = $args['id'] ?? ('xshop-ajax-search-' . wp_unique_id());
|
||||
$placeholder = $args['placeholder'] ?? esc_html__('Search products…', 'xshop');
|
||||
$action = $args['action'] ?? home_url('/');
|
||||
$minLength = 2;
|
||||
$limit = 6;
|
||||
?>
|
||||
<div class="xshop-search" data-xshop-search>
|
||||
<form role="search" method="get" action="<?php echo esc_url($action); ?>" class="xshop-search__form" data-xshop-search-form>
|
||||
<label class="xshop-sr-only" for="<?php echo esc_attr($uid); ?>"><?php esc_html_e('Search products', 'xshop'); ?></label>
|
||||
<input
|
||||
type="search"
|
||||
id="<?php echo esc_attr($uid); ?>"
|
||||
name="s"
|
||||
value="<?php echo esc_attr(get_search_query()); ?>"
|
||||
placeholder="<?php echo esc_attr($placeholder); ?>"
|
||||
autocomplete="off"
|
||||
aria-label="<?php esc_attr_e('Search products', 'xshop'); ?>"
|
||||
aria-expanded="false"
|
||||
aria-controls="<?php echo esc_attr($uid); ?>-listbox"
|
||||
aria-autocomplete="list"
|
||||
role="combobox"
|
||||
data-xshop-search-input
|
||||
data-min-length="<?php echo esc_attr((string) $minLength); ?>"
|
||||
data-limit="<?php echo esc_attr((string) $limit); ?>"
|
||||
/>
|
||||
<?php if (xshop_has_woocommerce()): ?>
|
||||
<input type="hidden" name="post_type" value="product" />
|
||||
<?php endif; ?>
|
||||
<button type="submit" class="xshop-btn xshop-btn--primary" aria-label="<?php esc_attr_e('Search', 'xshop'); ?>"><?php esc_html_e('Search', 'xshop'); ?></button>
|
||||
</form>
|
||||
|
||||
<div
|
||||
id="<?php echo esc_attr($uid); ?>-listbox"
|
||||
class="xshop-search__dropdown"
|
||||
role="listbox"
|
||||
hidden
|
||||
data-xshop-search-dropdown
|
||||
>
|
||||
<div class="xshop-search__status xshop-sr-only" aria-live="polite" aria-atomic="true" data-xshop-search-status></div>
|
||||
|
||||
<div class="xshop-search__loading" hidden data-xshop-search-loading>
|
||||
<span class="xshop-loading__spinner" aria-hidden="true"></span>
|
||||
<span><?php esc_html_e('Searching…', 'xshop'); ?></span>
|
||||
</div>
|
||||
|
||||
<ul class="xshop-search__results" role="presentation" data-xshop-search-results></ul>
|
||||
|
||||
<div class="xshop-search__empty" hidden data-xshop-search-empty>
|
||||
<p><?php esc_html_e('No products found.', 'xshop'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="xshop-search__error" hidden data-xshop-search-error>
|
||||
<p><?php esc_html_e('Search is temporarily unavailable. Press Enter to search.', 'xshop'); ?></p>
|
||||
</div>
|
||||
|
||||
<a href="#" class="xshop-search__viewall" hidden data-xshop-search-viewall>
|
||||
<?php esc_html_e('View all results', 'xshop'); ?> →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,7 +42,7 @@ $hasLogo = has_custom_logo();
|
||||
|
||||
<div class="xshop-header__actions">
|
||||
<div class="xshop-header__search xshop-header__search--desktop">
|
||||
<?php get_template_part('template-parts/components/search-form', null, ['placeholder' => esc_html__('Search…', 'xshop')]); ?>
|
||||
<?php get_template_part('template-parts/components/ajax-search', null, ['placeholder' => esc_html__('Search products…', 'xshop')]); ?>
|
||||
</div>
|
||||
|
||||
<?php if (xshop_has_woocommerce()): ?>
|
||||
@@ -75,6 +75,6 @@ $hasLogo = has_custom_logo();
|
||||
]);
|
||||
?>
|
||||
<div style="margin-block-start:var(--xshop-space-4)">
|
||||
<?php get_template_part('template-parts/components/search-form', null, ['placeholder' => esc_html__('Search…', 'xshop')]); ?>
|
||||
<?php get_template_part('template-parts/components/ajax-search', null, ['placeholder' => esc_html__('Search products…', 'xshop'), 'id' => 'xshop-ajax-search-mobile-' . wp_unique_id()]); ?>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
Reference in New Issue
Block a user