@countriesdb/widget 0.1.19 → 0.1.21

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.
package/dist/index.js CHANGED
@@ -389,12 +389,19 @@
389
389
  /**
390
390
  * Handle API error by showing error message in select
391
391
  */
392
- function handleApiError(select, errorMessage) {
392
+ function handleApiError(select, errorMessage, replace = false) {
393
393
  const message = errorMessage instanceof Error ? errorMessage.message : errorMessage;
394
394
  const defaultValue = select.dataset.defaultValue ?? '';
395
395
  // Add "Error: " prefix to match old widget behavior and test expectations
396
396
  const formattedMessage = message.startsWith('Error: ') ? message : `Error: ${message}`;
397
- select.innerHTML += `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
397
+ if (replace) {
398
+ select.innerHTML = `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
399
+ }
400
+ else {
401
+ select.innerHTML += `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
402
+ }
403
+ // Ensure select is enabled so users can see the error
404
+ select.disabled = false;
398
405
  }
399
406
 
400
407
  /**
@@ -704,8 +711,7 @@
704
711
  : null;
705
712
  // Check if linked country select is multi-select (not allowed)
706
713
  if (linkedCountrySelect && linkedCountrySelect.hasAttribute('multiple')) {
707
- const defaultValue = select.dataset.defaultValue ?? '';
708
- select.innerHTML = `<option value="${defaultValue}" disabled>Error: Cannot link to multi-select country. Use data-country-code instead.</option>`;
714
+ handleApiError(select, 'Cannot link to multi-select country. Use data-country-code instead.', true);
709
715
  continue;
710
716
  }
711
717
  // No direct link → maybe data-country-code
@@ -715,8 +721,7 @@
715
721
  await updateSubdivisionSelect(select, apiKey, backendUrl, state, config, select.dataset.countryCode);
716
722
  }
717
723
  else {
718
- const defaultValue = select.dataset.defaultValue ?? '';
719
- select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
724
+ handleApiError(select, 'No country select present');
720
725
  }
721
726
  }
722
727
  // Always dispatch an update event for user-initiated subdivision changes
@@ -762,7 +767,8 @@
762
767
  // Use GeoIP only if data-preselected attribute is not set at all
763
768
  const shouldUseGeoIP = preselectedValue === undefined || preselectedValue === null;
764
769
  // Check if this subdivision select prefers official subdivisions
765
- const preferOfficial = select.hasAttribute('data-prefer-official');
770
+ const preferOfficial = select.hasAttribute('data-prefer-official') ||
771
+ config.preferOfficialSubdivisions;
766
772
  const languageHeaders = CountriesDBClient.getLanguageHeaders(config.forcedLanguage, config.defaultLanguage);
767
773
  const subdivisionsResult = await CountriesDBClient.fetchSubdivisions({
768
774
  apiKey,
@@ -859,8 +865,7 @@
859
865
  }
860
866
  else if (!select.dataset.country ||
861
867
  !document.querySelector(`.country-selection[data-name="${select.dataset.country}"]`)) {
862
- const defaultValue = select.dataset.defaultValue ?? '';
863
- select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
868
+ handleApiError(select, 'No country select present');
864
869
  }
865
870
  }
866
871
  /**
@@ -889,8 +894,7 @@
889
894
  if (name && seenNames[name]) {
890
895
  select.removeAttribute('data-name');
891
896
  initializeSelect(select, '&mdash;');
892
- const defaultValue = select.dataset.defaultValue ?? '';
893
- select.innerHTML += `<option value="${defaultValue}" disabled>Error: Duplicate field</option>`;
897
+ handleApiError(select, 'Duplicate field');
894
898
  continue;
895
899
  }
896
900
  if (name) {
@@ -1054,6 +1058,7 @@
1054
1058
  followUpward: config.followUpward || false,
1055
1059
  showSubdivisionType: config.showSubdivisionType !== false,
1056
1060
  allowParentSelection: config.allowParentSelection || false,
1061
+ preferOfficialSubdivisions: config.preferOfficialSubdivisions || false,
1057
1062
  subdivisionRomanizationPreference: config.subdivisionRomanizationPreference,
1058
1063
  preferLocalVariant: config.preferLocalVariant || false,
1059
1064
  subdivisionNameFilter: config.subdivisionNameFilter,
@@ -1063,6 +1068,7 @@
1063
1068
  followUpward: config.followUpward || false,
1064
1069
  showSubdivisionType: config.showSubdivisionType !== false,
1065
1070
  allowParentSelection: config.allowParentSelection || false,
1071
+ preferOfficialSubdivisions: config.preferOfficialSubdivisions || false,
1066
1072
  subdivisionRomanizationPreference: config.subdivisionRomanizationPreference,
1067
1073
  preferLocalVariant: config.preferLocalVariant || false,
1068
1074
  forcedLanguage: config.forcedLanguage,
@@ -1095,6 +1101,10 @@
1095
1101
  * Get configuration from options or script URL parameters
1096
1102
  */
1097
1103
  function getConfigFromOptionsOrScript(options) {
1104
+ // Check for global config first (for bundled widgets that need config before auto-init)
1105
+ const globalConfig = typeof window !== 'undefined' && window.CountriesDBConfig
1106
+ ? window.CountriesDBConfig
1107
+ : null;
1098
1108
  // Try to get config from script URL (for backward compatibility with widget.blade.php)
1099
1109
  let scriptUrl = null;
1100
1110
  try {
@@ -1123,36 +1133,57 @@
1123
1133
  // Ignore errors
1124
1134
  }
1125
1135
  const config = {
1126
- publicKey: options.publicKey || scriptUrl?.searchParams.get('public_key') || '',
1127
- backendUrl: options.backendUrl ?? scriptUrl?.searchParams.get('backend_url') ?? getBackendUrlFromScript(),
1128
- defaultLanguage: options.defaultLanguage || scriptUrl?.searchParams.get('default_language') || undefined,
1129
- forcedLanguage: options.forcedLanguage || scriptUrl?.searchParams.get('forced_language') || undefined,
1136
+ // Priority: options > globalConfig > scriptUrl params > defaults
1137
+ publicKey: options.publicKey ?? globalConfig?.publicKey ?? scriptUrl?.searchParams.get('public_key') ?? '',
1138
+ backendUrl: options.backendUrl ?? globalConfig?.backendUrl ?? scriptUrl?.searchParams.get('backend_url') ?? getBackendUrlFromScript(),
1139
+ defaultLanguage: options.defaultLanguage ?? globalConfig?.defaultLanguage ?? scriptUrl?.searchParams.get('default_language') ?? undefined,
1140
+ forcedLanguage: options.forcedLanguage ?? globalConfig?.forcedLanguage ?? scriptUrl?.searchParams.get('forced_language') ?? undefined,
1130
1141
  showSubdivisionType: options.showSubdivisionType !== undefined
1131
1142
  ? options.showSubdivisionType
1132
- : parseBoolean(scriptUrl?.searchParams.get('show_subdivision_type') ?? '1'),
1143
+ : globalConfig?.showSubdivisionType !== undefined
1144
+ ? globalConfig.showSubdivisionType
1145
+ : parseBoolean(scriptUrl?.searchParams.get('show_subdivision_type') ?? '1'),
1133
1146
  followRelated: options.followRelated !== undefined
1134
1147
  ? options.followRelated
1135
- : parseBoolean(scriptUrl?.searchParams.get('follow_related') ?? 'false'),
1148
+ : globalConfig?.followRelated !== undefined
1149
+ ? globalConfig.followRelated
1150
+ : parseBoolean(scriptUrl?.searchParams.get('follow_related') ?? 'false'),
1136
1151
  followUpward: options.followUpward !== undefined
1137
1152
  ? options.followUpward
1138
- : parseBoolean(scriptUrl?.searchParams.get('follow_upward') ?? 'false'),
1153
+ : globalConfig?.followUpward !== undefined
1154
+ ? globalConfig.followUpward
1155
+ : parseBoolean(scriptUrl?.searchParams.get('follow_upward') ?? 'false'),
1139
1156
  allowParentSelection: options.allowParentSelection !== undefined
1140
1157
  ? options.allowParentSelection
1141
- : parseBoolean(scriptUrl?.searchParams.get('allow_parent_selection') ?? 'false'),
1158
+ : globalConfig?.allowParentSelection !== undefined
1159
+ ? globalConfig.allowParentSelection
1160
+ : parseBoolean(scriptUrl?.searchParams.get('allow_parent_selection') ?? 'false'),
1142
1161
  isoCountryNames: options.isoCountryNames !== undefined
1143
1162
  ? options.isoCountryNames
1144
- : parseBoolean(scriptUrl?.searchParams.get('iso_country_names') ?? 'false'),
1163
+ : globalConfig?.isoCountryNames !== undefined
1164
+ ? globalConfig.isoCountryNames
1165
+ : parseBoolean(scriptUrl?.searchParams.get('iso_country_names') ?? 'false'),
1166
+ preferOfficialSubdivisions: options.preferOfficialSubdivisions !== undefined
1167
+ ? options.preferOfficialSubdivisions
1168
+ : globalConfig?.preferOfficialSubdivisions !== undefined
1169
+ ? globalConfig.preferOfficialSubdivisions
1170
+ : parseBoolean(scriptUrl?.searchParams.get('prefer_official') ?? 'false'),
1145
1171
  subdivisionRomanizationPreference: options.subdivisionRomanizationPreference ||
1172
+ globalConfig?.subdivisionRomanizationPreference ||
1146
1173
  scriptUrl?.searchParams.get('subdivision_romanization_preference') ||
1147
1174
  undefined,
1148
1175
  preferLocalVariant: options.preferLocalVariant !== undefined
1149
1176
  ? options.preferLocalVariant
1150
- : parseBoolean(scriptUrl?.searchParams.get('prefer_local_variant') ?? 'false'),
1151
- countryNameFilter: options.countryNameFilter,
1152
- subdivisionNameFilter: options.subdivisionNameFilter,
1177
+ : globalConfig?.preferLocalVariant !== undefined
1178
+ ? globalConfig.preferLocalVariant
1179
+ : parseBoolean(scriptUrl?.searchParams.get('prefer_local_variant') ?? 'false'),
1180
+ countryNameFilter: options.countryNameFilter ?? globalConfig?.countryNameFilter,
1181
+ subdivisionNameFilter: options.subdivisionNameFilter ?? globalConfig?.subdivisionNameFilter,
1153
1182
  autoInit: options.autoInit !== undefined
1154
1183
  ? options.autoInit
1155
- : parseBoolean(scriptUrl?.searchParams.get('auto_init') ?? 'true'),
1184
+ : globalConfig?.autoInit !== undefined
1185
+ ? globalConfig.autoInit
1186
+ : parseBoolean(scriptUrl?.searchParams.get('auto_init') ?? 'true'),
1156
1187
  };
1157
1188
  // Resolve filter functions from global scope if specified by name
1158
1189
  if (scriptUrl) {
@@ -1252,14 +1283,14 @@
1252
1283
  * Show error when both follow_related and follow_upward are enabled
1253
1284
  */
1254
1285
  function showParamConflictError() {
1255
- const errorMessage = 'Error: Cannot enable both follow_related and follow_upward';
1286
+ const errorMessage = 'Cannot enable both follow_related and follow_upward';
1256
1287
  const countrySelects = Array.from(document.querySelectorAll('.country-selection'));
1257
1288
  for (const select of countrySelects) {
1258
- select.innerHTML = `<option value="${select.dataset.defaultValue ?? ''}" disabled>${errorMessage}</option>`;
1289
+ handleApiError(select, errorMessage, true);
1259
1290
  }
1260
1291
  const subdivisionSelects = Array.from(document.querySelectorAll('.subdivision-selection'));
1261
1292
  for (const select of subdivisionSelects) {
1262
- select.innerHTML = `<option value="${select.dataset.defaultValue ?? ''}" disabled>${errorMessage}</option>`;
1293
+ handleApiError(select, errorMessage, true);
1263
1294
  }
1264
1295
  }
1265
1296
  // Expose public loader