mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-15 22:18:10 +08:00
feat(select): add helperText and errorText properties (#30143)
Issue number: resolves #29205 --------- ## What is the current behavior? Select does not support helper and error text. ## What is the new behavior? - Adds support for `helperText` and `errorText` - Adds parts for `helper-text`, `error-text` and `supporting-text` - Adds an e2e test for helper and error text with functional tests and screenshot tests ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information [Preview](https://ionic-framework-git-rou-11551-ionic1.vercel.app/src/components/select/test/bottom-content) --------- Co-authored-by: swimer11 <65334157+swimer11@users.noreply.github.com> --------- Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
This commit is contained in:
@@ -41,6 +41,9 @@ import type { SelectChangeEventDetail, SelectInterface, SelectCompareFn } from '
|
||||
* @part icon - The select icon container.
|
||||
* @part container - The container for the selected text or placeholder.
|
||||
* @part label - The label text describing the select.
|
||||
* @part supporting-text - Supporting text displayed beneath the select.
|
||||
* @part helper-text - Supporting text displayed beneath the select when the select is valid.
|
||||
* @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-select',
|
||||
@@ -52,6 +55,8 @@ import type { SelectChangeEventDetail, SelectInterface, SelectCompareFn } from '
|
||||
})
|
||||
export class Select implements ComponentInterface {
|
||||
private inputId = `ion-sel-${selectIds++}`;
|
||||
private helperTextId = `${this.inputId}-helper-text`;
|
||||
private errorTextId = `${this.inputId}-error-text`;
|
||||
private overlay?: OverlaySelect;
|
||||
private focusEl?: HTMLButtonElement;
|
||||
private mutationO?: MutationObserver;
|
||||
@@ -98,6 +103,16 @@ export class Select implements ComponentInterface {
|
||||
*/
|
||||
@Prop() fill?: 'outline' | 'solid';
|
||||
|
||||
/**
|
||||
* Text that is placed under the select and displayed when an error is detected.
|
||||
*/
|
||||
@Prop() errorText?: string;
|
||||
|
||||
/**
|
||||
* Text that is placed under the select and displayed when no error is detected.
|
||||
*/
|
||||
@Prop() helperText?: string;
|
||||
|
||||
/**
|
||||
* The interface the select should use: `action-sheet`, `popover`, `alert`, or `modal`.
|
||||
*/
|
||||
@@ -1014,6 +1029,8 @@ export class Select implements ComponentInterface {
|
||||
aria-label={this.ariaLabel}
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded={`${isExpanded}`}
|
||||
aria-describedby={this.getHintTextID()}
|
||||
aria-invalid={this.getHintTextID() === this.errorTextId}
|
||||
aria-required={`${required}`}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
@@ -1022,6 +1039,55 @@ export class Select implements ComponentInterface {
|
||||
);
|
||||
}
|
||||
|
||||
private getHintTextID(): string | undefined {
|
||||
const { el, helperText, errorText, helperTextId, errorTextId } = this;
|
||||
|
||||
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
|
||||
return errorTextId;
|
||||
}
|
||||
|
||||
if (helperText) {
|
||||
return helperTextId;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the helper text or error text values
|
||||
*/
|
||||
private renderHintText() {
|
||||
const { helperText, errorText, helperTextId, errorTextId } = this;
|
||||
|
||||
return [
|
||||
<div id={helperTextId} class="helper-text" part="supporting-text helper-text">
|
||||
{helperText}
|
||||
</div>,
|
||||
<div id={errorTextId} class="error-text" part="supporting-text error-text">
|
||||
{errorText}
|
||||
</div>,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for rendering helper text, and error text. This element
|
||||
* should only be rendered if hint text is set.
|
||||
*/
|
||||
private renderBottomContent() {
|
||||
const { helperText, errorText } = this;
|
||||
|
||||
/**
|
||||
* undefined and empty string values should
|
||||
* be treated as not having helper/error text.
|
||||
*/
|
||||
const hasHintText = !!helperText || !!errorText;
|
||||
if (!hasHintText) {
|
||||
return;
|
||||
}
|
||||
|
||||
return <div class="select-bottom">{this.renderHintText()}</div>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value } =
|
||||
this;
|
||||
@@ -1101,6 +1167,7 @@ export class Select implements ComponentInterface {
|
||||
{hasFloatingOrStackedLabel && this.renderSelectIcon()}
|
||||
{shouldRenderHighlight && <div class="select-highlight"></div>}
|
||||
</label>
|
||||
{this.renderBottomContent()}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user