@keenthemes/ktui 1.0.24 → 1.0.26

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.
Files changed (53) hide show
  1. package/dist/ktui.js +337 -18
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +319 -11
  5. package/examples/datatable/checkbox-events-test.html +400 -0
  6. package/examples/datatable/credentials-test.html +423 -0
  7. package/examples/datatable/remote-checkbox-test.html +365 -0
  8. package/examples/modal/persistent-test.html +205 -0
  9. package/examples/select/dark-mode-test.html +93 -0
  10. package/examples/select/dropdowncontainer-test.html +111 -0
  11. package/examples/select/dynamic-methods.html +273 -0
  12. package/examples/select/formdata-remote-test.html +161 -0
  13. package/examples/select/modal-positioning-test.html +336 -0
  14. package/examples/select/remote-data-preselected.html +283 -0
  15. package/lib/cjs/components/datatable/datatable-checkbox.js +16 -3
  16. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  17. package/lib/cjs/components/datatable/datatable.js +3 -5
  18. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  19. package/lib/cjs/components/image-input/image-input.js.map +1 -1
  20. package/lib/cjs/components/modal/modal.js +3 -1
  21. package/lib/cjs/components/modal/modal.js.map +1 -1
  22. package/lib/cjs/components/select/config.js +5 -0
  23. package/lib/cjs/components/select/config.js.map +1 -1
  24. package/lib/cjs/components/select/dropdown.js +25 -2
  25. package/lib/cjs/components/select/dropdown.js.map +1 -1
  26. package/lib/cjs/components/select/select.js +285 -7
  27. package/lib/cjs/components/select/select.js.map +1 -1
  28. package/lib/cjs/components/select/templates.js.map +1 -1
  29. package/lib/esm/components/datatable/datatable-checkbox.js +16 -3
  30. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  31. package/lib/esm/components/datatable/datatable.js +3 -5
  32. package/lib/esm/components/datatable/datatable.js.map +1 -1
  33. package/lib/esm/components/image-input/image-input.js.map +1 -1
  34. package/lib/esm/components/modal/modal.js +3 -1
  35. package/lib/esm/components/modal/modal.js.map +1 -1
  36. package/lib/esm/components/select/config.js +5 -0
  37. package/lib/esm/components/select/config.js.map +1 -1
  38. package/lib/esm/components/select/dropdown.js +25 -2
  39. package/lib/esm/components/select/dropdown.js.map +1 -1
  40. package/lib/esm/components/select/select.js +285 -7
  41. package/lib/esm/components/select/select.js.map +1 -1
  42. package/lib/esm/components/select/templates.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/components/datatable/datatable-checkbox.ts +18 -3
  45. package/src/components/datatable/datatable.ts +3 -0
  46. package/src/components/datatable/types.ts +1 -0
  47. package/src/components/image-input/image-input.ts +12 -15
  48. package/src/components/modal/modal.ts +5 -1
  49. package/src/components/select/config.ts +6 -0
  50. package/src/components/select/dropdown.ts +32 -3
  51. package/src/components/select/select.css +4 -4
  52. package/src/components/select/select.ts +350 -9
  53. package/src/components/select/templates.ts +2 -1
