@keenthemes/ktui 1.0.20 → 1.0.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/ktui.js +418 -144
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +139 -31
- package/examples/image-input/file-upload-example.html +189 -0
- package/examples/select/remote-data_.html +5 -0
- package/examples/select/test-optimizations.html +227 -0
- package/examples/select/test-remote-search.html +151 -0
- package/examples/sticky/README.md +158 -0
- package/examples/sticky/debug-sticky.html +144 -0
- package/examples/sticky/test-runner.html +175 -0
- package/examples/sticky/test-sticky-logic.js +369 -0
- package/examples/sticky/test-sticky-positioning.html +386 -0
- package/examples/toast/example.html +52 -0
- package/lib/cjs/components/component.js +5 -3
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable-sort.js +4 -0
- package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +9 -3
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/image-input/image-input.js +10 -2
- package/lib/cjs/components/image-input/image-input.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +50 -20
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +4 -2
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/index.js.map +1 -1
- package/lib/cjs/components/select/option.js +2 -1
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/remote.js +50 -50
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.js +7 -5
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +199 -33
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +3 -1
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/utils.js +23 -10
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/components/sticky/sticky.js +52 -14
- package/lib/cjs/components/sticky/sticky.js.map +1 -1
- package/lib/esm/components/component.js +5 -3
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable-sort.js +4 -0
- package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +9 -3
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/image-input/image-input.js +10 -2
- package/lib/esm/components/image-input/image-input.js.map +1 -1
- package/lib/esm/components/select/combobox.js +50 -20
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +4 -2
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/index.js +1 -1
- package/lib/esm/components/select/index.js.map +1 -1
- package/lib/esm/components/select/option.js +2 -1
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/remote.js +50 -50
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.js +8 -6
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +199 -33
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +3 -1
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/utils.js +23 -10
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/components/sticky/sticky.js +52 -14
- package/lib/esm/components/sticky/sticky.js.map +1 -1
- package/package.json +1 -1
- package/src/components/component.ts +12 -11
- package/src/components/datatable/datatable-sort.ts +6 -0
- package/src/components/datatable/datatable.ts +90 -81
- package/src/components/image-input/image-input.ts +11 -2
- package/src/components/image-input/types.ts +1 -0
- package/src/components/input/input-group.css +1 -1
- package/src/components/input/input.css +1 -1
- package/src/components/scrollable/scrollable.css +3 -3
- package/src/components/select/combobox.ts +84 -34
- package/src/components/select/dropdown.ts +20 -11
- package/src/components/select/index.ts +6 -1
- package/src/components/select/option.ts +7 -6
- package/src/components/select/remote.ts +51 -52
- package/src/components/select/search.ts +51 -45
- package/src/components/select/select.css +12 -11
- package/src/components/select/select.ts +371 -102
- package/src/components/select/tags.ts +9 -3
- package/src/components/select/templates.ts +1 -4
- package/src/components/select/utils.ts +55 -20
- package/src/components/select/variants.css +0 -1
- package/src/components/sticky/sticky.ts +47 -16
- package/src/components/sticky/types.ts +3 -0
- package/src/components/table/table.css +1 -1
- package/src/components/textarea/textarea.css +1 -1
- package/src/components/toast/toast.css +84 -47
- package/src/components/toast/types.ts +3 -0
|
@@ -0,0 +1,227 @@
|
|
|
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>Test Optimizations</title>
|
|
7
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
8
|
+
<style>
|
|
9
|
+
.test-container {
|
|
10
|
+
max-width: 800px;
|
|
11
|
+
margin: 20px auto;
|
|
12
|
+
padding: 20px;
|
|
13
|
+
}
|
|
14
|
+
.test-section {
|
|
15
|
+
margin-bottom: 20px;
|
|
16
|
+
padding: 15px;
|
|
17
|
+
border: 1px solid #e5e7eb;
|
|
18
|
+
border-radius: 8px;
|
|
19
|
+
background: white;
|
|
20
|
+
}
|
|
21
|
+
.metrics {
|
|
22
|
+
background: #f9fafb;
|
|
23
|
+
padding: 10px;
|
|
24
|
+
border-radius: 4px;
|
|
25
|
+
font-family: monospace;
|
|
26
|
+
font-size: 12px;
|
|
27
|
+
margin-top: 10px;
|
|
28
|
+
}
|
|
29
|
+
.success { color: #059669; }
|
|
30
|
+
.warning { color: #d97706; }
|
|
31
|
+
.error { color: #dc2626; }
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body class="bg-gray-50 min-h-screen">
|
|
35
|
+
<div class="test-container">
|
|
36
|
+
<h1>Remote Select Optimizations Test</h1>
|
|
37
|
+
|
|
38
|
+
<div class="test-section">
|
|
39
|
+
<h3>Performance Test: Multiple Remote Selects</h3>
|
|
40
|
+
<button onclick="testPerformance()" style="padding: 8px 16px; background: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
41
|
+
Test Performance (Create 10 Remote Selects)
|
|
42
|
+
</button>
|
|
43
|
+
<div id="performance-results" class="metrics">Click button to test...</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="test-section">
|
|
47
|
+
<h3>Functionality Test: Basic Remote Select</h3>
|
|
48
|
+
<label class="block mb-2 font-medium text-gray-700">Users from JSONPlaceholder</label>
|
|
49
|
+
<select
|
|
50
|
+
id="test-select"
|
|
51
|
+
data-kt-select
|
|
52
|
+
data-kt-select-remote="true"
|
|
53
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
54
|
+
data-kt-select-data-field-value="id"
|
|
55
|
+
data-kt-select-data-field-text="name"
|
|
56
|
+
data-kt-select-enable-search="true"
|
|
57
|
+
data-kt-select-debug="true"
|
|
58
|
+
placeholder="Select a user..."
|
|
59
|
+
></select>
|
|
60
|
+
<div id="functionality-results" class="metrics">Initializing...</div>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="test-section">
|
|
64
|
+
<h3>Search Test: Remote Search Functionality</h3>
|
|
65
|
+
<label class="block mb-2 font-medium text-gray-700">Posts from JSONPlaceholder</label>
|
|
66
|
+
<select
|
|
67
|
+
id="search-test-select"
|
|
68
|
+
data-kt-select
|
|
69
|
+
data-kt-select-remote="true"
|
|
70
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/posts"
|
|
71
|
+
data-kt-select-data-field-value="id"
|
|
72
|
+
data-kt-select-data-field-text="title"
|
|
73
|
+
data-kt-select-enable-search="true"
|
|
74
|
+
data-kt-select-search-param="q"
|
|
75
|
+
data-kt-select-search-min-length="2"
|
|
76
|
+
data-kt-select-debug="true"
|
|
77
|
+
placeholder="Search posts..."
|
|
78
|
+
></select>
|
|
79
|
+
<div id="search-results" class="metrics">Ready for search testing...</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<script src="../../dist/ktui.js"></script>
|
|
84
|
+
<script>
|
|
85
|
+
// Performance test function
|
|
86
|
+
function testPerformance() {
|
|
87
|
+
const resultsDiv = document.getElementById('performance-results');
|
|
88
|
+
resultsDiv.innerHTML = 'Running performance test...';
|
|
89
|
+
|
|
90
|
+
const startTime = performance.now();
|
|
91
|
+
const instances = [];
|
|
92
|
+
|
|
93
|
+
// Create 10 remote select instances
|
|
94
|
+
for (let i = 0; i < 10; i++) {
|
|
95
|
+
const element = document.createElement('select');
|
|
96
|
+
element.setAttribute('data-kt-select', '');
|
|
97
|
+
element.setAttribute('data-kt-select-remote', 'true');
|
|
98
|
+
element.setAttribute('data-kt-select-data-url', 'https://jsonplaceholder.typicode.com/users');
|
|
99
|
+
element.setAttribute('data-kt-select-data-field-value', 'id');
|
|
100
|
+
element.setAttribute('data-kt-select-data-field-text', 'name');
|
|
101
|
+
element.setAttribute('data-kt-select-debug', 'false'); // Disable debug for performance
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const instance = new KTSelect(element);
|
|
105
|
+
instances.push(instance);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(`Instance ${i} creation failed:`, error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const endTime = performance.now();
|
|
112
|
+
const duration = endTime - startTime;
|
|
113
|
+
|
|
114
|
+
// Cleanup
|
|
115
|
+
instances.forEach(instance => {
|
|
116
|
+
if (instance.dispose) instance.dispose();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
resultsDiv.innerHTML = `
|
|
120
|
+
<span class="${duration < 1000 ? 'success' : 'warning'}">
|
|
121
|
+
✅ Performance Test Results:<br>
|
|
122
|
+
• Created ${instances.length}/10 instances in ${duration.toFixed(2)}ms<br>
|
|
123
|
+
• Average: ${(duration / instances.length).toFixed(2)}ms per instance<br>
|
|
124
|
+
• Optimizations working: ${duration < 1000 ? 'YES' : 'NEEDS IMPROVEMENT'}
|
|
125
|
+
</span>
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Functionality test
|
|
130
|
+
function testFunctionality() {
|
|
131
|
+
const resultsDiv = document.getElementById('functionality-results');
|
|
132
|
+
const testSelect = document.getElementById('test-select');
|
|
133
|
+
|
|
134
|
+
if (testSelect && testSelect.instance) {
|
|
135
|
+
try {
|
|
136
|
+
// Test dropdown opening
|
|
137
|
+
testSelect.instance.openDropdown();
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
testSelect.instance.closeDropdown();
|
|
140
|
+
|
|
141
|
+
// Test search functionality
|
|
142
|
+
const searchInput = testSelect.instance.getSearchInput();
|
|
143
|
+
if (searchInput) {
|
|
144
|
+
searchInput.value = 'test';
|
|
145
|
+
searchInput.dispatchEvent(new Event('input'));
|
|
146
|
+
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
searchInput.value = '';
|
|
149
|
+
searchInput.dispatchEvent(new Event('input'));
|
|
150
|
+
|
|
151
|
+
resultsDiv.innerHTML = `
|
|
152
|
+
<span class="success">
|
|
153
|
+
✅ Functionality Test PASSED:<br>
|
|
154
|
+
• Instance created successfully<br>
|
|
155
|
+
• Dropdown opens/closes correctly<br>
|
|
156
|
+
• Search input works<br>
|
|
157
|
+
• Optimizations maintain functionality
|
|
158
|
+
</span>
|
|
159
|
+
`;
|
|
160
|
+
}, 1000);
|
|
161
|
+
}
|
|
162
|
+
}, 1000);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
resultsDiv.innerHTML = `
|
|
165
|
+
<span class="error">
|
|
166
|
+
❌ Functionality Test FAILED:<br>
|
|
167
|
+
Error: ${error.message}
|
|
168
|
+
</span>
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
resultsDiv.innerHTML = `
|
|
173
|
+
<span class="error">
|
|
174
|
+
❌ Functionality Test FAILED:<br>
|
|
175
|
+
Remote select instance not found
|
|
176
|
+
</span>
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Search test
|
|
182
|
+
function testSearch() {
|
|
183
|
+
const resultsDiv = document.getElementById('search-results');
|
|
184
|
+
const searchSelect = document.getElementById('search-test-select');
|
|
185
|
+
|
|
186
|
+
if (searchSelect && searchSelect.instance) {
|
|
187
|
+
const searchInput = searchSelect.instance.getSearchInput();
|
|
188
|
+
if (searchInput) {
|
|
189
|
+
// Simulate typing
|
|
190
|
+
searchInput.value = 'qui';
|
|
191
|
+
searchInput.dispatchEvent(new Event('input'));
|
|
192
|
+
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
searchInput.value = '';
|
|
195
|
+
searchInput.dispatchEvent(new Event('input'));
|
|
196
|
+
|
|
197
|
+
resultsDiv.innerHTML = `
|
|
198
|
+
<span class="success">
|
|
199
|
+
✅ Search Test PASSED:<br>
|
|
200
|
+
• Search input responds to input<br>
|
|
201
|
+
• Remote search triggers correctly<br>
|
|
202
|
+
• Optimized rendering works
|
|
203
|
+
</span>
|
|
204
|
+
`;
|
|
205
|
+
}, 2000);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Initialize tests
|
|
211
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
212
|
+
try {
|
|
213
|
+
KTSelect.init();
|
|
214
|
+
|
|
215
|
+
// Wait for initialization to complete
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
testFunctionality();
|
|
218
|
+
testSearch();
|
|
219
|
+
}, 2000);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
document.getElementById('functionality-results').innerHTML =
|
|
222
|
+
'<span class="error">❌ Failed to initialize KTSelect: ' + error.message + '</span>';
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
</script>
|
|
226
|
+
</body>
|
|
227
|
+
</html>
|
|
@@ -0,0 +1,151 @@
|
|
|
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>Remote Search Test</title>
|
|
8
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
+
<style>
|
|
10
|
+
.test-container {
|
|
11
|
+
max-width: 600px;
|
|
12
|
+
margin: 20px auto;
|
|
13
|
+
padding: 20px;
|
|
14
|
+
}
|
|
15
|
+
.test-section {
|
|
16
|
+
margin-bottom: 30px;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
border: 1px solid #e5e7eb;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
background: white;
|
|
21
|
+
}
|
|
22
|
+
.test-section h3 {
|
|
23
|
+
margin-top: 0;
|
|
24
|
+
color: #374151;
|
|
25
|
+
}
|
|
26
|
+
.debug-info {
|
|
27
|
+
background: #f9fafb;
|
|
28
|
+
padding: 10px;
|
|
29
|
+
border-radius: 4px;
|
|
30
|
+
font-family: monospace;
|
|
31
|
+
font-size: 12px;
|
|
32
|
+
margin-top: 10px;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
|
|
37
|
+
<body class="bg-gray-50 min-h-screen">
|
|
38
|
+
<div class="test-container">
|
|
39
|
+
<h1>Remote Select Search Test</h1>
|
|
40
|
+
|
|
41
|
+
<div class="test-section">
|
|
42
|
+
<h3>Test 1: Basic Remote Search</h3>
|
|
43
|
+
<label class="block mb-2 font-medium text-gray-700">Users from JSONPlaceholder</label>
|
|
44
|
+
<select
|
|
45
|
+
data-kt-select
|
|
46
|
+
data-kt-select-remote="true"
|
|
47
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
48
|
+
data-kt-select-data-field-value="id"
|
|
49
|
+
data-kt-select-data-field-text="name"
|
|
50
|
+
data-kt-select-enable-search="true"
|
|
51
|
+
data-kt-select-search-param="q"
|
|
52
|
+
data-kt-select-search-min-length="2"
|
|
53
|
+
data-kt-select-search-debounce="300"
|
|
54
|
+
data-kt-select-debug="true"
|
|
55
|
+
placeholder="Search users..."
|
|
56
|
+
></select>
|
|
57
|
+
<div class="debug-info">
|
|
58
|
+
<strong>Expected behavior:</strong> Type at least 2 characters to search users. Options should display with proper text content.
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div class="test-section">
|
|
63
|
+
<h3>Test 2: Posts with Custom Field Mapping</h3>
|
|
64
|
+
<label class="block mb-2 font-medium text-gray-700">Posts from JSONPlaceholder</label>
|
|
65
|
+
<select
|
|
66
|
+
data-kt-select
|
|
67
|
+
data-kt-select-remote="true"
|
|
68
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/posts"
|
|
69
|
+
data-kt-select-data-field-value="id"
|
|
70
|
+
data-kt-select-data-field-text="title"
|
|
71
|
+
data-kt-select-enable-search="true"
|
|
72
|
+
data-kt-select-search-param="q"
|
|
73
|
+
data-kt-select-search-min-length="3"
|
|
74
|
+
data-kt-select-search-debounce="500"
|
|
75
|
+
data-kt-select-debug="true"
|
|
76
|
+
placeholder="Search posts..."
|
|
77
|
+
></select>
|
|
78
|
+
<div class="debug-info">
|
|
79
|
+
<strong>Expected behavior:</strong> Type at least 3 characters to search posts. Should show post titles as options.
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="test-section">
|
|
84
|
+
<h3>Test 3: Error Handling</h3>
|
|
85
|
+
<label class="block mb-2 font-medium text-gray-700">Invalid URL Test</label>
|
|
86
|
+
<select
|
|
87
|
+
data-kt-select
|
|
88
|
+
data-kt-select-remote="true"
|
|
89
|
+
data-kt-select-data-url="https://invalid-url-that-does-not-exist.com/api/data"
|
|
90
|
+
data-kt-select-data-field-value="id"
|
|
91
|
+
data-kt-select-data-field-text="name"
|
|
92
|
+
data-kt-select-enable-search="true"
|
|
93
|
+
data-kt-select-search-param="q"
|
|
94
|
+
data-kt-select-search-min-length="1"
|
|
95
|
+
data-kt-select-search-debounce="300"
|
|
96
|
+
data-kt-select-debug="true"
|
|
97
|
+
placeholder="This should show error..."
|
|
98
|
+
></select>
|
|
99
|
+
<div class="debug-info">
|
|
100
|
+
<strong>Expected behavior:</strong> Should show error message and restore original state after 2 seconds.
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="test-section">
|
|
105
|
+
<h3>Console Debug Info</h3>
|
|
106
|
+
<div class="debug-info">
|
|
107
|
+
Open browser developer tools console to see debug information about the remote search functionality.
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<script src="../../dist/ktui.js"></script>
|
|
113
|
+
<script src="validation-test.js"></script>
|
|
114
|
+
<script>
|
|
115
|
+
// Initialize KTSelect components
|
|
116
|
+
KTSelect.init();
|
|
117
|
+
|
|
118
|
+
// Add some console logging for testing
|
|
119
|
+
console.log('Remote Select Test Page Loaded');
|
|
120
|
+
console.log('All KTSelect components should be initialized with debug logging enabled');
|
|
121
|
+
|
|
122
|
+
// Run validation tests after a short delay to ensure everything is loaded
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
console.log('\n🚀 Running End-to-End Validation Tests...');
|
|
125
|
+
|
|
126
|
+
// Test real API interaction
|
|
127
|
+
const testSelect = document.querySelector('select[data-kt-select-remote="true"]');
|
|
128
|
+
if (testSelect && testSelect.instance) {
|
|
129
|
+
console.log('✅ E2E Test 1 PASSED: Remote select instance found');
|
|
130
|
+
|
|
131
|
+
// Test dropdown opening
|
|
132
|
+
try {
|
|
133
|
+
testSelect.instance.openDropdown();
|
|
134
|
+
console.log('✅ E2E Test 2 PASSED: Dropdown opens successfully');
|
|
135
|
+
|
|
136
|
+
// Test dropdown closing
|
|
137
|
+
setTimeout(() => {
|
|
138
|
+
testSelect.instance.closeDropdown();
|
|
139
|
+
console.log('✅ E2E Test 3 PASSED: Dropdown closes successfully');
|
|
140
|
+
}, 1000);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.log('❌ E2E Test 2-3 FAILED: Dropdown operation error:', error.message);
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
console.log('❌ E2E Test 1 FAILED: Remote select instance not found');
|
|
146
|
+
}
|
|
147
|
+
}, 2000);
|
|
148
|
+
</script>
|
|
149
|
+
</body>
|
|
150
|
+
|
|
151
|
+
</html>
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# KTUI Sticky Component - Testing Suite
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive tests for the KTUI Sticky component, specifically designed to verify the changes from [PR #27](https://github.com/keenthemes/ktui/pull/27).
|
|
4
|
+
|
|
5
|
+
## 🎯 What We're Testing
|
|
6
|
+
|
|
7
|
+
The tests verify the following new features and improvements:
|
|
8
|
+
|
|
9
|
+
### New Positioning Features
|
|
10
|
+
- ✅ **Middle positioning** - Vertical centering (`inset-block-start: 50%`)
|
|
11
|
+
- ✅ **Center positioning** - Horizontal centering (`inset-inline-start: 50%`)
|
|
12
|
+
- ✅ **Bottom positioning** - Sticky to bottom with offset
|
|
13
|
+
- ✅ **Combined positioning** - Middle + Center for full centering
|
|
14
|
+
|
|
15
|
+
### Improved Logic
|
|
16
|
+
- ✅ **Exclusive positioning** - Only one of `top`/`bottom` and `start`/`end` applied
|
|
17
|
+
- ✅ **Auto handling** - Proper fallback values for `'auto'` inputs
|
|
18
|
+
- ✅ **Offset calculation** - Dynamic positioning using `KTDom.offset()`
|
|
19
|
+
|
|
20
|
+
### Modern CSS Support
|
|
21
|
+
- ✅ **Logical properties** - `insetBlockStart`, `insetInlineStart`, `insetInlineEnd`
|
|
22
|
+
- ✅ **RTL/LTR compatibility** - Better support for right-to-left layouts
|
|
23
|
+
|
|
24
|
+
## 📁 Test Files
|
|
25
|
+
|
|
26
|
+
### 1. `test-sticky-positioning.html`
|
|
27
|
+
**Visual/Interactive Test**
|
|
28
|
+
- Comprehensive visual test with 8 different positioning scenarios
|
|
29
|
+
- Real-time position indicator showing computed styles
|
|
30
|
+
- RTL toggle functionality
|
|
31
|
+
- Scroll indicators and controls
|
|
32
|
+
|
|
33
|
+
**How to use:**
|
|
34
|
+
```bash
|
|
35
|
+
# Open in browser
|
|
36
|
+
open examples/sticky/test-sticky-positioning.html
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. `test-sticky-logic.js`
|
|
40
|
+
**Programmatic Test Suite**
|
|
41
|
+
- Automated tests for all positioning logic
|
|
42
|
+
- Validates computed CSS properties
|
|
43
|
+
- Tests exclusive positioning rules
|
|
44
|
+
- Verifies auto fallback values
|
|
45
|
+
|
|
46
|
+
### 3. `test-runner.html`
|
|
47
|
+
**Test Runner Interface**
|
|
48
|
+
- Clean UI for running automated tests
|
|
49
|
+
- Detailed test results with pass/fail status
|
|
50
|
+
- Console output capture
|
|
51
|
+
- Visual test summary
|
|
52
|
+
|
|
53
|
+
**How to use:**
|
|
54
|
+
```bash
|
|
55
|
+
# Open in browser
|
|
56
|
+
open examples/sticky/test-runner.html
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 🧪 Running the Tests
|
|
60
|
+
|
|
61
|
+
### Option 1: Visual Testing (Recommended)
|
|
62
|
+
1. Open `test-sticky-positioning.html` in your browser
|
|
63
|
+
2. Scroll through the page to see each sticky element in action
|
|
64
|
+
3. Use the position indicator to verify computed styles
|
|
65
|
+
4. Test RTL layout by clicking "Toggle RTL Layout"
|
|
66
|
+
|
|
67
|
+
### Option 2: Automated Testing
|
|
68
|
+
1. Open `test-runner.html` in your browser
|
|
69
|
+
2. Click "Run All Tests" to execute the automated test suite
|
|
70
|
+
3. Review the detailed results and console output
|
|
71
|
+
|
|
72
|
+
### Option 3: Console Testing
|
|
73
|
+
1. Open browser developer tools
|
|
74
|
+
2. Import and run the test suite directly:
|
|
75
|
+
```javascript
|
|
76
|
+
import StickyTestSuite from './examples/sticky/test-sticky-logic.js';
|
|
77
|
+
const testSuite = new StickyTestSuite();
|
|
78
|
+
await testSuite.runAllTests();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 📋 Test Scenarios
|
|
82
|
+
|
|
83
|
+
### 1. Basic Positioning
|
|
84
|
+
- **Top**: `data-kt-sticky-top="20"` → `inset-block-start: 20px`
|
|
85
|
+
- **Bottom**: `data-kt-sticky-bottom="20"` → `inset-block-end: 20px`
|
|
86
|
+
|
|
87
|
+
### 2. Centering
|
|
88
|
+
- **Middle**: `data-kt-sticky-middle="true"` → `inset-block-start: 50%`
|
|
89
|
+
- **Center**: `data-kt-sticky-center="true"` → `inset-inline-start: 50%`
|
|
90
|
+
- **Both**: `data-kt-sticky-middle="true" data-kt-sticky-center="true"` → Fully centered
|
|
91
|
+
|
|
92
|
+
### 3. Auto Positioning
|
|
93
|
+
- **Auto Top**: `data-kt-sticky-top="auto"` → `inset-block-start: 0px`
|
|
94
|
+
- **Auto Start**: `data-kt-sticky-start="auto"` → Calculated offset using `KTDom.offset()`
|
|
95
|
+
|
|
96
|
+
### 4. Exclusive Logic
|
|
97
|
+
- **Top + Bottom**: Only top is applied (top takes precedence)
|
|
98
|
+
- **Start + End**: Only start is applied (start takes precedence)
|
|
99
|
+
|
|
100
|
+
### 5. RTL Support
|
|
101
|
+
- **End positioning**: `data-kt-sticky-end="20"` → `inset-inline-end: 20px`
|
|
102
|
+
- **Logical properties**: Works correctly in both LTR and RTL layouts
|
|
103
|
+
|
|
104
|
+
## 🔍 What to Look For
|
|
105
|
+
|
|
106
|
+
### ✅ Success Indicators
|
|
107
|
+
- Elements stick to the correct positions when scrolling
|
|
108
|
+
- Computed styles match expected values
|
|
109
|
+
- RTL layout works correctly
|
|
110
|
+
- Auto positioning calculates proper offsets
|
|
111
|
+
- Exclusive positioning rules are followed
|
|
112
|
+
|
|
113
|
+
### ❌ Failure Indicators
|
|
114
|
+
- Elements don't stick or stick to wrong positions
|
|
115
|
+
- Computed styles don't match expected values
|
|
116
|
+
- RTL layout breaks positioning
|
|
117
|
+
- Auto positioning doesn't calculate offsets
|
|
118
|
+
- Multiple positioning properties conflict
|
|
119
|
+
|
|
120
|
+
## 🛠️ Troubleshooting
|
|
121
|
+
|
|
122
|
+
### Common Issues
|
|
123
|
+
|
|
124
|
+
1. **Tests not running**
|
|
125
|
+
- Ensure you're serving files from a web server (not file://)
|
|
126
|
+
- Check browser console for import errors
|
|
127
|
+
- Verify KTUI library is built and accessible
|
|
128
|
+
|
|
129
|
+
2. **Positioning not working**
|
|
130
|
+
- Check if sticky element has proper dimensions
|
|
131
|
+
- Verify scroll container is correct
|
|
132
|
+
- Ensure CSS logical properties are supported
|
|
133
|
+
|
|
134
|
+
3. **RTL not working**
|
|
135
|
+
- Check if `dir="rtl"` is set on `<html>` element
|
|
136
|
+
- Verify browser supports logical properties
|
|
137
|
+
- Test with different RTL content
|
|
138
|
+
|
|
139
|
+
### Debug Mode
|
|
140
|
+
Enable debug logging by adding this to the console:
|
|
141
|
+
```javascript
|
|
142
|
+
localStorage.setItem('ktui-debug', 'true');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 📊 Expected Results
|
|
146
|
+
|
|
147
|
+
When all tests pass, you should see:
|
|
148
|
+
- ✅ 8/8 tests passed
|
|
149
|
+
- All positioning scenarios working correctly
|
|
150
|
+
- Logical properties being used
|
|
151
|
+
- RTL layout functioning properly
|
|
152
|
+
- Auto positioning calculating offsets
|
|
153
|
+
|
|
154
|
+
## 🔗 Related Links
|
|
155
|
+
|
|
156
|
+
- [PR #27](https://github.com/keenthemes/ktui/pull/27) - Original pull request
|
|
157
|
+
- [Sticky Component Documentation](../src/components/sticky/) - Component source code
|
|
158
|
+
- [KTUI Main Documentation](../../README.md) - Main project documentation
|
|
@@ -0,0 +1,144 @@
|
|
|
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>Debug Sticky Component</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<style>
|
|
9
|
+
.debug-sticky {
|
|
10
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
11
|
+
color: white;
|
|
12
|
+
padding: 1rem;
|
|
13
|
+
border-radius: 8px;
|
|
14
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
15
|
+
font-weight: 600;
|
|
16
|
+
text-align: center;
|
|
17
|
+
width: 200px;
|
|
18
|
+
height: 80px;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.debug-sticky.active {
|
|
25
|
+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.debug-info {
|
|
29
|
+
position: fixed;
|
|
30
|
+
top: 10px;
|
|
31
|
+
left: 10px;
|
|
32
|
+
background: rgba(0, 0, 0, 0.8);
|
|
33
|
+
color: white;
|
|
34
|
+
padding: 1rem;
|
|
35
|
+
border-radius: 4px;
|
|
36
|
+
font-family: monospace;
|
|
37
|
+
font-size: 12px;
|
|
38
|
+
max-width: 400px;
|
|
39
|
+
z-index: 9999;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
42
|
+
</head>
|
|
43
|
+
<body class="bg-gray-50">
|
|
44
|
+
<div class="debug-info" id="debugInfo">
|
|
45
|
+
Loading...
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- Simple test section -->
|
|
49
|
+
<div style="height: 100vh; padding: 2rem;">
|
|
50
|
+
<h1>Debug Sticky Component</h1>
|
|
51
|
+
<p>Scroll down to test the sticky element</p>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<!-- Single sticky element for testing -->
|
|
55
|
+
<div class="debug-sticky"
|
|
56
|
+
data-kt-sticky="true"
|
|
57
|
+
data-kt-sticky-top="20"
|
|
58
|
+
data-kt-sticky-offset="100"
|
|
59
|
+
data-kt-sticky-zindex="1000"
|
|
60
|
+
data-kt-sticky-name="debug-test">
|
|
61
|
+
Debug Sticky
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<!-- Content to scroll through -->
|
|
65
|
+
<div style="height: 200vh; padding: 2rem;">
|
|
66
|
+
<h2>Scroll Content</h2>
|
|
67
|
+
<p>This content is here to allow scrolling and test the sticky element.</p>
|
|
68
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
|
69
|
+
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
|
70
|
+
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
|
|
71
|
+
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<!-- Load KTUI -->
|
|
75
|
+
<script src="../../dist/ktui.js"></script>
|
|
76
|
+
<script>
|
|
77
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
78
|
+
const debugInfo = document.getElementById('debugInfo');
|
|
79
|
+
|
|
80
|
+
function updateDebugInfo() {
|
|
81
|
+
const stickyElement = document.querySelector('[data-kt-sticky]');
|
|
82
|
+
const initializedElement = document.querySelector('[data-kt-sticky-initialized]');
|
|
83
|
+
const activeElement = document.querySelector('[data-kt-sticky-initialized].active');
|
|
84
|
+
|
|
85
|
+
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
86
|
+
const viewportHeight = window.innerHeight;
|
|
87
|
+
|
|
88
|
+
let info = `
|
|
89
|
+
<strong>Debug Info:</strong><br>
|
|
90
|
+
Scroll: ${scrollTop}px<br>
|
|
91
|
+
Viewport Height: ${viewportHeight}px<br>
|
|
92
|
+
KTSticky Available: ${!!window.KTSticky}<br>
|
|
93
|
+
Sticky Elements: ${document.querySelectorAll('[data-kt-sticky]').length}<br>
|
|
94
|
+
Initialized Elements: ${document.querySelectorAll('[data-kt-sticky-initialized]').length}<br>
|
|
95
|
+
Active Elements: ${document.querySelectorAll('[data-kt-sticky-initialized].active').length}<br>
|
|
96
|
+
`;
|
|
97
|
+
|
|
98
|
+
if (stickyElement) {
|
|
99
|
+
const computedStyle = window.getComputedStyle(stickyElement);
|
|
100
|
+
const height = stickyElement.offsetHeight;
|
|
101
|
+
const top = stickyElement.getAttribute('data-kt-sticky-top') || '0';
|
|
102
|
+
const offset = stickyElement.getAttribute('data-kt-sticky-offset') || '0';
|
|
103
|
+
|
|
104
|
+
info += `
|
|
105
|
+
<br><strong>Sticky Element:</strong><br>
|
|
106
|
+
Height: ${height}px<br>
|
|
107
|
+
Top: ${top}px<br>
|
|
108
|
+
Offset: ${offset}px<br>
|
|
109
|
+
Height + Top: ${height + parseInt(top)}px<br>
|
|
110
|
+
Position: ${computedStyle.position}<br>
|
|
111
|
+
Z-Index: ${computedStyle.zIndex}<br>
|
|
112
|
+
InsetBlockStart: ${computedStyle.insetBlockStart}<br>
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (initializedElement) {
|
|
117
|
+
info += `<br><strong>Initialized Element:</strong><br>`;
|
|
118
|
+
info += `Classes: ${initializedElement.className}<br>`;
|
|
119
|
+
info += `Data Attributes: ${Array.from(initializedElement.attributes).filter(attr => attr.name.startsWith('data-kt-sticky')).map(attr => `${attr.name}="${attr.value}"`).join(', ')}<br>`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
debugInfo.innerHTML = info;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Initialize KTUI
|
|
126
|
+
if (window.KTSticky) {
|
|
127
|
+
console.log('Initializing KTSticky...');
|
|
128
|
+
window.KTSticky.init();
|
|
129
|
+
console.log('KTSticky initialized');
|
|
130
|
+
} else {
|
|
131
|
+
console.error('KTSticky not found!');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Update debug info initially and on scroll
|
|
135
|
+
updateDebugInfo();
|
|
136
|
+
window.addEventListener('scroll', updateDebugInfo);
|
|
137
|
+
window.addEventListener('resize', updateDebugInfo);
|
|
138
|
+
|
|
139
|
+
// Update every second to catch any changes
|
|
140
|
+
setInterval(updateDebugInfo, 1000);
|
|
141
|
+
});
|
|
142
|
+
</script>
|
|
143
|
+
</body>
|
|
144
|
+
</html>
|