mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-24 14:58:36 +08:00
fix(alert): alert radio, checkbox and aria fixes
This commit is contained in:
@ -20,6 +20,7 @@ export class Alert {
|
|||||||
private animation: Animation;
|
private animation: Animation;
|
||||||
private activeId: string;
|
private activeId: string;
|
||||||
private inputType: string;
|
private inputType: string;
|
||||||
|
private hdrId: string;
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ export class Alert {
|
|||||||
@Prop() subTitle: string;
|
@Prop() subTitle: string;
|
||||||
@Prop() message: string;
|
@Prop() message: string;
|
||||||
@Prop() buttons: AlertButton[] = [];
|
@Prop() buttons: AlertButton[] = [];
|
||||||
@Prop() inputs: AlertInput[] = [];
|
@Prop({ mutable: true }) inputs: AlertInput[] = [];
|
||||||
@Prop() enableBackdropDismiss: boolean = true;
|
@Prop() enableBackdropDismiss: boolean = true;
|
||||||
|
|
||||||
@Prop() enterAnimation: AnimationBuilder;
|
@Prop() enterAnimation: AnimationBuilder;
|
||||||
@ -73,6 +74,12 @@ export class Alert {
|
|||||||
|
|
||||||
animation.onFinish((a: any) => {
|
animation.onFinish((a: any) => {
|
||||||
a.destroy();
|
a.destroy();
|
||||||
|
|
||||||
|
const firstInput = this.el.querySelector('[tabindex]') as HTMLElement;
|
||||||
|
if (firstInput) {
|
||||||
|
firstInput.focus();
|
||||||
|
}
|
||||||
|
|
||||||
this.ionViewDidEnter();
|
this.ionViewDidEnter();
|
||||||
resolve();
|
resolve();
|
||||||
}).play();
|
}).play();
|
||||||
@ -143,22 +150,31 @@ export class Alert {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rbClick(button: any) {
|
rbClick(inputIndex: number) {
|
||||||
this.inputs.forEach(input => {
|
this.inputs = this.inputs.map((input, index) => {
|
||||||
input.checked = (button === input);
|
input.checked = (inputIndex === index);
|
||||||
|
return input;
|
||||||
});
|
});
|
||||||
this.activeId = button.id;
|
|
||||||
|
|
||||||
if (button.handler) {
|
const rbButton = this.inputs[inputIndex];
|
||||||
button.handler(button);
|
this.activeId = rbButton.id;
|
||||||
|
|
||||||
|
if (rbButton.handler) {
|
||||||
|
rbButton.handler(rbButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cbClick(button: any) {
|
cbClick(inputIndex: number) {
|
||||||
button.checked = !button.checked;
|
this.inputs = this.inputs.map((input, index) => {
|
||||||
|
if (inputIndex === index) {
|
||||||
|
input.checked = !input.checked;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
});
|
||||||
|
|
||||||
if (button.handler) {
|
const cbButton = this.inputs[inputIndex];
|
||||||
button.handler(button);
|
if (cbButton.handler) {
|
||||||
|
cbButton.handler(cbButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +249,8 @@ export class Alert {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class='alert-checkbox-group'>
|
<div class='alert-checkbox-group'>
|
||||||
{ inputs.map(i => (
|
{ inputs.map((i, index) => (
|
||||||
<button onClick={() => this.cbClick(i)} aria-checked={i.checked} id={i.id} disabled={i.disabled} role='checkbox' class='alert-tappable alert-checkbox alert-checkbox-button'>
|
<button onClick={() => this.cbClick(index)} aria-checked={i.checked} id={i.id} disabled={i.disabled} tabIndex={0} role='checkbox' class='alert-tappable alert-checkbox alert-checkbox-button'>
|
||||||
<div class='button-inner'>
|
<div class='button-inner'>
|
||||||
<div class='alert-checkbox-icon'><div class='alert-checkbox-inner'></div></div>
|
<div class='alert-checkbox-icon'><div class='alert-checkbox-inner'></div></div>
|
||||||
<div class='alert-checkbox-label'>
|
<div class='alert-checkbox-label'>
|
||||||
@ -248,14 +264,12 @@ export class Alert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderRadio(inputs: AlertInput[]) {
|
renderRadio(inputs: AlertInput[]) {
|
||||||
const hdrId = 'TODO';
|
|
||||||
|
|
||||||
if (inputs.length === 0) return null;
|
if (inputs.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class='alert-radio-group' role='radiogroup' aria-labelledby={hdrId} aria-activedescendant={this.activeId}>
|
<div class='alert-radio-group' role='radiogroup' aria-labelledby={this.hdrId} aria-activedescendant={this.activeId}>
|
||||||
{ inputs.map(i => (
|
{ inputs.map((i, index) => (
|
||||||
<button onClick={() => this.rbClick(i)} aria-checked={i.checked} disabled={i.disabled} id={i.id} class='alert-radio-button alert-tappable alert-radio' role='radio'>
|
<button onClick={() => this.rbClick(index)} aria-checked={i.checked} disabled={i.disabled} id={i.id} tabIndex={0} class='alert-radio-button alert-tappable alert-radio' role='radio'>
|
||||||
<div class='button-inner'>
|
<div class='button-inner'>
|
||||||
<div class='alert-radio-icon'><div class='alert-radio-inner'></div></div>
|
<div class='alert-radio-icon'><div class='alert-radio-inner'></div></div>
|
||||||
<div class='alert-radio-label'>
|
<div class='alert-radio-label'>
|
||||||
@ -282,6 +296,7 @@ export class Alert {
|
|||||||
min={i.min}
|
min={i.min}
|
||||||
max={i.max}
|
max={i.max}
|
||||||
id={i.id}
|
id={i.id}
|
||||||
|
tabIndex={0}
|
||||||
class='alert-input'/>
|
class='alert-input'/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@ -290,16 +305,23 @@ export class Alert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const hdrId = 'TODO';
|
const hdrId = `${this.alertId}-hdr`;
|
||||||
const subHdrId = 'TODO';
|
const subHdrId = `${this.alertId}-sub-hdr`;
|
||||||
const msgId = 'TODO';
|
const msgId = `${this.alertId}-msg`;
|
||||||
|
|
||||||
|
if (this.title || !this.subTitle) {
|
||||||
|
this.hdrId = hdrId;
|
||||||
|
|
||||||
|
} else if (this.subTitle) {
|
||||||
|
this.hdrId = subHdrId;
|
||||||
|
}
|
||||||
|
|
||||||
const alertButtonGroupClass = {
|
const alertButtonGroupClass = {
|
||||||
'alert-button-group': true,
|
'alert-button-group': true,
|
||||||
'alert-button-group-vertical': this.buttons.length > 2
|
'alert-button-group-vertical': this.buttons.length > 2
|
||||||
};
|
};
|
||||||
|
|
||||||
let buttons = this.buttons
|
const buttons = this.buttons
|
||||||
.map(b => {
|
.map(b => {
|
||||||
if (typeof b === 'string') {
|
if (typeof b === 'string') {
|
||||||
b = { text: b };
|
b = { text: b };
|
||||||
@ -312,9 +334,9 @@ export class Alert {
|
|||||||
// checkboxes and inputs are all accepted, but they cannot be mixed.
|
// checkboxes and inputs are all accepted, but they cannot be mixed.
|
||||||
const inputTypes: string[] = [];
|
const inputTypes: string[] = [];
|
||||||
|
|
||||||
const inputs = this.inputs
|
this.inputs = this.inputs
|
||||||
.map((i, index) => {
|
.map((i, index) => {
|
||||||
const r: AlertInput = {
|
let r: AlertInput = {
|
||||||
type: i.type || 'text',
|
type: i.type || 'text',
|
||||||
name: i.name ? i.name : index + '',
|
name: i.name ? i.name : index + '',
|
||||||
placeholder: i.placeholder ? i.placeholder : '',
|
placeholder: i.placeholder ? i.placeholder : '',
|
||||||
@ -331,7 +353,7 @@ export class Alert {
|
|||||||
})
|
})
|
||||||
.filter(i => i !== null);
|
.filter(i => i !== null);
|
||||||
|
|
||||||
inputs.forEach(i => {
|
this.inputs.forEach(i => {
|
||||||
if (inputTypes.indexOf(i.type) < 0) {
|
if (inputTypes.indexOf(i.type) < 0) {
|
||||||
inputTypes.push(i.type);
|
inputTypes.push(i.type);
|
||||||
}
|
}
|
||||||
@ -362,19 +384,19 @@ export class Alert {
|
|||||||
{(() => {
|
{(() => {
|
||||||
switch (this.inputType) {
|
switch (this.inputType) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
return this.renderCheckbox(inputs);
|
return this.renderCheckbox(this.inputs);
|
||||||
|
|
||||||
case 'radio':
|
case 'radio':
|
||||||
return this.renderRadio(inputs);
|
return this.renderRadio(this.inputs);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return this.renderInput(inputs);
|
return this.renderInput(this.inputs);
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
|
|
||||||
<div class={alertButtonGroupClass}>
|
<div class={alertButtonGroupClass}>
|
||||||
{buttons.map(b =>
|
{buttons.map(b =>
|
||||||
<button class={this.buttonClass(b)} onClick={() => this.buttonClick(b)}>
|
<button class={this.buttonClass(b)} tabIndex={0} onClick={() => this.buttonClick(b)}>
|
||||||
<span class='button-inner'>
|
<span class='button-inner'>
|
||||||
{b.text}
|
{b.text}
|
||||||
</span>
|
</span>
|
||||||
@ -385,8 +407,15 @@ export class Alert {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostData() {
|
||||||
|
return {
|
||||||
|
id: this.alertId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface AlertOptions {
|
export interface AlertOptions {
|
||||||
title?: string;
|
title?: string;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
|
Reference in New Issue
Block a user