diff --git a/core/api.txt b/core/api.txt index 65146f6ab93..10697645eaf 100644 --- a/core/api.txt +++ b/core/api.txt @@ -439,6 +439,7 @@ ion-button,prop,expand,"block" | "full" | undefined,undefined,false,true ion-button,prop,fill,"clear" | "default" | "outline" | "solid" | undefined,undefined,false,true ion-button,prop,form,HTMLFormElement | string | undefined,undefined,false,false ion-button,prop,href,string | undefined,undefined,false,false +ion-button,prop,hue,"bold" | "subtle" | undefined,undefined,false,false ion-button,prop,mode,"ios" | "md",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 @@ -571,6 +572,126 @@ ion-button,css-prop,--ion-button-hue-bold-solid-semantic-hover-color ion-button,css-prop,--ion-button-hue-bold-solid-semantic-ripple-effect-color ion-button,css-prop,--ion-button-hue-bold-solid-semantic-ripple-effect-opacity ion-button,css-prop,--ion-button-hue-bold-solid-strong-font-weight +ion-button,css-prop,--ion-button-hue-subtle-clear-activated-background +ion-button,css-prop,--ion-button-hue-subtle-clear-activated-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-clear-activated-color +ion-button,css-prop,--ion-button-hue-subtle-clear-activated-opacity +ion-button,css-prop,--ion-button-hue-subtle-clear-default-background +ion-button,css-prop,--ion-button-hue-subtle-clear-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-clear-default-border-style +ion-button,css-prop,--ion-button-hue-subtle-clear-default-border-width +ion-button,css-prop,--ion-button-hue-subtle-clear-default-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-clear-default-color +ion-button,css-prop,--ion-button-hue-subtle-clear-default-font-weight +ion-button,css-prop,--ion-button-hue-subtle-clear-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-clear-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-clear-disabled-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-clear-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-clear-disabled-opacity +ion-button,css-prop,--ion-button-hue-subtle-clear-focus-background +ion-button,css-prop,--ion-button-hue-subtle-clear-focus-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-clear-focus-color +ion-button,css-prop,--ion-button-hue-subtle-clear-hover-background +ion-button,css-prop,--ion-button-hue-subtle-clear-hover-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-clear-hover-color +ion-button,css-prop,--ion-button-hue-subtle-clear-hover-opacity +ion-button,css-prop,--ion-button-hue-subtle-clear-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-clear-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-activated-background +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-activated-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-default-background +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-default-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-focus-background +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-focus-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-hover-background +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-hover-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-clear-semantic-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-clear-strong-font-weight +ion-button,css-prop,--ion-button-hue-subtle-outline-activated-background +ion-button,css-prop,--ion-button-hue-subtle-outline-activated-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-outline-activated-color +ion-button,css-prop,--ion-button-hue-subtle-outline-activated-opacity +ion-button,css-prop,--ion-button-hue-subtle-outline-default-background +ion-button,css-prop,--ion-button-hue-subtle-outline-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-outline-default-border-style +ion-button,css-prop,--ion-button-hue-subtle-outline-default-border-width +ion-button,css-prop,--ion-button-hue-subtle-outline-default-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-outline-default-color +ion-button,css-prop,--ion-button-hue-subtle-outline-default-font-weight +ion-button,css-prop,--ion-button-hue-subtle-outline-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-outline-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-outline-disabled-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-outline-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-outline-disabled-opacity +ion-button,css-prop,--ion-button-hue-subtle-outline-focus-background +ion-button,css-prop,--ion-button-hue-subtle-outline-focus-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-outline-focus-color +ion-button,css-prop,--ion-button-hue-subtle-outline-hover-background +ion-button,css-prop,--ion-button-hue-subtle-outline-hover-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-outline-hover-color +ion-button,css-prop,--ion-button-hue-subtle-outline-hover-opacity +ion-button,css-prop,--ion-button-hue-subtle-outline-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-outline-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-activated-background +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-activated-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-default-background +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-default-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-focus-background +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-focus-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-hover-background +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-hover-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-outline-semantic-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-outline-strong-font-weight +ion-button,css-prop,--ion-button-hue-subtle-solid-activated-background +ion-button,css-prop,--ion-button-hue-subtle-solid-activated-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-solid-activated-color +ion-button,css-prop,--ion-button-hue-subtle-solid-activated-opacity +ion-button,css-prop,--ion-button-hue-subtle-solid-default-background +ion-button,css-prop,--ion-button-hue-subtle-solid-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-solid-default-border-style +ion-button,css-prop,--ion-button-hue-subtle-solid-default-border-width +ion-button,css-prop,--ion-button-hue-subtle-solid-default-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-solid-default-color +ion-button,css-prop,--ion-button-hue-subtle-solid-default-font-weight +ion-button,css-prop,--ion-button-hue-subtle-solid-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-solid-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-solid-disabled-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-solid-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-solid-disabled-opacity +ion-button,css-prop,--ion-button-hue-subtle-solid-focus-background +ion-button,css-prop,--ion-button-hue-subtle-solid-focus-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-solid-focus-color +ion-button,css-prop,--ion-button-hue-subtle-solid-hover-background +ion-button,css-prop,--ion-button-hue-subtle-solid-hover-box-shadow +ion-button,css-prop,--ion-button-hue-subtle-solid-hover-color +ion-button,css-prop,--ion-button-hue-subtle-solid-hover-opacity +ion-button,css-prop,--ion-button-hue-subtle-solid-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-solid-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-activated-background +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-activated-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-default-background +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-default-border-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-default-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-disabled-background +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-disabled-border-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-disabled-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-focus-background +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-focus-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-hover-background +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-hover-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-ripple-effect-color +ion-button,css-prop,--ion-button-hue-subtle-solid-semantic-ripple-effect-opacity +ion-button,css-prop,--ion-button-hue-subtle-solid-strong-font-weight ion-button,css-prop,--ion-button-letter-spacing ion-button,css-prop,--ion-button-margin-bottom ion-button,css-prop,--ion-button-margin-end diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 77dc1472557..5ba767a3504 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -625,6 +625,10 @@ export namespace Components { * Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered. */ "href": string | undefined; + /** + * Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors. Defaults to `"bold"` if both the hue property and theme config are unset. + */ + "hue"?: Hue; /** * The mode determines the platform behaviors of the component. */ @@ -6478,6 +6482,10 @@ declare namespace LocalJSX { * Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered. */ "href"?: string | undefined; + /** + * Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors. Defaults to `"bold"` if both the hue property and theme config are unset. + */ + "hue"?: Hue; /** * The mode determines the platform behaviors of the component. */ @@ -10477,6 +10485,7 @@ declare namespace LocalJSX { "disabled": boolean; "expand": IonButtonExpand; "fill": IonButtonFill | 'default'; + "hue": Hue; "routerDirection": RouterDirection; "download": string | undefined; "href": string | undefined; diff --git a/core/src/components/button/_button.docs.scss b/core/src/components/button/_button.docs.scss index 73773466aee..b333c4136e6 100644 --- a/core/src/components/button/_button.docs.scss +++ b/core/src/components/button/_button.docs.scss @@ -13,6 +13,12 @@ * @prop --ion-button-hue-bold-outline-strong-font-weight: Font weight of the `bold` hue and `outline` fill combination on a `strong` button * @prop --ion-button-hue-bold-clear-default-font-weight: Font weight of the `bold` hue and `clear` fill combination in the default state * @prop --ion-button-hue-bold-clear-strong-font-weight: Font weight of the `bold` hue and `clear` fill combination on a `strong` button + * @prop --ion-button-hue-subtle-solid-default-font-weight: Font weight of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-strong-font-weight: Font weight of the `subtle` hue and `solid` fill combination on a `strong` button + * @prop --ion-button-hue-subtle-outline-default-font-weight: Font weight of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-strong-font-weight: Font weight of the `subtle` hue and `outline` fill combination on a `strong` button + * @prop --ion-button-hue-subtle-clear-default-font-weight: Font weight of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-strong-font-weight: Font weight of the `subtle` hue and `clear` fill combination on a `strong` button * @prop --ion-button-size-small-min-width: Minimum width of the `small` button size * @prop --ion-button-size-small-min-height: Minimum height of the `small` button size, and the width and height of an icon-only button of that size * @prop --ion-button-size-small-font-size: Font size of the `small` button size @@ -267,4 +273,118 @@ * @prop --ion-button-hue-bold-clear-semantic-disabled-background: Background of the `bold` hue and `clear` fill combination in the disabled state when a semantic color is applied * @prop --ion-button-hue-bold-clear-semantic-disabled-color: Text color of the `bold` hue and `clear` fill combination in the disabled state when a semantic color is applied * @prop --ion-button-hue-bold-clear-semantic-disabled-border-color: Border color of the `bold` hue and `clear` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-default-border-color: Border color of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-default-color: Text color of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-default-color: Text color of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-background: Background of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-color: Text color of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-border-width: Border width of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-border-style: Border style of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-border-color: Border color of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-default-box-shadow: Box shadow of the `subtle` hue and `solid` fill combination in the default state + * @prop --ion-button-hue-subtle-solid-ripple-effect-color: Ripple color of the `subtle` hue and `solid` fill combination + * @prop --ion-button-hue-subtle-solid-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `solid` fill combination + * @prop --ion-button-hue-subtle-solid-semantic-default-border-color: Border color of the `subtle` hue and `solid` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-default-background: Background of the `subtle` hue and `solid` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-default-color: Text color of the `subtle` hue and `solid` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-ripple-effect-color: Ripple color of the `subtle` hue and `solid` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `solid` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-focus-color: Text color of the `subtle` hue and `solid` fill combination in the focus state + * @prop --ion-button-hue-subtle-solid-focus-background: Background of the `subtle` hue and `solid` fill combination in the focus state + * @prop --ion-button-hue-subtle-solid-focus-box-shadow: Box shadow of the `subtle` hue and `solid` fill combination in the focus state + * @prop --ion-button-hue-subtle-solid-semantic-focus-background: Background of the `subtle` hue and `solid` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-focus-color: Text color of the `subtle` hue and `solid` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-hover-color: Text color of the `subtle` hue and `solid` fill combination in the hover state + * @prop --ion-button-hue-subtle-solid-hover-opacity: Opacity of the whole button of the `subtle` hue and `solid` fill combination in the hover state + * @prop --ion-button-hue-subtle-solid-hover-background: Background of the `subtle` hue and `solid` fill combination in the hover state + * @prop --ion-button-hue-subtle-solid-hover-box-shadow: Box shadow of the `subtle` hue and `solid` fill combination in the hover state + * @prop --ion-button-hue-subtle-solid-semantic-hover-background: Background of the `subtle` hue and `solid` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-hover-color: Text color of the `subtle` hue and `solid` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-activated-color: Text color of the `subtle` hue and `solid` fill combination in the activated state + * @prop --ion-button-hue-subtle-solid-activated-opacity: Opacity of the whole button of the `subtle` hue and `solid` fill combination in the activated state + * @prop --ion-button-hue-subtle-solid-activated-background: Background of the `subtle` hue and `solid` fill combination in the activated state + * @prop --ion-button-hue-subtle-solid-activated-box-shadow: Box shadow of the `subtle` hue and `solid` fill combination in the activated state + * @prop --ion-button-hue-subtle-solid-semantic-activated-background: Background of the `subtle` hue and `solid` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-activated-color: Text color of the `subtle` hue and `solid` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-disabled-background: Background of the `subtle` hue and `solid` fill combination in the disabled state + * @prop --ion-button-hue-subtle-solid-disabled-opacity: Opacity of the whole button of the `subtle` hue and `solid` fill combination in the disabled state + * @prop --ion-button-hue-subtle-solid-disabled-color: Text color of the `subtle` hue and `solid` fill combination in the disabled state + * @prop --ion-button-hue-subtle-solid-disabled-border-color: Border color of the `subtle` hue and `solid` fill combination in the disabled state + * @prop --ion-button-hue-subtle-solid-disabled-box-shadow: Box shadow of the `subtle` hue and `solid` fill combination in the disabled state + * @prop --ion-button-hue-subtle-solid-semantic-disabled-background: Background of the `subtle` hue and `solid` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-disabled-color: Text color of the `subtle` hue and `solid` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-solid-semantic-disabled-border-color: Border color of the `subtle` hue and `solid` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-default-border-width: Border width of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-default-border-style: Border style of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-default-background: Background of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-default-box-shadow: Box shadow of the `subtle` hue and `outline` fill combination in the default state + * @prop --ion-button-hue-subtle-outline-ripple-effect-color: Ripple color of the `subtle` hue and `outline` fill combination + * @prop --ion-button-hue-subtle-outline-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `outline` fill combination + * @prop --ion-button-hue-subtle-outline-semantic-default-border-color: Border color of the `subtle` hue and `outline` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-default-background: Background of the `subtle` hue and `outline` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-default-color: Text color of the `subtle` hue and `outline` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-ripple-effect-color: Ripple color of the `subtle` hue and `outline` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `outline` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-focus-color: Text color of the `subtle` hue and `outline` fill combination in the focus state + * @prop --ion-button-hue-subtle-outline-focus-background: Background of the `subtle` hue and `outline` fill combination in the focus state + * @prop --ion-button-hue-subtle-outline-focus-box-shadow: Box shadow of the `subtle` hue and `outline` fill combination in the focus state + * @prop --ion-button-hue-subtle-outline-semantic-focus-background: Background of the `subtle` hue and `outline` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-focus-color: Text color of the `subtle` hue and `outline` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-hover-color: Text color of the `subtle` hue and `outline` fill combination in the hover state + * @prop --ion-button-hue-subtle-outline-hover-opacity: Opacity of the whole button of the `subtle` hue and `outline` fill combination in the hover state + * @prop --ion-button-hue-subtle-outline-hover-background: Background of the `subtle` hue and `outline` fill combination in the hover state + * @prop --ion-button-hue-subtle-outline-hover-box-shadow: Box shadow of the `subtle` hue and `outline` fill combination in the hover state + * @prop --ion-button-hue-subtle-outline-semantic-hover-background: Background of the `subtle` hue and `outline` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-hover-color: Text color of the `subtle` hue and `outline` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-activated-color: Text color of the `subtle` hue and `outline` fill combination in the activated state + * @prop --ion-button-hue-subtle-outline-activated-opacity: Opacity of the whole button of the `subtle` hue and `outline` fill combination in the activated state + * @prop --ion-button-hue-subtle-outline-activated-background: Background of the `subtle` hue and `outline` fill combination in the activated state + * @prop --ion-button-hue-subtle-outline-activated-box-shadow: Box shadow of the `subtle` hue and `outline` fill combination in the activated state + * @prop --ion-button-hue-subtle-outline-semantic-activated-background: Background of the `subtle` hue and `outline` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-activated-color: Text color of the `subtle` hue and `outline` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-disabled-background: Background of the `subtle` hue and `outline` fill combination in the disabled state + * @prop --ion-button-hue-subtle-outline-disabled-opacity: Opacity of the whole button of the `subtle` hue and `outline` fill combination in the disabled state + * @prop --ion-button-hue-subtle-outline-disabled-color: Text color of the `subtle` hue and `outline` fill combination in the disabled state + * @prop --ion-button-hue-subtle-outline-disabled-border-color: Border color of the `subtle` hue and `outline` fill combination in the disabled state + * @prop --ion-button-hue-subtle-outline-disabled-box-shadow: Box shadow of the `subtle` hue and `outline` fill combination in the disabled state + * @prop --ion-button-hue-subtle-outline-semantic-disabled-background: Background of the `subtle` hue and `outline` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-disabled-color: Text color of the `subtle` hue and `outline` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-outline-semantic-disabled-border-color: Border color of the `subtle` hue and `outline` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-default-border-width: Border width of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-default-border-style: Border style of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-default-border-color: Border color of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-default-background: Background of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-default-box-shadow: Box shadow of the `subtle` hue and `clear` fill combination in the default state + * @prop --ion-button-hue-subtle-clear-ripple-effect-color: Ripple color of the `subtle` hue and `clear` fill combination + * @prop --ion-button-hue-subtle-clear-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `clear` fill combination + * @prop --ion-button-hue-subtle-clear-semantic-default-border-color: Border color of the `subtle` hue and `clear` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-default-background: Background of the `subtle` hue and `clear` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-default-color: Text color of the `subtle` hue and `clear` fill combination in the default state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-ripple-effect-color: Ripple color of the `subtle` hue and `clear` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-ripple-effect-opacity: Ripple opacity of the `subtle` hue and `clear` fill combination when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-focus-color: Text color of the `subtle` hue and `clear` fill combination in the focus state + * @prop --ion-button-hue-subtle-clear-focus-background: Background of the `subtle` hue and `clear` fill combination in the focus state + * @prop --ion-button-hue-subtle-clear-focus-box-shadow: Box shadow of the `subtle` hue and `clear` fill combination in the focus state + * @prop --ion-button-hue-subtle-clear-semantic-focus-background: Background of the `subtle` hue and `clear` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-focus-color: Text color of the `subtle` hue and `clear` fill combination in the focus state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-hover-color: Text color of the `subtle` hue and `clear` fill combination in the hover state + * @prop --ion-button-hue-subtle-clear-hover-opacity: Opacity of the whole button of the `subtle` hue and `clear` fill combination in the hover state + * @prop --ion-button-hue-subtle-clear-hover-background: Background of the `subtle` hue and `clear` fill combination in the hover state + * @prop --ion-button-hue-subtle-clear-hover-box-shadow: Box shadow of the `subtle` hue and `clear` fill combination in the hover state + * @prop --ion-button-hue-subtle-clear-semantic-hover-background: Background of the `subtle` hue and `clear` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-hover-color: Text color of the `subtle` hue and `clear` fill combination in the hover state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-activated-color: Text color of the `subtle` hue and `clear` fill combination in the activated state + * @prop --ion-button-hue-subtle-clear-activated-opacity: Opacity of the whole button of the `subtle` hue and `clear` fill combination in the activated state + * @prop --ion-button-hue-subtle-clear-activated-background: Background of the `subtle` hue and `clear` fill combination in the activated state + * @prop --ion-button-hue-subtle-clear-activated-box-shadow: Box shadow of the `subtle` hue and `clear` fill combination in the activated state + * @prop --ion-button-hue-subtle-clear-semantic-activated-background: Background of the `subtle` hue and `clear` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-activated-color: Text color of the `subtle` hue and `clear` fill combination in the activated state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-disabled-background: Background of the `subtle` hue and `clear` fill combination in the disabled state + * @prop --ion-button-hue-subtle-clear-disabled-opacity: Opacity of the whole button of the `subtle` hue and `clear` fill combination in the disabled state + * @prop --ion-button-hue-subtle-clear-disabled-color: Text color of the `subtle` hue and `clear` fill combination in the disabled state + * @prop --ion-button-hue-subtle-clear-disabled-border-color: Border color of the `subtle` hue and `clear` fill combination in the disabled state + * @prop --ion-button-hue-subtle-clear-disabled-box-shadow: Box shadow of the `subtle` hue and `clear` fill combination in the disabled state + * @prop --ion-button-hue-subtle-clear-semantic-disabled-background: Background of the `subtle` hue and `clear` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-disabled-color: Text color of the `subtle` hue and `clear` fill combination in the disabled state when a semantic color is applied + * @prop --ion-button-hue-subtle-clear-semantic-disabled-border-color: Border color of the `subtle` hue and `clear` fill combination in the disabled state when a semantic color is applied */ diff --git a/core/src/components/button/button.scss b/core/src/components/button/button.scss index 259ef176cea..dd411f3aedb 100644 --- a/core/src/components/button/button.scss +++ b/core/src/components/button/button.scss @@ -4,6 +4,7 @@ // Button // -------------------------------------------------- +$hues: bold, subtle; $fills: solid, outline, clear; $sizes: small, medium, large; $shapes: crisp, soft, round, rectangular; @@ -137,15 +138,17 @@ $spinner-sizes: xsmall, small, medium, large, xlarge; // Button: Fill Typography // -------------------------------------------------- -@each $fill in $fills { - :host(.button-hue-bold.button-fill-#{$fill}) { - font-weight: var(--ion-button-hue-bold-#{$fill}-default-font-weight); +@each $hue in $hues { + @each $fill in $fills { + :host(.button-hue-#{$hue}.button-fill-#{$fill}) { + font-weight: var(--ion-button-hue-#{$hue}-#{$fill}-default-font-weight); + } } -} -@each $fill in $fills { - :host(.button-hue-bold.button-fill-#{$fill}.button-strong) { - font-weight: var(--ion-button-hue-bold-#{$fill}-strong-font-weight); + @each $fill in $fills { + :host(.button-hue-#{$hue}.button-fill-#{$fill}.button-strong) { + font-weight: var(--ion-button-hue-#{$hue}-#{$fill}-strong-font-weight); + } } } @@ -292,168 +295,170 @@ $spinner-sizes: xsmall, small, medium, large, xlarge; // Button: Hues and Fills // -------------------------------------------------- -/** - * Each fill has a resting look and one for each state. Without a color, - * the button reads the plain tokens. With a color, it reads the `semantic` - * tokens, which use the color's base, contrast and so on. - */ -@each $fill in $fills { - $token: --ion-button-hue-bold-#{$fill}; +@each $hue in $hues { + /** + * Each fill has a resting look and one for each state. Without a color, + * the button reads the plain tokens. With a color, it reads the `semantic` + * tokens, which use the color's base, contrast and so on. + */ + @each $fill in $fills { + $token: --ion-button-hue-#{$hue}-#{$fill}; - :host(.button-hue-bold.button-fill-#{$fill}) { - color: var(#{$token}-default-color); - } + :host(.button-hue-#{$hue}.button-fill-#{$fill}) { + color: var(#{$token}-default-color); + } - :host(.button-hue-bold.button-fill-#{$fill}) .button-native { - border-width: var(#{$token}-default-border-width); - border-style: var(#{$token}-default-border-style); - border-color: var(#{$token}-default-border-color); + :host(.button-hue-#{$hue}.button-fill-#{$fill}) .button-native { + border-width: var(#{$token}-default-border-width); + border-style: var(#{$token}-default-border-style); + border-color: var(#{$token}-default-border-color); - background: var(#{$token}-default-background); + background: var(#{$token}-default-background); - box-shadow: var(#{$token}-default-box-shadow); - } + box-shadow: var(#{$token}-default-box-shadow); + } - // The ripple sits in this shadow root, out of reach of the global token CSS - :host(.button-hue-bold.button-fill-#{$fill}) ion-ripple-effect { - // A variable, because the ripple animates its opacity in a keyframe - --ion-ripple-effect-opacity: var(#{$token}-ripple-effect-opacity); + // The ripple sits in this shadow root, out of reach of the global token CSS + :host(.button-hue-#{$hue}.button-fill-#{$fill}) ion-ripple-effect { + // A variable, because the ripple animates its opacity in a keyframe + --ion-ripple-effect-opacity: var(#{$token}-ripple-effect-opacity); - color: var(#{$token}-ripple-effect-color); - } + color: var(#{$token}-ripple-effect-color); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color) .button-native { - border-color: var(#{$token}-semantic-default-border-color); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color) .button-native { + border-color: var(#{$token}-semantic-default-border-color); - background: var(#{$token}-semantic-default-background); - color: var(#{$token}-semantic-default-color); - } + background: var(#{$token}-semantic-default-background); + color: var(#{$token}-semantic-default-color); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color) ion-ripple-effect { - --ion-ripple-effect-opacity: var(#{$token}-semantic-ripple-effect-opacity); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color) ion-ripple-effect { + --ion-ripple-effect-opacity: var(#{$token}-semantic-ripple-effect-opacity); - color: var(#{$token}-semantic-ripple-effect-color); + color: var(#{$token}-semantic-ripple-effect-color); + } } -} -/** - * The states are written in this order: focus -> hover -> activated -> disabled. - * Their rules share a specificity, so a later state overrides an earlier - * one: disabled overrides all, and activated overrides hover and focus. - */ + /** + * The states are written in this order: focus -> hover -> activated -> disabled. + * Their rules share a specificity, so a later state overrides an earlier + * one: disabled overrides all, and activated overrides hover and focus. + */ -// Focused -@each $fill in $fills { - $token: --ion-button-hue-bold-#{$fill}; + // Focused + @each $fill in $fills { + $token: --ion-button-hue-#{$hue}-#{$fill}; - :host(.button-hue-bold.button-fill-#{$fill}.ion-focused) { - color: var(#{$token}-focus-color); - } + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-focused) { + color: var(#{$token}-focus-color); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-focused) .button-native { - background: var(#{$token}-focus-background); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-focused) .button-native { + background: var(#{$token}-focus-background); - box-shadow: var(#{$token}-focus-box-shadow); - } + box-shadow: var(#{$token}-focus-box-shadow); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color.ion-focused) .button-native { - background: var(#{$token}-semantic-focus-background); - color: var(#{$token}-semantic-focus-color); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color.ion-focused) .button-native { + background: var(#{$token}-semantic-focus-background); + color: var(#{$token}-semantic-focus-color); + } } -} -// Hover -@media (any-hover: hover) { - @each $fill in $fills { - $token: --ion-button-hue-bold-#{$fill}; + // Hover + @media (any-hover: hover) { + @each $fill in $fills { + $token: --ion-button-hue-#{$hue}-#{$fill}; - :host(.button-hue-bold.button-fill-#{$fill}:hover) { - color: var(#{$token}-hover-color); - } + :host(.button-hue-#{$hue}.button-fill-#{$fill}:hover) { + color: var(#{$token}-hover-color); + } - // Disabled keeps its own opacity - :host(.button-hue-bold.button-fill-#{$fill}:not(.button-disabled):hover) { - opacity: var(#{$token}-hover-opacity); - } + // Disabled keeps its own opacity + :host(.button-hue-#{$hue}.button-fill-#{$fill}:not(.button-disabled):hover) { + opacity: var(#{$token}-hover-opacity); + } - :host(.button-hue-bold.button-fill-#{$fill}:hover) .button-native { - background: var(#{$token}-hover-background); + :host(.button-hue-#{$hue}.button-fill-#{$fill}:hover) .button-native { + background: var(#{$token}-hover-background); - box-shadow: var(#{$token}-hover-box-shadow); - } + box-shadow: var(#{$token}-hover-box-shadow); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color:hover) .button-native { - background: var(#{$token}-semantic-hover-background); - color: var(#{$token}-semantic-hover-color); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color:hover) .button-native { + background: var(#{$token}-semantic-hover-background); + color: var(#{$token}-semantic-hover-color); + } } } -} -// Activated -@each $fill in $fills { - $token: --ion-button-hue-bold-#{$fill}; + // Activated + @each $fill in $fills { + $token: --ion-button-hue-#{$hue}-#{$fill}; - :host(.button-hue-bold.button-fill-#{$fill}.ion-activated) { - color: var(#{$token}-activated-color); - } + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-activated) { + color: var(#{$token}-activated-color); + } - // Disabled keeps its own opacity - :host(.button-hue-bold.button-fill-#{$fill}.ion-activated:not(.button-disabled)) { - opacity: var(#{$token}-activated-opacity); - } + // Disabled keeps its own opacity + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-activated:not(.button-disabled)) { + opacity: var(#{$token}-activated-opacity); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-activated) .button-native { - background: var(#{$token}-activated-background); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-activated) .button-native { + background: var(#{$token}-activated-background); - box-shadow: var(#{$token}-activated-box-shadow); - } + box-shadow: var(#{$token}-activated-box-shadow); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color.ion-activated) .button-native { - background: var(#{$token}-semantic-activated-background); - color: var(#{$token}-semantic-activated-color); - } + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color.ion-activated) .button-native { + background: var(#{$token}-semantic-activated-background); + color: var(#{$token}-semantic-activated-color); + } - /** - * Only `md` mode renders a ripple. When it does, the ripple shows the press, - * so the button keeps its default background instead of the activated one. - */ - :host(.button-hue-bold.button-fill-#{$fill}.ion-activated) .button-native:has(ion-ripple-effect) { - background: var(#{$token}-default-background); - } + /** + * Only `md` mode renders a ripple. When it does, the ripple shows the press, + * so the button keeps its default background instead of the activated one. + */ + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-activated) .button-native:has(ion-ripple-effect) { + background: var(#{$token}-default-background); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color.ion-activated) .button-native:has(ion-ripple-effect) { - background: var(#{$token}-semantic-default-background); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color.ion-activated) .button-native:has(ion-ripple-effect) { + background: var(#{$token}-semantic-default-background); + } } -} -// Disabled -@each $fill in $fills { - $token: --ion-button-hue-bold-#{$fill}; + // Disabled + @each $fill in $fills { + $token: --ion-button-hue-#{$hue}-#{$fill}; - :host(.button-hue-bold.button-fill-#{$fill}.button-disabled) { - // Keeps the default color when the theme doesn't set one - color: var(#{$token}-disabled-color, var(#{$token}-default-color)); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.button-disabled) { + // Keeps the default color when the theme doesn't set one + color: var(#{$token}-disabled-color, var(#{$token}-default-color)); - opacity: var(#{$token}-disabled-opacity); - } + opacity: var(#{$token}-disabled-opacity); + } - :host(.button-hue-bold.button-fill-#{$fill}.button-disabled) .button-native { - // Keeps the default border color when the theme doesn't set one - border-color: var(#{$token}-disabled-border-color, var(#{$token}-default-border-color)); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.button-disabled) .button-native { + // Keeps the default border color when the theme doesn't set one + border-color: var(#{$token}-disabled-border-color, var(#{$token}-default-border-color)); - background: var(#{$token}-disabled-background); + background: var(#{$token}-disabled-background); - box-shadow: var(#{$token}-disabled-box-shadow); - } + box-shadow: var(#{$token}-disabled-box-shadow); + } - :host(.button-hue-bold.button-fill-#{$fill}.ion-color.button-disabled) .button-native { - // Keeps the default border color when the theme doesn't set one - border-color: var(#{$token}-semantic-disabled-border-color, var(#{$token}-semantic-default-border-color)); + :host(.button-hue-#{$hue}.button-fill-#{$fill}.ion-color.button-disabled) .button-native { + // Keeps the default border color when the theme doesn't set one + border-color: var(#{$token}-semantic-disabled-border-color, var(#{$token}-semantic-default-border-color)); - background: var(#{$token}-semantic-disabled-background); + background: var(#{$token}-semantic-disabled-background); - // Keeps the default color when the theme doesn't set one - color: var(#{$token}-semantic-disabled-color, var(#{$token}-semantic-default-color)); + // Keeps the default color when the theme doesn't set one + color: var(#{$token}-semantic-disabled-color, var(#{$token}-semantic-default-color)); + } } } diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index 32475d01f4d..f6def341022 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -95,6 +95,14 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf */ @Prop({ reflect: true, mutable: true }) fill?: IonButtonFill | 'default'; + /** + * Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for + * a button with muted, subtle colors. + * + * Defaults to `"bold"` if both the hue property and theme config are unset. + */ + @Prop() hue?: Hue; + /** * When using a router, it specifies the transition direction when navigating to * another page using `href`. @@ -294,10 +302,13 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf } /** - * Gets the button hue from the theme config. Defaults to `bold` if it is unset. + * Gets the button hue. Uses the `hue` property if set, otherwise + * checks the theme config. Defaults to `bold` if neither is set. */ get hueValue(): Hue { - return config.getObjectValue('IonButton.hue', 'bold') as Hue; + const hueConfig = config.getObjectValue('IonButton.hue', 'bold') as Hue; + + return this.hue ?? hueConfig; } /** @@ -494,7 +505,6 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf [`${buttonType}-size-${sizeValue}`]: true, [`${buttonType}-shape-${shapeValue}`]: true, [`${buttonType}-fill-${fillValue}`]: true, - // TODO(FW-6838): read the hue prop first in the hue PR [`${buttonType}-hue-${hueValue}`]: true, [`${buttonType}-strong`]: strong, 'in-datetime': this.inDatetime, diff --git a/core/src/components/button/test/hue/button.e2e.ts b/core/src/components/button/test/hue/button.e2e.ts new file mode 100644 index 00000000000..808738a7226 --- /dev/null +++ b/core/src/components/button/test/hue/button.e2e.ts @@ -0,0 +1,17 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This behavior does not vary across directions + */ +configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('button: hue'), () => { + test('should render each hue in each fill and state', async ({ page }) => { + await page.goto(`/src/components/button/test/hue`, config); + + await page.setIonViewport(); + + await expect(page).toHaveScreenshot(screenshot(`button-hue`)); + }); + }); +}); diff --git a/core/src/components/button/test/hue/index.html b/core/src/components/button/test/hue/index.html new file mode 100644 index 00000000000..4f9cfd9383f --- /dev/null +++ b/core/src/components/button/test/hue/index.html @@ -0,0 +1,97 @@ + + +
+ +