@@ -0,0 +1,111 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Dropdown Container Test (Issue #52)</title>
8
+ <link rel="stylesheet" href="../../dist/styles.css">
9
+ </head>
10
+
11
+ <body class="bg-gray-50 min-h-screen">
12
+ <!-- Test 1: Default Placement (Control) -->
13
+ <div class="bg-white rounded-lg shadow p-8 w-full max-w-sm mt-10 mx-auto mb-6">
14
+ <form class="flex flex-col gap-6">
15
+ <div>
16
+ <label class="block mb-2 font-medium text-gray-700">Test 1: Default (No dropdownContainer)</label>
17
+ <p class="text-sm text-gray-500 mb-3">Expected: Selected class updates correctly</p>
18
+ <select
19
+ id="test-default"
20
+ class="kt-select"
21
+ data-kt-select="true"
22
+ data-kt-select-placeholder="Select a framework...">
23
+ <option value="react">React</option>
24
+ <option value="nextjs">Next.js</option>
25
+ <option value="angular">Angular</option>
26
+ <option value="vue">Vue</option>
27
+ <option value="svelte">Svelte</option>
28
+ </select>
29
+ </div>
30
+ </form>
31
+ </div>
32
+
33
+ <!-- Test 2: dropdownContainer: "body" (Issue #52) -->
34
+ <div class="bg-white rounded-lg shadow p-8 w-full max-w-sm mx-auto mb-6">
35
+ <form class="flex flex-col gap-6">
36
+ <div>
37
+ <label class="block mb-2 font-medium text-gray-700">Test 2: dropdownContainer: "body"</label>
38
+ <p class="text-sm text-gray-500 mb-3">
39
+ Expected: Selected class updates correctly<br>
40
+ </p>
41
+ <select
42
+ id="test-body"
43
+ class="kt-select"
44
+ data-kt-select="true"
45
+ data-kt-select-placeholder="Select a language..."
46
+ data-kt-select-config='{
47
+ "dropdownContainer": "body"
48
+ }'>
49
+ <option value="javascript">JavaScript</option>
50
+ <option value="typescript">TypeScript</option>
51
+ <option value="python">Python</option>
52
+ <option value="rust">Rust</option>
53
+ <option value="go">Go</option>
54
+ </select>
55
+ </div>
56
+ </form>
57
+ </div>
58
+
59
+ <!-- Test 3: Custom Container -->
60
+ <div class="bg-white rounded-lg shadow p-8 w-full max-w-sm mx-auto mb-6">
61
+ <form class="flex flex-col gap-6">
62
+ <div>
63
+ <label class="block mb-2 font-medium text-gray-700">Test 3: dropdownContainer: "#custom-container"</label>
64
+ <p class="text-sm text-gray-500 mb-3">Expected: Selected class updates correctly</p>
65
+ <select
66
+ id="test-custom"
67
+ class="kt-select"
68
+ data-kt-select="true"
69
+ data-kt-select-placeholder="Select a database..."
70
+ data-kt-select-config='{
71
+ "dropdownContainer": "#custom-container"
72
+ }'>
73
+ <option value="postgresql">PostgreSQL</option>
74
+ <option value="mysql">MySQL</option>
75
+ <option value="mongodb">MongoDB</option>
76
+ <option value="redis">Redis</option>
77
+ <option value="sqlite">SQLite</option>
78
+ </select>
79
+ </div>
80
+ </form>
81
+ </div>
82
+
83
+ <!-- Custom container element -->
84
+ <div id="custom-container"></div>
85
+
86
+ <script src="../../dist/ktui.js"></script>
87
+ <script>
88
+ // Add console logging to help with debugging
89
+ document.addEventListener('DOMContentLoaded', function() {
90
+ // Add change listeners to log selected class status
91
+ ['test-default', 'test-body', 'test-custom'].forEach(id => {
92
+ const select = document.getElementById(id);
93
+ if (select) {
94
+ select.addEventListener('change', function() {
95
+ setTimeout(() => {
96
+ const dropdown = select.nextElementSibling?.querySelector('[data-kt-select-dropdown]');
97
+ if (dropdown) {
98
+ const options = dropdown.querySelectorAll('[data-kt-select-option]');
99
+ const selectedCount = dropdown.querySelectorAll('[data-kt-select-option].selected').length;
100
+ console.log(`${id}: Found ${options.length} options, ${selectedCount} with .selected class`);
101
+ }
102
+ }, 100);
103
+ });
104
+ }
105
+ });
106
+ });
107
+ </script>
108
+ </body>
109
+
110
+ </html>
111
+
@@ -0,0 +1,273 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>KTSelect Dynamic Methods Example</title>
7
+ <link href="../../dist/styles.css" rel="stylesheet">
8
+ <script src="../../dist/ktui.js"></script>
9
+ </head>
10
+ <body class="p-8">
11
+ <div class="max-w-4xl mx-auto space-y-8">
12
+ <div>
13
+ <h1 class="text-3xl font-bold mb-4">KTSelect Dynamic Control Methods</h1>
14
+ <p class="text-gray-600 mb-6">
15
+ This example demonstrates the four dynamic control methods:
16
+ <code class="bg-gray-100 px-2 py-1 rounded">enable()</code>,
17
+ <code class="bg-gray-100 px-2 py-1 rounded">disable()</code>,
18
+ <code class="bg-gray-100 px-2 py-1 rounded">update()</code>, and
19
+ <code class="bg-gray-100 px-2 py-1 rounded">refresh()</code>
20
+ </p>
21
+ </div>
22
+
23
+ <!-- Example 1: Enable/Disable Methods -->
24
+ <div class="border border-gray-200 rounded-lg p-6 space-y-4">
25
+ <h2 class="text-xl font-semibold">1. Enable / Disable Methods</h2>
26
+ <p class="text-sm text-gray-600">
27
+ Programmatically enable or disable the select after initialization.
28
+ </p>
29
+
30
+ <div>
31
+ <label class="block text-sm font-medium mb-2">Fruit Selection</label>
32
+ <select class="kt-select" id="select1">
33
+ <option value="">Select a fruit</option>
34
+ <option value="apple">Apple</option>
35
+ <option value="banana">Banana</option>
36
+ <option value="cherry">Cherry</option>
37
+ <option value="date">Date</option>
38
+ <option value="elderberry">Elderberry</option>
39
+ </select>
40
+ </div>
41
+
42
+ <div class="flex gap-2">
43
+ <button id="enableBtn" class="kt-btn">
44
+ Enable Select
45
+ </button>
46
+ <button id="disableBtn" class="kt-btn kt-btn-secondary">
47
+ Disable Select
48
+ </button>
49
+ </div>
50
+
51
+ <div id="enableDisableStatus" class="text-sm text-gray-600"></div>
52
+ </div>
53
+
54
+ <!-- Example 2: Update Method -->
55
+ <div class="border border-gray-200 rounded-lg p-6 space-y-4">
56
+ <h2 class="text-xl font-semibold">2. Update Method</h2>
57
+ <p class="text-sm text-gray-600">
58
+ Sync the dropdown when native select options are modified programmatically.
59
+ </p>
60
+
61
+ <div>
62
+ <label class="block text-sm font-medium mb-2">Programming Languages</label>
63
+ <select class="kt-select" id="select2">
64
+ <option value="">Select a language</option>
65
+ <option value="javascript">JavaScript</option>
66
+ <option value="python">Python</option>
67
+ <option value="java">Java</option>
68
+ </select>
69
+ </div>
70
+
71
+ <div class="flex gap-2">
72
+ <button id="addOptionBtn" class="kt-btn">
73
+ Add Option
74
+ </button>
75
+ <button id="removeOptionBtn" class="kt-btn kt-btn-destructive">
76
+ Remove Last Option
77
+ </button>
78
+ <button id="replaceOptionsBtn" class="kt-btn kt-btn-outline">
79
+ Replace All Options
80
+ </button>
81
+ </div>
82
+
83
+ <div id="updateStatus" class="text-sm text-gray-600"></div>
84
+ </div>
85
+
86
+ <!-- Example 3: Refresh Method -->
87
+ <div class="border border-gray-200 rounded-lg p-6 space-y-4">
88
+ <h2 class="text-xl font-semibold">3. Refresh Method</h2>
89
+ <p class="text-sm text-gray-600">
90
+ Refresh the visual display after programmatic selection changes.
91
+ </p>
92
+
93
+ <div>
94
+ <label class="block text-sm font-medium mb-2">Countries (Multiple)</label>
95
+ <select class="kt-select" id="select3" multiple>
96
+ <option value="us">United States</option>
97
+ <option value="uk">United Kingdom</option>
98
+ <option value="ca">Canada</option>
99
+ <option value="au">Australia</option>
100
+ <option value="de">Germany</option>
101
+ </select>
102
+ </div>
103
+
104
+ <div class="flex gap-2">
105
+ <button id="selectRandomBtn" class="kt-btn">
106
+ Select Random Options
107
+ </button>
108
+ <button id="clearSelectionBtn" class="kt-btn kt-btn-secondary">
109
+ Clear Selection
110
+ </button>
111
+ <button id="refreshBtn" class="kt-btn kt-btn-outline">
112
+ Refresh Display
113
+ </button>
114
+ </div>
115
+
116
+ <div id="refreshStatus" class="text-sm text-gray-600"></div>
117
+ </div>
118
+
119
+ <!-- Example 4: Event Listeners -->
120
+ <div class="border border-gray-200 rounded-lg p-6 space-y-4">
121
+ <h2 class="text-xl font-semibold">4. Event Listeners</h2>
122
+ <p class="text-sm text-gray-600">
123
+ All dynamic methods dispatch custom events that you can listen to.
124
+ </p>
125
+
126
+ <div class="bg-gray-50 p-4 rounded">
127
+ <h3 class="font-medium mb-2">Event Log:</h3>
128
+ <div id="eventLog" class="text-sm font-mono space-y-1 max-h-48 overflow-y-auto"></div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+
133
+ <script>
134
+ // Initialize all selects
135
+ const select1 = new KTSelect(document.getElementById('select1'));
136
+ const select2 = new KTSelect(document.getElementById('select2'));
137
+ const select3 = new KTSelect(document.getElementById('select3'), {
138
+ multiple: true,
139
+ enableSelectAll: true
140
+ });
141
+
142
+ // Helper to log events
143
+ const eventLog = document.getElementById('eventLog');
144
+ function logEvent(selectId, eventType) {
145
+ const timestamp = new Date().toLocaleTimeString();
146
+ const entry = document.createElement('div');
147
+ entry.className = 'text-gray-700';
148
+ entry.textContent = `[${timestamp}] ${selectId}: ${eventType}`;
149
+ eventLog.prepend(entry);
150
+
151
+ // Keep only last 10 events
152
+ while (eventLog.children.length > 10) {
153
+ eventLog.removeChild(eventLog.lastChild);
154
+ }
155
+ }
156
+
157
+ // Example 1: Enable/Disable Methods
158
+ const enableDisableStatus = document.getElementById('enableDisableStatus');
159
+
160
+ document.getElementById('enableBtn').addEventListener('click', () => {
161
+ select1.enable();
162
+ enableDisableStatus.textContent = '✅ Select enabled';
163
+ });
164
+
165
+ document.getElementById('disableBtn').addEventListener('click', () => {
166
+ select1.disable();
167
+ enableDisableStatus.textContent = '🚫 Select disabled';
168
+ });
169
+
170
+ // Listen to enabled/disabled events
171
+ document.getElementById('select1').addEventListener('enabled', () => {
172
+ logEvent('select1', 'enabled');
173
+ });
174
+
175
+ document.getElementById('select1').addEventListener('disabled', () => {
176
+ logEvent('select1', 'disabled');
177
+ });
178
+
179
+ // Example 2: Update Method
180
+ const updateStatus = document.getElementById('updateStatus');
181
+ let optionCounter = 1;
182
+
183
+ document.getElementById('addOptionBtn').addEventListener('click', () => {
184
+ const nativeSelect = document.getElementById('select2');
185
+ const newOption = document.createElement('option');
186
+ newOption.value = `lang${optionCounter}`;
187
+ newOption.textContent = `New Language ${optionCounter}`;
188
+ nativeSelect.appendChild(newOption);
189
+
190
+ // Call update to sync the dropdown
191
+ select2.update();
192
+
193
+ updateStatus.textContent = `✅ Added "New Language ${optionCounter}" - dropdown synced`;
194
+ optionCounter++;
195
+ });
196
+
197
+ document.getElementById('removeOptionBtn').addEventListener('click', () => {
198
+ const nativeSelect = document.getElementById('select2');
199
+ const options = nativeSelect.querySelectorAll('option:not([value=""])');
200
+
201
+ if (options.length > 0) {
202
+ options[options.length - 1].remove();
203
+ select2.update();
204
+ updateStatus.textContent = '✅ Removed last option - dropdown synced';
205
+ } else {
206
+ updateStatus.textContent = '⚠️ No options to remove';
207
+ }
208
+ });
209
+
210
+ document.getElementById('replaceOptionsBtn').addEventListener('click', () => {
211
+ // Use update() with newOptions parameter
212
+ select2.update([
213
+ { value: 'rust', text: 'Rust' },
214
+ { value: 'go', text: 'Go' },
215
+ { value: 'typescript', text: 'TypeScript' },
216
+ { value: 'kotlin', text: 'Kotlin' }
217
+ ]);
218
+
219
+ updateStatus.textContent = '✅ Replaced all options with new set';
220
+ });
221
+
222
+ // Listen to updated event
223
+ document.getElementById('select2').addEventListener('updated', () => {
224
+ logEvent('select2', 'updated');
225
+ });
226
+
227
+ // Example 3: Refresh Method
228
+ const refreshStatus = document.getElementById('refreshStatus');
229
+
230
+ document.getElementById('selectRandomBtn').addEventListener('click', () => {
231
+ const nativeSelect = document.getElementById('select3');
232
+ const options = Array.from(nativeSelect.options);
233
+
234
+ // Randomly select 2-3 options
235
+ const numToSelect = Math.floor(Math.random() * 2) + 2;
236
+ const shuffled = options.sort(() => 0.5 - Math.random());
237
+
238
+ // Clear all selections first
239
+ options.forEach(opt => opt.selected = false);
240
+
241
+ // Select random options
242
+ shuffled.slice(0, numToSelect).forEach(opt => opt.selected = true);
243
+
244
+ // Refresh to update the display
245
+ select3.refresh();
246
+
247
+ refreshStatus.textContent = `✅ Selected ${numToSelect} random options - display refreshed`;
248
+ });
249
+
250
+ document.getElementById('clearSelectionBtn').addEventListener('click', () => {
251
+ const nativeSelect = document.getElementById('select3');
252
+ Array.from(nativeSelect.options).forEach(opt => opt.selected = false);
253
+
254
+ select3.refresh();
255
+ refreshStatus.textContent = '✅ Cleared all selections - display refreshed';
256
+ });
257
+
258
+ document.getElementById('refreshBtn').addEventListener('click', () => {
259
+ select3.refresh();
260
+ refreshStatus.textContent = '✅ Display refreshed';
261
+ });
262
+
263
+ // Listen to refreshed event
264
+ document.getElementById('select3').addEventListener('refreshed', () => {
265
+ logEvent('select3', 'refreshed');
266
+ });
267
+
268
+ // Initial log message
269
+ logEvent('page', 'Examples initialized');
270
+ </script>
271
+ </body>
272
+ </html>
273
+
@@ -0,0 +1,161 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Remote Select FormData Test</title>
7
+ <link rel="stylesheet" href="../../dist/styles.css" />
8
+ </head>
9
+
10
+ <body class="bg-gray-50 min-h-screen">
11
+ <div class="bg-white rounded-lg shadow p-8 w-full max-w-2xl mt-10 mx-auto">
12
+ <h1 class="text-xl font-semibold text-gray-900 mb-2">
13
+ Remote Select FormData Test
14
+ </h1>
15
+ <p class="text-sm text-gray-600 mb-6">
16
+ Verifies that remote KTSelect fields are included in FormData.
17
+ </p>
18
+
19
+ <form id="testForm" class="flex flex-col gap-6">
20
+ <div>
21
+ <label class="block mb-2 font-medium text-gray-700">
22
+ Regular Input (Control)
23
+ </label>
24
+ <input
25
+ type="text"
26
+ name="regularField"
27
+ value="test value"
28
+ class="w-full px-3 py-2 border border-gray-300 rounded"
29
+ placeholder="Regular input field" />
30
+ </div>
31
+
32
+ <div>
33
+ <label class="block mb-2 font-medium text-gray-700">
34
+ Local KTSelect (Control)
35
+ </label>
36
+ <select
37
+ name="localSelect"
38
+ data-kt-select="true"
39
+ class="kt-select">
40
+ <option value="">Select an option...</option>
41
+ <option value="option1">Option 1</option>
42
+ <option value="option2" selected>Option 2</option>
43
+ <option value="option3">Option 3</option>
44
+ </select>
45
+ </div>
46
+
47
+ <div>
48
+ <label class="block mb-2 font-medium text-gray-700">
49
+ Remote KTSelect (Test Subject)
50
+ </label>
51
+ <select
52
+ name="remoteSelect"
53
+ data-kt-select="true"
54
+ data-kt-select-remote="true"
55
+ data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
56
+ data-kt-select-data-value-field="id"
57
+ data-kt-select-data-field-text="name"
58
+ data-kt-select-placeholder="Select a user..."
59
+ class="kt-select">
60
+ <option value="">Select a user...</option>
61
+ </select>
62
+ </div>
63
+
64
+ <div class="flex gap-3">
65
+ <button
66
+ type="submit"
67
+ class="px-4 py-2 bg-gray-900 text-white text-sm font-medium rounded hover:bg-gray-800">
68
+ Test FormData
69
+ </button>
70
+ <button
71
+ type="button"
72
+ id="checkNativeValue"
73
+ class="px-4 py-2 bg-white border border-gray-300 text-gray-700 text-sm font-medium rounded hover:bg-gray-50">
74
+ Check Native Value
75
+ </button>
76
+ </div>
77
+ </form>
78
+
79
+ <div id="results" class="mt-6 space-y-3 text-sm"></div>
80
+
81
+ <div class="mt-6 p-4 bg-gray-50 border border-gray-200 rounded text-sm">
82
+ <div class="font-medium text-gray-900 mb-2">Test Steps:</div>
83
+ <ol class="list-decimal list-inside space-y-1 text-gray-700">
84
+ <li>Wait for remote data to load</li>
85
+ <li>Select a user from the remote dropdown</li>
86
+ <li>Click "Test FormData"</li>
87
+ <li>Verify remoteSelect field is included</li>
88
+ </ol>
89
+ </div>
90
+ </div>
91
+
92
+ <script src="../../dist/ktui.js"></script>
93
+ <script>
94
+ document.addEventListener('DOMContentLoaded', function () {
95
+ // Initialize KTSelect components
96
+ if (typeof KTSelect !== 'undefined') {
97
+ KTSelect.init();
98
+ }
99
+
100
+ const form = document.getElementById('testForm');
101
+ const resultsDiv = document.getElementById('results');
102
+ const remoteSelectEl = document.querySelector(
103
+ 'select[name="remoteSelect"]',
104
+ );
105
+ const checkNativeBtn = document.getElementById('checkNativeValue');
106
+
107
+ checkNativeBtn.addEventListener('click', function () {
108
+ resultsDiv.innerHTML = '';
109
+ const div = document.createElement('div');
110
+ div.className = 'p-3 bg-white border border-gray-200 rounded';
111
+
112
+ const nativeValue = remoteSelectEl.value;
113
+ const selectedOption = remoteSelectEl.querySelector(
114
+ 'option[selected]',
115
+ );
116
+
117
+ div.innerHTML = `
118
+ <div class="font-medium text-gray-900 mb-2">Native Select State</div>
119
+ <div class="space-y-1 text-gray-700">
120
+ <div>Value: <code class="bg-gray-100 px-1 rounded text-xs">"${nativeValue}"</code></div>
121
+ <div>Selected Option: ${selectedOption ? `"${selectedOption.value}"` : 'None'}</div>
122
+ </div>
123
+ `;
124
+ resultsDiv.appendChild(div);
125
+ });
126
+
127
+ form.addEventListener('submit', function (e) {
128
+ e.preventDefault();
129
+ resultsDiv.innerHTML = '';
130
+
131
+ const formData = new FormData(form);
132
+ const entries = Array.from(formData.entries());
133
+
134
+ const resultDiv = document.createElement('div');
135
+ resultDiv.className = 'p-3 bg-white border border-gray-200 rounded';
136
+ resultDiv.innerHTML = `
137
+ <div class="font-medium text-gray-900 mb-2">FormData Entries (${entries.length})</div>
138
+ <ul class="space-y-1">
139
+ ${entries.map(([key, value]) => `<li class="text-xs font-mono text-gray-700"><span class="font-medium">${key}:</span> "${value}"</li>`).join('')}
140
+ </ul>
141
+ `;
142
+ resultsDiv.appendChild(resultDiv);
143
+
144
+ const remoteSelectValue = formData.get('remoteSelect');
145
+ const verdict = document.createElement('div');
146
+ verdict.className = `p-3 mt-3 rounded border ${
147
+ remoteSelectValue
148
+ ? 'bg-white border-gray-900'
149
+ : 'bg-gray-100 border-gray-400'
150
+ }`;
151
+ verdict.innerHTML = `
152
+ <div class="font-medium ${remoteSelectValue ? 'text-gray-900' : 'text-gray-700'}">
153
+ ${remoteSelectValue ? 'PASS' : 'FAIL'}: Remote Select Field
154
+ </div>
155
+ `;
156
+ resultsDiv.appendChild(verdict);
157
+ });
158
+ });
159
+ </script>
160
+ </body>
161
+ </html>