@countriesdb/widget 0.1.23 → 0.1.24

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { CountriesDBClient } from '@countriesdb/widget-core';
5
5
  import { initializeSelect, populateCountrySelect, buildSubdivisionOptionsHTML, applyPreselectedValue, handleApiError, } from './dom-manipulation';
6
- import { dispatchUpdateEvent, isWidgetInitiatedEvent } from './event-system';
6
+ import { dispatchReadyEvent, dispatchUpdateEvent, isWidgetInitiatedEvent, } from './event-system';
7
7
  import { triggerFollowLogic, handleFollowRelatedFromSubdivision, handleFollowUpwardFromSubdivision, handleFollowUpwardFromCountry, } from './follow-logic';
8
8
  /**
9
9
  * Setup subdivision selection elements
@@ -20,7 +20,8 @@ export async function setupSubdivisionSelection(apiKey, backendUrl, state, confi
20
20
  : null;
21
21
  // Check if linked country select is multi-select (not allowed)
22
22
  if (linkedCountrySelect && linkedCountrySelect.hasAttribute('multiple')) {
23
- handleApiError(select, 'Cannot link to multi-select country. Use data-country-code instead.', true);
23
+ const defaultValue = select.dataset.defaultValue ?? '';
24
+ select.innerHTML = `<option value="${defaultValue}" disabled>Error: Cannot link to multi-select country. Use data-country-code instead.</option>`;
24
25
  continue;
25
26
  }
26
27
  // No direct link → maybe data-country-code
@@ -30,7 +31,8 @@ export async function setupSubdivisionSelection(apiKey, backendUrl, state, confi
30
31
  await updateSubdivisionSelect(select, apiKey, backendUrl, state, config, select.dataset.countryCode);
31
32
  }
32
33
  else {
33
- handleApiError(select, 'No country select present');
34
+ const defaultValue = select.dataset.defaultValue ?? '';
35
+ select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
34
36
  }
35
37
  }
36
38
  // Always dispatch an update event for user-initiated subdivision changes
@@ -76,8 +78,10 @@ export async function updateSubdivisionSelect(select, apiKey, backendUrl, state,
76
78
  // Use GeoIP only if data-preselected attribute is not set at all
77
79
  const shouldUseGeoIP = preselectedValue === undefined || preselectedValue === null;
78
80
  // Check if this subdivision select prefers official subdivisions
79
- const preferOfficial = select.hasAttribute('data-prefer-official') ||
80
- config.preferOfficialSubdivisions;
81
+ // Use data attribute if present, otherwise use config
82
+ const preferOfficial = select.hasAttribute('data-prefer-official')
83
+ ? true
84
+ : config.preferOfficialSubdivisions;
81
85
  const languageHeaders = CountriesDBClient.getLanguageHeaders(config.forcedLanguage, config.defaultLanguage);
82
86
  const subdivisionsResult = await CountriesDBClient.fetchSubdivisions({
83
87
  apiKey,
@@ -163,6 +167,10 @@ export async function updateSubdivisionSelect(select, apiKey, backendUrl, state,
163
167
  finally {
164
168
  // Mark initialization as complete
165
169
  state.isInitializing.delete(select);
170
+ dispatchReadyEvent(select, {
171
+ type: 'subdivision',
172
+ phase: isReload ? 'reload' : 'initial',
173
+ });
166
174
  // Only fire 'reload' if this is a reload, not initial load
167
175
  if (isReload && !valueSetByWidget) {
168
176
  dispatchUpdateEvent(select, {
@@ -174,7 +182,8 @@ export async function updateSubdivisionSelect(select, apiKey, backendUrl, state,
174
182
  }
175
183
  else if (!select.dataset.country ||
176
184
  !document.querySelector(`.country-selection[data-name="${select.dataset.country}"]`)) {
177
- handleApiError(select, 'No country select present');
185
+ const defaultValue = select.dataset.defaultValue ?? '';
186
+ select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
178
187
  }
179
188
  }
180
189
  /**
@@ -203,7 +212,8 @@ export async function setupCountrySelection(apiKey, backendUrl, state, config, s
203
212
  if (name && seenNames[name]) {
204
213
  select.removeAttribute('data-name');
205
214
  initializeSelect(select, '&mdash;');
206
- handleApiError(select, 'Duplicate field');
215
+ const defaultValue = select.dataset.defaultValue ?? '';
216
+ select.innerHTML += `<option value="${defaultValue}" disabled>Error: Duplicate field</option>`;
207
217
  continue;
208
218
  }
209
219
  if (name) {
@@ -304,6 +314,10 @@ export async function setupCountrySelection(apiKey, backendUrl, state, config, s
304
314
  finally {
305
315
  // Mark initialization as complete
306
316
  state.isInitializing.delete(select);
317
+ dispatchReadyEvent(select, {
318
+ type: 'country',
319
+ phase: 'initial',
320
+ });
307
321
  // If no preselected and no geoip selection happened, emit a regular update
308
322
  if (!valueSetByWidget) {
309
323
  dispatchUpdateEvent(select, { type: 'country', reason: 'regular' });
package/dist/types.d.ts CHANGED
@@ -27,6 +27,9 @@ export interface UpdateEventDetail {
27
27
  type?: 'country' | 'subdivision';
28
28
  reason?: 'regular' | 'geoip' | 'preselected' | 'reload' | 'follow';
29
29
  }
30
+ export interface ReadyEventDetail extends UpdateEventDetail {
31
+ phase: 'initial' | 'reload';
32
+ }
30
33
  export interface WidgetState {
31
34
  countriesMap: WeakMap<SelectElement, Country[]>;
32
35
  subdivisionsMap: WeakMap<SelectElement, Subdivision[]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@countriesdb/widget",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Country and state/province select widget with ISO 3166-1 and ISO 3166-2 codes. Auto-populates dropdowns with up-to-date country and subdivision data in multiple languages. Easy integration for forms, location selection, and address validation.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",