feat(toast): add "color" prop (#16100)

This commit also refactors ion-toast, so it uses shadow-dom,
this is required since CSS variables
does not work well in non-shadow-dom components.

fixes #16099
This commit is contained in:
Manu MA
2018-10-26 18:53:02 +02:00
committed by GitHub
parent f0141817d4
commit c982856dba
14 changed files with 75 additions and 55 deletions

View File

@ -4846,6 +4846,10 @@ export namespace Components {
*/ */
'closeButtonText'?: string; 'closeButtonText'?: string;
/** /**
* 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;
/**
* Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. * Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces.
*/ */
'cssClass'?: string | string[]; 'cssClass'?: string | string[];
@ -4913,6 +4917,10 @@ export namespace Components {
*/ */
'closeButtonText'?: string; 'closeButtonText'?: string;
/** /**
* 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;
/**
* Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. * Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces.
*/ */
'cssClass'?: string | string[]; 'cssClass'?: string | string[];

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '../../interface'; import { AnimationBuilder, Mode } from '../../interface';
export interface ActionSheetOptions { export interface ActionSheetOptions {
header?: string; header?: string;
@ -8,7 +8,7 @@ export interface ActionSheetOptions {
backdropDismiss?: boolean; backdropDismiss?: boolean;
translucent?: boolean; translucent?: boolean;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder, TextFieldTypes } from '../../interface'; import { AnimationBuilder, Mode, TextFieldTypes } from '../../interface';
export interface AlertOptions { export interface AlertOptions {
header?: string; header?: string;
@ -11,7 +11,7 @@ export interface AlertOptions {
translucent?: boolean; translucent?: boolean;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder, SpinnerTypes } from '../../interface'; import { AnimationBuilder, Mode, SpinnerTypes } from '../../interface';
export interface LoadingOptions { export interface LoadingOptions {
spinner?: SpinnerTypes; spinner?: SpinnerTypes;
@ -9,7 +9,7 @@ export interface LoadingOptions {
translucent?: boolean; translucent?: boolean;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate } from '../../interface'; import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Mode } from '../../interface';
export interface ModalOptions<T extends ComponentRef = ComponentRef> { export interface ModalOptions<T extends ComponentRef = ComponentRef> {
component: T; component: T;
@ -9,7 +9,7 @@ export interface ModalOptions<T extends ComponentRef = ComponentRef> {
delegate?: FrameworkDelegate; delegate?: FrameworkDelegate;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '../../interface'; import { AnimationBuilder, Mode } from '../../interface';
export interface PickerOptions { export interface PickerOptions {
columns: PickerColumn[]; columns: PickerColumn[];
@ -7,7 +7,7 @@ export interface PickerOptions {
backdropDismiss?: boolean; backdropDismiss?: boolean;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate } from '../../interface'; import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Mode } from '../../interface';
export interface PopoverOptions<T extends ComponentRef = ComponentRef> { export interface PopoverOptions<T extends ComponentRef = ComponentRef> {
component: T; component: T;
@ -11,7 +11,7 @@ export interface PopoverOptions<T extends ComponentRef = ComponentRef> {
delegate?: FrameworkDelegate; delegate?: FrameworkDelegate;
animated?: boolean; animated?: boolean;
mode?: string; mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -21,9 +21,10 @@ The toast can be dismissed automatically after a specific amount of time by pass
## Properties ## Properties
| Property | Attribute | Description | Type | | Property | Attribute | Description | Type |
| ----------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------- | | ----------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `animated` | `animated` | If `true`, the toast will animate. Defaults to `true`. | `boolean` | | `animated` | `animated` | If `true`, the toast will animate. Defaults to `true`. | `boolean` |
| `closeButtonText` | `close-button-text` | Text to display in the close button. | `string \| undefined` | | `closeButtonText` | `close-button-text` | Text to display in the close button. | `string \| undefined` |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` |
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | | `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` |
| `duration` | `duration` | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. | `number` | | `duration` | `duration` | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. | `number` |
| `enterAnimation` | -- | Animation to use when the toast is presented. | `AnimationBuilder \| undefined` | | `enterAnimation` | -- | Animation to use when the toast is presented. | `AnimationBuilder \| undefined` |

View File

@ -27,6 +27,7 @@
<ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true})">Show Toast with Close Button</ion-button> <ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true})">Show Toast with Close Button</ion-button>
<ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true, closeButtonText: 'closing time'})">Show Toast with Custom Close Button Text</ion-button> <ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true, closeButtonText: 'closing time'})">Show Toast with Custom Close Button Text</ion-button>
<ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true, translucent: true})">Show Translucent Toast</ion-button> <ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true, translucent: true})">Show Translucent Toast</ion-button>
<ion-button expand="block" onclick="presentToastWithOptions({message: 'click to close', showCloseButton: true, color: 'danger'})">Show Color Toast</ion-button>
<ion-toast-controller></ion-toast-controller> <ion-toast-controller></ion-toast-controller>

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '../../interface'; import { AnimationBuilder, Color, Mode } from '../../interface';
export interface ToastOptions { export interface ToastOptions {
message?: string; message?: string;
@ -10,7 +10,8 @@ export interface ToastOptions {
translucent?: boolean; translucent?: boolean;
animated?: boolean; animated?: boolean;
mode?: string; color?: Color;
mode?: Mode;
keyboardClose?: boolean; keyboardClose?: boolean;
id?: string; id?: string;

View File

@ -4,7 +4,7 @@
// iOS Toast // iOS Toast
// -------------------------------------------------- // --------------------------------------------------
.toast-ios { :host {
--background: #{$toast-ios-background-color}; --background: #{$toast-ios-background-color};
--button-color: #{$toast-ios-button-color}; --button-color: #{$toast-ios-button-color};
--color: #{$toast-ios-title-color}; --color: #{$toast-ios-title-color};
@ -12,7 +12,7 @@
font-size: $toast-ios-title-font-size; font-size: $toast-ios-title-font-size;
} }
.toast-ios .toast-wrapper { .toast-wrapper {
@include position-horizontal(10px, 10px); @include position-horizontal(10px, 10px);
@include margin(auto); @include margin(auto);
@include border-radius($toast-ios-border-radius); @include border-radius($toast-ios-border-radius);
@ -25,19 +25,15 @@
z-index: $z-index-overlay-wrapper; z-index: $z-index-overlay-wrapper;
} }
.toast-translucent-ios .toast-wrapper { :host(.toast-translucent) .toast-wrapper {
background: $toast-ios-translucent-background-color; background: $toast-ios-translucent-background-color;
backdrop-filter: $toast-ios-translucent-filter; backdrop-filter: $toast-ios-translucent-filter;
} }
.toast-ios .toast-wrapper.toast-middle { .toast-wrapper.toast-middle {
opacity: .01; opacity: .01;
} }
.toast-ios .toast-message { .toast-message {
@include padding($toast-ios-title-padding-top, $toast-ios-title-padding-end, $toast-ios-title-padding-bottom, $toast-ios-title-padding-start); @include padding($toast-ios-title-padding-top, $toast-ios-title-padding-end, $toast-ios-title-padding-bottom, $toast-ios-title-padding-start);
} }
.toast-ios .toast-button {
color: var(--button-color);
}

View File

@ -4,14 +4,14 @@
// Material Design Toast // Material Design Toast
// -------------------------------------------------- // --------------------------------------------------
.toast-md { :host {
--background: #{$toast-md-background}; --background: #{$toast-md-background};
--color: #{$toast-md-title-color}; --color: #{$toast-md-title-color};
font-size: $toast-md-title-font-size; font-size: $toast-md-title-font-size;
} }
.toast-md .toast-wrapper { .toast-wrapper {
@include position-horizontal(0, 0); @include position-horizontal(0, 0);
@include margin(auto); @include margin(auto);
@ -24,18 +24,18 @@
z-index: $z-index-overlay-wrapper; z-index: $z-index-overlay-wrapper;
} }
.toast-md .toast-wrapper.toast-top { .toast-wrapper.toast-top {
padding-top: var(--ion-safe-area-top, 0); padding-top: var(--ion-safe-area-top, 0);
} }
.toast-md .toast-wrapper.toast-bottom { .toast-wrapper.toast-bottom {
padding-bottom: var(--ion-safe-area-bottom, 0); padding-bottom: var(--ion-safe-area-bottom, 0);
} }
.toast-md .toast-wrapper.toast-middle { .toast-wrapper.toast-middle {
opacity: .01; opacity: .01;
} }
.toast-md .toast-message { .toast-message {
@include padding($toast-md-title-padding-top, $toast-md-title-padding-end, $toast-md-title-padding-bottom, $toast-md-title-padding-start); @include padding($toast-md-title-padding-top, $toast-md-title-padding-end, $toast-md-title-padding-bottom, $toast-md-title-padding-start);
} }

View File

@ -3,7 +3,9 @@
// Toast // Toast
// -------------------------------------------------- // --------------------------------------------------
ion-toast { :host {
--button-color: inherit;
/** /**
* @prop --background: Background of the toast * @prop --background: Background of the toast
* @prop --button-color: Color of the button text * @prop --button-color: Color of the button text
@ -26,6 +28,12 @@ ion-toast {
pointer-events: none; pointer-events: none;
} }
:host(.ion-color) {
--color: #{current-color(contrast)};
--background: #{current-color(base)};
--button-color: inherit;
}
.toast-wrapper { .toast-wrapper {
background: var(--background); background: var(--background);
} }
@ -42,7 +50,6 @@ ion-toast {
bottom: 0; bottom: 0;
} }
.toast-container { .toast-container {
display: flex; display: flex;
@ -53,7 +60,7 @@ ion-toast {
} }
.toast-button { .toast-button {
--color: inherit; color: var(--button-color);
font-size: $toast-button-font-size; font-size: $toast-button-font-size;
} }

View File

@ -1,8 +1,8 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop } from '@stencil/core'; import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop } from '@stencil/core';
import { Animation, AnimationBuilder, Config, Mode, OverlayEventDetail, OverlayInterface } from '../../interface'; import { Animation, AnimationBuilder, Color, Config, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { dismiss, eventMethod, present } from '../../utils/overlays'; import { dismiss, eventMethod, present } from '../../utils/overlays';
import { createThemedClasses, getClassMap } from '../../utils/theme'; import { createColorClasses, getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter'; import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave'; import { iosLeaveAnimation } from './animations/ios.leave';
@ -14,7 +14,8 @@ import { mdLeaveAnimation } from './animations/md.leave';
styleUrls: { styleUrls: {
ios: 'toast.ios.scss', ios: 'toast.ios.scss',
md: 'toast.md.scss' md: 'toast.md.scss'
} },
shadow: true
}) })
export class Toast implements ComponentInterface, OverlayInterface { export class Toast implements ComponentInterface, OverlayInterface {
@ -38,6 +39,13 @@ export class Toast implements ComponentInterface, OverlayInterface {
*/ */
@Prop() mode!: Mode; @Prop() mode!: Mode;
/**
* 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).
*/
@Prop() color?: Color;
/** /**
* Animation to use when the toast is presented. * Animation to use when the toast is presented.
*/ */
@ -173,16 +181,14 @@ export class Toast implements ComponentInterface, OverlayInterface {
} }
hostData() { hostData() {
const themedClasses = this.translucent ? createThemedClasses(this.mode, 'toast-translucent') : {};
return { return {
style: { style: {
zIndex: 60000 + this.overlayIndex, zIndex: 60000 + this.overlayIndex,
}, },
class: { class: {
...themedClasses, ...createColorClasses(this.color),
...createThemedClasses(this.mode, 'toast'), ...getClassMap(this.cssClass),
...getClassMap(this.cssClass) 'toast-translucent': this.translucent
} }
}; };
} }