@countriesdb/widget 0.1.35 → 1.0.0

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/README.md CHANGED
@@ -40,20 +40,15 @@ For detailed documentation, visit [countriesdb.com/docs](https://countriesdb.com
40
40
  ### Script Tag (UMD)
41
41
 
42
42
  ```html
43
- <script src="https://unpkg.com/@countriesdb/widget@latest/dist/index.js"></script>
44
- <script>
45
- CountriesWidget.CountriesWidgetLoad({
46
- publicKey: 'YOUR_PUBLIC_KEY',
47
- defaultLanguage: 'en'
48
- });
49
- </script>
43
+ <!-- Widget auto-initializes when script loads -->
44
+ <script src="https://unpkg.com/@countriesdb/widget@latest/dist/index.js?public_key=YOUR_PUBLIC_KEY"></script>
50
45
 
51
46
  <!-- Add CSS classes to your select elements -->
52
- <select class="country-selection" name="country">
47
+ <select class="country-selection" data-name="country1" name="country">
53
48
  <option value="">Select Country</option>
54
49
  </select>
55
50
 
56
- <select class="subdivision-selection" name="state" data-country="country">
51
+ <select class="subdivision-selection" name="state" data-country="country1">
57
52
  <option value="">Select State/Province</option>
58
53
  </select>
59
54
  ```
@@ -62,7 +57,10 @@ For detailed documentation, visit [countriesdb.com/docs](https://countriesdb.com
62
57
 
63
58
  ```html
64
59
  <script type="module">
65
- import { CountriesWidgetLoad } from '@countriesdb/widget';
60
+ import CountriesWidgetLoad from '@countriesdb/widget';
61
+
62
+ // Or use auto-init with window.CountriesDBConfig:
63
+ // import '@countriesdb/widget';
66
64
 
67
65
  CountriesWidgetLoad({
68
66
  publicKey: 'YOUR_PUBLIC_KEY',
@@ -74,12 +72,12 @@ For detailed documentation, visit [countriesdb.com/docs](https://countriesdb.com
74
72
  ### Node.js / Bundler
75
73
 
76
74
  ```javascript
77
- import { CountriesWidgetLoad } from '@countriesdb/widget';
75
+ import CountriesWidgetLoad from '@countriesdb/widget';
78
76
 
79
77
  CountriesWidgetLoad({
80
78
  publicKey: 'YOUR_PUBLIC_KEY',
81
- defaultLanguage: 'en',
82
- enableGeolocation: true
79
+ defaultLanguage: 'en'
80
+ // GeoIP is enabled by default unless disabled via data-preselected=""
83
81
  });
84
82
  ```
85
83
 
@@ -101,6 +99,7 @@ CountriesWidgetLoad({
101
99
  - `countryNameFilter` (optional): Custom function to filter/transform country names
102
100
  - `subdivisionNameFilter` (optional): Custom function to filter/transform subdivision names
103
101
  - `autoInit` (optional): Auto-initialize on load (default: `true`)
102
+ - `reload` (optional): Force re-initialization, clearing cached state and reapplying preselected values (default: `false`)
104
103
 
105
104
  ### Data Attributes
106
105
 
@@ -134,7 +133,7 @@ document.addEventListener('countriesWidget:update', (event) => {
134
133
  // value: 'US',
135
134
  // selectedValues: ['US'],
136
135
  // name: 'country1',
137
- // country: null,
136
+ // country: null, // For subdivision selects: linked country select's data-name
138
137
  // isSubdivision: false,
139
138
  // type: 'country',
140
139
  // reason: 'regular' | 'geoip' | 'preselected' | 'reload' | 'follow'
@@ -153,7 +152,7 @@ document.addEventListener('countriesWidget:ready', (event) => {
153
152
  // value: 'US',
154
153
  // selectedValues: ['US'],
155
154
  // name: 'country1',
156
- // country: null,
155
+ // country: null, // For subdivision selects: linked country select's data-name
157
156
  // isSubdivision: false,
158
157
  // type: 'country' | 'subdivision',
159
158
  // phase: 'initial' | 'reload'
@@ -186,7 +185,19 @@ document.addEventListener('countriesWidget:ready', (event) => {
186
185
  ### Custom Name Filter
187
186
 
188
187
  ```javascript
189
- CountriesWidgetLoad({
188
+ // Using window.CountriesDBConfig (before script loads)
189
+ window.CountriesDBConfig = {
190
+ publicKey: 'YOUR_PUBLIC_KEY',
191
+ countryNameFilter: (code, name, language, item) => {
192
+ if (code === 'US') {
193
+ return 'United States of America';
194
+ }
195
+ return name;
196
+ }
197
+ };
198
+
199
+ // Or using window.CountriesWidgetLoad (after script loads)
200
+ window.CountriesWidgetLoad({
190
201
  publicKey: 'YOUR_PUBLIC_KEY',
191
202
  countryNameFilter: (code, name, language, item) => {
192
203
  if (code === 'US') {
@@ -201,7 +212,25 @@ CountriesWidgetLoad({
201
212
 
202
213
  ### `CountriesWidgetLoad(options)`
203
214
 
204
- Main initialization function. Returns a Promise that resolves when initialization is complete.
215
+ Main initialization function. Returns a Promise that resolves to `true` when initialization is complete, or `false` if initialization failed (e.g., due to conflicting parameters like `followRelated` and `followUpward`).
216
+
217
+ **Parameters:**
218
+ - `options` (object): Configuration options (see [Options](#options) above)
219
+
220
+ **Example:**
221
+ ```javascript
222
+ // Basic initialization
223
+ await CountriesWidgetLoad({
224
+ publicKey: 'YOUR_PUBLIC_KEY',
225
+ defaultLanguage: 'en'
226
+ });
227
+
228
+ // Force reload (clears cached state and reapplies preselected values)
229
+ await CountriesWidgetLoad({
230
+ publicKey: 'YOUR_PUBLIC_KEY',
231
+ reload: true
232
+ });
233
+ ```
205
234
 
206
235
  For complete API documentation, visit [countriesdb.com/docs](https://countriesdb.com/docs).
207
236
 
@@ -214,7 +243,7 @@ For complete API documentation, visit [countriesdb.com/docs](https://countriesdb
214
243
 
215
244
  ## License
216
245
 
217
- PROPRIETARY - Copyright (c) NAYEE LLC. See [LICENSE](https://github.com/countriesdb/countriesdb/blob/main/packages/npm/widget/LICENSE) for details.
246
+ PROPRIETARY - Copyright (c) NAYEE LLC.
218
247
 
219
248
  **Developed by [NAYEE LLC](https://nayee.net)**
220
249
 
package/dist/index.esm.js CHANGED
@@ -649,50 +649,36 @@ async function updateSubdivisionSelect(select, apiKey, backendUrl, state, config
649
649
  if (preselectedSubdivision) {
650
650
  const isMultiple = select.hasAttribute('multiple');
651
651
  let subdivisionToSelect = preselectedSubdivision;
652
- // Check if the preselected subdivision is disabled (parent with children when allowParentSelection is false)
652
+ // If preselected is disabled and allowParentSelection is false, find first enabled child
653
653
  if (!config.allowParentSelection && !isMultiple) {
654
- const option = Array.from(select.options).find((opt) => opt.value === preselectedSubdivision.code);
655
- // If option is disabled, find the first child subdivision
656
- if (option && option.disabled) {
657
- const tree = buildSubdivisionTree(subdivisions);
658
- // Find the node in the tree
659
- function findNodeInTree(nodes, code) {
660
- for (const node of nodes) {
661
- if (node.code === code) {
662
- return node;
654
+ const preselectedOption = Array.from(select.options).find((opt) => opt.value === preselectedSubdivision.code);
655
+ if (preselectedOption?.disabled) {
656
+ // Find direct children by parent_id
657
+ const directChildren = subdivisions.filter((sub) => sub.parent_id === preselectedSubdivision.id);
658
+ if (directChildren.length > 0) {
659
+ // Sort by name and get first child
660
+ const sorted = directChildren.sort((a, b) => {
661
+ return (a.name || '').localeCompare(b.name || '', subdivisionsLanguage, { sensitivity: 'accent' });
662
+ });
663
+ const firstChild = sorted[0];
664
+ // Check if first child is also disabled (has its own children)
665
+ const firstChildOption = Array.from(select.options).find((opt) => opt.value === firstChild.code);
666
+ if (firstChildOption?.disabled) {
667
+ // First child is disabled, find its first child (grandchild)
668
+ const grandChildren = subdivisions.filter((sub) => sub.parent_id === firstChild.id);
669
+ if (grandChildren.length > 0) {
670
+ const sortedGrandChildren = grandChildren.sort((a, b) => {
671
+ return (a.name || '').localeCompare(b.name || '', subdivisionsLanguage, { sensitivity: 'accent' });
672
+ });
673
+ subdivisionToSelect = sortedGrandChildren[0];
663
674
  }
664
- if (node.children && node.children.length > 0) {
665
- const found = findNodeInTree(node.children, code);
666
- if (found)
667
- return found;
675
+ else {
676
+ subdivisionToSelect = firstChild;
668
677
  }
669
678
  }
670
- return null;
671
- }
672
- const preselectedNode = findNodeInTree(tree, preselectedSubdivision.code);
673
- // Get the first child (recursively if needed)
674
- function getFirstChild(node) {
675
- if (!node || !node.children || node.children.length === 0) {
676
- return null;
679
+ else {
680
+ subdivisionToSelect = firstChild;
677
681
  }
678
- // Sort children to get consistent first child
679
- const sortedChildren = [...node.children].sort((a, b) => {
680
- const nameA = a.name || '';
681
- const nameB = b.name || '';
682
- return nameA.localeCompare(nameB);
683
- });
684
- const firstChild = sortedChildren[0];
685
- // If first child also has children and would be disabled, recurse
686
- if (firstChild.children && firstChild.children.length > 0) {
687
- const deeperChild = getFirstChild(firstChild);
688
- return deeperChild || firstChild;
689
- }
690
- return firstChild;
691
- }
692
- const firstChild = preselectedNode ? getFirstChild(preselectedNode) : null;
693
- if (firstChild) {
694
- // Find the subdivision object by code
695
- subdivisionToSelect = subdivisions.find((sub) => sub.code === firstChild.code) || preselectedSubdivision;
696
682
  }
697
683
  }
698
684
  }