diff --git a/Modules/Company/Resources/views/_form.blade.php b/Modules/Company/Resources/views/_form.blade.php index a5bf21dc..6204e7a8 100644 --- a/Modules/Company/Resources/views/_form.blade.php +++ b/Modules/Company/Resources/views/_form.blade.php @@ -54,7 +54,7 @@ name="country_id" data-wms-select2 data-placeholder="Search and select a country" - class="w-full" + class="wms-select2-control" > @foreach ($countries as $country) diff --git a/resources/css/wms-select2.css b/resources/css/wms-select2.css index c47f2a56..d027ed85 100644 --- a/resources/css/wms-select2.css +++ b/resources/css/wms-select2.css @@ -1,16 +1,7 @@ -/* WMS Select2 professional dark theme. - Imported after Select2's own CSS so it overrides the vendor defaults. */ +/* WMS Select2 professional dark theme. Imported after Select2 base CSS. */ -.select2-hidden-accessible { - position: absolute !important; - width: 1px !important; - height: 1px !important; - overflow: hidden !important; - clip: rect(0 0 0 0) !important; - white-space: nowrap !important; - border: 0 !important; - padding: 0 !important; - margin: -1px !important; +.wms-select2-field { + min-width: 0; } .wms-select2-field .select2-container, @@ -23,6 +14,19 @@ margin-top: 0.5rem !important; } +.wms-select2-field select[data-wms-select2].select2-hidden-accessible, +.wms-select2-field select.wms-select2-control.select2-hidden-accessible { + position: absolute !important; + width: 1px !important; + height: 1px !important; + overflow: hidden !important; + clip: rect(0 0 0 0) !important; + white-space: nowrap !important; + border: 0 !important; + padding: 0 !important; + margin: -1px !important; +} + .select2-container--wms .select2-selection--single { position: relative !important; height: 3rem !important; @@ -71,15 +75,9 @@ .select2-container--wms .select2-selection--single .select2-selection__arrow b { border-color: rgb(212 212 216) transparent transparent transparent !important; - border-style: solid !important; border-width: 5px 4px 0 4px !important; - height: 0 !important; - left: 50% !important; margin-left: -4px !important; margin-top: -2px !important; - position: absolute !important; - top: 50% !important; - width: 0 !important; } .select2-container--wms.select2-container--open .select2-selection--single .select2-selection__arrow b { @@ -89,17 +87,16 @@ .select2-container--wms .select2-selection--single .select2-selection__clear { position: absolute !important; - right: 2.1rem !important; + right: 2.25rem !important; top: 0 !important; - height: 100% !important; width: 1rem !important; + height: 100% !important; background: transparent !important; border: 0 !important; border-radius: 0 !important; - box-shadow: none !important; color: rgb(161 161 170) !important; - font-size: 1.125rem !important; - line-height: 3rem !important; + font-size: 1.25rem !important; + line-height: 2.875rem !important; text-align: center !important; } @@ -116,6 +113,14 @@ box-shadow: 0 24px 60px rgb(0 0 0 / 0.45) !important; } +.select2-container--wms.select2-container--open .select2-dropdown--below { + margin-top: 0.375rem !important; +} + +.select2-container--wms.select2-container--open .select2-dropdown--above { + margin-top: -0.375rem !important; +} + .select2-container--wms .select2-search--dropdown { padding: 0.75rem !important; background: rgb(24 24 27) !important; @@ -123,12 +128,14 @@ .select2-container--wms .select2-search--dropdown .select2-search__field { height: 2.75rem !important; + width: 100% !important; border: 1px solid rgb(63 63 70) !important; border-radius: 0.75rem !important; background: rgb(9 9 11) !important; color: rgb(244 244 245) !important; padding: 0 0.875rem !important; font-size: 0.875rem !important; + font-weight: 500 !important; outline: none !important; } @@ -164,7 +171,7 @@ color: rgb(161 161 170) !important; } -/* Matching fallback before Select2 initialises. */ +/* Fallback styling before Select2 initialises, matching WMS inputs. */ .wms-select2-field > select[data-wms-select2], .wms-select2-field > select.wms-select2-control { margin-top: 0.5rem; diff --git a/resources/js/app.js b/resources/js/app.js index 956f9ecc..31873323 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -143,23 +143,21 @@ function renderWmsCharts() { function livewireComponentFor(element) { - if (!element || !window.Livewire) { + let current = element; + + while (current && current !== document.documentElement) { + if (current.hasAttribute && current.hasAttribute('wire:id')) { + break; + } + + current = current.parentElement; + } + + if (!current || !window.Livewire) { return null; } - let componentRoot = null; - - try { - componentRoot = element.closest('[wire\\:id]'); - } catch (error) { - componentRoot = null; - } - - if (!componentRoot) { - return null; - } - - return window.Livewire.find(componentRoot.getAttribute('wire:id')); + return window.Livewire.find(current.getAttribute('wire:id')); } function setLivewireProperty(element, model, value) { @@ -177,15 +175,12 @@ function setLivewireProperty(element, model, value) { * * @returns {void} */ -function initialiseSelect2(root = document) { +function initialiseSelect2() { if (!window.jQuery?.fn?.select2) { return; } - const $root = root instanceof window.Element ? $(root) : $(document); - const selector = 'select[data-helpdesk-select2], select[data-wms-select2], select.wms-select2-control'; - - $root.find(selector).add($root.is(selector) ? $root : $()).each(function () { + $('[data-helpdesk-select2], [data-wms-select2], .wms-select2-control').each(function () { const select = this; const $select = $(select); @@ -199,28 +194,36 @@ function initialiseSelect2(root = document) { $select.find('option[value=""]').first().text() || (isMultiple ? 'Select options' : 'Select option'); - if (!isMultiple && $select.find('option[value=""]').length === 0) { - $select.prepend(new Option('', '', false, false)); - } - $select.select2({ theme: 'wms', width: '100%', + minimumResultsForSearch: 0, allowClear: !isMultiple, closeOnSelect: !isMultiple, dropdownAutoWidth: false, placeholder, sorter(data) { - return data.sort((first, second) => first.text.localeCompare(second.text, undefined, { - sensitivity: 'base', - ignorePunctuation: true, - })); + return data.sort((first, second) => { + const firstText = (first.text || '').trim(); + const secondText = (second.text || '').trim(); + + if (!first.id) return -1; + if (!second.id) return 1; + + return firstText.localeCompare(secondText, undefined, { + sensitivity: 'base', + ignorePunctuation: true, + }); + }); }, }); $select.off('change.wms-select2-livewire'); + $select.on('change.wms-select2-livewire', function () { setLivewireProperty(this, this.dataset.wireModel, $select.val()); + + this.dispatchEvent(new Event('change', { bubbles: true })); }); }); } @@ -236,28 +239,11 @@ function bootUi() { } document.addEventListener('DOMContentLoaded', bootUi); -window.addEventListener('load', bootUi); -window.addEventListener('pageshow', bootUi); document.addEventListener('livewire:navigated', bootUi); document.addEventListener('livewire:init', () => { - Livewire.hook('morphed', ({ el }) => { - initialiseSelect2(el || document); + Livewire.hook('morphed', () => { + initialiseSelect2(); }); }); - -const select2Observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - mutation.addedNodes.forEach((node) => { - if (node instanceof window.Element) { - initialiseSelect2(node); - } - }); - }); -}); - -select2Observer.observe(document.documentElement, { - childList: true, - subtree: true, -});