diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 9cd5451510..8b135c6519 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -101,6 +101,7 @@ declare global { subTitle?: string, buttons?: ActionSheetButton[], enableBackdropDismiss?: boolean, + translucent?: boolean, enterAnimation?: AnimationBuilder, exitAnimation?: AnimationBuilder, actionSheetId?: string @@ -171,6 +172,7 @@ declare global { buttons?: AlertButton[], inputs?: AlertInput[], enableBackdropDismiss?: boolean, + translucent?: boolean, enterAnimation?: AnimationBuilder, exitAnimation?: AnimationBuilder, alertId?: string @@ -465,7 +467,8 @@ declare global { export interface IonCardHeaderAttributes extends HTMLAttributes { color?: string, - mode?: 'ios' | 'md' + mode?: 'ios' | 'md', + translucent?: boolean } } } @@ -842,6 +845,7 @@ declare global { color?: string, mode?: 'ios' | 'md', href?: string, + translucent?: boolean, activated?: boolean, toggleActive?: Function, show?: boolean, @@ -876,6 +880,7 @@ declare global { namespace JSXElements { export interface IonFooterAttributes extends HTMLAttributes { + translucent?: boolean } } } @@ -1074,6 +1079,7 @@ declare global { namespace JSXElements { export interface IonHeaderAttributes extends HTMLAttributes { + translucent?: boolean } } } @@ -1592,6 +1598,7 @@ declare global { content?: string, dismissOnPageChange?: boolean, duration?: number, + translucent?: boolean, enterAnimation?: AnimationBuilder, exitAnimation?: AnimationBuilder, loadingId?: string, @@ -2152,7 +2159,8 @@ declare global { exitAnimation?: AnimationBuilder, ev?: Event, popoverId?: string, - showBackdrop?: boolean + showBackdrop?: boolean, + translucent?: boolean } } } @@ -2886,71 +2894,6 @@ declare global { } -import { - PageTab as PageTab -} from './components/tabs/page-tab'; - -declare global { - interface HTMLPageTabElement extends PageTab, HTMLElement { - } - var HTMLPageTabElement: { - prototype: HTMLPageTabElement; - new (): HTMLPageTabElement; - }; - interface HTMLElementTagNameMap { - "page-tab": HTMLPageTabElement; - } - interface ElementTagNameMap { - "page-tab": HTMLPageTabElement; - } - namespace JSX { - interface IntrinsicElements { - "page-tab": JSXElements.PageTabAttributes; - } - } - namespace JSXElements { - export interface PageTabAttributes extends HTMLAttributes { - - } - } -} - - -import { - TabBar as IonTabbar -} from './components/tabs/tab-bar'; - -declare global { - interface HTMLIonTabbarElement extends IonTabbar, HTMLElement { - } - var HTMLIonTabbarElement: { - prototype: HTMLIonTabbarElement; - new (): HTMLIonTabbarElement; - }; - interface HTMLElementTagNameMap { - "ion-tabbar": HTMLIonTabbarElement; - } - interface ElementTagNameMap { - "ion-tabbar": HTMLIonTabbarElement; - } - namespace JSX { - interface IntrinsicElements { - "ion-tabbar": JSXElements.IonTabbarAttributes; - } - } - namespace JSXElements { - export interface IonTabbarAttributes extends HTMLAttributes { - - placement?: string, - tabs?: HTMLIonTabElement[], - selectedTab?: HTMLIonTabElement, - layout?: string, - highlight?: boolean - } - } -} - - import { TabbarButton as IonTabButton } from './components/tabs/tab-button'; @@ -3054,6 +2997,42 @@ declare global { } +import { + Tabbar as IonTabbar +} from './components/tabs/tabbar'; + +declare global { + interface HTMLIonTabbarElement extends IonTabbar, HTMLElement { + } + var HTMLIonTabbarElement: { + prototype: HTMLIonTabbarElement; + new (): HTMLIonTabbarElement; + }; + interface HTMLElementTagNameMap { + "ion-tabbar": HTMLIonTabbarElement; + } + interface ElementTagNameMap { + "ion-tabbar": HTMLIonTabbarElement; + } + namespace JSX { + interface IntrinsicElements { + "ion-tabbar": JSXElements.IonTabbarAttributes; + } + } + namespace JSXElements { + export interface IonTabbarAttributes extends HTMLAttributes { + + placement?: string, + tabs?: HTMLIonTabElement[], + selectedTab?: HTMLIonTabElement, + layout?: string, + highlight?: boolean, + translucent?: boolean + } + } +} + + import { Tabs as IonTabs } from './components/tabs/tabs'; @@ -3083,7 +3062,68 @@ declare global { tabbarHidden?: boolean, tabbarLayout?: string, tabbarPlacement?: string, - tabbarHighlight?: boolean + tabbarHighlight?: boolean, + translucent?: boolean + } + } +} + + +import { + PageTab as PageTab +} from './components/tabs/test/basic/page-tab'; + +declare global { + interface HTMLPageTabElement extends PageTab, HTMLElement { + } + var HTMLPageTabElement: { + prototype: HTMLPageTabElement; + new (): HTMLPageTabElement; + }; + interface HTMLElementTagNameMap { + "page-tab": HTMLPageTabElement; + } + interface ElementTagNameMap { + "page-tab": HTMLPageTabElement; + } + namespace JSX { + interface IntrinsicElements { + "page-tab": JSXElements.PageTabAttributes; + } + } + namespace JSXElements { + export interface PageTabAttributes extends HTMLAttributes { + + } + } +} + + +import { + TranslucentPageTab as TranslucentPageTab +} from './components/tabs/test/translucent/translucent-page-tab'; + +declare global { + interface HTMLTranslucentPageTabElement extends TranslucentPageTab, HTMLElement { + } + var HTMLTranslucentPageTabElement: { + prototype: HTMLTranslucentPageTabElement; + new (): HTMLTranslucentPageTabElement; + }; + interface HTMLElementTagNameMap { + "translucent-page-tab": HTMLTranslucentPageTabElement; + } + interface ElementTagNameMap { + "translucent-page-tab": HTMLTranslucentPageTabElement; + } + namespace JSX { + interface IntrinsicElements { + "translucent-page-tab": JSXElements.TranslucentPageTabAttributes; + } + } + namespace JSXElements { + export interface TranslucentPageTabAttributes extends HTMLAttributes { + } } } @@ -3211,6 +3251,7 @@ declare global { closeButtonText?: string, dismissOnPageChange?: boolean, position?: string, + translucent?: boolean, enterAnimation?: AnimationBuilder, exitAnimation?: AnimationBuilder, toastId?: string @@ -3315,7 +3356,8 @@ declare global { export interface IonToolbarAttributes extends HTMLAttributes { color?: string, - mode?: 'ios' | 'md' + mode?: 'ios' | 'md', + translucent?: boolean } } } diff --git a/packages/core/src/components/action-sheet/action-sheet.ios.scss b/packages/core/src/components/action-sheet/action-sheet.ios.scss index d815c16abe..204f69e774 100644 --- a/packages/core/src/components/action-sheet/action-sheet.ios.scss +++ b/packages/core/src/components/action-sheet/action-sheet.ios.scss @@ -29,7 +29,7 @@ $action-sheet-ios-group-margin-bottom: 10px !default; $action-sheet-ios-background: #f9f9f9 !default; /// @prop - Border color of the action sheet -$action-sheet-ios-border-color: #d6d6da !default; +$action-sheet-ios-border-color: rgba(0, 0, 0, .1) !default; /// @prop - Border radius of the action sheet $action-sheet-ios-border-radius: 13px !default; @@ -89,7 +89,7 @@ $action-sheet-ios-button-border-color: #d1d3d6 !default; $action-sheet-ios-button-background: transparent !default; /// @prop - Background color of the activated action sheet button -$action-sheet-ios-button-background-activated: #ebebeb !default; +$action-sheet-ios-button-background-activated: rgba(115, 115, 115, .1) !default; /// @prop - Destructive text color of the action sheet button $action-sheet-ios-button-destructive-text-color: #f53d3d !default; @@ -103,6 +103,12 @@ $action-sheet-ios-button-cancel-background: #fff !default; /// @prop - Font weight of the action sheet cancel button $action-sheet-ios-button-cancel-font-weight: 600 !default; +/// @prop - Filter of the translucent action-sheet +$action-sheet-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent action-sheet +$action-sheet-ios-translucent-opacity: .88 !default; + .action-sheet-ios { @include text-align($action-sheet-ios-text-align); @@ -113,20 +119,23 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default; @include margin(env(safe-area-inset-top), auto, env(safe-area-inset-bottom), auto); } + +// iOS Action Sheet Container +// ----------------------------------------- + .action-sheet-ios .action-sheet-container { @include padding($action-sheet-ios-padding-top, $action-sheet-ios-padding-end, $action-sheet-ios-padding-bottom, $action-sheet-ios-padding-start); } + +// iOS Action Sheet Group +// ----------------------------------------- + .action-sheet-ios .action-sheet-group { @include border-radius($action-sheet-ios-border-radius); @include margin(null, null, $action-sheet-ios-group-margin-bottom - 2, null); background: $action-sheet-ios-background; - - // scss-lint:disable VendorPrefix - -webkit-overflow-scrolling: touch; - // Prevents borders from going outside of the container - -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000); } .action-sheet-ios .action-sheet-group:first-child { @@ -137,6 +146,21 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default; @include margin(null, null, $action-sheet-ios-group-margin-bottom, null); } + +// iOS Translucent Action Sheet +// ----------------------------------------- + +.action-sheet-translucent-ios .action-sheet-group { + background: rgba($action-sheet-ios-background, $action-sheet-ios-translucent-opacity); + + backdrop-filter: $action-sheet-ios-translucent-filter; + -webkit-backdrop-filter: $action-sheet-ios-translucent-filter; +} + + +// iOS Action Sheet Title +// ----------------------------------------- + .action-sheet-ios .action-sheet-title { @include border-radius($action-sheet-ios-title-border-radius); @@ -151,6 +175,10 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default; color: $action-sheet-ios-title-color; } + +// iOS Action Sheet Buttons +// ----------------------------------------- + .action-sheet-ios .action-sheet-button { @include margin(0); diff --git a/packages/core/src/components/action-sheet/action-sheet.md.scss b/packages/core/src/components/action-sheet/action-sheet.md.scss index 89e5a99719..a9ff1875b2 100644 --- a/packages/core/src/components/action-sheet/action-sheet.md.scss +++ b/packages/core/src/components/action-sheet/action-sheet.md.scss @@ -86,6 +86,10 @@ $action-sheet-md-icon-margin-bottom: 0 !default; $action-sheet-md-icon-margin-start: 0 !default; + +// Material Design Action Sheet Title +// ----------------------------------------- + .action-sheet-md .action-sheet-title, .action-sheet-md .action-sheet-sub-title { @include padding($action-sheet-md-title-padding-top, $action-sheet-md-title-padding-end, $action-sheet-md-title-padding-bottom, $action-sheet-md-title-padding-start); @@ -96,6 +100,26 @@ $action-sheet-md-icon-margin-start: 0 !default; color: $action-sheet-md-title-color; } + +// Material Design Action Sheet Group +// ----------------------------------------- + +.action-sheet-md .action-sheet-group { + background: $action-sheet-md-background; +} + +.action-sheet-md .action-sheet-group:first-child { + @include padding($action-sheet-md-padding-top, null, null, null); +} + +.action-sheet-md .action-sheet-group:last-child { + @include padding(null, null, $action-sheet-md-padding-bottom, null); +} + + +// Material Design Action Sheet Buttons +// ----------------------------------------- + .action-sheet-md .action-sheet-button { @include padding($action-sheet-md-button-padding-top, $action-sheet-md-button-padding-end, $action-sheet-md-button-padding-bottom, $action-sheet-md-button-padding-start); @@ -128,18 +152,6 @@ $action-sheet-md-icon-margin-start: 0 !default; vertical-align: $action-sheet-md-icon-vertical-align; } -.action-sheet-md .action-sheet-group { - background: $action-sheet-md-background; -} - -.action-sheet-md .action-sheet-group:first-child { - @include padding($action-sheet-md-padding-top, null, null, null); -} - -.action-sheet-md .action-sheet-group:last-child { - @include padding(null, null, $action-sheet-md-padding-bottom, null); -} - .action-sheet-md .action-sheet-group .button-inner { justify-content: flex-start; } diff --git a/packages/core/src/components/action-sheet/action-sheet.tsx b/packages/core/src/components/action-sheet/action-sheet.tsx index edf17736de..46e271f6ee 100644 --- a/packages/core/src/components/action-sheet/action-sheet.tsx +++ b/packages/core/src/components/action-sheet/action-sheet.tsx @@ -1,6 +1,8 @@ import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Prop } from '@stencil/core'; import { Animation, AnimationBuilder, AnimationController, Config } from '../../index'; +import { createThemedClasses } from '../../utils/theme'; + import iOSEnterAnimation from './animations/ios.enter'; import iOSLeaveAnimation from './animations/ios.leave'; @@ -15,6 +17,9 @@ import iOSLeaveAnimation from './animations/ios.leave'; } }) export class ActionSheet { + mode: string; + color: string; + private animation: Animation; @Element() private el: HTMLElement; @@ -57,6 +62,7 @@ export class ActionSheet { @Prop() subTitle: string; @Prop() buttons: ActionSheetButton[]; @Prop() enableBackdropDismiss: boolean = true; + @Prop() translucent: boolean = false; @Prop() enterAnimation: AnimationBuilder; @Prop() exitAnimation: AnimationBuilder; @@ -160,6 +166,16 @@ export class ActionSheet { } } + buttonClass(button: ActionSheetButton): CssClassMap { + let buttonClass: string[] = !button.role + ? ['action-sheet-button'] + : [`action-sheet-button`, `action-sheet-${button.role}`]; + return buttonClass.reduce((prevValue: any, cssClass: any) => { + prevValue[cssClass] = true; + return prevValue; + }, {}); + } + protected buttonClick(button: ActionSheetButton) { let shouldDismiss = true; if (button.handler) { @@ -172,6 +188,18 @@ export class ActionSheet { } } + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'action-sheet-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { let userCssClass = 'action-sheet-content'; if (this.cssClass) { @@ -241,16 +269,6 @@ export class ActionSheet { ]; } - - buttonClass(button: ActionSheetButton): CssClassMap { - let buttonClass: string[] = !button.role - ? ['action-sheet-button'] - : [`action-sheet-button`, `action-sheet-${button.role}`]; - return buttonClass.reduce((prevValue: any, cssClass: any) => { - prevValue[cssClass] = true; - return prevValue; - }, {}); - } } export interface ActionSheetOptions { @@ -259,6 +277,7 @@ export interface ActionSheetOptions { cssClass?: string; buttons?: (ActionSheetButton | string)[]; enableBackdropDismiss?: boolean; + translucent?: boolean; } export interface ActionSheetButton { diff --git a/packages/core/src/components/action-sheet/test/translucent/index.html b/packages/core/src/components/action-sheet/test/translucent/index.html new file mode 100644 index 0000000000..0efaec75b7 --- /dev/null +++ b/packages/core/src/components/action-sheet/test/translucent/index.html @@ -0,0 +1,368 @@ + + + + + + Action Sheet - Translucent + + + + + + + + + + Action Sheet - Translucent + + + + + + + Basic + No Backdrop Dismiss + Alert from Action Sheet + Scrollable Options + Scroll Without Cancel + Cancel Only + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/core/src/components/alert/alert.ios.scss b/packages/core/src/components/alert/alert.ios.scss index c6e82b55f4..7bfb737d49 100644 --- a/packages/core/src/components/alert/alert.ios.scss +++ b/packages/core/src/components/alert/alert.ios.scss @@ -58,7 +58,6 @@ $alert-ios-message-padding-bottom: 21px !default; /// @prop - Padding start of the alert message $alert-ios-message-padding-start: $alert-ios-message-padding-end !default; - /// @prop - Font size of the alert message $alert-ios-message-font-size: 13px !default; @@ -135,7 +134,7 @@ $alert-ios-button-text-color: color($colors-ios, primary) !def $alert-ios-button-background-color: transparent !default; /// @prop - Background color of the alert activated button -$alert-ios-button-background-color-activated: #e9e9e9 !default; +$alert-ios-button-background-color-activated: rgba(115, 115, 115, .1) !default; /// @prop - Border width of the alert button $alert-ios-button-border-width: $hairlines-width !default; @@ -144,7 +143,7 @@ $alert-ios-button-border-width: $hairlines-width !default; $alert-ios-button-border-style: solid !default; /// @prop - Border color of the alert button -$alert-ios-button-border-color: #dbdbdf !default; +$alert-ios-button-border-color: rgba(0, 0, 0, .1) !default; /// @prop - Border radius of the alert button $alert-ios-button-border-radius: 0 !default; @@ -278,6 +277,12 @@ $alert-ios-checkbox-icon-border-color: $background-ios-color !default; /// @prop - Transform of the icon in the checkbox alert $alert-ios-checkbox-icon-transform: rotate(45deg) !default; +/// @prop - Filter of the translucent alert +$alert-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent alert +$alert-ios-translucent-opacity: .88 !default; + .alert-ios .alert-wrapper { @include border-radius($alert-ios-border-radius); @@ -292,6 +297,17 @@ $alert-ios-checkbox-icon-transform: rotate(45deg) !default; } +// iOS Translucent Alert +// ----------------------------------------- + +.alert-translucent-ios .alert-wrapper { + background: rgba($alert-ios-background, $alert-ios-translucent-opacity); + + backdrop-filter: $alert-ios-translucent-filter; + -webkit-backdrop-filter: $alert-ios-translucent-filter; +} + + // iOS Alert Header // -------------------------------------------------- diff --git a/packages/core/src/components/alert/alert.tsx b/packages/core/src/components/alert/alert.tsx index 72cbb583ff..1394d06d1e 100644 --- a/packages/core/src/components/alert/alert.tsx +++ b/packages/core/src/components/alert/alert.tsx @@ -3,6 +3,8 @@ import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, P import { Animation, AnimationBuilder, AnimationController, Config } from '../../index'; import { playAnimationAsync } from '../../utils/helpers'; +import { createThemedClasses } from '../../utils/theme'; + import iOSEnterAnimation from './animations/ios.enter'; import iOSLeaveAnimation from './animations/ios.leave'; @@ -17,6 +19,9 @@ import iOSLeaveAnimation from './animations/ios.leave'; } }) export class Alert { + mode: string; + color: string; + private animation: Animation; private activeId: string; private inputType: string; @@ -64,6 +69,7 @@ export class Alert { @Prop() buttons: AlertButton[] = []; @Prop({ mutable: true }) inputs: AlertInput[] = []; @Prop() enableBackdropDismiss: boolean = true; + @Prop() translucent: boolean = false; @Prop() enterAnimation: AnimationBuilder; @Prop() exitAnimation: AnimationBuilder; @@ -146,7 +152,7 @@ export class Alert { this.dismiss(); } - + protected backdropClick() { if (this.enableBackdropDismiss) { // const opts: NavOptions = { @@ -310,6 +316,19 @@ export class Alert { ); } + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'alert-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses, + id: this.alertId + }; + } + render() { const hdrId = `${this.alertId}-hdr`; const subHdrId = `${this.alertId}-sub-hdr`; @@ -413,12 +432,6 @@ export class Alert { ]; } - hostData() { - return { - id: this.alertId - }; - } - } @@ -431,6 +444,7 @@ export interface AlertOptions { inputs?: AlertInput[]; buttons?: (AlertButton|string)[]; enableBackdropDismiss?: boolean; + translucent?: boolean; } export interface AlertInput { diff --git a/packages/core/src/components/alert/test/translucent/index.html b/packages/core/src/components/alert/test/translucent/index.html new file mode 100644 index 0000000000..97f124f597 --- /dev/null +++ b/packages/core/src/components/alert/test/translucent/index.html @@ -0,0 +1,361 @@ + + + + + + Alert - Translucent + + + + + + + + + + Alert - Translucent + + + + + + + Alert + Alert Long Message + Multiple Buttons (>2) + Alert No Message + + + + + + + + + + + + + + + + Confirm + Prompt + Radio + Checkbox + + + + + + + + + \ No newline at end of file diff --git a/packages/core/src/components/card-header/card-header.ios.scss b/packages/core/src/components/card-header/card-header.ios.scss index 3251acb75d..e8421a885b 100644 --- a/packages/core/src/components/card-header/card-header.ios.scss +++ b/packages/core/src/components/card-header/card-header.ios.scss @@ -6,18 +6,34 @@ // -------------------------------------------------- /// @prop - Padding top of the card header -$card-ios-header-padding-top: 20px !default; +$card-ios-header-padding-top: 20px !default; /// @prop - Padding end of the card header -$card-ios-header-padding-end: $card-ios-header-padding-top !default; +$card-ios-header-padding-end: $card-ios-header-padding-top !default; /// @prop - Padding bottom of the card header -$card-ios-header-padding-bottom: 16px !default; +$card-ios-header-padding-bottom: 16px !default; /// @prop - Padding start of the card header -$card-ios-header-padding-start: $card-ios-header-padding-end !default; +$card-ios-header-padding-start: $card-ios-header-padding-end !default; + +/// @prop - Filter of the translucent card header +$card-ios-header-translucent-background: #fff !default; + +/// @prop - Filter of the translucent card header +$card-ios-header-translucent-filter: saturate(180%) blur(30px) !default; + +/// @prop - Opacity of the translucent cardheader +$card-ios-header-translucent-opacity: .88 !default; .card-header-ios { @include padding($card-ios-header-padding-top, $card-ios-header-padding-end, $card-ios-header-padding-bottom, $card-ios-header-padding-start); } + +.card-header-translucent-ios { + background-color: rgba($card-ios-header-translucent-background, $card-ios-header-translucent-opacity); + + -webkit-backdrop-filter: $card-ios-header-translucent-filter; + backdrop-filter: $card-ios-header-translucent-filter; +} diff --git a/packages/core/src/components/card-header/card-header.tsx b/packages/core/src/components/card-header/card-header.tsx index 0a51c789b5..f8d6a8e08c 100644 --- a/packages/core/src/components/card-header/card-header.tsx +++ b/packages/core/src/components/card-header/card-header.tsx @@ -1,5 +1,6 @@ import { Component, Prop } from '@stencil/core'; +import { createThemedClasses } from '../../utils/theme'; @Component({ tag: 'ion-card-header', @@ -26,6 +27,24 @@ export class CardHeader { */ @Prop() mode: 'ios' | 'md'; + /** + * @input {boolean} If true, adds transparency to the card header. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'card-header-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { return ; } diff --git a/packages/core/src/components/card/card.ios.scss b/packages/core/src/components/card/card.ios.scss index 936916a423..554a8b9c9b 100755 --- a/packages/core/src/components/card/card.ios.scss +++ b/packages/core/src/components/card/card.ios.scss @@ -52,6 +52,8 @@ $card-ios-text-color: #666 !default; background: $card-ios-background-color; box-shadow: $card-ios-box-shadow; + + transform: translateZ(0); } .card-ios ion-list { diff --git a/packages/core/src/components/card/test/basic/index.html b/packages/core/src/components/card/test/basic/index.html index 0b3a664b2c..cd1bfe5606 100644 --- a/packages/core/src/components/card/test/basic/index.html +++ b/packages/core/src/components/card/test/basic/index.html @@ -17,7 +17,7 @@ - + This is just your basic card with some text to boot. Like it? Keep scrolling... @@ -41,10 +41,26 @@
- +
+ + + Subtitle + + + Title + + - + + +
+ + +
+ +
+ Subtitle @@ -53,21 +69,21 @@ - + The British use the term "header", but the American term "head-shot" the English simply refuse to adopt.
- +
- +
- - + + Subtitle - + Title diff --git a/packages/core/src/components/fab/fab.ios.scss b/packages/core/src/components/fab/fab.ios.scss index a7f0efbf0d..41c4ac6bbc 100755 --- a/packages/core/src/components/fab/fab.ios.scss +++ b/packages/core/src/components/fab/fab.ios.scss @@ -37,6 +37,12 @@ $fab-ios-list-button-transition-timing-function: ease !default; /// @prop - Transition delay of the transform and opacity of the button in a list $fab-ios-list-button-transition-delay: 10ms !default; +/// @prop - Filter of the translucent fab +$fab-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent fab +$fab-ios-translucent-opacity: .88 !default; + .fab-ios { color: $fab-ios-text-color; @@ -70,6 +76,20 @@ $fab-ios-list-button-transition-delay: 10ms !default; fill: $fab-ios-list-button-icon-fill-color; } +// Translucent FAB buttons +// -------------------------------------------------- + +.fab-translucent-ios { + background-color: rgba($fab-ios-background-color, $fab-ios-translucent-opacity); + + -webkit-backdrop-filter: $fab-ios-translucent-filter; + backdrop-filter: $fab-ios-translucent-filter; +} + +.fab-translucent-ios-in-list { + background-color: rgba($fab-ios-list-button-background-color, $fab-ios-translucent-opacity); +} + // Generate iOS FAB colors // -------------------------------------------------- @@ -92,5 +112,13 @@ $fab-ios-list-button-transition-delay: 10ms !default; .fab-ios-#{$color-name}.activated { background-color: $bg-color-activated; } + + .fab-translucent-ios-#{$color-name} { + background-color: rgba($bg-color, $fab-ios-translucent-opacity); + } + + .fab-translucent-ios-#{$color-name}.activated { + background-color: rgba($bg-color-activated, $fab-ios-translucent-opacity); + } } diff --git a/packages/core/src/components/fab/fab.tsx b/packages/core/src/components/fab/fab.tsx index 4bd8850c1b..b663616b72 100755 --- a/packages/core/src/components/fab/fab.tsx +++ b/packages/core/src/components/fab/fab.tsx @@ -77,6 +77,12 @@ export class FabButton { */ @Prop() href: string; + /** + * @input {boolean} If true, adds transparency to the fab. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + @Prop() activated: boolean = false; @Prop() toggleActive: Function = () => {}; @@ -112,10 +118,16 @@ export class FabButton { if (!this.inList) { return []; } - return [ + let listClasses = [ `fab-in-list`, `fab-${this.mode}-in-list` ]; + + if (this.translucent) { + listClasses.push(`fab-translucent-${this.mode}-in-list`); + } + + return listClasses; } /** @@ -146,6 +158,7 @@ export class FabButton { render() { const themedClasses = createThemedClasses(this.mode, this.color, 'fab'); + const translucentClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'fab-translucent') : {}; const hostClasses = getElementClassObject(this.el.classList); const elementClasses: CssClassMap = [] @@ -163,6 +176,7 @@ export class FabButton { const fabClasses = { ...themedClasses, + ...translucentClasses, ...hostClasses, ...elementClasses }; diff --git a/packages/core/src/components/fab/test/basic/index.html b/packages/core/src/components/fab/test/basic/index.html index 0c60429111..3dc83ec13f 100644 --- a/packages/core/src/components/fab/test/basic/index.html +++ b/packages/core/src/components/fab/test/basic/index.html @@ -23,7 +23,7 @@ Test - + @@ -33,7 +33,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -109,17 +109,26 @@ insertLog('add'); } - function clickMainFAB() { + function clickMainFAB(container) { let message = 'Clicked open social menu'; insertLog(message); + + openLists(container); } function openSocial(network, container) { let message = 'Share in ' + network; insertLog(message); - var fab = document.getElementById(container); - fab.close(); + openLists(container); + } + + function openLists(container) { + var fabLists = document.getElementById(container).querySelectorAll('ion-fab-list'); + + for (var i = 0; i < fabLists.length; i++) { + fabLists[i].activated = true; + } } @@ -138,4 +147,4 @@ - + \ No newline at end of file diff --git a/packages/core/src/components/fab/test/translucent/index.html b/packages/core/src/components/fab/test/translucent/index.html new file mode 100644 index 0000000000..fa663840f3 --- /dev/null +++ b/packages/core/src/components/fab/test/translucent/index.html @@ -0,0 +1,189 @@ + + + + + Floating Action Button - Translucent + + + + + + + + + Floating Action Button - Translucent + + + + + + + + + + + + + + + + + +
log
+ Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Footer + + +
+ + + + +
+ + diff --git a/packages/core/src/components/footer/footer.ios.scss b/packages/core/src/components/footer/footer.ios.scss new file mode 100644 index 0000000000..5dc09168b6 --- /dev/null +++ b/packages/core/src/components/footer/footer.ios.scss @@ -0,0 +1,11 @@ +@import "../../themes/ionic.globals.ios"; + +// iOS Footer +// -------------------------------------------------- + +$footer-ios-translucent-filter: saturate(180%) blur(20px) !default; + +.footer-translucent-ios { + -webkit-backdrop-filter: $footer-ios-translucent-filter; + backdrop-filter: $footer-ios-translucent-filter; +} diff --git a/packages/core/src/components/footer/footer.tsx b/packages/core/src/components/footer/footer.tsx index 4496d0666a..867c082627 100644 --- a/packages/core/src/components/footer/footer.tsx +++ b/packages/core/src/components/footer/footer.tsx @@ -1,5 +1,6 @@ -import { Component } from '@stencil/core'; +import { Component, Prop } from '@stencil/core'; +import { createThemedClasses } from '../../utils/theme'; @Component({ tag: 'ion-footer', @@ -8,6 +9,29 @@ import { Component } from '@stencil/core'; } }) export class Footer { + mode: string; + color: string; + + /** + * @input {boolean} If true, adds transparency to the footer. + * Note: In order to scroll content behind the footer, the `fullscreen` + * attribute needs to be set on the content. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'header-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { return ; } diff --git a/packages/core/src/components/header/header.ios.scss b/packages/core/src/components/header/header.ios.scss new file mode 100644 index 0000000000..bf28ce482e --- /dev/null +++ b/packages/core/src/components/header/header.ios.scss @@ -0,0 +1,11 @@ +@import "../../themes/ionic.globals.ios"; + +// iOS Header +// -------------------------------------------------- + +$header-ios-translucent-filter: saturate(180%) blur(20px) !default; + +.header-translucent-ios { + -webkit-backdrop-filter: $header-ios-translucent-filter; + backdrop-filter: $header-ios-translucent-filter; +} diff --git a/packages/core/src/components/header/header.tsx b/packages/core/src/components/header/header.tsx index 2bddb5c997..59b6109116 100644 --- a/packages/core/src/components/header/header.tsx +++ b/packages/core/src/components/header/header.tsx @@ -1,13 +1,40 @@ -import { Component } from '@stencil/core'; +import { Component, Prop } from '@stencil/core'; +import { createThemedClasses } from '../../utils/theme'; @Component({ tag: 'ion-header', + styleUrls: { + ios: 'header.ios.scss' + }, host: { theme: 'header' } }) export class Header { + mode: string; + color: string; + + /** + * @input {boolean} If true, adds transparency to the header. + * Note: In order to scroll content behind the header, the `fullscreen` + * attribute needs to be set on the content. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'header-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { return ; } diff --git a/packages/core/src/components/loading/loading.ios.scss b/packages/core/src/components/loading/loading.ios.scss index 1328e36a61..cc113904b3 100644 --- a/packages/core/src/components/loading/loading.ios.scss +++ b/packages/core/src/components/loading/loading.ios.scss @@ -53,6 +53,12 @@ $loading-ios-spinner-crescent-color: $loading-ios-spinner-color !default; /// @prop - Color of the dots loading spinner $loading-ios-spinner-dots-color: $loading-ios-spinner-color !default; +/// @prop - Filter of the translucent loading +$loading-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent loading +$loading-ios-translucent-opacity: .88 !default; + .loading-ios .loading-wrapper { @include border-radius($loading-ios-border-radius); @@ -67,6 +73,17 @@ $loading-ios-spinner-dots-color: $loading-ios-spinner-color !default; } +// iOS Translucent Loading +// ----------------------------------------- + +.loading-translucent-ios .loading-wrapper { + background: rgba($loading-ios-background, $loading-ios-translucent-opacity); + + backdrop-filter: $loading-ios-translucent-filter; + -webkit-backdrop-filter: $loading-ios-translucent-filter; +} + + // iOS Loading Content // ----------------------------------------- diff --git a/packages/core/src/components/loading/loading.tsx b/packages/core/src/components/loading/loading.tsx index e918271f09..84cd9485d6 100644 --- a/packages/core/src/components/loading/loading.tsx +++ b/packages/core/src/components/loading/loading.tsx @@ -1,6 +1,8 @@ import { Animation, AnimationBuilder, AnimationController, Config } from '../../index'; import { Component, Element, Event, EventEmitter, Listen, Prop, State } from '@stencil/core'; +import { createThemedClasses } from '../../utils/theme'; + import iOSEnterAnimation from './animations/ios.enter'; import iOSLeaveAnimation from './animations/ios.leave'; @@ -15,9 +17,11 @@ import iOSLeaveAnimation from './animations/ios.leave'; } }) export class Loading { + color: string; + mode: string; + private animation: Animation; private durationTimeout: any; - private mode: string; @Element() private el: HTMLElement; @@ -60,6 +64,7 @@ export class Loading { @Prop() content: string; @Prop() dismissOnPageChange: boolean = false; @Prop() duration: number; + @Prop() translucent: boolean = false; @Prop() enterAnimation: AnimationBuilder; @Prop() exitAnimation: AnimationBuilder; @Prop() loadingId: string; @@ -182,6 +187,18 @@ export class Loading { this.dismiss(); } + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'loading-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { // TODO: cssClass @@ -227,6 +244,7 @@ export interface LoadingOptions { showBackdrop?: boolean; dismissOnPageChange?: boolean; duration?: number; + translucent?: boolean; } diff --git a/packages/core/src/components/loading/test/basic/e2e.js b/packages/core/src/components/loading/test/basic/e2e.js new file mode 100644 index 0000000000..589818cc8d --- /dev/null +++ b/packages/core/src/components/loading/test/basic/e2e.js @@ -0,0 +1,17 @@ +const { register, navigate, Page } = require('../../../../../scripts/e2e'); +const testPageURL = 'http://localhost:3333/src/components/loading/test/basic'; + +describe('loading: basic', () => { + + register('navigates', navigate(testPageURL)); + + describe('present', () => { + + register('shows loading', driver => { + const page = new Page(driver, testPageURL); + return page.present('.e2eShowLoading', { waitFor: 'ion-loading' }); + }); + + }); + +}); diff --git a/packages/core/src/components/loading/test/basic/index.html b/packages/core/src/components/loading/test/basic/index.html new file mode 100644 index 0000000000..101005d1c8 --- /dev/null +++ b/packages/core/src/components/loading/test/basic/index.html @@ -0,0 +1,122 @@ + + + + + + Loading - Basic + + + + + + + + + + Loading - Basic + + + + + Show Loading + Show Loading with long content + Show Loading with no spinner + Show Loading with translucent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/core/src/components/popover/popover.ios.scss b/packages/core/src/components/popover/popover.ios.scss index fa58051ba2..8ae287d3db 100644 --- a/packages/core/src/components/popover/popover.ios.scss +++ b/packages/core/src/components/popover/popover.ios.scss @@ -28,6 +28,12 @@ $popover-ios-background: $background-ios-color !default; /// @prop - Background of the popover arrow $popover-ios-arrow-background: $popover-ios-background !default; +/// @prop - Filter of the translucent popover +$popover-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent popover +$popover-ios-translucent-opacity: .88 !default; + .popover-ios .popover-content { @include border-radius($popover-ios-border-radius); @@ -79,3 +85,14 @@ $popover-ios-arrow-background: $popover-ios-background !default; .popover-ios.popover-bottom .popover-arrow::after { top: -6px; } + +// Translucent Popover +// ----------------------------------------- + +.popover-translucent-ios .popover-content, +.popover-translucent-ios .popover-arrow::after { + background: rgba($popover-ios-background, $popover-ios-translucent-opacity); + + -webkit-backdrop-filter: $popover-ios-translucent-filter; + backdrop-filter: $popover-ios-translucent-filter; +} \ No newline at end of file diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx index 6379cb0a7a..72056517a6 100644 --- a/packages/core/src/components/popover/popover.tsx +++ b/packages/core/src/components/popover/popover.tsx @@ -67,6 +67,7 @@ export class Popover { @Prop() ev: Event; @Prop() popoverId: string; @Prop() showBackdrop: boolean = true; + @Prop() translucent: boolean = false; present() { @@ -288,6 +289,18 @@ export class Popover { } } + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'popover-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { const ThisComponent = this.component; @@ -320,6 +333,7 @@ export interface PopoverOptions { componentProps?: any; showBackdrop?: boolean; enableBackdropDismiss?: boolean; + translucent?: boolean; enterAnimation?: AnimationBuilder; exitAnimation?: AnimationBuilder; cssClass?: string; diff --git a/packages/core/src/components/popover/test/basic/index.html b/packages/core/src/components/popover/test/basic/index.html index 26876b4e6b..5c641b3de7 100644 --- a/packages/core/src/components/popover/test/basic/index.html +++ b/packages/core/src/components/popover/test/basic/index.html @@ -23,9 +23,10 @@ - Show Popover - Show Long List Popover - No Event Popover + Show Popover + Show Translucent Popover + Show Long List Popover + No Event Popover @@ -43,12 +44,9 @@ diff --git a/packages/core/src/components/searchbar/test/toolbar/index.html b/packages/core/src/components/searchbar/test/toolbar/index.html index 785c5d8355..600f39d2c3 100644 --- a/packages/core/src/components/searchbar/test/toolbar/index.html +++ b/packages/core/src/components/searchbar/test/toolbar/index.html @@ -19,9 +19,18 @@ -
-
-
+ + + + + + + + + + + +
Search - Transparent Toolbar
@@ -52,7 +61,7 @@ diff --git a/packages/core/src/components/tabs/tab-bar.tsx b/packages/core/src/components/tabs/tabbar.tsx similarity index 70% rename from packages/core/src/components/tabs/tab-bar.tsx rename to packages/core/src/components/tabs/tabbar.tsx index 24071fb099..9a8a62e602 100644 --- a/packages/core/src/components/tabs/tab-bar.tsx +++ b/packages/core/src/components/tabs/tabbar.tsx @@ -1,12 +1,16 @@ import { Component, Listen, Prop, State } from '@stencil/core'; +import { createThemedClasses } from '../../utils/theme'; + @Component({ tag: 'ion-tabbar', host: { theme: 'tabbar' } }) -export class TabBar { +export class Tabbar { + mode: string; + color: string; @State() hidden = false; @@ -15,6 +19,7 @@ export class TabBar { @Prop() selectedTab: HTMLIonTabElement; @Prop() layout: string = 'icon-top'; @Prop() highlight: boolean = false; + @Prop() translucent: boolean = false; @Listen('body:keyboardWillHide') protected onKeyboardWillHide() { @@ -28,16 +33,23 @@ export class TabBar { } } + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'tabbar-translucent') : {}; + const layoutClass = `layout-${this.layout}`; const placementClass = `placement-${this.placement}`; + + const hostClasses = { + ...themedClasses, + 'tabbar-hidden': this.hidden, + [layoutClass]: true, + [placementClass]: true + }; + return { - 'role': 'tablist', - 'class': { - 'tabbar-hidden': this.hidden, - [layoutClass]: true, - [placementClass]: true - } + role: 'tablist', + class: hostClasses }; } diff --git a/packages/core/src/components/tabs/tabs.ios.scss b/packages/core/src/components/tabs/tabs.ios.scss index 6dacedc141..dd4bdc8d3a 100644 --- a/packages/core/src/components/tabs/tabs.ios.scss +++ b/packages/core/src/components/tabs/tabs.ios.scss @@ -43,6 +43,12 @@ $tabs-ios-tab-font-size: 10px !default; /// @prop - Size of the tab button icon $tabs-ios-tab-icon-size: 30px !default; +/// @prop - Filter of the translucent tabbar +$tabbar-ios-translucent-filter: saturate(210%) blur(20px) !default; + +/// @prop - Opacity of the translucent tabbar +$tabbar-ios-translucent-opacity: .8 !default; + .tabbar-ios { justify-content: center; @@ -140,6 +146,16 @@ $tabs-ios-tab-icon-size: 30px !default; // min-height: $tabs-ios-tab-min-height - 8; // } +// iOS Translucent Tabbar +// -------------------------------------------------- + +.tabbar-translucent-ios { + background-color: rgba($tabs-ios-background, $tabbar-ios-translucent-opacity); + + -webkit-backdrop-filter: $tabbar-ios-translucent-filter; + backdrop-filter: $tabbar-ios-translucent-filter; +} + // iOS Tabbar Color Mixin // -------------------------------------------------- @@ -160,6 +176,10 @@ $tabs-ios-tab-icon-size: 30px !default; fill: $color-contrast; } + .tabbar-translucent-ios-#{$color-name} { + background-color: rgba($color-base, $tabbar-ios-translucent-opacity); + } + } // iOS Tabbar Color Generation diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index 9d05a6e070..e7589a97b1 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -144,7 +144,6 @@ export interface NavOptions { } } }) export class Tabs { - private ids: number = -1; private tabsId: number = (++tabIds); @@ -180,6 +179,14 @@ export class Tabs { */ @Prop({ mutable: true }) tabbarHighlight: boolean; + /** + * @input {boolean} If true, adds transparency to the tabbar. + * Note: In order to scroll content behind the tabbar, the `fullscreen` + * attribute needs to be set on the content. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + /** * @output {any} Emitted when the tab changes. */ @@ -342,7 +349,9 @@ export class Tabs { const dom = [
-
]; + + ]; + if (!this.tabbarHidden) { dom.push( + layout={this.tabbarLayout} + translucent={this.translucent}> ); } diff --git a/packages/core/src/components/tabs/test/basic/index.html b/packages/core/src/components/tabs/test/basic/index.html index 05b08d9547..ee2c2f3356 100644 --- a/packages/core/src/components/tabs/test/basic/index.html +++ b/packages/core/src/components/tabs/test/basic/index.html @@ -42,17 +42,46 @@ diff --git a/packages/core/src/components/tabs/page-tab.tsx b/packages/core/src/components/tabs/test/basic/page-tab.tsx similarity index 81% rename from packages/core/src/components/tabs/page-tab.tsx rename to packages/core/src/components/tabs/test/basic/page-tab.tsx index 9d1964968f..7996f41a02 100644 --- a/packages/core/src/components/tabs/page-tab.tsx +++ b/packages/core/src/components/tabs/test/basic/page-tab.tsx @@ -70,11 +70,18 @@ export class PageTab {

/tab3

/tab4

/tab4/paginaaaa-two

- - - - - + + + + + + + + + + + +
]; } diff --git a/packages/core/src/components/tabs/test/translucent/index.html b/packages/core/src/components/tabs/test/translucent/index.html new file mode 100644 index 0000000000..9df9f2bf56 --- /dev/null +++ b/packages/core/src/components/tabs/test/translucent/index.html @@ -0,0 +1,91 @@ + + + + + Tab - Basic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/core/src/components/tabs/test/translucent/translucent-page-tab.tsx b/packages/core/src/components/tabs/test/translucent/translucent-page-tab.tsx new file mode 100644 index 0000000000..f7ced9eaed --- /dev/null +++ b/packages/core/src/components/tabs/test/translucent/translucent-page-tab.tsx @@ -0,0 +1,58 @@ +import { Component, Element } from '@stencil/core'; + +export interface Route { + path: string | null; + component: string; +} + +@Component({ + tag: 'translucent-page-tab' +}) +export class TranslucentPageTab { + + @Element() element: HTMLElement; + + getTabs() { + return this.element.closest('ion-tabs') as HTMLIonTabsElement; + } + + setLayout(value: string) { + this.getTabs().tabbarLayout = value; + } + + setPlacement(value: string) { + this.getTabs().tabbarPlacement = value; + } + + setHidden(value: boolean) { + this.getTabs().tabbarHidden = value; + } + + setHighlight(value: boolean) { + this.getTabs().tabbarHighlight = value; + } + + render() { + return [ + + + Tab Translucent + + , + + + + + + + + + + + + + + + ]; + } +} diff --git a/packages/core/src/components/toast/test/basic/index.html b/packages/core/src/components/toast/test/basic/index.html index 03faf66c89..7aa7ae0847 100644 --- a/packages/core/src/components/toast/test/basic/index.html +++ b/packages/core/src/components/toast/test/basic/index.html @@ -22,9 +22,39 @@ Show Toast Top Show Toast Middle Show Toast with long message - Show Toast with close button - Show Toast with close button and custom text + Show Toast with Close Button + Show Toast with Custom Close Button Text + Show Translucent Toast + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -32,23 +62,65 @@ function presentToast(position) { var toastController = document.querySelector('ion-toast-controller'); toastController.create({ - message: 'Hellooo', - position, - duration: 2000 - }) - .then(toast => { - toast.present(); - }); + message: 'Hellooo', + position, + duration: 2000 + }).then(toast => { + toast.present(); + }); } function presentToastWithOptions(opts) { var toastController = document.querySelector('ion-toast-controller'); - toastController.create(opts) - .then(toast => { - toast.present(); - }); + toastController.create(opts).then(toast => { + toast.present(); + }); } + + diff --git a/packages/core/src/components/toast/toast.ios.scss b/packages/core/src/components/toast/toast.ios.scss index c09ae08b61..64fb6be736 100644 --- a/packages/core/src/components/toast/toast.ios.scss +++ b/packages/core/src/components/toast/toast.ios.scss @@ -31,6 +31,12 @@ $toast-ios-title-padding-start: $toast-ios-title-padding-end ! /// @prop - Color of the toast button $toast-ios-button-color: rgba(71, 71, 71, 1) !default; +/// @prop - Filter of the translucent toast +$toast-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent toast +$toast-ios-translucent-opacity: .88 !default; + .toast-ios .toast-wrapper { @include position-horizontal(10px, 10px); @@ -47,6 +53,13 @@ $toast-ios-button-color: rgba(71, 71, 71, 1) !default; background: $toast-ios-background; } +.toast-translucent-ios .toast-wrapper { + background: rgba($toast-ios-background, $toast-ios-translucent-opacity); + + backdrop-filter: $toast-ios-translucent-filter; + -webkit-backdrop-filter: $toast-ios-translucent-filter; +} + .toast-ios .toast-wrapper.toast-top { @include transform(translate3d(0, -100%, 0)); diff --git a/packages/core/src/components/toast/toast.tsx b/packages/core/src/components/toast/toast.tsx index df8b8ffc3b..b450f0167c 100644 --- a/packages/core/src/components/toast/toast.tsx +++ b/packages/core/src/components/toast/toast.tsx @@ -1,6 +1,8 @@ import { Component, Element, Event, EventEmitter, Listen, Prop } from '@stencil/core'; import { Animation, AnimationBuilder, AnimationController, Config, CssClassMap } from '../../index'; +import { createThemedClasses } from '../../utils/theme'; + import iOSEnterAnimation from './animations/ios.enter'; import iOSLeaveAnimation from './animations/ios.leave'; @@ -15,6 +17,9 @@ import iOSLeaveAnimation from './animations/ios.leave'; } }) export class Toast { + mode: string; + color: string; + private animation: Animation; @Element() private el: HTMLElement; @@ -59,6 +64,7 @@ export class Toast { @Prop() closeButtonText: string; @Prop() dismissOnPageChange: boolean; @Prop() position: string; + @Prop() translucent: boolean = false; @Prop() enterAnimation: AnimationBuilder; @Prop() exitAnimation: AnimationBuilder; @Prop() toastId: string; @@ -156,6 +162,28 @@ export class Toast { this.dismiss(); } + wrapperClass(): CssClassMap { + let wrapperClass: string[] = !this.position + ? ['toast-wrapper', 'toast-bottom'] + : [`toast-wrapper`, `toast-${this.position}`]; + return wrapperClass.reduce((prevValue: any, cssClass: any) => { + prevValue[cssClass] = true; + return prevValue; + }, {}); + } + + hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'toast-translucent') : {}; + + const hostClasses = { + ...themedClasses + }; + + return { + class: hostClasses + }; + } + render() { let userCssClass = 'toast-content'; if (this.cssClass) { @@ -178,16 +206,6 @@ export class Toast { ); } - wrapperClass(): CssClassMap { - let wrapperClass: string[] = !this.position - ? ['toast-wrapper', 'toast-bottom'] - : [`toast-wrapper`, `toast-${this.position}`]; - return wrapperClass.reduce((prevValue: any, cssClass: any) => { - prevValue[cssClass] = true; - return prevValue; - }, {}); - } - } export interface ToastOptions { @@ -198,6 +216,7 @@ export interface ToastOptions { closeButtonText?: string; dismissOnPageChange?: boolean; position?: string; + translucent?: boolean; enterAnimation?: AnimationBuilder; exitAnimation?: AnimationBuilder; } diff --git a/packages/core/src/components/toolbar/test/basic/index.html b/packages/core/src/components/toolbar/test/basic/index.html index df2ec7dbba..2a54784f69 100644 --- a/packages/core/src/components/toolbar/test/basic/index.html +++ b/packages/core/src/components/toolbar/test/basic/index.html @@ -15,7 +15,13 @@ - + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae lobortis felis, eu sodales enim. Nam risus nibh, placerat at rutrum ac, vehicula vel velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis elementum ligula, ac aliquet nulla. Mauris non placerat mauris. Aenean dignissim lacinia porttitor. Praesent fringilla at est et ullamcorper. In ac ante ac massa porta venenatis ut id nibh. Fusce felis neque, aliquet in velit vitae, venenatis euismod libero. Donec vulputate, urna sed sagittis tempor, mi arcu tristique lacus, eget fringilla urna sem eget felis. Fusce dignissim lacus a scelerisque vehicula. Nulla nec enim nunc. + + Quisque nec dui eu nibh pulvinar bibendum quis ut nunc. Duis ex odio, sollicitudin ac mollis nec, fringilla non lacus. Maecenas sed tincidunt urna. Nunc feugiat maximus venenatis. Donec porttitor, felis eget porttitor tempor, quam nulla dapibus nisl, sit amet posuere sapien sapien malesuada tortor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque luctus, sapien nec tincidunt efficitur, nibh turpis faucibus felis, in sodales massa augue nec erat. Morbi sollicitudin nisi ex, et gravida nisi euismod eu. Suspendisse hendrerit dapibus orci, non viverra neque vestibulum id. Quisque vitae interdum ligula, quis consectetur nibh. + + Phasellus in mi at erat ultrices semper. Fusce sollicitudin at dolor ac lobortis. Morbi sit amet sem quis nulla pellentesque imperdiet. Nullam eu sem a enim maximus eleifend non vulputate leo. Proin quis congue lacus. Pellentesque placerat, quam at tempus pulvinar, nisl ligula tempor risus, quis pretium arcu odio et nulla. Nullam mollis consequat pharetra. Phasellus dictum velit sed purus mattis maximus. In molestie eget massa ut dignissim. In a interdum elit. In finibus nibh a mauris lobortis aliquet. Proin rutrum varius consequat. In mollis dapibus nisl, eu finibus urna viverra ac. Quisque scelerisque nisl eu suscipit consectetur. + diff --git a/packages/core/src/components/toolbar/test/translucent/index.html b/packages/core/src/components/toolbar/test/translucent/index.html new file mode 100644 index 0000000000..322bdd793c --- /dev/null +++ b/packages/core/src/components/toolbar/test/translucent/index.html @@ -0,0 +1,130 @@ + + + + + Toolbar - Translucent + + + + + + + + + Toolbar - Translucent + + + Toolbar - Primary Translucent + + + Toolbar - Secondary Translucent + + + Toolbar - Light Translucent + + + Toolbar - Danger Translucent + + + Toolbar - Dark Translucent + + + + + Toolbar - Danger Translucent + + + Toolbar - Dark Translucent + + + + + + + + + + + + + + + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae lobortis felis, eu sodales enim. Nam risus nibh, placerat at rutrum ac, vehicula vel velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis elementum ligula, ac aliquet nulla. Mauris non placerat mauris. Aenean dignissim lacinia porttitor. Praesent fringilla at est et ullamcorper. In ac ante ac massa porta venenatis ut id nibh. Fusce felis neque, aliquet in velit vitae, venenatis euismod libero. Donec vulputate, urna sed sagittis tempor, mi arcu tristique lacus, eget fringilla urna sem eget felis. Fusce dignissim lacus a scelerisque vehicula. Nulla nec enim nunc. + + Quisque nec dui eu nibh pulvinar bibendum quis ut nunc. Duis ex odio, sollicitudin ac mollis nec, fringilla non lacus. Maecenas sed tincidunt urna. Nunc feugiat maximus venenatis. Donec porttitor, felis eget porttitor tempor, quam nulla dapibus nisl, sit amet posuere sapien sapien malesuada tortor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque luctus, sapien nec tincidunt efficitur, nibh turpis faucibus felis, in sodales massa augue nec erat. Morbi sollicitudin nisi ex, et gravida nisi euismod eu. Suspendisse hendrerit dapibus orci, non viverra neque vestibulum id. Quisque vitae interdum ligula, quis consectetur nibh. + + Phasellus in mi at erat ultrices semper. Fusce sollicitudin at dolor ac lobortis. Morbi sit amet sem quis nulla pellentesque imperdiet. Nullam eu sem a enim maximus eleifend non vulputate leo. Proin quis congue lacus. Pellentesque placerat, quam at tempus pulvinar, nisl ligula tempor risus, quis pretium arcu odio et nulla. Nullam mollis consequat pharetra. Phasellus dictum velit sed purus mattis maximus. In molestie eget massa ut dignissim. In a interdum elit. In finibus nibh a mauris lobortis aliquet. Proin rutrum varius consequat. In mollis dapibus nisl, eu finibus urna viverra ac. Quisque scelerisque nisl eu suscipit consectetur. +

