Merge branch 'next' into ROU-4822
@ -30,6 +30,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
|||||||
- [Progress bar](#version-8x-progress-bar)
|
- [Progress bar](#version-8x-progress-bar)
|
||||||
- [Radio](#version-8x-radio)
|
- [Radio](#version-8x-radio)
|
||||||
- [Range](#version-8x-range)
|
- [Range](#version-8x-range)
|
||||||
|
- [Searchbar](#version-8x-searchbar)
|
||||||
- [Select](#version-8x-select)
|
- [Select](#version-8x-select)
|
||||||
- [Textarea](#version-8x-textarea)
|
- [Textarea](#version-8x-textarea)
|
||||||
- [Toggle](#version-8x-toggle)
|
- [Toggle](#version-8x-toggle)
|
||||||
@ -264,6 +265,10 @@ For more information on styling toast buttons, refer to the [Toast Theming docum
|
|||||||
|
|
||||||
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
|
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
|
||||||
|
|
||||||
|
<h4 id="version-8x-searchbar">Searchbar</h4>
|
||||||
|
|
||||||
|
- The `autocapitalize` property now defaults to `'off'`.
|
||||||
|
|
||||||
<h4 id="version-8x-select">Select</h4>
|
<h4 id="version-8x-select">Select</h4>
|
||||||
|
|
||||||
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-select` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy select syntax, refer to the [Select documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax).
|
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-select` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy select syntax, refer to the [Select documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax).
|
||||||
|
16
core/api.txt
@ -234,8 +234,8 @@ ion-button,prop,mode,"ios" | "md",undefined,false,false
|
|||||||
ion-button,prop,rel,string | undefined,undefined,false,false
|
ion-button,prop,rel,string | undefined,undefined,false,false
|
||||||
ion-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
ion-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||||
ion-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
ion-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||||
ion-button,prop,shape,"round" | undefined,undefined,false,true
|
ion-button,prop,shape,"rectangular" | "round" | undefined,undefined,false,true
|
||||||
ion-button,prop,size,"default" | "large" | "small" | undefined,undefined,false,true
|
ion-button,prop,size,"default" | "large" | "small" | "xlarge" | "xsmall" | undefined,undefined,false,true
|
||||||
ion-button,prop,strong,boolean,false,false,false
|
ion-button,prop,strong,boolean,false,false,false
|
||||||
ion-button,prop,target,string | undefined,undefined,false,false
|
ion-button,prop,target,string | undefined,undefined,false,false
|
||||||
ion-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
ion-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||||
@ -607,7 +607,7 @@ ion-input,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secon
|
|||||||
ion-input,prop,counter,boolean,false,false,false
|
ion-input,prop,counter,boolean,false,false,false
|
||||||
ion-input,prop,counterFormatter,((inputLength: number, maxLength: number) => string) | undefined,undefined,false,false
|
ion-input,prop,counterFormatter,((inputLength: number, maxLength: number) => string) | undefined,undefined,false,false
|
||||||
ion-input,prop,debounce,number | undefined,undefined,false,false
|
ion-input,prop,debounce,number | undefined,undefined,false,false
|
||||||
ion-input,prop,disabled,boolean,false,false,false
|
ion-input,prop,disabled,boolean,false,false,true
|
||||||
ion-input,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
|
ion-input,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
|
||||||
ion-input,prop,errorText,string | undefined,undefined,false,false
|
ion-input,prop,errorText,string | undefined,undefined,false,false
|
||||||
ion-input,prop,fill,"outline" | "solid" | undefined,undefined,false,false
|
ion-input,prop,fill,"outline" | "solid" | undefined,undefined,false,false
|
||||||
@ -624,7 +624,7 @@ ion-input,prop,multiple,boolean | undefined,undefined,false,false
|
|||||||
ion-input,prop,name,string,this.inputId,false,false
|
ion-input,prop,name,string,this.inputId,false,false
|
||||||
ion-input,prop,pattern,string | undefined,undefined,false,false
|
ion-input,prop,pattern,string | undefined,undefined,false,false
|
||||||
ion-input,prop,placeholder,string | undefined,undefined,false,false
|
ion-input,prop,placeholder,string | undefined,undefined,false,false
|
||||||
ion-input,prop,readonly,boolean,false,false,false
|
ion-input,prop,readonly,boolean,false,false,true
|
||||||
ion-input,prop,required,boolean,false,false,false
|
ion-input,prop,required,boolean,false,false,false
|
||||||
ion-input,prop,shape,"round" | undefined,undefined,false,false
|
ion-input,prop,shape,"round" | undefined,undefined,false,false
|
||||||
ion-input,prop,spellcheck,boolean,false,false,false
|
ion-input,prop,spellcheck,boolean,false,false,false
|
||||||
@ -657,6 +657,12 @@ ion-input,css-prop,--placeholder-font-style
|
|||||||
ion-input,css-prop,--placeholder-font-weight
|
ion-input,css-prop,--placeholder-font-weight
|
||||||
ion-input,css-prop,--placeholder-opacity
|
ion-input,css-prop,--placeholder-opacity
|
||||||
|
|
||||||
|
ion-input-password-toggle,shadow
|
||||||
|
ion-input-password-toggle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||||
|
ion-input-password-toggle,prop,hideIcon,string | undefined,undefined,false,false
|
||||||
|
ion-input-password-toggle,prop,mode,"ios" | "md",undefined,false,false
|
||||||
|
ion-input-password-toggle,prop,showIcon,string | undefined,undefined,false,false
|
||||||
|
|
||||||
ion-item,shadow
|
ion-item,shadow
|
||||||
ion-item,prop,button,boolean,false,false,false
|
ion-item,prop,button,boolean,false,false,false
|
||||||
ion-item,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
ion-item,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||||
@ -1269,7 +1275,7 @@ ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
|||||||
|
|
||||||
ion-searchbar,scoped
|
ion-searchbar,scoped
|
||||||
ion-searchbar,prop,animated,boolean,false,false,false
|
ion-searchbar,prop,animated,boolean,false,false,false
|
||||||
ion-searchbar,prop,autocapitalize,string,undefined,true,false
|
ion-searchbar,prop,autocapitalize,string,'off',false,false
|
||||||
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
|
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
|
||||||
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
||||||
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
|
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
|
||||||
|
57
core/src/components.d.ts
vendored
@ -545,11 +545,11 @@ export namespace Components {
|
|||||||
/**
|
/**
|
||||||
* Set to `"round"` for a button with more rounded corners.
|
* Set to `"round"` for a button with more rounded corners.
|
||||||
*/
|
*/
|
||||||
"shape"?: 'round';
|
"shape"?: 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
|
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
|
||||||
*/
|
*/
|
||||||
"size"?: 'small' | 'default' | 'large';
|
"size"?: 'xsmall' | 'small' | 'default' | 'large' | 'xlarge';
|
||||||
/**
|
/**
|
||||||
* If `true`, activates a button with a heavier font weight.
|
* If `true`, activates a button with a heavier font weight.
|
||||||
*/
|
*/
|
||||||
@ -1483,6 +1483,25 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
"value"?: string | number | null;
|
"value"?: string | number | null;
|
||||||
}
|
}
|
||||||
|
interface IonInputPasswordToggle {
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
"color"?: Color;
|
||||||
|
/**
|
||||||
|
* The icon that can be used to represent hiding a password. If not set, the "eyeOff" Ionicon will be used.
|
||||||
|
*/
|
||||||
|
"hideIcon"?: string;
|
||||||
|
/**
|
||||||
|
* The mode determines which platform styles to use.
|
||||||
|
*/
|
||||||
|
"mode"?: "ios" | "md";
|
||||||
|
/**
|
||||||
|
* The icon that can be used to represent showing a password. If not set, the "eye" Ionicon will be used.
|
||||||
|
*/
|
||||||
|
"showIcon"?: string;
|
||||||
|
"type": TextFieldTypes;
|
||||||
|
}
|
||||||
interface IonItem {
|
interface IonItem {
|
||||||
/**
|
/**
|
||||||
* If `true`, a button tag will be rendered and the item will be tappable.
|
* If `true`, a button tag will be rendered and the item will be tappable.
|
||||||
@ -4335,6 +4354,12 @@ declare global {
|
|||||||
prototype: HTMLIonInputElement;
|
prototype: HTMLIonInputElement;
|
||||||
new (): HTMLIonInputElement;
|
new (): HTMLIonInputElement;
|
||||||
};
|
};
|
||||||
|
interface HTMLIonInputPasswordToggleElement extends Components.IonInputPasswordToggle, HTMLStencilElement {
|
||||||
|
}
|
||||||
|
var HTMLIonInputPasswordToggleElement: {
|
||||||
|
prototype: HTMLIonInputPasswordToggleElement;
|
||||||
|
new (): HTMLIonInputPasswordToggleElement;
|
||||||
|
};
|
||||||
interface HTMLIonItemElement extends Components.IonItem, HTMLStencilElement {
|
interface HTMLIonItemElement extends Components.IonItem, HTMLStencilElement {
|
||||||
}
|
}
|
||||||
var HTMLIonItemElement: {
|
var HTMLIonItemElement: {
|
||||||
@ -5159,6 +5184,7 @@ declare global {
|
|||||||
"ion-infinite-scroll": HTMLIonInfiniteScrollElement;
|
"ion-infinite-scroll": HTMLIonInfiniteScrollElement;
|
||||||
"ion-infinite-scroll-content": HTMLIonInfiniteScrollContentElement;
|
"ion-infinite-scroll-content": HTMLIonInfiniteScrollContentElement;
|
||||||
"ion-input": HTMLIonInputElement;
|
"ion-input": HTMLIonInputElement;
|
||||||
|
"ion-input-password-toggle": HTMLIonInputPasswordToggleElement;
|
||||||
"ion-item": HTMLIonItemElement;
|
"ion-item": HTMLIonItemElement;
|
||||||
"ion-item-divider": HTMLIonItemDividerElement;
|
"ion-item-divider": HTMLIonItemDividerElement;
|
||||||
"ion-item-group": HTMLIonItemGroupElement;
|
"ion-item-group": HTMLIonItemGroupElement;
|
||||||
@ -5747,11 +5773,11 @@ declare namespace LocalJSX {
|
|||||||
/**
|
/**
|
||||||
* Set to `"round"` for a button with more rounded corners.
|
* Set to `"round"` for a button with more rounded corners.
|
||||||
*/
|
*/
|
||||||
"shape"?: 'round';
|
"shape"?: 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
|
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
|
||||||
*/
|
*/
|
||||||
"size"?: 'small' | 'default' | 'large';
|
"size"?: 'xsmall' | 'small' | 'default' | 'large' | 'xlarge';
|
||||||
/**
|
/**
|
||||||
* If `true`, activates a button with a heavier font weight.
|
* If `true`, activates a button with a heavier font weight.
|
||||||
*/
|
*/
|
||||||
@ -6713,6 +6739,25 @@ declare namespace LocalJSX {
|
|||||||
*/
|
*/
|
||||||
"value"?: string | number | null;
|
"value"?: string | number | null;
|
||||||
}
|
}
|
||||||
|
interface IonInputPasswordToggle {
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
"color"?: Color;
|
||||||
|
/**
|
||||||
|
* The icon that can be used to represent hiding a password. If not set, the "eyeOff" Ionicon will be used.
|
||||||
|
*/
|
||||||
|
"hideIcon"?: string;
|
||||||
|
/**
|
||||||
|
* The mode determines which platform styles to use.
|
||||||
|
*/
|
||||||
|
"mode"?: "ios" | "md";
|
||||||
|
/**
|
||||||
|
* The icon that can be used to represent showing a password. If not set, the "eye" Ionicon will be used.
|
||||||
|
*/
|
||||||
|
"showIcon"?: string;
|
||||||
|
"type"?: TextFieldTypes;
|
||||||
|
}
|
||||||
interface IonItem {
|
interface IonItem {
|
||||||
/**
|
/**
|
||||||
* If `true`, a button tag will be rendered and the item will be tappable.
|
* If `true`, a button tag will be rendered and the item will be tappable.
|
||||||
@ -8145,7 +8190,7 @@ declare namespace LocalJSX {
|
|||||||
/**
|
/**
|
||||||
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
||||||
*/
|
*/
|
||||||
"autocapitalize": string;
|
"autocapitalize"?: string;
|
||||||
/**
|
/**
|
||||||
* Set the input's autocomplete property.
|
* Set the input's autocomplete property.
|
||||||
*/
|
*/
|
||||||
@ -9088,6 +9133,7 @@ declare namespace LocalJSX {
|
|||||||
"ion-infinite-scroll": IonInfiniteScroll;
|
"ion-infinite-scroll": IonInfiniteScroll;
|
||||||
"ion-infinite-scroll-content": IonInfiniteScrollContent;
|
"ion-infinite-scroll-content": IonInfiniteScrollContent;
|
||||||
"ion-input": IonInput;
|
"ion-input": IonInput;
|
||||||
|
"ion-input-password-toggle": IonInputPasswordToggle;
|
||||||
"ion-item": IonItem;
|
"ion-item": IonItem;
|
||||||
"ion-item-divider": IonItemDivider;
|
"ion-item-divider": IonItemDivider;
|
||||||
"ion-item-group": IonItemGroup;
|
"ion-item-group": IonItemGroup;
|
||||||
@ -9186,6 +9232,7 @@ declare module "@stencil/core" {
|
|||||||
"ion-infinite-scroll": LocalJSX.IonInfiniteScroll & JSXBase.HTMLAttributes<HTMLIonInfiniteScrollElement>;
|
"ion-infinite-scroll": LocalJSX.IonInfiniteScroll & JSXBase.HTMLAttributes<HTMLIonInfiniteScrollElement>;
|
||||||
"ion-infinite-scroll-content": LocalJSX.IonInfiniteScrollContent & JSXBase.HTMLAttributes<HTMLIonInfiniteScrollContentElement>;
|
"ion-infinite-scroll-content": LocalJSX.IonInfiniteScrollContent & JSXBase.HTMLAttributes<HTMLIonInfiniteScrollContentElement>;
|
||||||
"ion-input": LocalJSX.IonInput & JSXBase.HTMLAttributes<HTMLIonInputElement>;
|
"ion-input": LocalJSX.IonInput & JSXBase.HTMLAttributes<HTMLIonInputElement>;
|
||||||
|
"ion-input-password-toggle": LocalJSX.IonInputPasswordToggle & JSXBase.HTMLAttributes<HTMLIonInputPasswordToggleElement>;
|
||||||
"ion-item": LocalJSX.IonItem & JSXBase.HTMLAttributes<HTMLIonItemElement>;
|
"ion-item": LocalJSX.IonItem & JSXBase.HTMLAttributes<HTMLIonItemElement>;
|
||||||
"ion-item-divider": LocalJSX.IonItemDivider & JSXBase.HTMLAttributes<HTMLIonItemDividerElement>;
|
"ion-item-divider": LocalJSX.IonItemDivider & JSXBase.HTMLAttributes<HTMLIonItemDividerElement>;
|
||||||
"ion-item-group": LocalJSX.IonItemGroup & JSXBase.HTMLAttributes<HTMLIonItemGroupElement>;
|
"ion-item-group": LocalJSX.IonItemGroup & JSXBase.HTMLAttributes<HTMLIonItemGroupElement>;
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
220
core/src/components/button/button.ionic.scss
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
@import "./button";
|
||||||
|
@import "./button.ionic.vars";
|
||||||
|
|
||||||
|
// Ionic Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
:host {
|
||||||
|
--border-radius: #{$button-ionic-border-radius};
|
||||||
|
--padding-bottom: var(--padding-top);
|
||||||
|
--padding-end: #{$button-ionic-padding-end};
|
||||||
|
--padding-start: var(--padding-end);
|
||||||
|
--padding-top: #{$button-ionic-padding-top};
|
||||||
|
--focus-ring-color: #9ec4fd;
|
||||||
|
--focus-ring-width: 2px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
min-height: #{$button-ionic-min-height};
|
||||||
|
|
||||||
|
font-size: #{$button-ionic-font-size};
|
||||||
|
|
||||||
|
// Target area
|
||||||
|
&::after {
|
||||||
|
@include position(50%, 0, null, 0);
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
min-height: px-to-rem(48);
|
||||||
|
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(ion-icon[slot="start"]) {
|
||||||
|
@include margin-horizontal(null, px-to-rem(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(ion-icon[slot="end"]) {
|
||||||
|
@include margin-horizontal(px-to-rem(8), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button Sizes
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Extra Small and Small Button */
|
||||||
|
:host(.button-xsmall),
|
||||||
|
:host(.button-small) {
|
||||||
|
::slotted(ion-icon[slot="start"]) {
|
||||||
|
@include margin-horizontal(null, px-to-rem(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(ion-icon[slot="end"]) {
|
||||||
|
@include margin-horizontal(px-to-rem(4), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra Small Button */
|
||||||
|
:host(.button-xsmall) {
|
||||||
|
--border-radius: #{$button-ionic-xsmall-border-radius};
|
||||||
|
--padding-top: #{$button-ionic-xsmall-padding-top};
|
||||||
|
--padding-end: #{$button-ionic-xsmall-padding-end};
|
||||||
|
|
||||||
|
min-height: #{$button-ionic-xsmall-min-height};
|
||||||
|
|
||||||
|
font-size: #{$button-ionic-xsmall-font-size};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Small Button */
|
||||||
|
:host(.button-small) {
|
||||||
|
--border-radius: #{$button-ionic-small-border-radius};
|
||||||
|
--padding-top: #{$button-ionic-small-padding-top};
|
||||||
|
--padding-end: #{$button-ionic-small-padding-end};
|
||||||
|
|
||||||
|
min-height: #{$button-ionic-small-min-height};
|
||||||
|
|
||||||
|
font-size: #{$button-ionic-small-font-size};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Large Button */
|
||||||
|
:host(.button-large) {
|
||||||
|
--padding-top: #{$button-ionic-large-padding-top};
|
||||||
|
--padding-end: #{$button-ionic-large-padding-end};
|
||||||
|
|
||||||
|
min-height: #{$button-ionic-large-min-height};
|
||||||
|
|
||||||
|
font-size: #{$button-ionic-large-font-size};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra Large Button */
|
||||||
|
:host(.button-xlarge) {
|
||||||
|
--padding-top: #{$button-ionic-xlarge-padding-top};
|
||||||
|
--padding-end: #{$button-ionic-xlarge-padding-end};
|
||||||
|
|
||||||
|
min-height: #{$button-ionic-xlarge-min-height};
|
||||||
|
|
||||||
|
font-size: #{$button-ionic-xlarge-font-size};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button with Icons
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Button containing only an icon */
|
||||||
|
::slotted(ion-icon[slot="start"]),
|
||||||
|
::slotted(ion-icon[slot="end"]),
|
||||||
|
::slotted(ion-icon[slot="icon-only"]) {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button extra small */
|
||||||
|
:host(.button-has-icon-only.button-xsmall) {
|
||||||
|
--padding-end: #{$button-has-icon-only-padding-end-xsmall};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button small */
|
||||||
|
:host(.button-has-icon-only.button-small) {
|
||||||
|
--padding-end: #{$button-has-icon-only-padding-end-small};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default */
|
||||||
|
:host(.button-has-icon-only) {
|
||||||
|
--padding-end: #{$button-has-icon-only-padding-end};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button large */
|
||||||
|
:host(.button-has-icon-only.button-large) {
|
||||||
|
--padding-end: #{$button-has-icon-only-padding-end-large};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button extra large */
|
||||||
|
:host(.button-has-icon-only.button-xlarge) {
|
||||||
|
--padding-end: #{$button-has-icon-only-padding-end-xlarge};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button Shapes
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Button Shape Rectangular
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
:host(.button-rectangular) {
|
||||||
|
--border-radius: #{$button-ionic-rectangular-border};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button Shape Round
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
:host(.button-round) {
|
||||||
|
--border-radius: #{$button-ionic-round-border};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button Focused
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Only show the focus ring when the button is focused
|
||||||
|
:host(.ion-focused) .button-native {
|
||||||
|
outline: var(--focus-ring-width) solid var(--focus-ring-color);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill Solid Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
:host(.button-solid) {
|
||||||
|
--background-activated: #{ion-color(primary, shade)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill Outline Button
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.button-outline) {
|
||||||
|
--border-width: #{$button-ionic-outline-border-width};
|
||||||
|
--border-style: #{$button-ionic-outline-border-style};
|
||||||
|
--background-activated: #e3e3e3;
|
||||||
|
--background-activated-opacity: 1;
|
||||||
|
--background-focused: transparent;
|
||||||
|
--background-hover: transparent;
|
||||||
|
--background-focused-opacity: 0.1;
|
||||||
|
--color-activated: #{ion-color(primary, base)};
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.button-outline.ion-focused) {
|
||||||
|
--border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill Clear Button
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.button-clear) {
|
||||||
|
--background-activated: #e3e3e3;
|
||||||
|
--background-activated-opacity: 1;
|
||||||
|
--background-focused: transparent;
|
||||||
|
--background-hover: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button Hover
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.button-outline),
|
||||||
|
:host(.button-clear) {
|
||||||
|
--background-hover: #121212;
|
||||||
|
--background-hover-opacity: 0.04;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button: Disabled
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.button-disabled) {
|
||||||
|
--color: #c9c9c9;
|
||||||
|
--border-color: var(--color);
|
||||||
|
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.button-solid.button-disabled) {
|
||||||
|
--background: #f5f5f5;
|
||||||
|
}
|
164
core/src/components/button/button.ionic.vars.scss
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
@import "../../themes/ionic.globals.ios";
|
||||||
|
|
||||||
|
// Ionic Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border radius of the button
|
||||||
|
$button-ionic-border-radius: px-to-rem(8) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding top of the button
|
||||||
|
$button-ionic-padding-top: px-to-rem(12) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the button
|
||||||
|
$button-ionic-padding-end: px-to-rem(16) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding bottom of the button
|
||||||
|
$button-ionic-padding-bottom: $button-ionic-padding-top !default;
|
||||||
|
|
||||||
|
/// @prop - Padding start of the button
|
||||||
|
$button-ionic-padding-start: $button-ionic-padding-end !default;
|
||||||
|
|
||||||
|
/// @prop - Minimum height of the button
|
||||||
|
$button-ionic-min-height: px-to-rem(40) !default;
|
||||||
|
|
||||||
|
/// @prop - Font size of the button text
|
||||||
|
/// The maximum font size is calculated by taking the default font size
|
||||||
|
/// and multiplying it by 3, since 310% of the default is the maximum
|
||||||
|
$button-ionic-font-size: dynamic-font-max(14px, 3) !default;
|
||||||
|
|
||||||
|
// Ionic Extra Small Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border radius of the extra small button
|
||||||
|
$button-ionic-xsmall-border-radius: px-to-rem(4) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding top of the extra small button
|
||||||
|
$button-ionic-xsmall-padding-top: px-to-rem(4) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the extra small button
|
||||||
|
$button-ionic-xsmall-padding-end: px-to-rem(12) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding bottom of the extra small button
|
||||||
|
$button-ionic-xsmall-padding-bottom: $button-ionic-xsmall-padding-top !default;
|
||||||
|
|
||||||
|
/// @prop - Padding start of the extra small button
|
||||||
|
$button-ionic-xsmall-padding-start: $button-ionic-xsmall-padding-end !default;
|
||||||
|
|
||||||
|
/// @prop - Minimum height of the extra small button
|
||||||
|
$button-ionic-xsmall-min-height: px-to-rem(24) !default;
|
||||||
|
|
||||||
|
/// @prop - Font size of the extra small button text
|
||||||
|
/// The maximum font size is calculated by taking the default font size
|
||||||
|
/// and multiplying it by 3, since 310% of the default is the maximum
|
||||||
|
$button-ionic-xsmall-font-size: dynamic-font-max(12px, 3) !default;
|
||||||
|
|
||||||
|
// Ionic Small Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border radius of the small button
|
||||||
|
$button-ionic-small-border-radius: px-to-rem(4) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding top of the small button
|
||||||
|
$button-ionic-small-padding-top: px-to-rem(8) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the small button
|
||||||
|
$button-ionic-small-padding-end: px-to-rem(16) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding bottom of the small button
|
||||||
|
$button-ionic-small-padding-bottom: $button-ionic-small-padding-top !default;
|
||||||
|
|
||||||
|
/// @prop - Padding start of the small button
|
||||||
|
$button-ionic-small-padding-start: $button-ionic-small-padding-end !default;
|
||||||
|
|
||||||
|
/// @prop - Minimum height of the small button
|
||||||
|
$button-ionic-small-min-height: px-to-rem(32) !default;
|
||||||
|
|
||||||
|
/// @prop - Font size of the small button text
|
||||||
|
/// The maximum font size is calculated by taking the default font size
|
||||||
|
/// and multiplying it by 3, since 310% of the default is the maximum
|
||||||
|
$button-ionic-small-font-size: dynamic-font-max(12px, 3) !default;
|
||||||
|
|
||||||
|
// Ionic Large Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Padding top of the large button
|
||||||
|
$button-ionic-large-padding-top: px-to-rem(16) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the large button
|
||||||
|
$button-ionic-large-padding-end: px-to-rem(24) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding bottom of the large button
|
||||||
|
$button-ionic-large-padding-bottom: $button-ionic-large-padding-top !default;
|
||||||
|
|
||||||
|
/// @prop - Padding start of the large button
|
||||||
|
$button-ionic-large-padding-start: $button-ionic-large-padding-end !default;
|
||||||
|
|
||||||
|
/// @prop - Minimum height of the large button
|
||||||
|
$button-ionic-large-min-height: px-to-rem(48) !default;
|
||||||
|
|
||||||
|
/// @prop - Font size of the large button text
|
||||||
|
/// The maximum font size is calculated by taking the default font size
|
||||||
|
/// and multiplying it by 3, since 310% of the default is the maximum
|
||||||
|
$button-ionic-large-font-size: dynamic-font-max(16px, 3) !default;
|
||||||
|
|
||||||
|
// Ionic Extra Large Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Padding top of the extra large button
|
||||||
|
$button-ionic-xlarge-padding-top: px-to-rem(16) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the extra large button
|
||||||
|
$button-ionic-xlarge-padding-end: px-to-rem(32) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding bottom of the extra large button
|
||||||
|
$button-ionic-xlarge-padding-bottom: $button-ionic-xlarge-padding-top !default;
|
||||||
|
|
||||||
|
/// @prop - Padding start of the extra large button
|
||||||
|
$button-ionic-xlarge-padding-start: $button-ionic-xlarge-padding-end !default;
|
||||||
|
|
||||||
|
/// @prop - Minimum height of the extra large button
|
||||||
|
$button-ionic-xlarge-min-height: px-to-rem(56) !default;
|
||||||
|
|
||||||
|
/// @prop - Font size of the extra large button text
|
||||||
|
/// The maximum font size is calculated by taking the default font size
|
||||||
|
/// and multiplying it by 3, since 310% of the default is the maximum
|
||||||
|
$button-ionic-xlarge-font-size: dynamic-font-max(20px, 3) !default;
|
||||||
|
|
||||||
|
// Ionic Rectangular Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border radius of the rectangular button
|
||||||
|
$button-ionic-rectangular-border: 0 !default;
|
||||||
|
|
||||||
|
// Ionic Round Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border radius of the round button
|
||||||
|
$button-ionic-round-border: px-to-rem(999) !default;
|
||||||
|
|
||||||
|
// Ionic Outline Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Border width of the outline button
|
||||||
|
$button-ionic-outline-border-width: 1px !default;
|
||||||
|
|
||||||
|
/// @prop - Border style of the outline button
|
||||||
|
$button-ionic-outline-border-style: solid !default;
|
||||||
|
|
||||||
|
// Ionic Icon Only Button
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @prop - Padding end of the icon only button
|
||||||
|
$button-has-icon-only-padding-end: px-to-rem(13) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the icon only extra small button
|
||||||
|
$button-has-icon-only-padding-end-xsmall: px-to-rem(6) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the icon only small button
|
||||||
|
$button-has-icon-only-padding-end-small: px-to-rem(10) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the icon only large button
|
||||||
|
$button-has-icon-only-padding-end-large: px-to-rem(16) !default;
|
||||||
|
|
||||||
|
/// @prop - Padding end of the icon only extra large button
|
||||||
|
$button-has-icon-only-padding-end-xlarge: px-to-rem(18) !default;
|
@ -26,7 +26,7 @@ import type { RouterDirection } from '../router/utils/interface';
|
|||||||
styleUrls: {
|
styleUrls: {
|
||||||
ios: 'button.ios.scss',
|
ios: 'button.ios.scss',
|
||||||
md: 'button.md.scss',
|
md: 'button.md.scss',
|
||||||
ionic: 'button.md.scss',
|
ionic: 'button.ionic.scss',
|
||||||
},
|
},
|
||||||
shadow: true,
|
shadow: true,
|
||||||
})
|
})
|
||||||
@ -117,7 +117,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
|||||||
/**
|
/**
|
||||||
* Set to `"round"` for a button with more rounded corners.
|
* Set to `"round"` for a button with more rounded corners.
|
||||||
*/
|
*/
|
||||||
@Prop({ reflect: true }) shape?: 'round';
|
@Prop({ reflect: true }) shape?: 'round' | 'rectangular';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to `"small"` for a button with less height and padding, to `"default"`
|
* Set to `"small"` for a button with less height and padding, to `"default"`
|
||||||
@ -126,7 +126,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
|||||||
* is inside of an item, where the size is `"small"` by default. Set the size to
|
* is inside of an item, where the size is `"small"` by default. Set the size to
|
||||||
* `"default"` inside of an item to make it a standard size button.
|
* `"default"` inside of an item to make it a standard size button.
|
||||||
*/
|
*/
|
||||||
@Prop({ reflect: true }) size?: 'small' | 'default' | 'large';
|
@Prop({ reflect: true }) size?: 'xsmall' | 'small' | 'default' | 'large' | 'xlarge';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `true`, activates a button with a heavier font weight.
|
* If `true`, activates a button with a heavier font weight.
|
||||||
@ -216,6 +216,24 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
|||||||
return 'bounded';
|
return 'bounded';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the "xsmall" and "xlarge" sizes if the theme is "ios" or "md"
|
||||||
|
*/
|
||||||
|
private getSize(): string | undefined {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const { size } = this;
|
||||||
|
|
||||||
|
if (size === undefined && this.inItem) {
|
||||||
|
return 'small';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((theme === 'ios' || theme === 'md') && (size === 'xsmall' || size === 'xlarge')) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the form element based on the provided `form` selector
|
* Finds the form element based on the provided `form` selector
|
||||||
* or element reference provided.
|
* or element reference provided.
|
||||||
@ -321,7 +339,6 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
|||||||
disabled,
|
disabled,
|
||||||
rel,
|
rel,
|
||||||
target,
|
target,
|
||||||
size,
|
|
||||||
href,
|
href,
|
||||||
color,
|
color,
|
||||||
expand,
|
expand,
|
||||||
@ -332,7 +349,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
|||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const finalSize = size === undefined && this.inItem ? 'small' : size;
|
const finalSize = this.getSize();
|
||||||
const TagType = href === undefined ? 'button' : ('a' as any);
|
const TagType = href === undefined ? 'button' : ('a' as any);
|
||||||
const attrs =
|
const attrs =
|
||||||
TagType === 'button'
|
TagType === 'button'
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
import { configs, test } from '@utils/test/playwright';
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
configs().forEach(({ title, config, screenshot }) => {
|
/**
|
||||||
test.describe(title('button: clear'), () => {
|
* Fill="clear" does not render differently based on the direction.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'], themes: ['ios', 'md', 'ionic'] }).forEach(({ title, config, screenshot }) => {
|
||||||
|
test.describe(title('button: fill: clear'), () => {
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
await page.goto(`/src/components/button/test/clear`, config);
|
await page.goto(`/src/components/button/test/clear`, config);
|
||||||
|
|
||||||
await page.setIonViewport();
|
await page.setIonViewport();
|
||||||
|
|
||||||
await expect(page).toHaveScreenshot(screenshot(`button-clear`));
|
await expect(page).toHaveScreenshot(screenshot(`button-fill-clear`));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 113 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 44 KiB |
@ -1,69 +0,0 @@
|
|||||||
import { expect } from '@playwright/test';
|
|
||||||
import { configs, test } from '@utils/test/playwright';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All content takes up the full width, so RTL has no effect.
|
|
||||||
*/
|
|
||||||
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
||||||
test.describe(title('button: round'), () => {
|
|
||||||
test.describe('default', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.goto(`/src/components/button/test/round`, config);
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
const container = page.locator('#default');
|
|
||||||
|
|
||||||
await expect(container).toHaveScreenshot(screenshot(`button-round`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe('outline', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.goto(`/src/components/button/test/round`, config);
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
const container = page.locator('#outline');
|
|
||||||
|
|
||||||
await expect(container).toHaveScreenshot(screenshot(`button-outline-round`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe('clear', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.goto(`/src/components/button/test/round`, config);
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
const container = page.locator('#clear');
|
|
||||||
|
|
||||||
await expect(container).toHaveScreenshot(screenshot(`button-clear-round`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe('color', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.goto(`/src/components/button/test/round`, config);
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
const container = page.locator('#color');
|
|
||||||
|
|
||||||
await expect(container).toHaveScreenshot(screenshot(`button-color-round`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.describe('expand', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.goto(`/src/components/button/test/round`, config);
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
const container = page.locator('#expand');
|
|
||||||
|
|
||||||
await expect(container).toHaveScreenshot(screenshot(`button-expand-round`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 16 KiB |
111
core/src/components/button/test/shape/button.e2e.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import { expect } from '@playwright/test';
|
||||||
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All content takes up the full width, so RTL has no effect.
|
||||||
|
*/
|
||||||
|
// TODO: FW-6077 - Add ionic theme on MD mode to this test.
|
||||||
|
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||||
|
test.describe(title('button: shape'), () => {
|
||||||
|
test.describe('round', () => {
|
||||||
|
test.describe('default', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.goto(`/src/components/button/test/shape`, config);
|
||||||
|
|
||||||
|
await page.setIonViewport();
|
||||||
|
|
||||||
|
const container = page.locator('#default');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-round`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('outline', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.goto(`/src/components/button/test/shape`, config);
|
||||||
|
|
||||||
|
await page.setIonViewport();
|
||||||
|
|
||||||
|
const container = page.locator('#outline');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-outline-round`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('clear', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.goto(`/src/components/button/test/shape`, config);
|
||||||
|
|
||||||
|
await page.setIonViewport();
|
||||||
|
|
||||||
|
const container = page.locator('#clear');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-clear-round`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('color', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.goto(`/src/components/button/test/shape`, config);
|
||||||
|
|
||||||
|
await page.setIonViewport();
|
||||||
|
|
||||||
|
const container = page.locator('#color');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-color-round`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('expand', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.goto(`/src/components/button/test/shape`, config);
|
||||||
|
|
||||||
|
await page.setIonViewport();
|
||||||
|
|
||||||
|
const container = page.locator('#expand');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-expand-round`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape="rectangular" is only available in the Ionic theme.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'], themes: ['ionic'] }).forEach(({ title, screenshot, config }) => {
|
||||||
|
test.describe(title('button: shape'), () => {
|
||||||
|
test.describe('rectangular', () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
ion-button {
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="container">
|
||||||
|
<ion-button shape="rectangular" fill="solid">Rectangular Button, Solid</ion-button>
|
||||||
|
<ion-button class="ion-focused" shape="rectangular" fill="solid">Rectangular Button, Solid, Focused</ion-button>
|
||||||
|
<ion-button class="ion-activated" shape="rectangular" fill="solid">Rectangular Button, Solid, Activated</ion-button>
|
||||||
|
|
||||||
|
<ion-button shape="rectangular" fill="outline">Rectangular Button, Outline</ion-button>
|
||||||
|
<ion-button class="ion-focused" shape="rectangular" fill="outline">Rectangular Button, Outline, Focused</ion-button>
|
||||||
|
<ion-button class="ion-activated" shape="rectangular" fill="outline">Rectangular Button, Outline, Activated</ion-button>
|
||||||
|
|
||||||
|
<ion-button shape="rectangular" fill="clear">Rectangular Button</ion-button>
|
||||||
|
<ion-button class="ion-focused" shape="rectangular" fill="clear">Rectangular Button, Focused</ion-button>
|
||||||
|
<ion-button class="ion-activated" shape="rectangular" fill="clear">Rectangular Button, Activated</ion-button>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const container = page.locator('#container');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`button-shape-rectangular`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 22 KiB |
@ -1,7 +1,8 @@
|
|||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
import { configs, test } from '@utils/test/playwright';
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
// TODO: FW-6077 - Limit this test to just the Ionic theme on MD mode.
|
||||||
|
configs({ directions: ['ltr'], themes: ['ionic', 'md', 'ios'] }).forEach(({ title, screenshot, config }) => {
|
||||||
test.describe(title('button: size'), () => {
|
test.describe(title('button: size'), () => {
|
||||||
test('should render small buttons', async ({ page }) => {
|
test('should render small buttons', async ({ page }) => {
|
||||||
await page.setContent(
|
await page.setContent(
|
||||||
@ -60,3 +61,26 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following tests are specific to the Ionic theme and do not depend on the text direction.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'], themes: ['ionic'] }).forEach(({ title, screenshot, config }) => {
|
||||||
|
test.describe(title('button: size'), () => {
|
||||||
|
test('should render xsmall buttons', async ({ page }) => {
|
||||||
|
await page.setContent(`<ion-button size="xsmall" fill="solid">X-Small Button</ion-button>`, config);
|
||||||
|
|
||||||
|
const wrapper = page.locator('ion-button');
|
||||||
|
|
||||||
|
await expect(wrapper).toHaveScreenshot(screenshot(`button-size-x-small`));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render xlarge buttons', async ({ page }) => {
|
||||||
|
await page.setContent(`<ion-button size="xlarge" fill="solid">X-Large Button</ion-button>`, config);
|
||||||
|
|
||||||
|
const wrapper = page.locator('ion-button');
|
||||||
|
|
||||||
|
await expect(wrapper).toHaveScreenshot(screenshot(`button-size-x-large`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |