country-select-pro 5.6.4 → 5.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * CountrySelect Pro v5.6.4
2
+ * CountrySelect Pro v5.6.6
3
3
  * ---------------------------------------------------------------------------
4
4
  * Features:
5
5
  * - SVG Arrow Down icon
@@ -10,10 +10,19 @@
10
10
  */
11
11
 
12
12
  class CountrySelect {
13
+
13
14
  constructor(element, options = {}) {
14
15
  this.input = element;
15
16
  if (!this.input) return;
16
17
 
18
+ // προσθέτεις class
19
+ if (!this.input.classList.contains('checkout-trigger')) {
20
+ this.input.classList.add('checkout-trigger');
21
+ }
22
+
23
+ // μετά ελέγχεις αν έχει ήδη init
24
+ if (this.input.dataset.csInitialized === '1') return;
25
+
17
26
  // Configuration
18
27
  this.schema = this.input.dataset.schema || "{img} {name}";
19
28
  this.schemaReturn = this.input.dataset.schemaReturn || this.schema;
@@ -334,18 +343,41 @@ class CountrySelect {
334
343
  /** AUTO-INIT (STATIC & HTMX) **/
335
344
  const initCS = (target) => {
336
345
  const root = (target && target.querySelectorAll) ? target : document;
337
- root.querySelectorAll('.country-select').forEach(el => {
338
- const hasWrapper = el.nextSibling && el.nextSibling.classList && el.nextSibling.classList.contains('cs-wrapper');
339
- if (!hasWrapper) new CountrySelect(el);
346
+
347
+ if (root.matches?.('.country-select')) {
348
+ if (root.dataset.csInitialized !== '1') {
349
+ new CountrySelect(root);
350
+ }
351
+ }
352
+
353
+ root.querySelectorAll?.('.country-select').forEach(el => {
354
+ if (el.dataset.csInitialized === '1') return;
355
+ new CountrySelect(el);
340
356
  });
341
357
  };
358
+
342
359
  const setupListeners = () => {
343
360
  initCS(document);
344
- ['htmx:afterProcess', 'htmx:afterSettle'].forEach(evt => document.body.addEventListener(evt, (e) => initCS(e.detail.target || e.target)));
345
- new MutationObserver((m) => m.forEach(mu => mu.addedNodes.length && initCS(mu.target))).observe(document.body, {
361
+
362
+ document.body.addEventListener('htmx:afterSettle', (e) => {
363
+ initCS(e.detail.target || e.target);
364
+ });
365
+
366
+ new MutationObserver((mutations) => {
367
+ mutations.forEach(mu => {
368
+ mu.addedNodes.forEach(node => {
369
+ if (node.nodeType !== 1) return;
370
+ initCS(node);
371
+ });
372
+ });
373
+ }).observe(document.body, {
346
374
  childList: true,
347
375
  subtree: true
348
376
  });
349
377
  };
350
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', setupListeners);
351
- else setupListeners();
378
+
379
+ if (document.readyState === 'loading') {
380
+ document.addEventListener('DOMContentLoaded', setupListeners);
381
+ } else {
382
+ setupListeners();
383
+ }
@@ -1 +1 @@
1
- class CountrySelect{constructor(e,t={}){if(this.input=e,!this.input)return;this.schema=this.input.dataset.schema||"{img} {name}",this.schemaReturn=this.input.dataset.schemaReturn||this.schema,this.valueType=this.input.dataset.valueType||"code",this.rowLimit=parseInt(this.input.dataset.countryRowValues)||5,this.hasSearch="false"!==this.input.dataset.countrySearch,this.dropdownWidth=this.input.dataset.dropdownWidth||"auto";const i=this.input.dataset.preferred||"";this.preferredCodes=i?i.split(",").map(e=>e.trim().toUpperCase()):[],this.config={placeholder:this.input.dataset.placeholder||"Select",...t},this.countries=[],this.filteredCountries=[],this.isOpen=!1,this.activeIndex=-1,this.rowHeight=44,this._init()}async _init(){this._applyStyles(),this._setupDOM(),this._bindEvents(),await this._loadData()}_applyStyles(){const e="cs-v57-styles";if(!document.getElementById(e)){const t=document.createElement("style");t.id=e,t.textContent="\n .cs-wrapper { position: relative; font-family: inherit; width: 100%; outline: none; }\n .cs-trigger { \n /* Bootstrap 5 Exact Specs */\n padding: 0.375rem 2.25rem 0.375rem 0.75rem; \n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.375rem;\n transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;\n display: flex; align-items: center; gap: 8px; cursor: pointer; \n min-height: calc(1.5em + 0.75rem + 2px); \n box-sizing: border-box; position: relative;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px 12px;\n }\n \n .input-group > .cs-wrapper { flex: 1 1 auto; width: 1%; }\n .cs-wrapper.is-invalid .cs-trigger { border-color: #dc3545 !important; }\n .cs-error-msg { display: none; color: #dc3545; font-size: 0.825em; margin-top: 4px; position: absolute; left: 0; top: 100%; width: 100%; z-index: 10; }\n .cs-wrapper.is-invalid .cs-error-msg { display: block; }\n\n /* Focus state Bootstrap 5 */\n .cs-wrapper:focus-within .cs-trigger {\n border-color: #86b7fe;\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n }\n\n .cs-dropdown { \n position: absolute; left: 0; right: 0; background: #fff; \n border: 1px solid rgba(0,0,0,.15); border-radius: 0.375rem;\n z-index: 2050; display: none; margin-top: 0.125rem;\n box-shadow: 0 0.5rem 1rem rgba(0,0,0,.175);\n overflow: hidden; max-width: 95vw;\n }\n \n .cs-wrapper.drop-up .cs-dropdown { \n bottom: calc(100% + 0.25rem); top: auto;\n box-shadow: 0 -0.5rem 1rem rgba(0,0,0,.175);\n }\n .cs-wrapper.open .cs-dropdown { display: block; }\n \n .cs-search-box { padding: 8px; border-bottom: 1px solid #dee2e6; background: #f8f9fa; }\n .cs-search-input { \n width: 100%; padding: 0.375rem 0.75rem; border: 1px solid #ced4da; \n border-radius: 0.25rem; outline: none; font-size: 0.875rem;\n }\n .cs-list { overflow-y: auto; scrollbar-width: thin; scroll-behavior: auto; min-height: 50px; padding: 0.375rem 0; }\n .cs-option { \n padding: 0.5rem 0.75rem; display: flex; align-items: center; gap: 10px; \n cursor: pointer; font-size: 0.9rem; transition: background 0.1s;\n }\n .cs-option:hover { background-color: #f8f9fa; }\n .cs-option.active { background-color: #0d6efd; color: #fff; }\n \n .cs-wrapper img { width: 20px !important; height: 14px !important; object-fit: cover; border-radius: 2px; flex-shrink: 0; }\n .cs-selected-content { display: flex; align-items: center; gap: 8px; overflow: hidden; white-space: nowrap; line-height: 1; }\n .cs-divider { height: 1px; background: #dee2e6; margin: 0.375rem 0; pointer-events: none; }\n .cs-hidden { display: none !important; }\n ",document.head.appendChild(t)}}_setupDOM(){Object.assign(this.input.style,{position:"absolute",opacity:"0",width:"1px",height:"1px",pointerEvents:"none"}),this.wrapper=document.createElement("div"),this.wrapper.className="cs-wrapper",this.wrapper.tabIndex=0;const e=this.input.value?"":this.config.placeholder;this.wrapper.innerHTML=`\n <div class="cs-trigger"><span class="cs-selected-content">${e}</span></div>\n <div class="cs-error-msg"></div>\n <div class="cs-dropdown">\n <div class="cs-search-box ${this.hasSearch?"":"cs-hidden"}">\n <input type="text" class="cs-search-input" placeholder="Search..." autocomplete="off" tabindex="-1">\n </div>\n <div class="cs-list"><div class="cs-loading" style="padding:15px; text-align:center;">Loading...</div></div>\n </div>\n `;this.wrapper.querySelector(".cs-dropdown").style.width="auto"===this.dropdownWidth?"100%":this.dropdownWidth,this.input.parentNode.insertBefore(this.wrapper,this.input.nextSibling)}_updatePosition(){const e=this.wrapper.getBoundingClientRect(),t=this.rowLimit*this.rowHeight+(this.hasSearch?60:0),i=window.innerHeight-e.bottom,s=e.top;i<t&&s>t?this.wrapper.classList.add("drop-up"):this.wrapper.classList.remove("drop-up")}async _loadData(){try{const e=await fetch("https://restcountries.com/v3.1/all?fields=name,flags,cca2,idd"),t=await e.json();this.countries=t.map(e=>({name:e.name.common,code:e.cca2.toUpperCase(),flag:e.flags.svg,phone:e.idd.root+(e.idd.suffixes?e.idd.suffixes.length>1?"":e.idd.suffixes[0]:""),isPreferred:this.preferredCodes.includes(e.cca2.toUpperCase())})).sort((e,t)=>e.name.localeCompare(t.name)),this.filteredCountries=[...this.countries],this._renderOptions(),this._syncInitialValue()}catch(e){console.error("CountrySelect API Fail",e)}}_syncInitialValue(){const e=this.input.value;if(!e)return void(this.wrapper.querySelector(".cs-selected-content").innerHTML=this.config.placeholder);const t=this.countries.find(t=>"phone"===this.valueType?t.phone===e:"name"===this.valueType?t.name===e:t.code===e);t&&this._updateUI(t)}_parseTemplate(e,t){return e.replace("{img}",`<img src="${t.flag}">`).replace("{name}",`<span>${t.name}</span>`).replace("{code}",`<span>${t.code}</span>`).replace("{phone}",`<span>${t.phone}</span>`)}_renderOptions(){const e=this.wrapper.querySelector(".cs-list");if(!e)return;e.innerHTML="";const t=this.wrapper.querySelector(".cs-search-input")?.value||"",i=this.filteredCountries.filter(e=>e.isPreferred),s=this.filteredCountries.filter(e=>!e.isPreferred),n=(e,t)=>{const i=document.createElement("div");return i.className="cs-option "+(t===this.activeIndex?"active":""),i.innerHTML=this._parseTemplate(this.schema,e),i.onclick=t=>{t.stopPropagation(),this._select(e)},i};if(i.forEach((t,i)=>e.appendChild(n(t,i))),i.length>0&&s.length>0&&!t){const t=document.createElement("div");t.className="cs-divider",e.appendChild(t)}s.forEach((t,s)=>e.appendChild(n(t,i.length+s)))}_select(e){this._updateUI(e),this.input.value="phone"===this.valueType?e.phone:"name"===this.valueType?e.name:e.code,this.input.setCustomValidity(""),this.wrapper.classList.remove("is-invalid"),this.input.dispatchEvent(new Event("change",{bubbles:!0})),this.input.dispatchEvent(new Event("input",{bubbles:!0})),this.input.dispatchEvent(new Event("country-change",{bubbles:!0})),this._toggle(!1),this.wrapper.focus()}_updateUI(e){const t=this.wrapper.querySelector(".cs-selected-content");t&&(t.innerHTML=this._parseTemplate(this.schemaReturn,e))}_toggle(e){if(0!==this.countries.length){if(this.isOpen=void 0!==e?e:!this.isOpen,this.isOpen){this._updatePosition(),document.dispatchEvent(new CustomEvent("cs-close-others",{detail:{opener:this.wrapper}})),this._renderOptions();this.wrapper.querySelector(".cs-list").style.maxHeight=this.rowLimit*this.rowHeight+"px";const e=[...this.filteredCountries.filter(e=>e.isPreferred),...this.filteredCountries.filter(e=>!e.isPreferred)];this.activeIndex=e.findIndex(e=>this.input.value.includes(e.code)||this.input.value.includes(e.phone)),this.activeIndex>-1&&setTimeout(()=>this._scrollToActive(),0),this.hasSearch&&setTimeout(()=>this.wrapper.querySelector(".cs-search-input").focus(),50)}this.wrapper.classList.toggle("open",this.isOpen)}}_bindEvents(){this.wrapper.querySelector(".cs-trigger").onclick=e=>{e.stopPropagation(),this._toggle()},this.wrapper.addEventListener("keydown",e=>{if(!this.isOpen&&"ArrowDown"===e.key)return e.preventDefault(),void this._toggle(!0);this.isOpen&&("ArrowDown"===e.key?(e.preventDefault(),this.activeIndex++,this._renderOptions(),this._scrollToActive()):"ArrowUp"===e.key?(e.preventDefault(),this.activeIndex--,this._renderOptions(),this._scrollToActive()):"Escape"===e.key&&this._toggle(!1))}),this.hasSearch&&(this.wrapper.querySelector(".cs-search-input").oninput=e=>{const t=e.target.value.toLowerCase();this.filteredCountries=this.countries.filter(e=>e.name.toLowerCase().includes(t)||e.phone.includes(t)),this.activeIndex=0,this._renderOptions()}),document.addEventListener("click",e=>{this.wrapper.contains(e.target)||this._toggle(!1)}),document.addEventListener("cs-close-others",e=>{e.detail.opener!==this.wrapper&&(this.isOpen=!1,this.wrapper.classList.remove("open"))})}_scrollToActive(){const e=this.wrapper.querySelector(".cs-list"),t=e.querySelectorAll(".cs-option")[this.activeIndex];if(t){const i=t.offsetTop-e.offsetHeight/2+this.rowHeight/2;e.scrollTop=i}}}const initCS=e=>{(e&&e.querySelectorAll?e:document).querySelectorAll(".country-select").forEach(e=>{e.nextSibling&&e.nextSibling.classList&&e.nextSibling.classList.contains("cs-wrapper")||new CountrySelect(e)})},setupListeners=()=>{initCS(document),["htmx:afterProcess","htmx:afterSettle"].forEach(e=>document.body.addEventListener(e,e=>initCS(e.detail.target||e.target))),new MutationObserver(e=>e.forEach(e=>e.addedNodes.length&&initCS(e.target))).observe(document.body,{childList:!0,subtree:!0})};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",setupListeners):setupListeners();
1
+ class CountrySelect{constructor(e,t={}){if(this.input=e,!this.input)return;if(this.input.classList.contains("checkout-trigger")||this.input.classList.add("checkout-trigger"),"1"===this.input.dataset.csInitialized)return;this.schema=this.input.dataset.schema||"{img} {name}",this.schemaReturn=this.input.dataset.schemaReturn||this.schema,this.valueType=this.input.dataset.valueType||"code",this.rowLimit=parseInt(this.input.dataset.countryRowValues)||5,this.hasSearch="false"!==this.input.dataset.countrySearch,this.dropdownWidth=this.input.dataset.dropdownWidth||"auto";const i=this.input.dataset.preferred||"";this.preferredCodes=i?i.split(",").map(e=>e.trim().toUpperCase()):[],this.config={placeholder:this.input.dataset.placeholder||"Select",...t},this.countries=[],this.filteredCountries=[],this.isOpen=!1,this.activeIndex=-1,this.rowHeight=44,this._init()}async _init(){this._applyStyles(),this._setupDOM(),this._bindEvents(),await this._loadData()}_applyStyles(){const e="cs-v57-styles";if(!document.getElementById(e)){const t=document.createElement("style");t.id=e,t.textContent="\n .cs-wrapper { position: relative; font-family: inherit; width: 100%; outline: none; }\n .cs-trigger { \n /* Bootstrap 5 Exact Specs */\n padding: 0.375rem 2.25rem 0.375rem 0.75rem; \n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.375rem;\n transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;\n display: flex; align-items: center; gap: 8px; cursor: pointer; \n min-height: calc(1.5em + 0.75rem + 2px); \n box-sizing: border-box; position: relative;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px 12px;\n }\n \n .input-group > .cs-wrapper { flex: 1 1 auto; width: 1%; }\n .cs-wrapper.is-invalid .cs-trigger { border-color: #dc3545 !important; }\n .cs-error-msg { display: none; color: #dc3545; font-size: 0.825em; margin-top: 4px; position: absolute; left: 0; top: 100%; width: 100%; z-index: 10; }\n .cs-wrapper.is-invalid .cs-error-msg { display: block; }\n\n /* Focus state Bootstrap 5 */\n .cs-wrapper:focus-within .cs-trigger {\n border-color: #86b7fe;\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n }\n\n .cs-dropdown { \n position: absolute; left: 0; right: 0; background: #fff; \n border: 1px solid rgba(0,0,0,.15); border-radius: 0.375rem;\n z-index: 2050; display: none; margin-top: 0.125rem;\n box-shadow: 0 0.5rem 1rem rgba(0,0,0,.175);\n overflow: hidden; max-width: 95vw;\n }\n \n .cs-wrapper.drop-up .cs-dropdown { \n bottom: calc(100% + 0.25rem); top: auto;\n box-shadow: 0 -0.5rem 1rem rgba(0,0,0,.175);\n }\n .cs-wrapper.open .cs-dropdown { display: block; }\n \n .cs-search-box { padding: 8px; border-bottom: 1px solid #dee2e6; background: #f8f9fa; }\n .cs-search-input { \n width: 100%; padding: 0.375rem 0.75rem; border: 1px solid #ced4da; \n border-radius: 0.25rem; outline: none; font-size: 0.875rem;\n }\n .cs-list { overflow-y: auto; scrollbar-width: thin; scroll-behavior: auto; min-height: 50px; padding: 0.375rem 0; }\n .cs-option { \n padding: 0.5rem 0.75rem; display: flex; align-items: center; gap: 10px; \n cursor: pointer; font-size: 0.9rem; transition: background 0.1s;\n }\n .cs-option:hover { background-color: #f8f9fa; }\n .cs-option.active { background-color: #0d6efd; color: #fff; }\n \n .cs-wrapper img { width: 20px !important; height: 14px !important; object-fit: cover; border-radius: 2px; flex-shrink: 0; }\n .cs-selected-content { display: flex; align-items: center; gap: 8px; overflow: hidden; white-space: nowrap; line-height: 1; }\n .cs-divider { height: 1px; background: #dee2e6; margin: 0.375rem 0; pointer-events: none; }\n .cs-hidden { display: none !important; }\n ",document.head.appendChild(t)}}_setupDOM(){Object.assign(this.input.style,{position:"absolute",opacity:"0",width:"1px",height:"1px",pointerEvents:"none"}),this.wrapper=document.createElement("div"),this.wrapper.className="cs-wrapper",this.wrapper.tabIndex=0;const e=this.input.value?"":this.config.placeholder;this.wrapper.innerHTML=`\n <div class="cs-trigger"><span class="cs-selected-content">${e}</span></div>\n <div class="cs-error-msg"></div>\n <div class="cs-dropdown">\n <div class="cs-search-box ${this.hasSearch?"":"cs-hidden"}">\n <input type="text" class="cs-search-input" placeholder="Search..." autocomplete="off" tabindex="-1">\n </div>\n <div class="cs-list"><div class="cs-loading" style="padding:15px; text-align:center;">Loading...</div></div>\n </div>\n `;this.wrapper.querySelector(".cs-dropdown").style.width="auto"===this.dropdownWidth?"100%":this.dropdownWidth,this.input.parentNode.insertBefore(this.wrapper,this.input.nextSibling)}_updatePosition(){const e=this.wrapper.getBoundingClientRect(),t=this.rowLimit*this.rowHeight+(this.hasSearch?60:0),i=window.innerHeight-e.bottom,s=e.top;i<t&&s>t?this.wrapper.classList.add("drop-up"):this.wrapper.classList.remove("drop-up")}async _loadData(){try{const e=await fetch("https://restcountries.com/v3.1/all?fields=name,flags,cca2,idd"),t=await e.json();this.countries=t.map(e=>({name:e.name.common,code:e.cca2.toUpperCase(),flag:e.flags.svg,phone:e.idd.root+(e.idd.suffixes?e.idd.suffixes.length>1?"":e.idd.suffixes[0]:""),isPreferred:this.preferredCodes.includes(e.cca2.toUpperCase())})).sort((e,t)=>e.name.localeCompare(t.name)),this.filteredCountries=[...this.countries],this._renderOptions(),this._syncInitialValue()}catch(e){console.error("CountrySelect API Fail",e)}}_syncInitialValue(){const e=this.input.value;if(!e)return void(this.wrapper.querySelector(".cs-selected-content").innerHTML=this.config.placeholder);const t=this.countries.find(t=>"phone"===this.valueType?t.phone===e:"name"===this.valueType?t.name===e:t.code===e);t&&this._updateUI(t)}_parseTemplate(e,t){return e.replace("{img}",`<img src="${t.flag}">`).replace("{name}",`<span>${t.name}</span>`).replace("{code}",`<span>${t.code}</span>`).replace("{phone}",`<span>${t.phone}</span>`)}_renderOptions(){const e=this.wrapper.querySelector(".cs-list");if(!e)return;e.innerHTML="";const t=this.wrapper.querySelector(".cs-search-input")?.value||"",i=this.filteredCountries.filter(e=>e.isPreferred),s=this.filteredCountries.filter(e=>!e.isPreferred),n=(e,t)=>{const i=document.createElement("div");return i.className="cs-option "+(t===this.activeIndex?"active":""),i.innerHTML=this._parseTemplate(this.schema,e),i.onclick=t=>{t.stopPropagation(),this._select(e)},i};if(i.forEach((t,i)=>e.appendChild(n(t,i))),i.length>0&&s.length>0&&!t){const t=document.createElement("div");t.className="cs-divider",e.appendChild(t)}s.forEach((t,s)=>e.appendChild(n(t,i.length+s)))}_select(e){this._updateUI(e),this.input.value="phone"===this.valueType?e.phone:"name"===this.valueType?e.name:e.code,this.input.setCustomValidity(""),this.wrapper.classList.remove("is-invalid"),this.input.dispatchEvent(new Event("change",{bubbles:!0})),this.input.dispatchEvent(new Event("input",{bubbles:!0})),this.input.dispatchEvent(new Event("country-change",{bubbles:!0})),this._toggle(!1),this.wrapper.focus()}_updateUI(e){const t=this.wrapper.querySelector(".cs-selected-content");t&&(t.innerHTML=this._parseTemplate(this.schemaReturn,e))}_toggle(e){if(0!==this.countries.length){if(this.isOpen=void 0!==e?e:!this.isOpen,this.isOpen){this._updatePosition(),document.dispatchEvent(new CustomEvent("cs-close-others",{detail:{opener:this.wrapper}})),this._renderOptions();this.wrapper.querySelector(".cs-list").style.maxHeight=this.rowLimit*this.rowHeight+"px";const e=[...this.filteredCountries.filter(e=>e.isPreferred),...this.filteredCountries.filter(e=>!e.isPreferred)];this.activeIndex=e.findIndex(e=>this.input.value.includes(e.code)||this.input.value.includes(e.phone)),this.activeIndex>-1&&setTimeout(()=>this._scrollToActive(),0),this.hasSearch&&setTimeout(()=>this.wrapper.querySelector(".cs-search-input").focus(),50)}this.wrapper.classList.toggle("open",this.isOpen)}}_bindEvents(){this.wrapper.querySelector(".cs-trigger").onclick=e=>{e.stopPropagation(),this._toggle()},this.wrapper.addEventListener("keydown",e=>{if(!this.isOpen&&"ArrowDown"===e.key)return e.preventDefault(),void this._toggle(!0);this.isOpen&&("ArrowDown"===e.key?(e.preventDefault(),this.activeIndex++,this._renderOptions(),this._scrollToActive()):"ArrowUp"===e.key?(e.preventDefault(),this.activeIndex--,this._renderOptions(),this._scrollToActive()):"Escape"===e.key&&this._toggle(!1))}),this.hasSearch&&(this.wrapper.querySelector(".cs-search-input").oninput=e=>{const t=e.target.value.toLowerCase();this.filteredCountries=this.countries.filter(e=>e.name.toLowerCase().includes(t)||e.phone.includes(t)),this.activeIndex=0,this._renderOptions()}),document.addEventListener("click",e=>{this.wrapper.contains(e.target)||this._toggle(!1)}),document.addEventListener("cs-close-others",e=>{e.detail.opener!==this.wrapper&&(this.isOpen=!1,this.wrapper.classList.remove("open"))})}_scrollToActive(){const e=this.wrapper.querySelector(".cs-list"),t=e.querySelectorAll(".cs-option")[this.activeIndex];if(t){const i=t.offsetTop-e.offsetHeight/2+this.rowHeight/2;e.scrollTop=i}}}const initCS=e=>{const t=e&&e.querySelectorAll?e:document;t.matches?.(".country-select")&&"1"!==t.dataset.csInitialized&&new CountrySelect(t),t.querySelectorAll?.(".country-select").forEach(e=>{"1"!==e.dataset.csInitialized&&new CountrySelect(e)})},setupListeners=()=>{initCS(document),document.body.addEventListener("htmx:afterSettle",e=>{initCS(e.detail.target||e.target)}),new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{1===e.nodeType&&initCS(e)})})}).observe(document.body,{childList:!0,subtree:!0})};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",setupListeners):setupListeners();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "country-select-pro",
3
- "version": "5.6.4",
3
+ "version": "5.6.6",
4
4
  "description": "A lightweight, zero-dependency, vanilla JavaScript country selector with localized browser validation and Bootstrap 5 integration.",
5
5
  "main": "dist/country-select.js",
6
6
  "jsdelivr": "dist/country-select.min.js",