mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
refactor(components): update to use shadow DOM and work with css variables
- updates components to use shadow DOM or scoped if they require css variables - moves global styles to an external stylesheet that needs to be imported - adds support for additional colors and removes the Sass loops to generate colors for each component - several property renames, bug fixes, and test updates Co-authored-by: Manu Mtz.-Almeida <manu.mtza@gmail.com> Co-authored-by: Adam Bradley <adambradley25@gmail.com> Co-authored-by: Cam Wiegert <cam@camwiegert.com>
This commit is contained in:
@ -4,91 +4,58 @@
|
||||
// iOS FAB Button
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-ios {
|
||||
color: $fab-ios-text-color;
|
||||
background-color: $fab-ios-background-color;
|
||||
|
||||
box-shadow: $fab-ios-box-shadow;
|
||||
|
||||
transition: $fab-ios-transition;
|
||||
:host {
|
||||
--box-shadow: #{$fab-ios-box-shadow};
|
||||
--transition: #{$fab-ios-transition};
|
||||
}
|
||||
|
||||
.fab-button-ios.activated {
|
||||
background-color: $fab-ios-background-color-activated;
|
||||
:host(.activated) {
|
||||
--background: #{current-color(tint)};
|
||||
--box-shadow: #{$fab-ios-box-shadow-activated};
|
||||
|
||||
box-shadow: $fab-ios-box-shadow-activated;
|
||||
|
||||
transform: $fab-ios-transform;
|
||||
transition: $fab-ios-transition-activated;
|
||||
--transform: #{$fab-ios-transform};
|
||||
--transition: #{$fab-ios-transition-activated};
|
||||
}
|
||||
|
||||
.fab-button-ios .icon {
|
||||
::slotted(ion-icon),
|
||||
.fab-button-close-icon {
|
||||
font-size: $fab-ios-icon-font-size;
|
||||
|
||||
fill: $fab-ios-icon-fill-color;
|
||||
}
|
||||
|
||||
// FAB buttons in a list
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-ios-in-list {
|
||||
color: $fab-ios-list-button-text-color;
|
||||
background-color: $fab-ios-list-button-background-color;
|
||||
|
||||
transition: transform $fab-ios-list-button-transition-duration $fab-ios-list-button-transition-timing-function $fab-ios-list-button-transition-delay,
|
||||
opacity $fab-ios-list-button-transition-duration $fab-ios-list-button-transition-timing-function $fab-ios-list-button-transition-delay;
|
||||
:host(.fab-button-in-list) {
|
||||
--ion-color-contrast: #{$fab-ios-list-button-text-color};
|
||||
--ion-color-base: #{$fab-ios-list-button-background-color};
|
||||
--transition: #{transform $fab-ios-list-button-transition-duration $fab-ios-list-button-transition-timing-function $fab-ios-list-button-transition-delay,
|
||||
opacity $fab-ios-list-button-transition-duration $fab-ios-list-button-transition-timing-function $fab-ios-list-button-transition-delay};
|
||||
}
|
||||
|
||||
.fab-button-ios-in-list.activated {
|
||||
background-color: $fab-ios-list-button-background-color-activated;
|
||||
:host(.fab-button-in-list.activated) {
|
||||
--background: #{$fab-ios-list-button-background-color-activated};
|
||||
}
|
||||
|
||||
.fab-button-ios-in-list .icon {
|
||||
fill: $fab-ios-list-button-icon-fill-color;
|
||||
}
|
||||
|
||||
// Translucent FAB buttons
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-translucent-ios {
|
||||
background-color: $fab-ios-translucent-background-color;
|
||||
:host(.fab-translucent) {
|
||||
--background: #{$fab-ios-translucent-background-color};
|
||||
|
||||
backdrop-filter: $fab-ios-translucent-filter;
|
||||
--backdrop-filter: #{$fab-ios-translucent-filter};
|
||||
}
|
||||
|
||||
.fab-translucent-ios-in-list {
|
||||
background-color: $fab-ios-list-button-translucent-background-color;
|
||||
:host(.fab-translucent-in-list) {
|
||||
--background: #{$fab-ios-list-button-translucent-background-color};
|
||||
}
|
||||
|
||||
|
||||
// Generate iOS FAB colors
|
||||
// --------------------------------------------------
|
||||
|
||||
@each $color-name, $color-value in $colors-ios {
|
||||
$bg-color: ion-color($colors-ios, $color-name, base, ios);
|
||||
$bg-color-activated: ion-color($colors-ios, $color-name, tint, ios);
|
||||
$fg-color: ion-color($colors-ios, $color-name, contrast, ios);
|
||||
|
||||
.fab-button-ios-#{$color-name} {
|
||||
color: $fg-color;
|
||||
background-color: $bg-color;
|
||||
}
|
||||
|
||||
.fab-button-ios-#{$color-name} .icon {
|
||||
fill: $fg-color;
|
||||
}
|
||||
|
||||
.fab-button-ios-#{$color-name}.activated {
|
||||
background-color: $bg-color-activated;
|
||||
}
|
||||
|
||||
.fab-translucent-ios-#{$color-name} {
|
||||
background-color: ion-color($colors-ios, $color-name, base, ios, $fab-ios-translucent-background-color-alpha);
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.fab-translucent-ios-#{$color-name}.activated {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
// .fab-translucent-ios-#{$color-name} {
|
||||
// background-color: ion-color($color-name, base, $fab-ios-translucent-background-color-alpha);
|
||||
// opacity: .8;
|
||||
// }
|
||||
|
||||
// .fab-translucent-ios-#{$color-name}.activated {
|
||||
// opacity: 1;
|
||||
// }
|
@ -19,16 +19,16 @@ $fab-ios-transition: .2s transform cubi
|
||||
$fab-ios-transition-activated: .2s transform ease-out !default;
|
||||
|
||||
/// @prop - Background color of the button
|
||||
$fab-ios-background-color: ion-color($colors-ios, primary, base, ios) !default;
|
||||
$fab-ios-background-color: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Background color alpha of the button in translucent mode
|
||||
$fab-ios-translucent-background-color-alpha: .9 !default;
|
||||
|
||||
/// @prop - Background color of the button in translucent mode
|
||||
$fab-ios-translucent-background-color: ion-color($colors-ios, primary, base, ios, $fab-ios-translucent-background-color-alpha) !default;
|
||||
$fab-ios-translucent-background-color: ion-color(primary, base, $fab-ios-translucent-background-color-alpha) !default;
|
||||
|
||||
/// @prop - Text color of the button
|
||||
$fab-ios-text-color: ion-color($colors-ios, $fab-ios-background-color, contrast, ios) !default;
|
||||
$fab-ios-text-color: ion-color(primary, contrast) !default;
|
||||
|
||||
/// @prop - Color of the button icon
|
||||
$fab-ios-icon-fill-color: $fab-ios-text-color !default;
|
||||
@ -37,25 +37,25 @@ $fab-ios-icon-fill-color: $fab-ios-text-colo
|
||||
$fab-ios-icon-font-size: 28px !default;
|
||||
|
||||
/// @prop - Background color of the activated button
|
||||
$fab-ios-background-color-activated: ion-color($colors-ios, $fab-ios-background-color, tint, ios) !default;
|
||||
$fab-ios-background-color-activated: ion-color(primary, tint) !default;
|
||||
|
||||
/// @prop - Background color of the button in a list
|
||||
$fab-ios-list-button-background-color: ion-color($colors-ios, light, base, ios) !default;
|
||||
$fab-ios-list-button-background-color: ion-color(light, base) !default;
|
||||
|
||||
/// @prop - Background color of the button in a list
|
||||
$fab-ios-list-button-translucent-background-color-alpha: .8 !default;
|
||||
|
||||
/// @prop - Background color of the button in a list
|
||||
$fab-ios-list-button-translucent-background-color: css-var($background-ios-color-value, background-ios-color, $fab-ios-list-button-translucent-background-color-alpha) !default;
|
||||
$fab-ios-list-button-translucent-background-color: rgba(var(--ion-background-color-rgb, $background-color-rgb), $fab-ios-list-button-translucent-background-color-alpha) !default;
|
||||
|
||||
/// @prop - Text color of the button in a list
|
||||
$fab-ios-list-button-text-color: ion-color($colors-ios, $fab-ios-list-button-background-color, contrast, ios) !default;
|
||||
$fab-ios-list-button-text-color: ion-color(light, contrast) !default;
|
||||
|
||||
/// @prop - Color of the button icon in a list
|
||||
$fab-ios-list-button-icon-fill-color: $fab-ios-list-button-text-color !default;
|
||||
|
||||
/// @prop - Background color of the activated button in a list
|
||||
$fab-ios-list-button-background-color-activated: ion-color($colors-ios, $fab-ios-list-button-background-color, tint, ios) !default;
|
||||
$fab-ios-list-button-background-color-activated: ion-color(primary, tint) !default;
|
||||
|
||||
/// @prop - Transition duration of the transform and opacity of the button in a list
|
||||
$fab-ios-list-button-transition-duration: 200ms !default;
|
||||
|
@ -4,82 +4,37 @@
|
||||
// Material Design FAB Button
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-md {
|
||||
color: $fab-md-text-color;
|
||||
background-color: $fab-md-background-color;
|
||||
:host {
|
||||
--box-shadow: #{$fab-md-box-shadow};
|
||||
|
||||
box-shadow: $fab-md-box-shadow;
|
||||
|
||||
transition: box-shadow $fab-button-md-transition-duration $fab-button-md-transition-timing-function,
|
||||
--transition: #{box-shadow $fab-button-md-transition-duration $fab-button-md-transition-timing-function,
|
||||
background-color $fab-button-md-transition-duration $fab-button-md-transition-timing-function,
|
||||
color $fab-button-md-transition-duration $fab-button-md-transition-timing-function;
|
||||
color $fab-button-md-transition-duration $fab-button-md-transition-timing-function};
|
||||
}
|
||||
|
||||
.fab-button-md.activated {
|
||||
background-color: $fab-md-background-color-activated;
|
||||
box-shadow: $fab-md-box-shadow-activated;
|
||||
:host(.activated) {
|
||||
--box-shadow: #{$fab-md-box-shadow-activated};
|
||||
}
|
||||
|
||||
.fab-button-md .icon {
|
||||
fill: $fab-md-icon-fill-color;
|
||||
::slotted(ion-icon),
|
||||
.fab-button-close-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
// FAB buttons in a list
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-md-in-list {
|
||||
color: $fab-md-list-button-text-color;
|
||||
background-color: $fab-md-list-button-background-color;
|
||||
|
||||
transition: transform $fab-md-list-button-transition-duration $fab-md-list-button-transition-timing-function $fab-md-list-button-transition-delay,
|
||||
:host(.fab-button-in-list) {
|
||||
--ion-color-contrast: #{$fab-md-list-button-text-color};
|
||||
--ion-color-base: #{$fab-md-list-button-background-color};
|
||||
--transition: #{transform $fab-md-list-button-transition-duration $fab-md-list-button-transition-timing-function $fab-md-list-button-transition-delay,
|
||||
opacity $fab-md-list-button-transition-duration $fab-md-list-button-transition-timing-function $fab-md-list-button-transition-delay,
|
||||
box-shadow $fab-button-md-transition-duration $fab-button-md-transition-timing-function,
|
||||
background-color $fab-button-md-transition-duration $fab-button-md-transition-timing-function,
|
||||
color $fab-button-md-transition-duration $fab-button-md-transition-timing-function;
|
||||
color $fab-button-md-transition-duration $fab-button-md-transition-timing-function};
|
||||
}
|
||||
|
||||
.fab-button-md-in-list.activated {
|
||||
background-color: $fab-md-list-button-background-color-activated;
|
||||
:host(.fab-button-in-list.activated) {
|
||||
--background: #{$fab-md-list-button-background-color-activated};
|
||||
}
|
||||
|
||||
.fab-button-md-in-list .icon {
|
||||
fill: $fab-md-list-button-icon-fill-color;
|
||||
}
|
||||
|
||||
|
||||
// Material Design FAB Ripple
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-md .button-effect {
|
||||
background-color: ion-color($colors-md, $fab-md-background-color, contrast, md);
|
||||
}
|
||||
|
||||
|
||||
// Generate MD FAB colors
|
||||
// --------------------------------------------------
|
||||
|
||||
@each $color-name, $color-value in $colors-md {
|
||||
|
||||
$bg-color: ion-color($colors-md, $color-name, base, md);
|
||||
$bg-color-activated: ion-color($colors-md, $bg-color, tint, md);
|
||||
$fg-color: ion-color($colors-md, $color-name, contrast, md);
|
||||
|
||||
.fab-button-md-#{$color-name} {
|
||||
color: $fg-color;
|
||||
background-color: $bg-color;
|
||||
}
|
||||
|
||||
.fab-button-md-#{$color-name} .icon {
|
||||
fill: $fg-color;
|
||||
}
|
||||
|
||||
.fab-button-md-#{$color-name}.activated {
|
||||
background-color: $bg-color-activated;
|
||||
}
|
||||
|
||||
.fab-button-md-#{$color-name} .ripple-effect {
|
||||
background-color: $fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,28 +10,28 @@ $fab-md-box-shadow: 0 4px 6px 0 rgba(0, 0, 0, .14)
|
||||
$fab-md-box-shadow-activated: 0 5px 15px 0 rgba(0, 0, 0, .4), 0 4px 7px 0 rgba(0, 0, 0, .1) !default;
|
||||
|
||||
/// @prop - Background color of the button
|
||||
$fab-md-background-color: ion-color($colors-md, primary, base, md) !default;
|
||||
$fab-md-background-color: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Text color of the button
|
||||
$fab-md-text-color: ion-color($colors-md, $fab-md-background-color, contrast, md) !default;
|
||||
$fab-md-text-color: ion-color(primary, contrast) !default;
|
||||
|
||||
/// @prop - Color of the button icon
|
||||
$fab-md-icon-fill-color: $fab-md-text-color !default;
|
||||
|
||||
/// @prop - Background color of the activated button
|
||||
$fab-md-background-color-activated: ion-color($colors-md, $fab-md-background-color, tint, md) !default;
|
||||
$fab-md-background-color-activated: ion-color(primary, tint) !default;
|
||||
|
||||
/// @prop - Background color of the button in a list
|
||||
$fab-md-list-button-background-color: ion-color($colors-md, light, base, md) !default;
|
||||
$fab-md-list-button-background-color: ion-color(light, base) !default;
|
||||
|
||||
/// @prop - Text color of the button in a list
|
||||
$fab-md-list-button-text-color: ion-color($colors-md, $fab-md-list-button-background-color, contrast, md) !default;
|
||||
$fab-md-list-button-text-color: ion-color(light, contrast) !default;
|
||||
|
||||
/// @prop - Color of the button icon in a list
|
||||
$fab-md-list-button-icon-fill-color: $fab-md-list-button-text-color !default;
|
||||
|
||||
/// @prop - Background color of the activated button in a list
|
||||
$fab-md-list-button-background-color-activated: ion-color($colors-md, $fab-md-list-button-background-color, tint, md) !default;
|
||||
$fab-md-list-button-background-color-activated: ion-color(primary, tint) !default;
|
||||
|
||||
/// @prop - Transition duration of the transform and opacity of the button in a list
|
||||
$fab-md-list-button-transition-duration: 200ms !default;
|
||||
|
@ -3,9 +3,36 @@
|
||||
// Floating Action Buttons
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button {
|
||||
@include text-align(center);
|
||||
@include appearance(none);
|
||||
:host {
|
||||
--ion-color-base: #{ion-color(primary, base)};
|
||||
--ion-color-contrast: #{ion-color(primary, contrast)};
|
||||
--ion-color-tint: #{ion-color(primary, tint)};
|
||||
|
||||
--size: #{$fab-size};
|
||||
--background: #{current-color(base)};
|
||||
--transition: background-color, opacity 100ms linear;
|
||||
|
||||
--padding-start: calc((#{$fab-size} - var(--size)) / 2);
|
||||
--padding-end: calc((#{$fab-size} - var(--size)) / 2);
|
||||
--padding-top: calc((#{$fab-size} - var(--size)) / 2);
|
||||
--padding-bottom: calc((#{$fab-size} - var(--size)) / 2);
|
||||
|
||||
font-size: 14px;
|
||||
color: #{current-color(contrast)};
|
||||
}
|
||||
|
||||
:host(.activated) {
|
||||
--background: #{current-color(tint)};
|
||||
}
|
||||
|
||||
.fab-button-native {
|
||||
@include margin(
|
||||
var(--padding-top),
|
||||
var(--padding-end),
|
||||
var(--padding-bottom),
|
||||
var(--padding-start)
|
||||
);
|
||||
text-align: center;
|
||||
@include border-radius(50%);
|
||||
|
||||
position: relative;
|
||||
@ -13,37 +40,46 @@
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
width: $fab-size;
|
||||
height: $fab-size;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
|
||||
border: 0;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: $fab-size;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: var(--size);
|
||||
text-overflow: ellipsis;
|
||||
text-transform: none;
|
||||
white-space: nowrap;
|
||||
color: inherit;
|
||||
background: var(--background);
|
||||
box-shadow: var(--box-shadow);
|
||||
cursor: pointer;
|
||||
transition: background-color, opacity 100ms linear;
|
||||
transform: var(--transform);
|
||||
transition: var(--transition);
|
||||
|
||||
background-clip: padding-box;
|
||||
|
||||
font-kerning: none;
|
||||
user-select: none;
|
||||
|
||||
contain: strict;
|
||||
|
||||
appearance: none;
|
||||
|
||||
&:active,
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fab-button ion-icon {
|
||||
font-size: 24px;
|
||||
::slotted(ion-icon) {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.fab-button-inner {
|
||||
@include position(0, 0, null, 0);
|
||||
|
||||
position: absolute;
|
||||
display: flex;
|
||||
|
||||
flex-flow: row nowrap;
|
||||
@ -51,7 +87,9 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
|
||||
transition: all ease-in-out 300ms;
|
||||
@ -62,13 +100,8 @@
|
||||
// FAB Mini
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-fab-button[mini] .fab-button {
|
||||
@include margin(($fab-size - $fab-mini-size) / 2);
|
||||
|
||||
width: $fab-mini-size;
|
||||
height: $fab-mini-size;
|
||||
|
||||
line-height: $fab-mini-size;
|
||||
:host([mini]) {
|
||||
--size: #{$fab-mini-size};
|
||||
}
|
||||
|
||||
// FAB Close Icon
|
||||
@ -78,9 +111,11 @@ ion-fab-button[mini] .fab-button {
|
||||
@include position(0, 0, null, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
|
||||
opacity: 0;
|
||||
@ -89,19 +124,19 @@ ion-fab-button[mini] .fab-button {
|
||||
transition-property: transform, opacity;
|
||||
}
|
||||
|
||||
.fab-button-close-icon .icon-inner {
|
||||
@include margin(auto);
|
||||
}
|
||||
|
||||
// FAB Animation
|
||||
// --------------------------------------------------
|
||||
|
||||
.fab-button-close-active .fab-button-close-icon {
|
||||
:host(.fab-button-close-active) .fab-button-close-icon {
|
||||
opacity: 1;
|
||||
transform: scale(1) rotateZ(0deg);
|
||||
}
|
||||
|
||||
.fab-button-close-active .fab-button-inner {
|
||||
:host(.fab-button-close-active) .fab-button-inner {
|
||||
opacity: 0;
|
||||
transform: scale(.4) rotateZ(45deg);
|
||||
}
|
||||
|
||||
ion-ripple-effect {
|
||||
color: var(--ripple-color);
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { Color, CssClassMap, Mode } from '../../interface';
|
||||
import { createThemedClasses, getElementClassMap } from '../../utils/theme';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-fab-button',
|
||||
styleUrls: {
|
||||
ios: 'fab-button.ios.scss',
|
||||
md: 'fab-button.md.scss'
|
||||
}
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class FabButton {
|
||||
private inList = false;
|
||||
@ -64,39 +65,39 @@ export class FabButton {
|
||||
private getFabClassMap(): CssClassMap {
|
||||
return {
|
||||
'fab-button-in-list': this.inList,
|
||||
[`fab-button-${this.mode}-in-list`]: this.inList,
|
||||
[`fab-button-translucent-${this.mode}-in-list`]:
|
||||
this.inList && this.translucent,
|
||||
'fab-button-translucent-in-list': this.inList && this.translucent,
|
||||
'fab-button-close-active': this.activated,
|
||||
'fab-button-show': this.show
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const themedClasses = createThemedClasses(
|
||||
this.mode,
|
||||
this.color,
|
||||
'fab-button'
|
||||
);
|
||||
const translucentClasses = this.translucent
|
||||
? createThemedClasses(this.mode, this.color, 'fab-button-translucent')
|
||||
: {};
|
||||
const hostClasses = getElementClassMap(this.el.classList);
|
||||
const TagType = this.href ? 'a' : 'button';
|
||||
const fabClasses = {
|
||||
...this.getFabClassMap(),
|
||||
...themedClasses,
|
||||
...translucentClasses,
|
||||
...hostClasses
|
||||
hostData() {
|
||||
|
||||
return {
|
||||
'tappable': true,
|
||||
class: {
|
||||
...createColorClasses(this.color),
|
||||
...this.getFabClassMap(),
|
||||
'fab-button-translucent': this.translucent
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const TagType = this.href ? 'a' : 'button';
|
||||
|
||||
return (
|
||||
<TagType class={fabClasses} disabled={this.disabled} href={this.href}>
|
||||
<ion-icon name="close" class="fab-button-close-icon" />
|
||||
<span class="fab-button-inner">
|
||||
<slot />
|
||||
<TagType
|
||||
class="fab-button-native"
|
||||
disabled={this.disabled}
|
||||
href={this.href}>
|
||||
<span class="fab-button-close-icon">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</span>
|
||||
{this.mode === 'md' && <ion-ripple-effect tapClick={true} />}
|
||||
<span class="fab-button-inner">
|
||||
<slot></slot>
|
||||
</span>
|
||||
{ this.mode === 'md' && <ion-ripple-effect tapClick={true} parent={this.el}/> }
|
||||
</TagType>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user