fix(datetime): allow disabling datetime with prefer-wheel (#28511)

Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->
It is possible to navigate the columns of a disabled Datetime with
`prefer-wheel` via the keyboard.



https://github.com/ionic-team/ionic-framework/assets/14926794/9c9dafc4-4b77-45a6-a276-70201c5c3ea5



## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Picker Column Internal has a disabled state that disables the full
column
- When a Datetime is disabled with `prefer-wheel`, the columns in the
Datetime will be disabled
- It is no longer possible to navigate the wheels in a disabled Datetime
via the keyboard


Comparison of native & Ionic components:

![Screenshot 2023-11-10 at 10 58
25 AM](https://github.com/ionic-team/ionic-framework/assets/14926794/e2bec1b3-30f8-4f64-8658-27b971884b7a)


## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->

---------

Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
This commit is contained in:
Shawn Taylor
2023-11-22 11:07:43 -05:00
committed by GitHub
parent b833f0e826
commit 01130e12e1
14 changed files with 153 additions and 32 deletions

View File

@ -1538,7 +1538,7 @@ export class Datetime implements ComponentInterface {
}
private renderCombinedDatePickerColumn() {
const { defaultParts, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
const { defaultParts, disabled, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
const activePart = this.getActivePartsWithFallback();
@ -1617,6 +1617,7 @@ export class Datetime implements ComponentInterface {
<ion-picker-column-internal
class="date-column"
color={this.color}
disabled={disabled}
items={items}
value={todayString}
onIonChange={(ev: CustomEvent) => {
@ -1728,7 +1729,7 @@ export class Datetime implements ComponentInterface {
return [];
}
const { workingParts } = this;
const { disabled, workingParts } = this;
const activePart = this.getActivePartsWithFallback();
@ -1736,6 +1737,7 @@ export class Datetime implements ComponentInterface {
<ion-picker-column-internal
class="day-column"
color={this.color}
disabled={disabled}
items={days}
value={(workingParts.day !== null ? workingParts.day : this.defaultParts.day) ?? undefined}
onIonChange={(ev: CustomEvent) => {
@ -1772,7 +1774,7 @@ export class Datetime implements ComponentInterface {
return [];
}
const { workingParts } = this;
const { disabled, workingParts } = this;
const activePart = this.getActivePartsWithFallback();
@ -1780,6 +1782,7 @@ export class Datetime implements ComponentInterface {
<ion-picker-column-internal
class="month-column"
color={this.color}
disabled={disabled}
items={months}
value={workingParts.month}
onIonChange={(ev: CustomEvent) => {
@ -1815,7 +1818,7 @@ export class Datetime implements ComponentInterface {
return [];
}
const { workingParts } = this;
const { disabled, workingParts } = this;
const activePart = this.getActivePartsWithFallback();
@ -1823,6 +1826,7 @@ export class Datetime implements ComponentInterface {
<ion-picker-column-internal
class="year-column"
color={this.color}
disabled={disabled}
items={years}
value={workingParts.year}
onIonChange={(ev: CustomEvent) => {
@ -1888,7 +1892,7 @@ export class Datetime implements ComponentInterface {
}
private renderHourPickerColumn(hoursData: PickerColumnItem[]) {
const { workingParts } = this;
const { disabled, workingParts } = this;
if (hoursData.length === 0) return [];
const activePart = this.getActivePartsWithFallback();
@ -1896,6 +1900,7 @@ export class Datetime implements ComponentInterface {
return (
<ion-picker-column-internal
color={this.color}
disabled={disabled}
value={activePart.hour}
items={hoursData}
numericInput
@ -1916,7 +1921,7 @@ export class Datetime implements ComponentInterface {
);
}
private renderMinutePickerColumn(minutesData: PickerColumnItem[]) {
const { workingParts } = this;
const { disabled, workingParts } = this;
if (minutesData.length === 0) return [];
const activePart = this.getActivePartsWithFallback();
@ -1924,6 +1929,7 @@ export class Datetime implements ComponentInterface {
return (
<ion-picker-column-internal
color={this.color}
disabled={disabled}
value={activePart.minute}
items={minutesData}
numericInput
@ -1944,7 +1950,7 @@ export class Datetime implements ComponentInterface {
);
}
private renderDayPeriodPickerColumn(dayPeriodData: PickerColumnItem[]) {
const { workingParts } = this;
const { disabled, workingParts } = this;
if (dayPeriodData.length === 0) {
return [];
}
@ -1956,6 +1962,7 @@ export class Datetime implements ComponentInterface {
<ion-picker-column-internal
style={isDayPeriodRTL ? { order: '-1' } : {}}
color={this.color}
disabled={disabled}
value={activePart.ampm}
items={dayPeriodData}
onIonChange={(ev: CustomEvent) => {

View File

@ -0,0 +1,39 @@
import { h } from '@stencil/core';
import { newSpecPage } from '@stencil/core/testing';
import { Datetime } from '../../../datetime/datetime';
import { PickerColumnInternal } from '../../../picker-column-internal/picker-column-internal';
import { PickerInternal } from '../../../picker-internal/picker-internal';
describe('ion-datetime disabled', () => {
beforeEach(() => {
// IntersectionObserver isn't available in test environment
const mockIntersectionObserver = jest.fn();
mockIntersectionObserver.mockReturnValue({
observe: () => null,
unobserve: () => null,
disconnect: () => null,
});
global.IntersectionObserver = mockIntersectionObserver;
});
it('picker should be disabled in prefer wheel mode', async () => {
const page = await newSpecPage({
components: [Datetime, PickerColumnInternal, PickerInternal],
template: () => (
<ion-datetime id="inline-datetime-wheel" disabled prefer-wheel value="2022-04-21T00:00:00"></ion-datetime>
),
});
await page.waitForChanges();
const datetime = page.body.querySelector('ion-datetime')!;
const columns = datetime.shadowRoot!.querySelectorAll('ion-picker-column-internal');
await expect(columns.length).toEqual(4);
columns.forEach((column) => {
expect(column.disabled).toBe(true);
});
});
});

View File

@ -66,6 +66,11 @@
<h2>Inline - No Default Value</h2>
<ion-datetime id="inline-datetime-no-value" disabled></ion-datetime>
</div>
<div class="grid-item">
<h2>Inline - Prefer Wheel</h2>
<ion-datetime id="inline-datetime-wheel" disabled prefer-wheel value="2022-04-21T00:00:00"></ion-datetime>
</div>
</div>
</ion-content>
<script>