{# Input Macros ============ Reusable input components with Alpine.js integration. Usage: {% from 'shared/macros/inputs.html' import search_autocomplete %} {{ search_autocomplete( search_var='userSearchQuery', results_var='userSearchResults', show_dropdown_var='showUserDropdown', loading_var='searchingUsers', disabled_var='transferring', select_action='selectUser(user)', display_field='username', secondary_field='email', placeholder='Search by name or email...' ) }} #} {# Search Autocomplete =================== A search input with dropdown results for autocomplete functionality. Parameters: - search_var: Alpine.js variable for search query (required) - results_var: Alpine.js variable containing search results array (required) - show_dropdown_var: Alpine.js variable controlling dropdown visibility (required) - loading_var: Alpine.js variable for loading state (default: 'searching') - disabled_var: Alpine.js variable for disabled state (default: none) - search_action: Alpine.js action on input (default: 'search()') - select_action: Alpine.js action when item selected, receives 'item' (required) - selected_check: Alpine.js expression to check if item is selected (optional) - display_field: Field name for primary display text (default: 'name') - secondary_field: Field name for secondary text (optional) - id_field: Field name for item ID (default: 'id') - placeholder: Input placeholder text (default: 'Search...') - min_chars: Minimum characters before showing results (default: 2) - no_results_text: Text when no results found (default: 'No results found') - loading_text: Text while loading (default: 'Searching...') #} {% macro search_autocomplete( search_var, results_var, show_dropdown_var, loading_var='searching', disabled_var=none, search_action='search()', select_action='selectItem(item)', selected_check=none, display_field='name', secondary_field=none, id_field='id', placeholder='Search...', min_chars=2, no_results_text='No results found', loading_text='Searching...' ) %}
{# Search Results Dropdown #}
{# No Results #}
{{ no_results_text }}
{# Loading #}
{{ loading_text }}
{% endmacro %} {# Selected Item Display ===================== A display component for showing the currently selected item with clear button. Parameters: - selected_var: Alpine.js variable containing selected item (required) - display_field: Field name for primary display text (default: 'name') - secondary_field: Field name for secondary text (optional) - clear_action: Alpine.js action to clear selection (required) - label: Label text before the selection (default: 'Selected:') #} {% macro selected_item_display( selected_var, display_field='name', secondary_field=none, clear_action='clearSelection()', label='Selected:' ) %}
{{ label }} {% if secondary_field %} () {% endif %}
{% endmacro %} {# Number Stepper ============== A number input with +/- buttons for incrementing/decrementing values. Useful for quantity selectors in carts, product pages, batch sizes, etc. Parameters: - model: Alpine.js x-model variable (required) - min: Minimum allowed value (default: 1) - max: Maximum allowed value (default: none - unlimited) - step: Increment/decrement step (default: 1) - size: 'sm' | 'md' | 'lg' (default: 'md') - disabled_var: Alpine.js variable for disabled state (optional) - name: Input name for form submission (optional) - id: Input id attribute (optional) - label: Accessible label for screen readers (default: 'Quantity') Usage: {{ number_stepper(model='quantity', min=1, max=99) }} {{ number_stepper(model='cart.items[index].qty', min=1, max='item.stock', size='sm') }} {{ number_stepper(model='batchSize', min=100, max=5000, step=100, size='lg') }} #} {% macro number_stepper( model, min=1, max=none, step=1, size='md', disabled_var=none, name=none, id=none, label='Quantity' ) %} {% set sizes = { 'sm': { 'btn': 'px-2 py-1', 'input': 'px-2 py-1 text-xs w-12', 'icon': 'w-3 h-3' }, 'md': { 'btn': 'px-3 py-2', 'input': 'px-3 py-2 text-sm w-16', 'icon': 'w-4 h-4' }, 'lg': { 'btn': 'px-4 py-3', 'input': 'px-4 py-3 text-base w-20', 'icon': 'w-5 h-5' } } %} {% set s = sizes[size] %}
{% endmacro %} {# Store Selector (Tom Select) ============================ An async searchable store selector using Tom Select. Searches stores by name and code with autocomplete. Prerequisites: - Tom Select CSS/JS must be loaded (included in admin/base.html) - store-selector.js must be loaded Parameters: - ref_name: Alpine.js x-ref name for the select element (default: 'storeSelect') - id: HTML id attribute (default: 'store-select') - placeholder: Placeholder text (default: 'Search store by name or code...') - width: CSS width class (default: 'w-80') - on_init: JS callback name when Tom Select is initialized (optional) Usage: {% from 'shared/macros/inputs.html' import store_selector %} {{ store_selector( ref_name='storeSelect', placeholder='Select a store...', width='w-96' ) }} // In your Alpine.js component init(): this.$nextTick(() => { initStoreSelector(this.$refs.storeSelect, { onSelect: (store) => this.onStoreSelected(store), onClear: () => this.onStoreCleared() }); }); #} {% macro store_selector( ref_name='storeSelect', id='store-select', placeholder='Search store by name or code...', width='w-80' ) %}
{% endmacro %} {# Toggle Switch ============= A toggle switch component for binary options (on/off, monthly/annual, etc.) with optional labels on both sides. Parameters: - model: Alpine.js x-model variable (required) - left_label: Label for the "off" state (optional) - right_label: Label for the "on" state (optional) - right_badge: Small badge/extra text for right label (optional) - size: 'sm' | 'md' | 'lg' (default: 'md') - color: Tailwind color name for active state (default: 'indigo') Usage: {{ toggle_switch(model='annual', left_label='Monthly', right_label='Annual', right_badge='Save 2 months') }} {{ toggle_switch(model='darkMode', size='sm') }} #} {% macro toggle_switch( model, left_label=none, right_label=none, right_badge=none, size='md', color='indigo' ) %} {% set sizes = { 'sm': {'track': 'w-10 h-5', 'thumb': 'w-4 h-4', 'translate': 'translate-x-5', 'text': 'text-sm'}, 'md': {'track': 'w-14 h-7', 'thumb': 'w-5 h-5', 'translate': 'translate-x-7', 'text': 'text-base'}, 'lg': {'track': 'w-16 h-8', 'thumb': 'w-6 h-6', 'translate': 'translate-x-8', 'text': 'text-lg'} } %} {% set s = sizes[size] %}
{% if left_label %} {{ left_label }} {% endif %} {% if right_label %} {{ right_label }} {% if right_badge %} {{ right_badge }} {% endif %} {% endif %}
{% endmacro %}