+ + + + + + + + + + + + + +
+ + + + Footer Toolbar - Danger + + + Footer Toolbar - Primary + + + Footer Toolbar - Translucent + + +
+
+ + + + + + + diff --git a/packages/core/src/components/toolbar/toolbar.ios.scss b/packages/core/src/components/toolbar/toolbar.ios.scss index 11c29edbeb..4a7fe7880c 100644 --- a/packages/core/src/components/toolbar/toolbar.ios.scss +++ b/packages/core/src/components/toolbar/toolbar.ios.scss @@ -33,6 +33,12 @@ $toolbar-ios-button-strong-font-weight: 600 !default; /// @prop - Height of the navigation bar $navbar-ios-height: $toolbar-ios-height !default; +/// @prop - Filter of the translucent toolbar +$toolbar-ios-translucent-filter: saturate(180%) blur(20px) !default; + +/// @prop - Opacity of the translucent toolbar +$toolbar-ios-translucent-opacity: .88 !default; + .toolbar-ios { @include padding($toolbar-ios-padding); @@ -76,6 +82,21 @@ $navbar-ios-height: $toolbar-ios-height !default; } +// iOS Translucent Toolbar +// -------------------------------------------------- + +.header-translucent-ios .toolbar-background-ios, +.footer-translucent-ios .toolbar-background-ios, +.toolbar-translucent-ios .toolbar-background-ios { + background: rgba($toolbar-ios-background, $toolbar-ios-translucent-opacity); +} + +.toolbar-translucent-ios .toolbar-background-ios { + -webkit-backdrop-filter: $toolbar-ios-translucent-filter; + backdrop-filter: $toolbar-ios-translucent-filter; +} + + // iOS Toolbar Content // -------------------------------------------------- @@ -104,6 +125,17 @@ $navbar-ios-height: $toolbar-ios-height !default; @include ios-bar-button-solid($color-name, $color-base, $color-contrast); } } + + // Colored toolbars with translucency + .header-translucent-ios .toolbar-ios-#{$color-name}, + .footer-translucent-ios .toolbar-ios-#{$color-name}, + .toolbar-translucent-ios-#{$color-name} { + + .toolbar-background-ios { + background: rgba($color-base, $toolbar-ios-translucent-opacity); + } + + } } diff --git a/packages/core/src/components/toolbar/toolbar.tsx b/packages/core/src/components/toolbar/toolbar.tsx index b9e254a3ae..2255f5fbbe 100644 --- a/packages/core/src/components/toolbar/toolbar.tsx +++ b/packages/core/src/components/toolbar/toolbar.tsx @@ -32,6 +32,14 @@ export class Toolbar { */ @Prop() mode: 'ios' | 'md'; + /** + * @input {boolean} If true, adds transparency to the header. + * Note: In order to scroll content behind the header, the `fullscreen` + * attribute needs to be set on the content. + * Only affects `ios` mode. Defaults to `false`. + */ + @Prop() translucent: boolean = false; + componentDidLoad() { const buttons = this.el.querySelectorAll('ion-button') as any; for (var i = 0; i < buttons.length; i++) { @@ -40,10 +48,15 @@ export class Toolbar { } hostData() { + const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'toolbar-translucent') : {}; + + const hostClasses = { + ...themedClasses, + 'statusbar-padding': this.config.getBoolean('statusbarPadding') + }; + return { - class: { - 'statusbar-padding': this.config.getBoolean('statusbarPadding') - } + class: hostClasses }; } diff --git a/packages/core/src/themes/ionic.theme.default.ios.scss b/packages/core/src/themes/ionic.theme.default.ios.scss index 3783b2eab0..d11c7f4f42 100644 --- a/packages/core/src/themes/ionic.theme.default.ios.scss +++ b/packages/core/src/themes/ionic.theme.default.ios.scss @@ -23,7 +23,7 @@ $content-ios-margin: $content-margin !default; $toolbar-ios-height: 44px !default; $toolbar-ios-padding: 4px !default; $toolbar-ios-background: $toolbar-background !default; -$toolbar-ios-border-color: rgba(0, 0, 0, .3) !default; +$toolbar-ios-border-color: rgba(0, 0, 0, .2) !default; $toolbar-ios-text-color: $toolbar-text-color !default; $toolbar-ios-active-color: $toolbar-active-color !default; $toolbar-ios-inactive-color: $toolbar-inactive-color !default; @@ -33,7 +33,7 @@ $toolbar-ios-inactive-color: $toolbar-inactive-color !default; // -------------------------------------------------- $tabs-ios-background: $tabs-background !default; -$tabs-ios-border-color: rgba(0, 0, 0, .3) !default; +$tabs-ios-border-color: rgba(0, 0, 0, .2) !default; $tabs-ios-tab-color-inactive: $tabs-tab-color-inactive !default; $tabs-ios-tab-color-active: $tabs-tab-color-active !default;