chore: add shared components and update docs
- Add vendor selector component for admin pages - Add input macros for form handling - Add truck icon for shipping UI - Update vendor operations expansion plan - Update mkdocs configuration - Update dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,50 @@
|
||||
[x-cloak] { display: none !important; }
|
||||
</style>
|
||||
|
||||
<!-- Tom Select CSS with CDN fallback -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/tom-select@2.4.1/dist/css/tom-select.default.min.css"
|
||||
onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/vendor/tom-select.default.min.css') }}';"
|
||||
/>
|
||||
<!-- Tom Select Dark Mode Overrides -->
|
||||
<style>
|
||||
.dark .ts-wrapper .ts-control {
|
||||
background-color: rgb(55 65 81);
|
||||
border-color: rgb(75 85 99);
|
||||
color: rgb(209 213 219);
|
||||
}
|
||||
.dark .ts-wrapper .ts-control input {
|
||||
color: rgb(209 213 219);
|
||||
}
|
||||
.dark .ts-wrapper .ts-control input::placeholder {
|
||||
color: rgb(156 163 175);
|
||||
}
|
||||
.dark .ts-dropdown {
|
||||
background-color: rgb(55 65 81);
|
||||
border-color: rgb(75 85 99);
|
||||
color: rgb(209 213 219);
|
||||
}
|
||||
.dark .ts-dropdown .option {
|
||||
color: rgb(209 213 219);
|
||||
}
|
||||
.dark .ts-dropdown .option.active {
|
||||
background-color: rgb(147 51 234);
|
||||
color: white;
|
||||
}
|
||||
.dark .ts-dropdown .option:hover {
|
||||
background-color: rgb(75 85 99);
|
||||
}
|
||||
.dark .ts-wrapper.focus .ts-control {
|
||||
border-color: rgb(147 51 234);
|
||||
box-shadow: 0 0 0 1px rgb(147 51 234);
|
||||
}
|
||||
.dark .ts-dropdown .no-results,
|
||||
.dark .ts-dropdown .loading {
|
||||
color: rgb(156 163 175);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Flatpickr CSS with CDN fallback (loaded on demand via block) -->
|
||||
{% block flatpickr_css %}{% endblock %}
|
||||
|
||||
@@ -65,7 +109,25 @@
|
||||
<!-- 5. FIFTH: API Client (depends on Utils) -->
|
||||
<script src="{{ url_for('static', path='shared/js/api-client.js') }}"></script>
|
||||
|
||||
<!-- 6. SIXTH: Alpine.js v3 with CDN fallback (with defer) -->
|
||||
<!-- 6. SIXTH: Tom Select with CDN fallback -->
|
||||
<script>
|
||||
(function() {
|
||||
var script = document.createElement('script');
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/tom-select@2.4.1/dist/js/tom-select.complete.min.js';
|
||||
script.onerror = function() {
|
||||
console.warn('Tom Select CDN failed, loading local copy...');
|
||||
var fallbackScript = document.createElement('script');
|
||||
fallbackScript.src = '{{ url_for("static", path="shared/js/vendor/tom-select.complete.min.js") }}';
|
||||
document.head.appendChild(fallbackScript);
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- 7. SEVENTH: Vendor Selector (depends on Tom Select and API Client) -->
|
||||
<script src="{{ url_for('static', path='shared/js/vendor-selector.js') }}"></script>
|
||||
|
||||
<!-- 8. EIGHTH: Alpine.js v3 with CDN fallback (with defer) -->
|
||||
<script>
|
||||
(function() {
|
||||
var script = document.createElement('script');
|
||||
@@ -84,13 +146,13 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- 7. OPTIONAL: Chart.js with CDN fallback (loaded on demand via block) -->
|
||||
<!-- 9. OPTIONAL: Chart.js with CDN fallback (loaded on demand via block) -->
|
||||
{% block chartjs_script %}{% endblock %}
|
||||
|
||||
<!-- 8. OPTIONAL: Flatpickr with CDN fallback (loaded on demand via block) -->
|
||||
<!-- 10. OPTIONAL: Flatpickr with CDN fallback (loaded on demand via block) -->
|
||||
{% block flatpickr_script %}{% endblock %}
|
||||
|
||||
<!-- 9. LAST: Page-specific scripts -->
|
||||
<!-- 11. LAST: Page-specific scripts -->
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -231,3 +231,54 @@
|
||||
</button>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Vendor Selector (Tom Select)
|
||||
============================
|
||||
An async searchable vendor selector using Tom Select.
|
||||
Searches vendors by name and code with autocomplete.
|
||||
|
||||
Prerequisites:
|
||||
- Tom Select CSS/JS must be loaded (included in admin/base.html)
|
||||
- vendor-selector.js must be loaded
|
||||
|
||||
Parameters:
|
||||
- ref_name: Alpine.js x-ref name for the select element (default: 'vendorSelect')
|
||||
- id: HTML id attribute (default: 'vendor-select')
|
||||
- placeholder: Placeholder text (default: 'Search vendor 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 vendor_selector %}
|
||||
|
||||
{{ vendor_selector(
|
||||
ref_name='vendorSelect',
|
||||
placeholder='Select a vendor...',
|
||||
width='w-96'
|
||||
) }}
|
||||
|
||||
// In your Alpine.js component init():
|
||||
this.$nextTick(() => {
|
||||
initVendorSelector(this.$refs.vendorSelect, {
|
||||
onSelect: (vendor) => this.onVendorSelected(vendor),
|
||||
onClear: () => this.onVendorCleared()
|
||||
});
|
||||
});
|
||||
#}
|
||||
{% macro vendor_selector(
|
||||
ref_name='vendorSelect',
|
||||
id='vendor-select',
|
||||
placeholder='Search vendor by name or code...',
|
||||
width='w-80'
|
||||
) %}
|
||||
<div class="{{ width }}">
|
||||
<select
|
||||
id="{{ id }}"
|
||||
x-ref="{{ ref_name }}"
|
||||
placeholder="{{ placeholder }}"
|
||||
aria-label="Vendor selector"
|
||||
></select>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
Reference in New Issue
Block a user