@@ -163,6 +163,172 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
163163 await expect ( ionChange ) . toHaveReceivedEventDetail ( { value : 12 } ) ;
164164 await expect ( column ) . toHaveJSProperty ( 'value' , 12 ) ;
165165 } ) ;
166+
167+ test ( 'should allow typing 22 in a column where the max value is 23 and not just set it to 2' , async ( {
168+ page,
169+ } , testInfo ) => {
170+ testInfo . annotations . push ( {
171+ type : 'issue' ,
172+ description : 'https://github.com/ionic-team/ionic-framework/issues/28877' ,
173+ } ) ;
174+ await page . setContent (
175+ `
176+ <ion-picker>
177+ <ion-picker-column id="hours"></ion-picker-column>
178+ <ion-picker-column id="minutes"></ion-picker-column>
179+ </ion-picker>
180+
181+ <script>
182+ const hoursColumn = document.querySelector('ion-picker-column#hours');
183+ hoursColumn.numericInput = true;
184+ const hourItems = [
185+ { text: '01', value: 1 },
186+ { text: '02', value: 2},
187+ { text: '20', value: 20 },
188+ { text: '21', value: 21 },
189+ { text: '22', value: 22 },
190+ { text: '23', value: 23 }
191+ ];
192+
193+ hourItems.forEach((item) => {
194+ const option = document.createElement('ion-picker-column-option');
195+ option.value = item.value;
196+ option.textContent = item.text;
197+
198+ hoursColumn.appendChild(option);
199+ });
200+
201+ const minutesColumn = document.querySelector('ion-picker-column#minutes');
202+ minutesColumn.numericInput = true;
203+ const minuteItems = [
204+ { text: '00', value: 0 },
205+ { text: '15', value: 15 },
206+ { text: '30', value: 30 },
207+ { text: '45', value: 45 }
208+ ];
209+
210+ minuteItems.forEach((item) => {
211+ const option = document.createElement('ion-picker-column-option');
212+ option.value = item.value;
213+ option.textContent = item.text;
214+
215+ minutesColumn.appendChild(option);
216+ });
217+ </script>
218+ ` ,
219+ config
220+ ) ;
221+
222+ const hoursColumn = page . locator ( 'ion-picker-column#hours' ) ;
223+ const minutesColumn = page . locator ( 'ion-picker-column#minutes' ) ;
224+ const hoursIonChange = await ( hoursColumn as E2ELocator ) . spyOnEvent ( 'ionChange' ) ;
225+ const minutesIonChange = await ( minutesColumn as E2ELocator ) . spyOnEvent ( 'ionChange' ) ;
226+ const highlight = page . locator ( 'ion-picker .picker-highlight' ) ;
227+
228+ const box = await highlight . boundingBox ( ) ;
229+ if ( box !== null ) {
230+ await page . mouse . click ( box . x + box . width / 2 , box . y + box . height / 2 ) ;
231+ }
232+
233+ // Simulate typing '2230' (22 hours, 30 minutes)
234+ await page . keyboard . press ( 'Digit2' ) ;
235+ await page . keyboard . press ( 'Digit2' ) ;
236+ await page . keyboard . press ( 'Digit3' ) ;
237+ await page . keyboard . press ( 'Digit0' ) ;
238+
239+ // Ensure the hours column is set to 22
240+ await expect ( hoursIonChange ) . toHaveReceivedEventDetail ( { value : 22 } ) ;
241+ await expect ( hoursColumn ) . toHaveJSProperty ( 'value' , 22 ) ;
242+
243+ // Ensure the minutes column is set to 30
244+ await expect ( minutesIonChange ) . toHaveReceivedEventDetail ( { value : 30 } ) ;
245+ await expect ( minutesColumn ) . toHaveJSProperty ( 'value' , 30 ) ;
246+ } ) ;
247+
248+ test ( 'should set value to 2 and not wait for another digit when max value is 12' , async ( { page } , testInfo ) => {
249+ testInfo . annotations . push ( {
250+ type : 'issue' ,
251+ description : 'https://github.com/ionic-team/ionic-framework/issues/28877' ,
252+ } ) ;
253+ await page . setContent (
254+ `
255+ <ion-picker>
256+ <ion-picker-column id="hours"></ion-picker-column>
257+ <ion-picker-column id="minutes"></ion-picker-column>
258+ </ion-picker>
259+
260+ <script>
261+ const hoursColumn = document.querySelector('ion-picker-column#hours');
262+ hoursColumn.numericInput = true;
263+ const hourItems = [
264+ { text: '01', value: 1 },
265+ { text: '02', value: 2 },
266+ { text: '03', value: 3 },
267+ { text: '04', value: 4 },
268+ { text: '05', value: 5 },
269+ { text: '06', value: 6 },
270+ { text: '07', value: 7 },
271+ { text: '08', value: 8 },
272+ { text: '09', value: 9 },
273+ { text: '10', value: 10 },
274+ { text: '11', value: 11 },
275+ { text: '12', value: 12 }
276+ ];
277+
278+ hourItems.forEach((item) => {
279+ const option = document.createElement('ion-picker-column-option');
280+ option.value = item.value;
281+ option.textContent = item.text;
282+
283+ hoursColumn.appendChild(option);
284+ });
285+
286+ const minutesColumn = document.querySelector('ion-picker-column#minutes');
287+ minutesColumn.numericInput = true;
288+ const minuteItems = [
289+ { text: '00', value: 0 },
290+ { text: '15', value: 15 },
291+ { text: '30', value: 30 },
292+ { text: '45', value: 45 }
293+ ];
294+
295+ minuteItems.forEach((item) => {
296+ const option = document.createElement('ion-picker-column-option');
297+ option.value = item.value;
298+ option.textContent = item.text;
299+
300+ minutesColumn.appendChild(option);
301+ });
302+ </script>
303+ ` ,
304+ config
305+ ) ;
306+
307+ const hoursColumn = page . locator ( 'ion-picker-column#hours' ) ;
308+ const minutesColumn = page . locator ( 'ion-picker-column#minutes' ) ;
309+ const hoursIonChange = await ( hoursColumn as E2ELocator ) . spyOnEvent ( 'ionChange' ) ;
310+ const minutesIonChange = await ( minutesColumn as E2ELocator ) . spyOnEvent ( 'ionChange' ) ;
311+ const highlight = page . locator ( 'ion-picker .picker-highlight' ) ;
312+
313+ const box = await highlight . boundingBox ( ) ;
314+ if ( box !== null ) {
315+ await page . mouse . click ( box . x + box . width / 2 , box . y + box . height / 2 ) ;
316+ }
317+
318+ // Simulate typing '245' (2 hours, 45 minutes)
319+ await page . keyboard . press ( 'Digit2' ) ;
320+ await page . keyboard . press ( 'Digit4' ) ;
321+ await page . keyboard . press ( 'Digit5' ) ;
322+
323+ // Ensure the hours column is set to 2
324+ await expect ( hoursIonChange ) . toHaveReceivedEventDetail ( { value : 2 } ) ;
325+ await expect ( hoursColumn ) . toHaveJSProperty ( 'value' , 2 ) ;
326+
327+ // Ensure the minutes column is set to 45
328+ await expect ( minutesIonChange ) . toHaveReceivedEventDetail ( { value : 45 } ) ;
329+ await expect ( minutesColumn ) . toHaveJSProperty ( 'value' , 45 ) ;
330+ } ) ;
331+
166332 test ( 'pressing Enter should dismiss the keyboard' , async ( { page } ) => {
167333 test . info ( ) . annotations . push ( {
168334 type : 'issue' ,
0 commit comments