This commit is contained in:
Liam DeBeasi
2024-02-06 18:29:47 -05:00
parent ed7f30b672
commit ff3c491680
4 changed files with 88 additions and 3 deletions

View File

@@ -4067,6 +4067,7 @@ declare global {
};
interface HTMLIonPickerColumnElementEventMap {
"ionChange": PickerColumnChangeEventDetail;
"ionValueChange": void;
}
interface HTMLIonPickerColumnElement extends Components.IonPickerColumn, HTMLStencilElement {
addEventListener<K extends keyof HTMLIonPickerColumnElementEventMap>(type: K, listener: (this: HTMLIonPickerColumnElement, ev: IonPickerColumnCustomEvent<HTMLIonPickerColumnElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
@@ -6648,6 +6649,7 @@ declare namespace LocalJSX {
* Emitted when the value has changed.
*/
"onIonChange"?: (event: IonPickerColumnCustomEvent<PickerColumnChangeEventDetail>) => void;
"onIonValueChange"?: (event: IonPickerColumnCustomEvent<void>) => void;
/**
* The selected option in the picker.
*/

View File

@@ -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,
})}
>
<button tabindex="-1" aria-label={ariaLabel} disabled={disabled} onClick={() => this.onClick()}>
<button
aria-label={ariaLabel}
aria-selected={selected ? 'true' : 'false'}
role={selected ? 'spinbutton' : undefined}
aria-hidden={selected ? undefined : 'true'}
aria-valuetext={ariaLabel ?? this.el.innerText}
tabindex="-1"
disabled={disabled}
onClick={() => this.onClick()}
>
<slot></slot>
</button>
</Host>

View File

@@ -69,6 +69,8 @@ export class PickerColumn implements ComponentInterface {
*/
@Event() ionChange!: EventEmitter<PickerColumnChangeEventDetail>;
@Event() ionValueChange!: EventEmitter<void>
@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 {
>
<slot name="prefix"></slot>
<div
onKeyDown={(ev) => {
console.log('helloooo',ev)
const buttons = Array.from(this.el.querySelectorAll<HTMLIonPickerColumnOptionElement>('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) => {

View File

@@ -25,6 +25,15 @@
<ion-picker-column-option value="6" color="tertiary">Sixth</ion-picker-column-option>
<ion-picker-column-option value="7" color="tertiary">Seventh</ion-picker-column-option>
</ion-picker-column>
<ion-picker-column color="tertiary" value="3">
<ion-picker-column-option value="1" color="tertiary">First</ion-picker-column-option>
<ion-picker-column-option value="2" color="tertiary">Second</ion-picker-column-option>
<ion-picker-column-option value="3" color="tertiary">Third</ion-picker-column-option>
<ion-picker-column-option value="4" color="tertiary">Fourth</ion-picker-column-option>
<ion-picker-column-option value="5" color="tertiary">Fifth</ion-picker-column-option>
<ion-picker-column-option value="6" color="tertiary">Sixth</ion-picker-column-option>
<ion-picker-column-option value="7" color="tertiary">Seventh</ion-picker-column-option>
</ion-picker-column>
</ion-picker>
</ion-content>
</ion-app>