Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [8.5.2](https://github.com/ionic-team/ionic-framework/compare/v8.5.1...v8.5.2) (2025-03-26)


### Bug Fixes

* **datetime:** support typing time values in a 24-hour format ([#30147](https://github.com/ionic-team/ionic-framework/issues/30147)) ([ac6e6a0](https://github.com/ionic-team/ionic-framework/commit/ac6e6a03174263d09ec55c9742a026862a3df444)), closes [#28877](https://github.com/ionic-team/ionic-framework/issues/28877)
* **range:** emit ionInput when value changes ([#30293](https://github.com/ionic-team/ionic-framework/issues/30293)) ([7789bb5](https://github.com/ionic-team/ionic-framework/commit/7789bb59ee5c76074ff4872dc6a50ae2d83df8f5)), closes [#29619](https://github.com/ionic-team/ionic-framework/issues/29619)
* **segment-button:** ensure consistent disabled state for segment-content error handling ([#30288](https://github.com/ionic-team/ionic-framework/issues/30288)) ([1cfa915](https://github.com/ionic-team/ionic-framework/commit/1cfa915e8fe362951c521bce970a9f5f10918ab2))





## [8.5.1](https://github.com/ionic-team/ionic-framework/compare/v8.5.0...v8.5.1) (2025-03-19)


Expand Down
13 changes: 13 additions & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [8.5.2](https://github.com/ionic-team/ionic-framework/compare/v8.5.1...v8.5.2) (2025-03-26)


### Bug Fixes

* **datetime:** support typing time values in a 24-hour format ([#30147](https://github.com/ionic-team/ionic-framework/issues/30147)) ([ac6e6a0](https://github.com/ionic-team/ionic-framework/commit/ac6e6a03174263d09ec55c9742a026862a3df444)), closes [#28877](https://github.com/ionic-team/ionic-framework/issues/28877)
* **range:** emit ionInput when value changes ([#30293](https://github.com/ionic-team/ionic-framework/issues/30293)) ([7789bb5](https://github.com/ionic-team/ionic-framework/commit/7789bb59ee5c76074ff4872dc6a50ae2d83df8f5)), closes [#29619](https://github.com/ionic-team/ionic-framework/issues/29619)
* **segment-button:** ensure consistent disabled state for segment-content error handling ([#30288](https://github.com/ionic-team/ionic-framework/issues/30288)) ([1cfa915](https://github.com/ionic-team/ionic-framework/commit/1cfa915e8fe362951c521bce970a9f5f10918ab2))





## [8.5.1](https://github.com/ionic-team/ionic-framework/compare/v8.5.0...v8.5.1) (2025-03-19)


Expand Down
50 changes: 25 additions & 25 deletions core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "8.5.1",
"version": "8.5.2",
"description": "Base components for Ionic",
"keywords": [
"ionic",
Expand Down Expand Up @@ -44,7 +44,7 @@
"@clack/prompts": "^0.10.0",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@playwright/test": "^1.51.0",
"@playwright/test": "^1.51.1",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.10.0",
Expand Down
6 changes: 3 additions & 3 deletions core/src/components/datetime/datetime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ export class Datetime implements ComponentInterface {
});

this.setActiveParts({
...activePart,
...this.getActivePartsWithFallback(),
hour: ev.detail.value,
});

Expand Down Expand Up @@ -2024,7 +2024,7 @@ export class Datetime implements ComponentInterface {
});

this.setActiveParts({
...activePart,
...this.getActivePartsWithFallback(),
minute: ev.detail.value,
});

Expand Down Expand Up @@ -2070,7 +2070,7 @@ export class Datetime implements ComponentInterface {
});

this.setActiveParts({
...activePart,
...this.getActivePartsWithFallback(),
ampm: ev.detail.value,
hour,
});
Expand Down
149 changes: 65 additions & 84 deletions core/src/components/picker/picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,15 +410,72 @@ export class Picker implements ComponentInterface {
colEl: HTMLIonPickerColumnElement,
value: string,
zeroBehavior: 'start' | 'end' = 'start'
) => {
): boolean => {
if (!value) {
return false;
}

const behavior = zeroBehavior === 'start' ? /^0+/ : /0$/;
value = value.replace(behavior, '');
const option = Array.from(colEl.querySelectorAll('ion-picker-column-option')).find((el) => {
return el.disabled !== true && el.textContent!.replace(behavior, '') === value;
});

if (option) {
colEl.setValue(option.value);
}

return !!option;
};

/**
* Attempts to intelligently search the first and second
* column as if they're number columns for the provided numbers
* where the first two numbers are the first column
* and the last 2 are the last column. Tries to allow for the first
* number to be ignored for situations where typos occurred.
*/
private multiColumnSearch = (
firstColumn: HTMLIonPickerColumnElement,
secondColumn: HTMLIonPickerColumnElement,
input: string
) => {
if (input.length === 0) {
return;
}

const inputArray = input.split('');
const hourValue = inputArray.slice(0, 2).join('');
// Try to find a match for the first two digits in the first column
const foundHour = this.searchColumn(firstColumn, hourValue);

// If we have more than 2 digits and found a match for hours,
// use the remaining digits for the second column (minutes)
if (inputArray.length > 2 && foundHour) {
const minuteValue = inputArray.slice(2, 4).join('');
this.searchColumn(secondColumn, minuteValue);
}
// If we couldn't find a match for the two-digit hour, try single digit approaches
else if (!foundHour && inputArray.length >= 1) {
// First try the first digit as a single-digit hour
let singleDigitHour = inputArray[0];
let singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);

// If that didn't work, try the second digit as a single-digit hour
// (handles case where user made a typo in the first digit, or they typed over themselves)
if (!singleDigitFound) {
inputArray.shift();
singleDigitHour = inputArray[0];
singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);
}

// If we found a single-digit hour and have remaining digits,
// use up to 2 of the remaining digits for the second column
if (singleDigitFound && inputArray.length > 1) {
const remainingDigits = inputArray.slice(1, 3).join('');
this.searchColumn(secondColumn, remainingDigits);
}
}
};

private selectMultiColumn = () => {
Expand All @@ -433,91 +490,15 @@ export class Picker implements ComponentInterface {
const lastColumn = numericPickers[1];

let value = inputEl.value;
let minuteValue;
switch (value.length) {
case 1:
this.searchColumn(firstColumn, value);
break;
case 2:
/**
* If the first character is `0` or `1` it is
* possible that users are trying to type `09`
* or `11` into the hour field, so we should look
* at that first.
*/
const firstCharacter = inputEl.value.substring(0, 1);
value = firstCharacter === '0' || firstCharacter === '1' ? inputEl.value : firstCharacter;

this.searchColumn(firstColumn, value);

/**
* If only checked the first value,
* we can check the second value
* for a match in the minutes column
*/
if (value.length === 1) {
minuteValue = inputEl.value.substring(inputEl.value.length - 1);
this.searchColumn(lastColumn, minuteValue, 'end');
}
break;
case 3:
/**
* If the first character is `0` or `1` it is
* possible that users are trying to type `09`
* or `11` into the hour field, so we should look
* at that first.
*/
const firstCharacterAgain = inputEl.value.substring(0, 1);
value =
firstCharacterAgain === '0' || firstCharacterAgain === '1'
? inputEl.value.substring(0, 2)
: firstCharacterAgain;

this.searchColumn(firstColumn, value);

/**
* If only checked the first value,
* we can check the second value
* for a match in the minutes column
*/
minuteValue = value.length === 1 ? inputEl.value.substring(1) : inputEl.value.substring(2);

this.searchColumn(lastColumn, minuteValue, 'end');
break;
case 4:
/**
* If the first character is `0` or `1` it is
* possible that users are trying to type `09`
* or `11` into the hour field, so we should look
* at that first.
*/
const firstCharacterAgainAgain = inputEl.value.substring(0, 1);
value =
firstCharacterAgainAgain === '0' || firstCharacterAgainAgain === '1'
? inputEl.value.substring(0, 2)
: firstCharacterAgainAgain;
this.searchColumn(firstColumn, value);
if (value.length > 4) {
const startIndex = inputEl.value.length - 4;
const newString = inputEl.value.substring(startIndex);

/**
* If only checked the first value,
* we can check the second value
* for a match in the minutes column
*/
const minuteValueAgain =
value.length === 1
? inputEl.value.substring(1, inputEl.value.length)
: inputEl.value.substring(2, inputEl.value.length);
this.searchColumn(lastColumn, minuteValueAgain, 'end');

break;
default:
const startIndex = inputEl.value.length - 4;
const newString = inputEl.value.substring(startIndex);

inputEl.value = newString;
this.selectMultiColumn();
break;
inputEl.value = newString;
value = newString;
}

this.multiColumnSearch(firstColumn, lastColumn, value);
};

/**
Expand Down
Loading
Loading