diff --git a/core/src/components.d.ts b/core/src/components.d.ts index e4d9bef870..be93d86de1 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -4067,6 +4067,7 @@ declare global { }; interface HTMLIonPickerColumnElementEventMap { "ionChange": PickerColumnChangeEventDetail; + "ionValueChange": void; } interface HTMLIonPickerColumnElement extends Components.IonPickerColumn, HTMLStencilElement { addEventListener(type: K, listener: (this: HTMLIonPickerColumnElement, ev: IonPickerColumnCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; @@ -6648,6 +6649,7 @@ declare namespace LocalJSX { * Emitted when the value has changed. */ "onIonChange"?: (event: IonPickerColumnCustomEvent) => void; + "onIonValueChange"?: (event: IonPickerColumnCustomEvent) => void; /** * The selected option in the picker. */ diff --git a/core/src/components/picker-column-option/picker-column-option.tsx b/core/src/components/picker-column-option/picker-column-option.tsx index 87b828574f..09ab298ede 100644 --- a/core/src/components/picker-column-option/picker-column-option.tsx +++ b/core/src/components/picker-column-option/picker-column-option.tsx @@ -33,6 +33,7 @@ export class PickerColumnOption implements ComponentInterface { * after the component is loaded. */ @State() ariaLabel?: string | null = null; + @State() selected = false; /** * If `true`, the user cannot interact with the picker column option. @@ -72,11 +73,27 @@ export class PickerColumnOption implements ComponentInterface { this.ariaLabel = inheritedAttributes['aria-label'] || null; } + private columnValueChange = () => { + const { pickerColumn } = this; + if (pickerColumn) { + this.selected = pickerColumn.value === this.value; + } + } + connectedCallback() { - this.pickerColumn = this.el.closest('ion-picker-column'); + const pickerColumn = this.pickerColumn = this.el.closest('ion-picker-column'); + + if (pickerColumn) { + pickerColumn.addEventListener('ionValueChange', this.columnValueChange) + this.columnValueChange(); + } } disconnectedCallback() { + if (this.pickerColumn) { + this. pickerColumn.removeEventListener('ionValueChange', this.columnValueChange) + } + this.pickerColumn = null; } @@ -114,7 +131,7 @@ export class PickerColumnOption implements ComponentInterface { } render() { - const { color, disabled, ariaLabel } = this; + const { color, disabled, ariaLabel, selected } = this; const mode = getIonMode(this); return ( @@ -124,7 +141,16 @@ export class PickerColumnOption implements ComponentInterface { ['option-disabled']: disabled, })} > - diff --git a/core/src/components/picker-column/picker-column.tsx b/core/src/components/picker-column/picker-column.tsx index 50577812ef..d5f6cab9cb 100644 --- a/core/src/components/picker-column/picker-column.tsx +++ b/core/src/components/picker-column/picker-column.tsx @@ -69,6 +69,8 @@ export class PickerColumn implements ComponentInterface { */ @Event() ionChange!: EventEmitter; + @Event() ionValueChange!: EventEmitter + @Watch('value') valueChange() { if (this.isColumnVisible) { @@ -78,6 +80,7 @@ export class PickerColumn implements ComponentInterface { */ this.scrollActiveItemIntoView(true); } + this.ionValueChange.emit(); } /** @@ -475,6 +478,51 @@ export class PickerColumn implements ComponentInterface { >
{ + console.log('helloooo',ev) + + const buttons = Array.from(this.el.querySelectorAll('ion-picker-column-option')); + + let index = buttons.findIndex((option) => { + + /** + * If the whole picker column is disabled, the current value should appear active + * If the current value item is specifically disabled, it should not appear active + */ + if (!this.disabled && option.disabled) { + return false; + } + + return option.value === this.value; + }); + + if (index > -1) { + if (ev.key === 'ArrowDown') { + index += 1; + } else if (ev.key === 'ArrowUp') { + index -= 1; + } + + if (index < 0) { + index = 0; + } else if (index - 1 > buttons.length) { + index = buttons.length - 1; + } + + const buttonToFocus = buttons[index]; + if (buttonToFocus) { + this.value = buttonToFocus.value; + setTimeout(() => { + buttonToFocus.tabIndex = 0; + buttonToFocus.focus(); + }, 500); + } + + ev.preventDefault(); + + } + + }} class="picker-opts" tabindex={disabled ? undefined : 0} ref={(el) => { diff --git a/core/src/components/picker/test/a11y/index.html b/core/src/components/picker/test/a11y/index.html index ad27eebe1d..d6f209c9c2 100644 --- a/core/src/components/picker/test/a11y/index.html +++ b/core/src/components/picker/test/a11y/index.html @@ -25,6 +25,15 @@ Sixth Seventh + + First + Second + Third + Fourth + Fifth + Sixth + Seventh +