diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 8d3c764b41..91968cff8d 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -553,6 +553,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. + */ + "hue"?: 'bold' | 'subtle'; /** * The mode determines the platform behaviors of the component. */ @@ -5916,6 +5920,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. + */ + "hue"?: 'bold' | 'subtle'; /** * The mode determines the platform behaviors of the component. */ diff --git a/core/src/components/button/button.ionic.scss b/core/src/components/button/button.ionic.scss index efc4277d84..2650cabdf4 100644 --- a/core/src/components/button/button.ionic.scss +++ b/core/src/components/button/button.ionic.scss @@ -52,6 +52,11 @@ --ripple-color: var(--background-activated); } +:host(.button-solid.button-subtle) { + --background: #{globals.ion-color(primary, subtle)}; + --color: #{globals.ion-color(primary, base)}; +} + // Outline Button // -------------------------------------------------- @@ -81,6 +86,11 @@ // Ripple Effect // ------------------------------------------------------------------------------- +:host(.button-solid.button-subtle.ion-color) .button-native { + background: globals.current-color(subtle); + color: globals.current-color(base); +} + :host(.button-solid.ion-color) ion-ripple-effect { color: globals.current-color(shade); } diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index b676026318..b735c7c47b 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -75,6 +75,12 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf */ @Prop({ reflect: true }) expand?: 'full' | 'block'; + /** + * Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for + * a button with muted, subtle colors. + */ + @Prop() hue?: 'bold' | 'subtle' = 'bold'; + /** * Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"` * for a transparent button with a border, or to `"solid"` for a button with a filled background. @@ -349,8 +355,20 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf }; render() { - const { buttonType, type, disabled, rel, target, href, color, expand, hasIconOnly, strong, inheritedAttributes } = - this; + const { + buttonType, + type, + disabled, + rel, + target, + href, + color, + expand, + hue, + hasIconOnly, + strong, + inheritedAttributes, + } = this; const theme = getIonTheme(this); const mode = getIonMode(this); @@ -394,6 +412,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf [theme]: true, [buttonType]: true, [`${buttonType}-${expand}`]: expand !== undefined, + [`${buttonType}-${hue}`]: hue !== undefined, [`${buttonType}-${size}`]: size !== undefined, [`${buttonType}-${shape}`]: true, [`${buttonType}-${fill}`]: true, diff --git a/core/src/components/button/test/basic/index.html b/core/src/components/button/test/basic/index.html index 19efe474ce..3976c6abf1 100644 --- a/core/src/components/button/test/basic/index.html +++ b/core/src/components/button/test/basic/index.html @@ -12,6 +12,12 @@ + + @@ -23,6 +29,8 @@ +

Bold (default) Buttons

+

Default Default.focused @@ -83,48 +91,68 @@ Dark.activated

+

Subtle Buttons

+

- Opacity: 0.2 + Default + Default.focused + Default.activated

- Button Disabled - Secondary Disabled - Disabled opacity: 1 + Primary + Primary.focused + Primary.activated

- Toggle Disabled + Secondary + Secondary.focused + Secondary.activated

- Change Color - Change Color + Tertiary + Tertiary.focused + Tertiary.activated +

+ +

+ Success + Success.focused + Success.activated +

+ +

+ Warning + Warning.focused + Warning.activated +

+ +

+ Danger + Danger.focused + Danger.activated +

+ +

+ Light + Light.focused + Light.activated +

+ +

+ Medium + Medium.focused + Medium.activated +

+ +

+ Dark + Dark.focused + Dark.activated

- - diff --git a/core/src/themes/functions.color.scss b/core/src/themes/functions.color.scss index 702bdf0bcf..f3989ff763 100644 --- a/core/src/themes/functions.color.scss +++ b/core/src/themes/functions.color.scss @@ -93,6 +93,7 @@ $contrast: map-get($value, contrast); $shade: map-get($value, shade); $tint: map-get($value, tint); + $subtle: map-get($value, subtle); --ion-color-base: var(--ion-color-#{$color-name}, #{$base}) !important; --ion-color-base-rgb: var(--ion-color-#{$color-name}-rgb, #{color-to-rgb-list($base)}) !important; @@ -100,6 +101,7 @@ --ion-color-contrast-rgb: var(--ion-color-#{$color-name}-contrast-rgb, #{color-to-rgb-list($contrast)}) !important; --ion-color-shade: var(--ion-color-#{$color-name}-shade, #{$shade}) !important; --ion-color-tint: var(--ion-color-#{$color-name}-tint, #{$tint}) !important; + --ion-color-subtle: var(--ion-color-#{$color-name}-subtle, #{$subtle}) !important; } // Generates the CSS variables for each color diff --git a/core/src/themes/ionic/ionic.theme.default.scss b/core/src/themes/ionic/ionic.theme.default.scss index cd702ae984..b13e52aeb4 100644 --- a/core/src/themes/ionic/ionic.theme.default.scss +++ b/core/src/themes/ionic/ionic.theme.default.scss @@ -17,77 +17,69 @@ // TODO(ROU-10778, ROU-10875): Sync the color names to the design system of // ios and md. This will allow us to have a single color map. -$primary: #105cef; -$secondary: initial; -$tertiary: initial; -$success: #1fbd3b; -$warning: #e18300; -$danger: #bf2222; -$light: #f2f4fd; -$medium: initial; -$neutral: #626262; -$dark: initial; - $ionic-colors: ( primary: ( - base: $primary, - contrast: #fff, - shade: color.get-color-shade($primary), - tint: color.get-color-tint($primary), + base: globals.$ion-semantics-primary-base, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-semantics-primary-800, + tint: globals.$ion-semantics-primary-500, + subtle: globals.$ion-semantics-primary-100, ), secondary: ( - base: $secondary, - contrast: $secondary, - shade: color.get-color-shade($secondary), - tint: color.get-color-tint($secondary), + base: globals.$ion-semantics-info-base, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-semantics-info-800, + tint: globals.$ion-semantics-info-500, + subtle: globals.$ion-semantics-info-100, ), tertiary: ( - base: $tertiary, - contrast: $tertiary, - shade: color.get-color-shade($tertiary), - tint: color.get-color-tint($tertiary), + base: globals.$ion-primitives-violet-700, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-primitives-violet-800, + tint: globals.$ion-primitives-violet-500, + subtle: globals.$ion-primitives-violet-100, ), success: ( - base: $success, - contrast: #000, - shade: color.get-color-shade($success), - tint: color.get-color-tint($success), + base: globals.$ion-semantics-success-base, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-semantics-success-800, + tint: globals.$ion-semantics-success-500, + subtle: globals.$ion-semantics-success-100, ), warning: ( - base: $warning, - contrast: #000, - shade: color.get-color-shade($warning), - tint: color.get-color-tint($warning), + base: globals.$ion-semantics-warning-base, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-semantics-warning-800, + tint: globals.$ion-semantics-warning-500, + subtle: globals.$ion-semantics-warning-100, ), danger: ( - base: $danger, - contrast: #fff, - shade: color.get-color-shade($danger), - tint: color.get-color-tint($danger), + base: globals.$ion-semantics-danger-base, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-semantics-danger-800, + tint: globals.$ion-semantics-danger-500, + subtle: globals.$ion-semantics-danger-100, ), light: ( - base: $light, - contrast: #000, - shade: color.get-color-shade($light), - tint: color.get-color-tint($light), + base: globals.$ion-primitives-neutral-200, + contrast: globals.$ion-primitives-base-black, + shade: globals.$ion-primitives-neutral-300, + tint: globals.$ion-primitives-neutral-100, + subtle: globals.$ion-primitives-neutral-100, ), medium: ( - base: $medium, - contrast: $medium, - shade: color.get-color-shade($medium), - tint: color.get-color-tint($medium), - ), - neutral: ( - base: $neutral, - contrast: #fff, - shade: color.get-color-shade($neutral), - tint: color.get-color-tint($neutral), + base: globals.$ion-primitives-neutral-700, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-primitives-neutral-800, + tint: globals.$ion-primitives-neutral-500, + subtle: globals.$ion-primitives-neutral-100, ), dark: ( - base: $dark, - contrast: $dark, - shade: color.get-color-shade($dark), - tint: color.get-color-tint($dark), + base: globals.$ion-primitives-neutral-1100, + contrast: globals.$ion-primitives-base-white, + shade: globals.$ion-primitives-neutral-1200, + tint: globals.$ion-primitives-neutral-900, + subtle: globals.$ion-primitives-neutral-100, ), ); diff --git a/packages/angular/src/directives/proxies.ts b/packages/angular/src/directives/proxies.ts index daed64577b..208a31fc06 100644 --- a/packages/angular/src/directives/proxies.ts +++ b/packages/angular/src/directives/proxies.ts @@ -345,14 +345,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs { @ProxyCmp({ - inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'] + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'] }) @Component({ selector: 'ion-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'], + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'], }) export class IonButton { protected el: HTMLElement; diff --git a/packages/angular/standalone/src/directives/proxies.ts b/packages/angular/standalone/src/directives/proxies.ts index df589497e9..488ea5191d 100644 --- a/packages/angular/standalone/src/directives/proxies.ts +++ b/packages/angular/standalone/src/directives/proxies.ts @@ -439,14 +439,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs { @ProxyCmp({ defineCustomElementFn: defineIonButton, - inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'] + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'] }) @Component({ selector: 'ion-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'], + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'], standalone: true }) export class IonButton { diff --git a/packages/vue/src/proxies.ts b/packages/vue/src/proxies.ts index d5a84a2e39..9549becf54 100644 --- a/packages/vue/src/proxies.ts +++ b/packages/vue/src/proxies.ts @@ -162,6 +162,7 @@ export const IonButton = /*@__PURE__*/ defineContainer('ion-butto 'buttonType', 'disabled', 'expand', + 'hue', 'fill', 'routerDirection', 'routerAnimation',