diff --git a/core/api.txt b/core/api.txt index f3fdbbd60a..26be0122bd 100644 --- a/core/api.txt +++ b/core/api.txt @@ -623,6 +623,7 @@ ion-input,prop,placeholder,string | undefined,undefined,false,false ion-input,prop,readonly,boolean,false,false,true ion-input,prop,required,boolean,false,false,false ion-input,prop,shape,"round" | undefined,undefined,false,false +ion-input,prop,size,"large" | undefined,undefined,false,false ion-input,prop,spellcheck,boolean,false,false,false ion-input,prop,step,string | undefined,undefined,false,false ion-input,prop,theme,"ios" | "md" | "ionic",undefined,false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index eec75790d3..9cd8c797de 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -1450,6 +1450,10 @@ export namespace Components { * The shape of the input. If "round" it will have an increased border radius. */ "shape"?: 'round'; + /** + * The size of the input. If "large", it will have an increased height. By default the size is unset. This property only applies to the `"ionic"` theme. + */ + "size"?: 'large'; /** * If `true`, the element will have its spelling and grammar checked. */ @@ -6694,6 +6698,10 @@ declare namespace LocalJSX { * The shape of the input. If "round" it will have an increased border radius. */ "shape"?: 'round'; + /** + * The size of the input. If "large", it will have an increased height. By default the size is unset. This property only applies to the `"ionic"` theme. + */ + "size"?: 'large'; /** * If `true`, the element will have its spelling and grammar checked. */ diff --git a/core/src/components/input/input.ionic.scss b/core/src/components/input/input.ionic.scss index 3d1a752d80..863679e7c7 100644 --- a/core/src/components/input/input.ionic.scss +++ b/core/src/components/input/input.ionic.scss @@ -3,3 +3,12 @@ // Ionic Input // -------------------------------------------------- + + + +// Ionic Input Sizes +// -------------------------------------------------- + +:host(.input-size-large) { + min-height: 48px; +} diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx index 227324f11b..9208f170f0 100644 --- a/core/src/components/input/input.tsx +++ b/core/src/components/input/input.tsx @@ -4,6 +4,7 @@ import type { NotchController } from '@utils/forms'; import { createNotchController } from '@utils/forms'; import type { Attributes } from '@utils/helpers'; import { inheritAriaAttributes, debounceEvent, inheritAttributes, componentOnReady } from '@utils/helpers'; +import { printIonWarning } from '@utils/logging'; import { createSlotMutationController } from '@utils/slot-mutation-controller'; import type { SlotMutationController } from '@utils/slot-mutation-controller'; import { createColorClasses, hostContext } from '@utils/theme'; @@ -251,6 +252,12 @@ export class Input implements ComponentInterface { */ @Prop() step?: string; + /** + * The size of the input. If "large", it will have an increased height. By default the + * size is unset. This property only applies to the `"ionic"` theme. + */ + @Prop() size?: 'large'; + /** * The type of control to display. The default type is text. */ @@ -464,6 +471,16 @@ export class Input implements ComponentInterface { return typeof this.value === 'number' ? this.value.toString() : (this.value || '').toString(); } + private getSize() { + const theme = getIonTheme(this); + const { size } = this; + if (theme !== 'ionic' && size === 'large') { + printIonWarning(`The "${size}" size is not supported in the ${theme} theme.`); + return undefined; + } + return size; + } + private onInput = (ev: InputEvent | Event) => { const input = ev.target as HTMLInputElement | null; if (input) { @@ -686,6 +703,7 @@ export class Input implements ComponentInterface { const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus } = this; const theme = getIonTheme(this); const value = this.getValue(); + const size = this.getSize(); const inItem = hostContext('ion-item', this.el); const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem; @@ -721,6 +739,7 @@ export class Input implements ComponentInterface { 'label-floating': labelShouldFloat, [`input-fill-${fill}`]: fill !== undefined, [`input-shape-${shape}`]: shape !== undefined, + [`input-size-${size}`]: size !== undefined, [`input-label-placement-${labelPlacement}`]: true, 'in-item': inItem, 'in-item-color': hostContext('ion-item.ion-color', this.el), diff --git a/core/src/components/input/test/size/index.html b/core/src/components/input/test/size/index.html new file mode 100644 index 0000000000..06605abfa9 --- /dev/null +++ b/core/src/components/input/test/size/index.html @@ -0,0 +1,74 @@ + + + + + Input - Size + + + + + + + + + + + + + + Input - Size + + + + +
+
+

No Fill: No Size

+ +
+ +
+

Outline: No Size

+ +
+ +
+

No Fill: Large Size

+ +
+ +
+

Outline: Large Size

+ +
+
+
+
+ + diff --git a/core/src/components/input/test/size/input.e2e.ts b/core/src/components/input/test/size/input.e2e.ts new file mode 100644 index 0000000000..169219f9cf --- /dev/null +++ b/core/src/components/input/test/size/input.e2e.ts @@ -0,0 +1,78 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * Size is only available in the Ionic theme + */ +configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('input: size'), () => { + test.describe('input: size large', () => { + test('should not have visual regressions', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + const input = page.locator('ion-input'); + await expect(input).toHaveScreenshot(screenshot(`input-size-large`)); + }); + test('should render correctly with floating label', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + const input = page.locator('ion-input'); + await expect(input).toHaveScreenshot(screenshot(`input-size-large-label-floating`)); + }); + test('should not have visual regressions with fill outline', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + const input = page.locator('ion-input'); + await expect(input).toHaveScreenshot(screenshot(`input-size-large-outline`)); + }); + test('should not have visual regressions with fill outline and round shape', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + const input = page.locator('ion-input'); + await expect(input).toHaveScreenshot(screenshot(`input-size-large-outline-round`)); + }); + }); + }); +}); diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..5420110a6d Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..ae42bb53dc Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..576fd032b7 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..3f70df2eb1 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..bce33fcd71 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..2238b50eab Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-label-floating-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..3f70df2eb1 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..bce33fcd71 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..2238b50eab Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..3f70df2eb1 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..bce33fcd71 Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..2238b50eab Binary files /dev/null and b/core/src/components/input/test/size/input.e2e.ts-snapshots/input-size-large-outline-round-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/packages/angular/src/directives/proxies.ts b/packages/angular/src/directives/proxies.ts index acec987bcf..5eeaea7529 100644 --- a/packages/angular/src/directives/proxies.ts +++ b/packages/angular/src/directives/proxies.ts @@ -957,7 +957,7 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite @ProxyCmp({ - inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'theme', 'type', 'value'], + inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'size', 'spellcheck', 'step', 'theme', 'type', 'value'], methods: ['setFocus', 'getInputElement'] }) @Component({ @@ -965,7 +965,7 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'theme', 'type', 'value'], + inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'size', 'spellcheck', 'step', 'theme', 'type', 'value'], }) export class IonInput { protected el: HTMLElement; diff --git a/packages/vue/src/proxies.ts b/packages/vue/src/proxies.ts index 30d640d44f..cf55136c06 100644 --- a/packages/vue/src/proxies.ts +++ b/packages/vue/src/proxies.ts @@ -427,6 +427,7 @@ export const IonInput = /*@__PURE__*/ defineContainer