mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
fix(inputs): disabled handling (#16071)
This commit is contained in:
@ -564,13 +564,13 @@ export class Radio {
|
||||
}
|
||||
|
||||
export declare interface RadioGroup extends StencilComponents<'IonRadioGroup'> {}
|
||||
@Component({ selector: 'ion-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['allowEmptySelection', 'name', 'disabled', 'value'] })
|
||||
@Component({ selector: 'ion-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['allowEmptySelection', 'name', 'value'] })
|
||||
export class RadioGroup {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(r: ElementRef) {
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['allowEmptySelection', 'name', 'disabled', 'value']);
|
||||
proxyInputs(this, el, ['allowEmptySelection', 'name', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange']);
|
||||
}
|
||||
}
|
||||
|
70
core/src/components.d.ts
vendored
70
core/src/components.d.ts
vendored
@ -1292,7 +1292,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the datetime as a valid ISO 8601 datetime string.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
/**
|
||||
* Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`.
|
||||
*/
|
||||
@ -1386,7 +1386,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the datetime as a valid ISO 8601 datetime string.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
/**
|
||||
* Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`.
|
||||
*/
|
||||
@ -1847,7 +1847,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the input.
|
||||
*/
|
||||
'value': string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
interface IonInputAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
@ -1989,7 +1989,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the input.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
|
||||
interface IonItemDivider {
|
||||
@ -2207,7 +2207,7 @@ export namespace Components {
|
||||
*/
|
||||
'mode': Mode;
|
||||
/**
|
||||
* The position determines where and how the label behaves inside an item. Possible values are: 'inline' | 'fixed' | 'stacked' | 'floating'
|
||||
* The position determines where and how the label behaves inside an item.
|
||||
*/
|
||||
'position'?: 'fixed' | 'stacked' | 'floating';
|
||||
}
|
||||
@ -2225,7 +2225,7 @@ export namespace Components {
|
||||
*/
|
||||
'onIonStyle'?: (event: CustomEvent<StyleEvent>) => void;
|
||||
/**
|
||||
* The position determines where and how the label behaves inside an item. Possible values are: 'inline' | 'fixed' | 'stacked' | 'floating'
|
||||
* The position determines where and how the label behaves inside an item.
|
||||
*/
|
||||
'position'?: 'fixed' | 'stacked' | 'floating';
|
||||
}
|
||||
@ -2564,7 +2564,7 @@ export namespace Components {
|
||||
*/
|
||||
'contentId'?: string;
|
||||
/**
|
||||
* If `true`, the menu is disabled. Default `false`.
|
||||
* If `true`, the menu is disabled. Defaults to `false`.
|
||||
*/
|
||||
'disabled': boolean;
|
||||
/**
|
||||
@ -2596,7 +2596,7 @@ export namespace Components {
|
||||
*/
|
||||
'side': Side;
|
||||
/**
|
||||
* If `true`, swiping the menu is enabled. Default `true`.
|
||||
* If `true`, swiping the menu is enabled. Defaults to `true`.
|
||||
*/
|
||||
'swipeGesture': boolean;
|
||||
/**
|
||||
@ -2614,7 +2614,7 @@ export namespace Components {
|
||||
*/
|
||||
'contentId'?: string;
|
||||
/**
|
||||
* If `true`, the menu is disabled. Default `false`.
|
||||
* If `true`, the menu is disabled. Defaults to `false`.
|
||||
*/
|
||||
'disabled'?: boolean;
|
||||
/**
|
||||
@ -2650,7 +2650,7 @@ export namespace Components {
|
||||
*/
|
||||
'side'?: Side;
|
||||
/**
|
||||
* If `true`, swiping the menu is enabled. Default `true`.
|
||||
* If `true`, swiping the menu is enabled. Defaults to `true`.
|
||||
*/
|
||||
'swipeGesture'?: boolean;
|
||||
/**
|
||||
@ -3308,14 +3308,10 @@ export namespace Components {
|
||||
|
||||
interface IonRadioGroup {
|
||||
/**
|
||||
* If `true`, the radios can be deselected. Default false.
|
||||
* If `true`, the radios can be deselected. Defaults to `false`.
|
||||
*/
|
||||
'allowEmptySelection': boolean;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the radio group. Default false.
|
||||
*/
|
||||
'disabled': boolean;
|
||||
/**
|
||||
* The name of the control, which is submitted with the form data.
|
||||
*/
|
||||
'name': string;
|
||||
@ -3326,14 +3322,10 @@ export namespace Components {
|
||||
}
|
||||
interface IonRadioGroupAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
* If `true`, the radios can be deselected. Default false.
|
||||
* If `true`, the radios can be deselected. Defaults to `false`.
|
||||
*/
|
||||
'allowEmptySelection'?: boolean;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the radio group. Default false.
|
||||
*/
|
||||
'disabled'?: boolean;
|
||||
/**
|
||||
* The name of the control, which is submitted with the form data.
|
||||
*/
|
||||
'name'?: string;
|
||||
@ -3371,7 +3363,7 @@ export namespace Components {
|
||||
/**
|
||||
* the value of the radio.
|
||||
*/
|
||||
'value': any | null;
|
||||
'value'?: any | null;
|
||||
}
|
||||
interface IonRadioAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
@ -3814,7 +3806,7 @@ export namespace Components {
|
||||
|
||||
interface IonSearchbar {
|
||||
/**
|
||||
* If `true`, enable searchbar animation. Default `false`.
|
||||
* If `true`, enable searchbar animation. Defaults to `false`.
|
||||
*/
|
||||
'animated': boolean;
|
||||
/**
|
||||
@ -3862,11 +3854,11 @@ export namespace Components {
|
||||
*/
|
||||
'setFocus': () => void;
|
||||
/**
|
||||
* If `true`, show the cancel button. Default `false`.
|
||||
* If `true`, show the cancel button. Defaults to `false`.
|
||||
*/
|
||||
'showCancelButton': boolean;
|
||||
/**
|
||||
* If `true`, enable spellcheck on the input. Default `false`.
|
||||
* If `true`, enable spellcheck on the input. Defaults to `false`.
|
||||
*/
|
||||
'spellcheck': boolean;
|
||||
/**
|
||||
@ -3876,11 +3868,11 @@ export namespace Components {
|
||||
/**
|
||||
* the value of the searchbar.
|
||||
*/
|
||||
'value': string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
interface IonSearchbarAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
* If `true`, enable searchbar animation. Default `false`.
|
||||
* If `true`, enable searchbar animation. Defaults to `false`.
|
||||
*/
|
||||
'animated'?: boolean;
|
||||
/**
|
||||
@ -3948,11 +3940,11 @@ export namespace Components {
|
||||
*/
|
||||
'searchIcon'?: string;
|
||||
/**
|
||||
* If `true`, show the cancel button. Default `false`.
|
||||
* If `true`, show the cancel button. Defaults to `false`.
|
||||
*/
|
||||
'showCancelButton'?: boolean;
|
||||
/**
|
||||
* If `true`, enable spellcheck on the input. Default `false`.
|
||||
* If `true`, enable spellcheck on the input. Defaults to `false`.
|
||||
*/
|
||||
'spellcheck'?: boolean;
|
||||
/**
|
||||
@ -3962,7 +3954,7 @@ export namespace Components {
|
||||
/**
|
||||
* the value of the searchbar.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
|
||||
interface IonSegmentButton {
|
||||
@ -3975,7 +3967,7 @@ export namespace Components {
|
||||
*/
|
||||
'color'?: Color;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the segment button. Default false.
|
||||
* If `true`, the user cannot interact with the segment button. Defaults to `false`.
|
||||
*/
|
||||
'disabled': boolean;
|
||||
/**
|
||||
@ -3997,7 +3989,7 @@ export namespace Components {
|
||||
*/
|
||||
'color'?: Color;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the segment button. Default false.
|
||||
* If `true`, the user cannot interact with the segment button. Defaults to `false`.
|
||||
*/
|
||||
'disabled'?: boolean;
|
||||
/**
|
||||
@ -4067,7 +4059,7 @@ export namespace Components {
|
||||
/**
|
||||
* The text value of the option.
|
||||
*/
|
||||
'value'?: any;
|
||||
'value'?: any | null;
|
||||
}
|
||||
interface IonSelectOptionAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
@ -4089,7 +4081,7 @@ export namespace Components {
|
||||
/**
|
||||
* The text value of the option.
|
||||
*/
|
||||
'value'?: any;
|
||||
'value'?: any | null;
|
||||
}
|
||||
|
||||
interface IonSelectPopover {
|
||||
@ -4816,7 +4808,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the textarea.
|
||||
*/
|
||||
'value': string;
|
||||
'value'?: string | null;
|
||||
/**
|
||||
* Indicates how the control wraps text. Possible values are: `"hard"`, `"soft"`, `"off"`.
|
||||
*/
|
||||
@ -4910,7 +4902,7 @@ export namespace Components {
|
||||
/**
|
||||
* The value of the textarea.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
/**
|
||||
* Indicates how the control wraps text. Possible values are: `"hard"`, `"soft"`, `"off"`.
|
||||
*/
|
||||
@ -5102,7 +5094,7 @@ export namespace Components {
|
||||
*/
|
||||
'color'?: Color;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the toggle. Default false.
|
||||
* If `true`, the user cannot interact with the toggle. Defaults to `false`.
|
||||
*/
|
||||
'disabled': boolean;
|
||||
/**
|
||||
@ -5116,7 +5108,7 @@ export namespace Components {
|
||||
/**
|
||||
* the value of the toggle.
|
||||
*/
|
||||
'value': string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
interface IonToggleAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
@ -5128,7 +5120,7 @@ export namespace Components {
|
||||
*/
|
||||
'color'?: Color;
|
||||
/**
|
||||
* If `true`, the user cannot interact with the toggle. Default false.
|
||||
* If `true`, the user cannot interact with the toggle. Defaults to `false`.
|
||||
*/
|
||||
'disabled'?: boolean;
|
||||
/**
|
||||
@ -5158,7 +5150,7 @@ export namespace Components {
|
||||
/**
|
||||
* the value of the toggle.
|
||||
*/
|
||||
'value'?: string;
|
||||
'value'?: string | null;
|
||||
}
|
||||
|
||||
interface IonToolbar {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { CheckedInputChangeEvent, Color, Mode, StyleEvent } from '../../interface';
|
||||
import { deferEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { renderHiddenInput } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -78,10 +78,6 @@ export class Checkbox implements ComponentInterface {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
}
|
||||
|
||||
@Watch('checked')
|
||||
checkedChanged(isChecked: boolean) {
|
||||
this.ionChange.emit({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { InputChangeEvent, Mode, PickerColumn, PickerColumnOption, PickerOptions, StyleEvent } from '../../interface';
|
||||
import { clamp, deferEvent } from '../../utils/helpers';
|
||||
import { clamp } from '../../utils/helpers';
|
||||
import { hostContext } from '../../utils/theme';
|
||||
|
||||
import { DatetimeData, LocaleData, convertDataToISO, convertFormatToKey, convertToArrayOfNumbers, convertToArrayOfStrings, dateDataSortValue, dateSortValue, dateValueRange, daysInMonth, getValueFromFormat, parseDate, parseTemplate, renderDatetime, renderTextFormat, updateDate } from './datetime-util';
|
||||
@ -179,7 +179,7 @@ export class Datetime implements ComponentInterface {
|
||||
/**
|
||||
* The value of the datetime as a valid ISO 8601 datetime string.
|
||||
*/
|
||||
@Prop({ mutable: true }) value?: string;
|
||||
@Prop({ mutable: true }) value?: string | null;
|
||||
|
||||
/**
|
||||
* Update the datetime value when the value changes
|
||||
@ -212,7 +212,6 @@ export class Datetime implements ComponentInterface {
|
||||
// first see if locale names were provided in the inputs
|
||||
// then check to see if they're in the config
|
||||
// if neither were provided then it will use default English names
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
this.locale = {
|
||||
// this.locale[type] = convertToArrayOfStrings((this[type] ? this[type] : this.config.get(type), type);
|
||||
monthNames: convertToArrayOfStrings(this.monthNames, 'monthNames'),
|
||||
@ -222,9 +221,6 @@ export class Datetime implements ComponentInterface {
|
||||
};
|
||||
|
||||
this.updateDatetimeValue(this.value);
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
@ -502,7 +498,7 @@ export class Datetime implements ComponentInterface {
|
||||
this.text = renderDatetime(template, this.datetimeValue, this.locale);
|
||||
}
|
||||
|
||||
hasValue(): boolean {
|
||||
private hasValue(): boolean {
|
||||
const val = this.datetimeValue;
|
||||
return Object.keys(val).length > 0;
|
||||
}
|
||||
@ -538,7 +534,6 @@ export class Datetime implements ComponentInterface {
|
||||
onClick={this.open.bind(this)}
|
||||
class="datetime-cover"
|
||||
>
|
||||
{this.mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
];
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ dates in JavaScript.
|
||||
| `pickerFormat` | `picker-format` | The format of the date and time picker columns the user selects. A datetime input can have one or many datetime parts, each getting their own column which allow individual selection of that particular datetime part. For example, year and month columns are two individually selectable columns which help choose an exact date from the datetime picker. Each column follows the string parse format. Defaults to use `displayFormat`. | `string \| undefined` |
|
||||
| `pickerOptions` | -- | Any additional options that the picker interface can accept. See the [Picker API docs](../../picker/Picker) for the picker options. | `PickerOptions \| undefined` |
|
||||
| `placeholder` | `placeholder` | The text to display when there's no date selected yet. Using lowercase to match the input attribute | `null \| string \| undefined` |
|
||||
| `value` | `value` | The value of the datetime as a valid ISO 8601 datetime string. | `string \| undefined` |
|
||||
| `value` | `value` | The value of the datetime as a valid ISO 8601 datetime string. | `null \| string \| undefined` |
|
||||
| `yearValues` | -- | Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. | `number \| number[] \| string \| undefined` |
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>MM DD YY</ion-label>
|
||||
<ion-label position="floating">MM DD YY</ion-label>
|
||||
<ion-datetime display-format="MM DD YY" placeholder="Select Date"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { Color, Mode, StyleEvent, TextFieldTypes, TextInputChangeEvent } from '../../interface';
|
||||
import { debounceEvent, deferEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { debounceEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -173,7 +173,7 @@ export class Input implements ComponentInterface {
|
||||
/**
|
||||
* The value of the input.
|
||||
*/
|
||||
@Prop({ mutable: true }) value = '';
|
||||
@Prop({ mutable: true }) value?: string | null = '';
|
||||
|
||||
/**
|
||||
* Update the native input element when the value changes
|
||||
@ -229,12 +229,11 @@ export class Input implements ComponentInterface {
|
||||
if (this.clearOnEdit === undefined && this.type === 'password') {
|
||||
this.clearOnEdit = true;
|
||||
}
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
this.debounceChanged();
|
||||
this.emitStyle();
|
||||
|
||||
this.ionInputDidLoad.emit();
|
||||
}
|
||||
@ -333,7 +332,8 @@ export class Input implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
renderHiddenInput(this.el, this.name, this.getValue(), this.disabled);
|
||||
const value = this.getValue();
|
||||
renderHiddenInput(this.el, this.name, value, this.disabled);
|
||||
|
||||
return [
|
||||
<input
|
||||
@ -362,7 +362,7 @@ export class Input implements ComponentInterface {
|
||||
step={this.step}
|
||||
size={this.size}
|
||||
type={this.type}
|
||||
value={this.getValue()}
|
||||
value={value}
|
||||
onInput={this.onInput}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={this.onFocus}
|
||||
|
@ -39,7 +39,7 @@ It is meant for text `type` inputs only, such as `"text"`, `"password"`, `"email
|
||||
| `spellcheck` | `spellcheck` | If `true`, the element will have its spelling and grammar checked. Defaults to `false`. | `boolean` |
|
||||
| `step` | `step` | Works with the min and max attributes to limit the increments at which a value can be set. Possible values are: `"any"` or a positive floating point number. | `string \| undefined` |
|
||||
| `type` | `type` | The type of control to display. The default type is text. Possible values are: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, or `"url"`. | `"date" \| "email" \| "number" \| "password" \| "search" \| "tel" \| "text" \| "url"` |
|
||||
| `value` | `value` | The value of the input. | `string` |
|
||||
| `value` | `value` | The value of the input. | `null \| string \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -142,6 +142,11 @@
|
||||
// iOS Stacked & Floating Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-label-floating),
|
||||
:host(.item-label-stacked) {
|
||||
--min-height: 68px;
|
||||
}
|
||||
|
||||
:host(.item-label-stacked) ::slotted(ion-input),
|
||||
:host(.item-label-floating) ::slotted(ion-input),
|
||||
:host(.item-label-stacked) ::slotted(ion-textarea),
|
||||
|
@ -158,6 +158,11 @@
|
||||
// Material Design Stacked & Floating Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-label-floating),
|
||||
:host(.item-label-stacked) {
|
||||
--min-height: 65px;
|
||||
}
|
||||
|
||||
// TODO: refactor
|
||||
:host(.item-label-stacked) ::slotted(ion-input),
|
||||
:host(.item-label-floating) ::slotted(ion-input),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, ComponentInterface, Element, Listen, Prop, State } from '@stencil/core';
|
||||
|
||||
import { Color, CssClassMap, Mode, RouterDirection } from '../../interface';
|
||||
import { Color, CssClassMap, Mode, RouterDirection, StyleEvent } from '../../interface';
|
||||
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -80,23 +80,25 @@ export class Item implements ComponentInterface {
|
||||
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
|
||||
|
||||
@Listen('ionStyle')
|
||||
itemStyle(ev: UIEvent) {
|
||||
itemStyle(ev: CustomEvent<StyleEvent>) {
|
||||
ev.stopPropagation();
|
||||
|
||||
const tagName: string = (ev.target as HTMLElement).tagName;
|
||||
const updatedStyles = ev.detail as any;
|
||||
const updatedKeys = Object.keys(ev.detail);
|
||||
const tagName = (ev.target as HTMLElement).tagName;
|
||||
const updatedStyles = ev.detail;
|
||||
const newStyles = {} as any;
|
||||
const childStyles = this.itemStyles.get(tagName) || {};
|
||||
|
||||
let hasStyleChange = false;
|
||||
for (const key of updatedKeys) {
|
||||
Object.keys(updatedStyles).forEach(key => {
|
||||
const itemKey = `item-${key}`;
|
||||
const newValue = updatedStyles[key];
|
||||
if (newValue !== childStyles[itemKey]) {
|
||||
hasStyleChange = true;
|
||||
}
|
||||
newStyles[itemKey] = newValue;
|
||||
}
|
||||
if (newValue) {
|
||||
newStyles[itemKey] = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasStyleChange) {
|
||||
this.itemStyles.set(tagName, newStyles);
|
||||
|
@ -5,6 +5,33 @@ it('item: inputs', async () => {
|
||||
url: '/src/components/item/test/inputs?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
// Default case, enabled and no value
|
||||
let compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
// Disable everything
|
||||
await page.click('#btnDisabled');
|
||||
compare = await page.compareScreenshot('should disable all');
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
// Reenable and set some value
|
||||
await page.click('#btnDisabled');
|
||||
await page.click('#btnSomeValue');
|
||||
compare = await page.compareScreenshot('should reenable and set value');
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
// Set "null"
|
||||
await page.click('#btnNullValue');
|
||||
compare = await page.compareScreenshot('should set null');
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
// Set "empty"
|
||||
await page.click('#btnEmptyValue');
|
||||
compare = await page.compareScreenshot('should set empty');
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
// Set "empty"
|
||||
await page.click('#btnEmptyValue');
|
||||
compare = await page.compareScreenshot('should set empty');
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
|
@ -16,31 +16,26 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Item inputs</ion-title>
|
||||
<ion-buttons slot="primary">
|
||||
<ion-button id="toggleDisabled" class="e2eDisableButton" onClick="toggleDisabled()">
|
||||
<span id="toggleDisabledSpan"></span>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-content padding-vertical>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Simple item</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item id="item" onclick="testClick(event)">
|
||||
<ion-item id="item" button onclick="testClick(event)">
|
||||
<ion-label>Item Button</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label position="floating">DateTime</ion-label>
|
||||
<ion-datetime id="datetime" value="2016-12-09" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY" required></ion-datetime>
|
||||
<ion-label>DateTime</ion-label>
|
||||
<ion-datetime id="datetime" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label position="floating">Select</ion-label>
|
||||
<ion-label>Select</ion-label>
|
||||
<ion-select id="select">
|
||||
<ion-select-option value="">No Game Console</ion-select-option>
|
||||
<ion-select-option value="nes">NES</ion-select-option>
|
||||
@ -54,12 +49,12 @@
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle</ion-label>
|
||||
<ion-toggle name="Actually" slot="end" id="toggle" checked></ion-toggle>
|
||||
<ion-toggle id="toggle" name="Actually" slot="end"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label position="floating">Input (text)</ion-label>
|
||||
<ion-input id="text" value="Text"></ion-input>
|
||||
<ion-label>Input (text)</ion-label>
|
||||
<ion-input id="text"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
@ -69,12 +64,7 @@
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Checkbox</ion-label>
|
||||
<ion-checkbox id="checkbox" slot="start" checked></ion-checkbox>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle (left)</ion-label>
|
||||
<ion-toggle id="toggle" slot="start" checked></ion-toggle>
|
||||
<ion-checkbox id="checkbox" slot="start"></ion-checkbox>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
@ -82,33 +72,115 @@
|
||||
<ion-range id="range" value="10"></ion-range>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-list-header>Controls</ion-list-header>
|
||||
<ion-item-divider>Value Controls</ion-item-divider>
|
||||
|
||||
<ion-item button onClick="toggleDisabled()" id="btnDisabled">
|
||||
Toggle Disable
|
||||
</ion-item>
|
||||
<ion-item button onClick="setSomeValue()" id="btnSomeValue">
|
||||
Set some value
|
||||
</ion-item>
|
||||
<ion-item button onClick="setEmptyValue()" id="btnEmptyValue">
|
||||
Set empty value
|
||||
</ion-item>
|
||||
<ion-item button onClick="setNullValue()" id="btnNullValue">
|
||||
Set "null" value
|
||||
</ion-item>
|
||||
<ion-item button onClick="setUndefinedValue()" id="btnUndefinedValue">
|
||||
Set "undefined" value
|
||||
</ion-item>
|
||||
<ion-item-divider>Label Controls</ion-item-divider>
|
||||
<ion-item button onClick="setLabelDefault()" id="btnLabelDefault">
|
||||
Default
|
||||
</ion-item>
|
||||
<ion-item button onClick="setLabelFloating()" id="btnLabelFloating">
|
||||
Floating
|
||||
</ion-item>
|
||||
<ion-item button onClick="setLabelStacked()" id="btnLabelStacked">
|
||||
Stacked
|
||||
</ion-item>
|
||||
<ion-item button onClick="setLabelFixed()" id="btnLabelFixed">
|
||||
Fixed
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
var disabledIds = ['item', 'datetime', 'select', 'toggle', 'text', 'placeholder', 'checkbox', 'toggle', 'range']
|
||||
var toggleDisabledButton = document.getElementById('toggleDisabledSpan');
|
||||
var isDisabled = true;
|
||||
|
||||
toggleDisabled();
|
||||
var ids = ['item', 'datetime', 'select', 'toggle', 'text', 'placeholder', 'checkbox', 'toggle', 'range']
|
||||
var isDisabled = false;
|
||||
|
||||
function toggleDisabled() {
|
||||
isDisabled = !isDisabled;
|
||||
toggleAll(isDisabled);
|
||||
toggleDisabledButton.innerHTML = isDisabled ? 'Enable' : 'Disable';
|
||||
Object.values(getInputs()).forEach(el => el.disabled = isDisabled);
|
||||
}
|
||||
|
||||
function toggleAll(disabled) {
|
||||
for (var i = 0; i < disabledIds.length; i++) {
|
||||
var el = document.getElementById(disabledIds[i]);
|
||||
el.disabled = disabled;
|
||||
function setSomeValue() {
|
||||
const {datetime, select, toggle, text, placeholder, checkbox, range} = getInputs();
|
||||
text.value = placeholder.value = 'Some text';
|
||||
toggle.checked = checkbox.checked = true;
|
||||
datetime.value = '2016-12-09';
|
||||
range.value = 20;
|
||||
select.value = 'nes';
|
||||
}
|
||||
|
||||
function setEmptyValue() {
|
||||
const {datetime, select, text, placeholder, range} = getInputs();
|
||||
text.value = placeholder.value = '';
|
||||
datetime.value = '';
|
||||
range.value = 0;
|
||||
select.value = '';
|
||||
}
|
||||
|
||||
function setNullValue() {
|
||||
Object.values(getInputs()).forEach(el => el.value = null);
|
||||
const {toggle, checkbox} = getInputs();
|
||||
toggle.checked = checkbox.checked = false;
|
||||
}
|
||||
|
||||
function setUndefinedValue() {
|
||||
Object.values(getInputs()).forEach(el => el.value = undefined);
|
||||
const {toggle, checkbox} = getInputs();
|
||||
toggle.checked = checkbox.checked = false;
|
||||
}
|
||||
|
||||
function setLabelDefault() {
|
||||
setLabelPosition(undefined);
|
||||
}
|
||||
|
||||
function setLabelFixed() {
|
||||
setLabelPosition('fixed');
|
||||
}
|
||||
|
||||
function setLabelFloating() {
|
||||
setLabelPosition('floating');
|
||||
}
|
||||
|
||||
function setLabelStacked() {
|
||||
setLabelPosition('stacked');
|
||||
}
|
||||
|
||||
function setLabelPosition(position) {
|
||||
Array.from(document.querySelectorAll('ion-label'))
|
||||
.forEach(label => label.position = position);
|
||||
}
|
||||
|
||||
function getInputs() {
|
||||
const elements = {};
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
elements[ids[i]] = document.getElementById(ids[i]);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
function testClick(ev) {
|
||||
console.log('CLICK!', ev.target.tagName, ev.target.textContent.trim());
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
@ -21,7 +21,7 @@
|
||||
:host(.label-stacked) {
|
||||
@include margin(null, null, 4px, null);
|
||||
|
||||
font-size: 12px;
|
||||
font-size: 13.6px;
|
||||
}
|
||||
|
||||
:host(.label-floating) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.label-stacked) {
|
||||
font-size: 12px;
|
||||
font-size: 12.8px;
|
||||
}
|
||||
|
||||
:host(.label-floating) {
|
||||
|
@ -29,7 +29,6 @@ export class Label implements ComponentInterface {
|
||||
|
||||
/**
|
||||
* The position determines where and how the label behaves inside an item.
|
||||
* Possible values are: 'inline' | 'fixed' | 'stacked' | 'floating'
|
||||
*/
|
||||
@Prop() position?: 'fixed' | 'stacked' | 'floating';
|
||||
|
||||
@ -42,11 +41,10 @@ export class Label implements ComponentInterface {
|
||||
|
||||
componentWillLoad() {
|
||||
this.noAnimate = (this.position === 'floating');
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.positionChanged();
|
||||
|
||||
if (this.noAnimate) {
|
||||
setTimeout(() => {
|
||||
this.noAnimate = false;
|
||||
@ -56,6 +54,10 @@ export class Label implements ComponentInterface {
|
||||
|
||||
@Watch('position')
|
||||
positionChanged() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
private emitStyle() {
|
||||
const position = this.position;
|
||||
this.ionStyle.emit({
|
||||
'label': true,
|
||||
|
@ -12,7 +12,7 @@ Label is a wrapper element that can be used in combination with `ion-item`, `ion
|
||||
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `position` | `position` | The position determines where and how the label behaves inside an item. Possible values are: 'inline' \| 'fixed' \| 'stacked' \| 'floating' | `"fixed" \| "floating" \| "stacked" \| undefined` |
|
||||
| `position` | `position` | The position determines where and how the label behaves inside an item. | `"fixed" \| "floating" \| "stacked" \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -77,7 +77,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
}
|
||||
|
||||
/**
|
||||
* If `true`, the menu is disabled. Default `false`.
|
||||
* If `true`, the menu is disabled. Defaults to `false`.
|
||||
*/
|
||||
@Prop({ mutable: true }) disabled = false;
|
||||
|
||||
@ -102,7 +102,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
}
|
||||
|
||||
/**
|
||||
* If `true`, swiping the menu is enabled. Default `true`.
|
||||
* If `true`, swiping the menu is enabled. Defaults to `true`.
|
||||
*/
|
||||
@Prop() swipeGesture = true;
|
||||
|
||||
|
@ -16,11 +16,11 @@ These can be controlled from the templates, or programmatically using the MenuCo
|
||||
| Property | Attribute | Description | Type |
|
||||
| -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------- |
|
||||
| `contentId` | `content-id` | The content's id the menu should use. | `string \| undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the menu is disabled. Default `false`. | `boolean` |
|
||||
| `disabled` | `disabled` | If `true`, the menu is disabled. Defaults to `false`. | `boolean` |
|
||||
| `maxEdgeStart` | `max-edge-start` | The edge threshold for dragging the menu open. If a drag/swipe happens over this value, the menu is not triggered. | `number` |
|
||||
| `menuId` | `menu-id` | An id for the menu. | `string \| undefined` |
|
||||
| `side` | `side` | Which side of the view the menu should be placed. Default `"start"`. | `"end" \| "start"` |
|
||||
| `swipeGesture` | `swipe-gesture` | If `true`, swiping the menu is enabled. Default `true`. | `boolean` |
|
||||
| `swipeGesture` | `swipe-gesture` | If `true`, swiping the menu is enabled. Defaults to `true`. | `boolean` |
|
||||
| `type` | `type` | The display type of the menu. Available options: `"overlay"`, `"reveal"`, `"push"`. | `string` |
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ export class RadioGroup implements ComponentInterface {
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
/**
|
||||
* If `true`, the radios can be deselected. Default false.
|
||||
* If `true`, the radios can be deselected. Defaults to `false`.
|
||||
*/
|
||||
@Prop() allowEmptySelection = false;
|
||||
|
||||
@ -23,18 +23,6 @@ export class RadioGroup implements ComponentInterface {
|
||||
*/
|
||||
@Prop() name: string = this.inputId;
|
||||
|
||||
/**
|
||||
* If `true`, the user cannot interact with the radio group. Default false.
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
@Watch('disabled')
|
||||
disabledChanged() {
|
||||
for (const radio of this.radios) {
|
||||
radio.disabled = this.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the value of the radio group.
|
||||
*/
|
||||
@ -99,7 +87,6 @@ export class RadioGroup implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
this.disabledChanged();
|
||||
this.updateRadios();
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,11 @@ radio button within the same group.
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type |
|
||||
| --------------------- | ----------------------- | ------------------------------------------------------------------------ | --------- |
|
||||
| `allowEmptySelection` | `allow-empty-selection` | If `true`, the radios can be deselected. Default false. | `boolean` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the radio group. Default false. | `boolean` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `value` | -- | the value of the radio group. | `any` |
|
||||
| Property | Attribute | Description | Type |
|
||||
| --------------------- | ----------------------- | --------------------------------------------------------------- | --------- |
|
||||
| `allowEmptySelection` | `allow-empty-selection` | If `true`, the radios can be deselected. Defaults to `false`. | `boolean` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `value` | -- | the value of the radio group. | `any` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { CheckedInputChangeEvent, Color, Mode, StyleEvent } from '../../interface';
|
||||
import { deferEvent } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -52,7 +51,7 @@ export class Radio implements ComponentInterface {
|
||||
/**
|
||||
* the value of the radio.
|
||||
*/
|
||||
@Prop({ mutable: true }) value!: any | null;
|
||||
@Prop({ mutable: true }) value?: any | null;
|
||||
|
||||
/**
|
||||
* Emitted when the radio loads.
|
||||
@ -85,9 +84,6 @@ export class Radio implements ComponentInterface {
|
||||
@Event() ionBlur!: EventEmitter<void>;
|
||||
|
||||
componentWillLoad() {
|
||||
this.ionSelect = deferEvent(this.ionSelect);
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
|
||||
if (this.value == null) {
|
||||
this.value = this.inputId;
|
||||
}
|
||||
@ -139,7 +135,7 @@ export class Radio implements ComponentInterface {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
emitStyle() {
|
||||
private emitStyle() {
|
||||
this.ionStyle.emit({
|
||||
'radio-checked': this.checked,
|
||||
'interactive-disabled': this.disabled,
|
||||
|
@ -19,7 +19,7 @@
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
flex: 3;
|
||||
align-items: center;
|
||||
|
||||
font-family: $font-family-base;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Prop, QueueApi, State, Watch } from '@stencil/core';
|
||||
|
||||
import { Color, Gesture, GestureDetail, InputChangeEvent, Mode, RangeValue, StyleEvent } from '../../interface';
|
||||
import { clamp, debounceEvent, deferEvent } from '../../utils/helpers';
|
||||
import { clamp, debounceEvent } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
import { Knob, RangeEventDetail } from './range-interface';
|
||||
@ -148,8 +148,6 @@ export class Range implements ComponentInterface {
|
||||
@Event() ionBlur!: EventEmitter<void>;
|
||||
|
||||
componentWillLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
|
||||
this.updateRatio();
|
||||
this.debounceChanged();
|
||||
this.emitStyle();
|
||||
|
@ -11,23 +11,23 @@ A Searchbar should be used instead of an input to search lists. A clear button i
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type |
|
||||
| ------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
||||
| `animated` | `animated` | If `true`, enable searchbar animation. Default `false`. | `boolean` |
|
||||
| `autocomplete` | `autocomplete` | Set the input's autocomplete property. Default `"off"`. | `"off" \| "on"` |
|
||||
| `autocorrect` | `autocorrect` | Set the input's autocorrect property. Default `"off"`. | `"off" \| "on"` |
|
||||
| `cancelButtonIcon` | `cancel-button-icon` | Set the cancel button icon. Only applies to `md` mode. Defaults to `"md-arrow-back"`. | `string` |
|
||||
| `cancelButtonText` | `cancel-button-text` | Set the the cancel button text. Only applies to `ios` mode. Default: `"Cancel"`. | `string` |
|
||||
| `clearIcon` | `clear-icon` | Set the clear icon. Defaults to `"close-circle"` for `ios` and `"close"` for `md`. | `string \| undefined` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. Default `250`. | `number` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `placeholder` | `placeholder` | Set the input's placeholder. Default `"Search"`. | `string` |
|
||||
| `searchIcon` | `search-icon` | The icon to use as the search icon. Defaults to `"search"`. | `string \| undefined` |
|
||||
| `showCancelButton` | `show-cancel-button` | If `true`, show the cancel button. Default `false`. | `boolean` |
|
||||
| `spellcheck` | `spellcheck` | If `true`, enable spellcheck on the input. Default `false`. | `boolean` |
|
||||
| `type` | `type` | Set the type of the input. Values: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, `"url"`. Default `"search"`. | `string` |
|
||||
| `value` | `value` | the value of the searchbar. | `string` |
|
||||
| Property | Attribute | Description | Type |
|
||||
| ------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
||||
| `animated` | `animated` | If `true`, enable searchbar animation. Defaults to `false`. | `boolean` |
|
||||
| `autocomplete` | `autocomplete` | Set the input's autocomplete property. Default `"off"`. | `"off" \| "on"` |
|
||||
| `autocorrect` | `autocorrect` | Set the input's autocorrect property. Default `"off"`. | `"off" \| "on"` |
|
||||
| `cancelButtonIcon` | `cancel-button-icon` | Set the cancel button icon. Only applies to `md` mode. Defaults to `"md-arrow-back"`. | `string` |
|
||||
| `cancelButtonText` | `cancel-button-text` | Set the the cancel button text. Only applies to `ios` mode. Default: `"Cancel"`. | `string` |
|
||||
| `clearIcon` | `clear-icon` | Set the clear icon. Defaults to `"close-circle"` for `ios` and `"close"` for `md`. | `string \| undefined` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. Default `250`. | `number` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `placeholder` | `placeholder` | Set the input's placeholder. Default `"Search"`. | `string` |
|
||||
| `searchIcon` | `search-icon` | The icon to use as the search icon. Defaults to `"search"`. | `string \| undefined` |
|
||||
| `showCancelButton` | `show-cancel-button` | If `true`, show the cancel button. Defaults to `false`. | `boolean` |
|
||||
| `spellcheck` | `spellcheck` | If `true`, enable spellcheck on the input. Defaults to `false`. | `boolean` |
|
||||
| `type` | `type` | Set the type of the input. Values: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, `"url"`. Default `"search"`. | `string` |
|
||||
| `value` | `value` | the value of the searchbar. | `null \| string \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -39,7 +39,7 @@ export class Searchbar implements ComponentInterface {
|
||||
@Prop() mode!: Mode;
|
||||
|
||||
/**
|
||||
* If `true`, enable searchbar animation. Default `false`.
|
||||
* If `true`, enable searchbar animation. Defaults to `false`.
|
||||
*/
|
||||
@Prop() animated = false;
|
||||
|
||||
@ -89,12 +89,12 @@ export class Searchbar implements ComponentInterface {
|
||||
@Prop() searchIcon?: string;
|
||||
|
||||
/**
|
||||
* If `true`, show the cancel button. Default `false`.
|
||||
* If `true`, show the cancel button. Defaults to `false`.
|
||||
*/
|
||||
@Prop() showCancelButton = false;
|
||||
|
||||
/**
|
||||
* If `true`, enable spellcheck on the input. Default `false`.
|
||||
* If `true`, enable spellcheck on the input. Defaults to `false`.
|
||||
*/
|
||||
@Prop() spellcheck = false;
|
||||
|
||||
@ -106,7 +106,7 @@ export class Searchbar implements ComponentInterface {
|
||||
/**
|
||||
* the value of the searchbar.
|
||||
*/
|
||||
@Prop({ mutable: true }) value = '';
|
||||
@Prop({ mutable: true }) value?: string | null = '';
|
||||
|
||||
/**
|
||||
* Emitted when a keyboard input ocurred.
|
||||
@ -141,7 +141,7 @@ export class Searchbar implements ComponentInterface {
|
||||
@Watch('value')
|
||||
protected valueChanged() {
|
||||
const inputEl = this.nativeInput;
|
||||
const value = this.value;
|
||||
const value = this.getValue();
|
||||
if (inputEl && inputEl.value !== value) {
|
||||
inputEl.value = value;
|
||||
}
|
||||
@ -176,7 +176,7 @@ export class Searchbar implements ComponentInterface {
|
||||
// setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
|
||||
// wait for 4 frames
|
||||
setTimeout(() => {
|
||||
const value = this.value;
|
||||
const value = this.getValue();
|
||||
if (value !== '') {
|
||||
this.value = '';
|
||||
this.ionInput.emit();
|
||||
@ -235,8 +235,9 @@ export class Searchbar implements ComponentInterface {
|
||||
* based on the input value and if it is focused. (ios only)
|
||||
*/
|
||||
private positionElements() {
|
||||
const value = this.getValue();
|
||||
const prevAlignLeft = this.shouldAlignLeft;
|
||||
const shouldAlignLeft = (!this.animated || (this.value && this.value.toString().trim() !== '') || !!this.focused);
|
||||
const shouldAlignLeft = (!this.animated || value.trim() !== '' || !!this.focused);
|
||||
this.shouldAlignLeft = shouldAlignLeft;
|
||||
|
||||
if (this.mode !== 'ios') {
|
||||
@ -322,12 +323,16 @@ export class Searchbar implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private getValue() {
|
||||
return this.value || '';
|
||||
}
|
||||
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
...createColorClasses(this.color),
|
||||
'searchbar-animated': this.animated && this.config.getBoolean('animated', true),
|
||||
'searchbar-has-value': (this.value !== ''),
|
||||
'searchbar-has-value': (this.getValue() !== ''),
|
||||
'searchbar-show-cancel': this.showCancelButton,
|
||||
'searchbar-left-aligned': this.shouldAlignLeft,
|
||||
'searchbar-has-focus': this.focused
|
||||
@ -364,7 +369,7 @@ export class Searchbar implements ComponentInterface {
|
||||
onFocus={this.onFocus}
|
||||
placeholder={this.placeholder}
|
||||
type={this.type}
|
||||
value={this.value}
|
||||
value={this.getValue()}
|
||||
autoComplete={this.autocomplete}
|
||||
autoCorrect={this.autocorrect}
|
||||
spellCheck={this.spellcheck}
|
||||
|
@ -12,7 +12,7 @@ Segment buttons are groups of related buttons inside of a [Segment](../../segmen
|
||||
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
||||
| `checked` | `checked` | If `true`, the segment button is selected. Defaults to `false`. | `boolean` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the segment button. Default false. | `boolean` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the segment button. Defaults to `false`. | `boolean` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `value` | `value` | The value of the segment button. | `string` |
|
||||
|
||||
|
@ -33,7 +33,7 @@ export class SegmentButton implements ComponentInterface {
|
||||
@Prop({ mutable: true }) checked = false;
|
||||
|
||||
/**
|
||||
* If `true`, the user cannot interact with the segment button. Default false.
|
||||
* If `true`, the user cannot interact with the segment button. Defaults to `false`.
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
|
@ -15,14 +15,6 @@ SelectOption is a component that is a child element of Select. For more informat
|
||||
| `value` | -- | The text value of the option. | `any` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Detail | Description |
|
||||
| -------------------------- | ------ | --------------------------------------- |
|
||||
| `ionSelectOptionDidLoad` | | Emitted when the select option loads. |
|
||||
| `ionSelectOptionDidUnload` | | Emitted when the select option unloads. |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-select-option'
|
||||
tag: 'ion-select-option',
|
||||
})
|
||||
export class SelectOption implements ComponentInterface {
|
||||
|
||||
@ -22,15 +22,17 @@ export class SelectOption implements ComponentInterface {
|
||||
/**
|
||||
* The text value of the option.
|
||||
*/
|
||||
@Prop({ mutable: true }) value?: any;
|
||||
@Prop({ mutable: true }) value?: any | null;
|
||||
|
||||
/**
|
||||
* Emitted when the select option loads.
|
||||
* @internal
|
||||
*/
|
||||
@Event() ionSelectOptionDidLoad!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* Emitted when the select option unloads.
|
||||
* @internal
|
||||
*/
|
||||
@Event() ionSelectOptionDidUnload!: EventEmitter<void>;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Method, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { ActionSheetButton, ActionSheetOptions, AlertOptions, CssClassMap, Mode, OverlaySelect, PopoverOptions, SelectInputChangeEvent, SelectInterface, SelectPopoverOption, StyleEvent } from '../../interface';
|
||||
import { deferEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { renderHiddenInput } from '../../utils/helpers';
|
||||
import { hostContext } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -228,10 +228,7 @@ export class Select implements ComponentInterface {
|
||||
this.value = this.multiple ? [] : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
|
||||
const label = this.getLabel();
|
||||
if (label) {
|
||||
this.labelId = label.id = this.name + '-lbl';
|
||||
|
@ -13,26 +13,26 @@ The textarea component accepts the [native textarea attributes](https://develope
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type |
|
||||
| ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
||||
| `autocapitalize` | `autocapitalize` | Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Defaults to `"none"`. | `string` |
|
||||
| `autofocus` | `autofocus` | This Boolean attribute lets you specify that a form control should have input focus when the page loads. Defaults to `false`. | `boolean` |
|
||||
| `clearOnEdit` | `clear-on-edit` | If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types. | `boolean` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `cols` | `cols` | The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. | `number \| undefined` |
|
||||
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. Default `0`. | `number` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the textarea. Defaults to `false`. | `boolean` |
|
||||
| `maxlength` | `maxlength` | If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter. | `number \| undefined` |
|
||||
| `minlength` | `minlength` | If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter. | `number \| undefined` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `placeholder` | `placeholder` | Instructional text that shows before the input has a value. | `string \| undefined` |
|
||||
| `readonly` | `readonly` | If `true`, the user cannot modify the value. Defaults to `false`. | `boolean` |
|
||||
| `required` | `required` | If `true`, the user must fill in a value before submitting a form. | `boolean` |
|
||||
| `rows` | `rows` | The number of visible text lines for the control. | `number \| undefined` |
|
||||
| `spellcheck` | `spellcheck` | If `true`, the element will have its spelling and grammar checked. Defaults to `false`. | `boolean` |
|
||||
| `value` | `value` | The value of the textarea. | `string` |
|
||||
| `wrap` | `wrap` | Indicates how the control wraps text. Possible values are: `"hard"`, `"soft"`, `"off"`. | `string \| undefined` |
|
||||
| Property | Attribute | Description | Type |
|
||||
| ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
||||
| `autocapitalize` | `autocapitalize` | Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Defaults to `"none"`. | `string` |
|
||||
| `autofocus` | `autofocus` | This Boolean attribute lets you specify that a form control should have input focus when the page loads. Defaults to `false`. | `boolean` |
|
||||
| `clearOnEdit` | `clear-on-edit` | If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types. | `boolean` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `cols` | `cols` | The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. | `number \| undefined` |
|
||||
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. Default `0`. | `number` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the textarea. Defaults to `false`. | `boolean` |
|
||||
| `maxlength` | `maxlength` | If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter. | `number \| undefined` |
|
||||
| `minlength` | `minlength` | If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter. | `number \| undefined` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `placeholder` | `placeholder` | Instructional text that shows before the input has a value. | `string \| undefined` |
|
||||
| `readonly` | `readonly` | If `true`, the user cannot modify the value. Defaults to `false`. | `boolean` |
|
||||
| `required` | `required` | If `true`, the user must fill in a value before submitting a form. | `boolean` |
|
||||
| `rows` | `rows` | The number of visible text lines for the control. | `number \| undefined` |
|
||||
| `spellcheck` | `spellcheck` | If `true`, the element will have its spelling and grammar checked. Defaults to `false`. | `boolean` |
|
||||
| `value` | `value` | The value of the textarea. | `null \| string \| undefined` |
|
||||
| `wrap` | `wrap` | Indicates how the control wraps text. Possible values are: `"hard"`, `"soft"`, `"off"`. | `string \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { Color, Mode, StyleEvent, TextInputChangeEvent } from '../../interface';
|
||||
import { debounceEvent, deferEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { debounceEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -123,14 +123,15 @@ export class Textarea implements ComponentInterface {
|
||||
/**
|
||||
* The value of the textarea.
|
||||
*/
|
||||
@Prop({ mutable: true }) value = '';
|
||||
@Prop({ mutable: true }) value?: string | null = '';
|
||||
|
||||
/**
|
||||
* Update the native input element when the value changes
|
||||
*/
|
||||
@Watch('value')
|
||||
protected valueChanged() {
|
||||
const { nativeInput, value } = this;
|
||||
const nativeInput = this.nativeInput;
|
||||
const value = this.getValue();
|
||||
if (nativeInput!.value !== value) {
|
||||
nativeInput!.value = value;
|
||||
}
|
||||
@ -162,12 +163,14 @@ export class Textarea implements ComponentInterface {
|
||||
*/
|
||||
@Event() ionFocus!: EventEmitter<void>;
|
||||
|
||||
componentDidLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
this.debounceChanged();
|
||||
componentWillLoad() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.debounceChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets focus on the specified `ion-textarea`. Use this method instead of the global
|
||||
* `input.focus()`.
|
||||
@ -241,7 +244,11 @@ export class Textarea implements ComponentInterface {
|
||||
}
|
||||
|
||||
private hasValue(): boolean {
|
||||
return this.value !== '';
|
||||
return this.getValue() !== '';
|
||||
}
|
||||
|
||||
private getValue(): string {
|
||||
return this.value || '';
|
||||
}
|
||||
|
||||
hostData() {
|
||||
@ -253,7 +260,8 @@ export class Textarea implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
renderHiddenInput(this.el, this.name, this.value, this.disabled);
|
||||
const value = this.getValue();
|
||||
renderHiddenInput(this.el, this.name, value, this.disabled);
|
||||
|
||||
return (
|
||||
<textarea
|
||||
@ -277,7 +285,7 @@ export class Textarea implements ComponentInterface {
|
||||
onFocus={this.onFocus}
|
||||
onKeyDown={this.onKeyDown}
|
||||
>
|
||||
{this.value}
|
||||
{value}
|
||||
</textarea>
|
||||
);
|
||||
}
|
||||
|
@ -9,14 +9,14 @@ Toggles change the state of a single option. Toggles can be switched on or off b
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type |
|
||||
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
||||
| `checked` | `checked` | If `true`, the toggle is selected. Defaults to `false`. | `boolean` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the toggle. Default false. | `boolean` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `value` | `value` | the value of the toggle. | `string` |
|
||||
| Property | Attribute | Description | Type |
|
||||
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
||||
| `checked` | `checked` | If `true`, the toggle is selected. Defaults to `false`. | `boolean` |
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the toggle. Defaults to `false`. | `boolean` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `"ios" \| "md"` |
|
||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` |
|
||||
| `value` | `value` | the value of the toggle. | `null \| string \| undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, Queu
|
||||
|
||||
import { CheckedInputChangeEvent, Color, Gesture, GestureDetail, Mode, StyleEvent } from '../../interface';
|
||||
import { hapticSelection } from '../../utils/haptic';
|
||||
import { deferEvent, renderHiddenInput } from '../../utils/helpers';
|
||||
import { renderHiddenInput } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
@ -51,14 +51,14 @@ export class Toggle implements ComponentInterface {
|
||||
@Prop({ mutable: true }) checked = false;
|
||||
|
||||
/**
|
||||
* If `true`, the user cannot interact with the toggle. Default false.
|
||||
* If `true`, the user cannot interact with the toggle. Defaults to `false`.
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
/**
|
||||
* the value of the toggle.
|
||||
*/
|
||||
@Prop() value = 'on';
|
||||
@Prop() value?: string | null = 'on';
|
||||
|
||||
/**
|
||||
* Emitted when the value property has changed.
|
||||
@ -90,16 +90,14 @@ export class Toggle implements ComponentInterface {
|
||||
|
||||
@Watch('disabled')
|
||||
disabledChanged() {
|
||||
this.ionStyle.emit({
|
||||
'interactive-disabled': this.disabled,
|
||||
});
|
||||
this.emitStyle();
|
||||
if (this.gesture) {
|
||||
this.gesture.setDisabled(this.disabled);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.ionStyle = deferEvent(this.ionStyle);
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
@ -125,6 +123,12 @@ export class Toggle implements ComponentInterface {
|
||||
this.disabledChanged();
|
||||
}
|
||||
|
||||
private emitStyle() {
|
||||
this.ionStyle.emit({
|
||||
'interactive-disabled': this.disabled,
|
||||
});
|
||||
}
|
||||
|
||||
private onStart(detail: GestureDetail) {
|
||||
this.pivotX = detail.currentX;
|
||||
this.activated = true;
|
||||
@ -171,6 +175,10 @@ export class Toggle implements ComponentInterface {
|
||||
this.ionBlur.emit();
|
||||
}
|
||||
|
||||
private getValue() {
|
||||
return this.value || '';
|
||||
}
|
||||
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
@ -186,7 +194,8 @@ export class Toggle implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
renderHiddenInput(this.el, this.name, (this.checked ? this.value : ''), this.disabled);
|
||||
const value = this.getValue();
|
||||
renderHiddenInput(this.el, this.name, (this.checked ? value : ''), this.disabled);
|
||||
|
||||
return [
|
||||
<div class="toggle-icon">
|
||||
@ -201,7 +210,7 @@ export class Toggle implements ComponentInterface {
|
||||
checked={this.checked}
|
||||
id={this.inputId}
|
||||
name={this.name}
|
||||
value={this.value}
|
||||
value={value}
|
||||
disabled={this.disabled}
|
||||
ref={r => this.nativeInput = (r as any)}
|
||||
/>,
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface TextInputChangeEvent {
|
||||
value: string | undefined;
|
||||
value: string | undefined | null;
|
||||
}
|
||||
|
||||
export interface CheckedInputChangeEvent extends TextInputChangeEvent {
|
||||
|
Reference in New Issue
Block a user