diff --git a/angular/src/directives/proxies.ts b/angular/src/directives/proxies.ts
index 1a2b083a47b..a6a97b7b00e 100644
--- a/angular/src/directives/proxies.ts
+++ b/angular/src/directives/proxies.ts
@@ -239,12 +239,15 @@ export class Fab {
}
export declare interface FabButton extends StencilComponents<'IonFabButton'> {}
-@Component({ selector: 'ion-fab-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '', inputs: ['mode', 'color', 'activated', 'disabled', 'routerDirection', 'href', 'translucent', 'show'] })
+@Component({ selector: 'ion-fab-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '', inputs: ['mode', 'color', 'activated', 'disabled', 'href', 'routerDirection', 'show', 'translucent', 'type'] })
export class FabButton {
+ ionFocus: EventEmitter;
+ ionBlur: EventEmitter;
constructor(r: ElementRef) {
const el = r.nativeElement;
- proxyInputs(this, el, ['mode', 'color', 'activated', 'disabled', 'routerDirection', 'href', 'translucent', 'show']);
+ proxyInputs(this, el, ['mode', 'color', 'activated', 'disabled', 'href', 'routerDirection', 'show', 'translucent', 'type']);
+ proxyOutputs(this, el, ['ionFocus', 'ionBlur']);
}
}
diff --git a/core/src/components.d.ts b/core/src/components.d.ts
index c768d7ea3be..a07308d27ee 100644
--- a/core/src/components.d.ts
+++ b/core/src/components.d.ts
@@ -1412,6 +1412,10 @@ export namespace Components {
* If true, the fab button will be translucent. Defaults to `false`.
*/
'translucent': boolean;
+ /**
+ * The type of the button. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
+ */
+ 'type': 'submit' | 'reset' | 'button';
}
interface IonFabButtonAttributes extends StencilHTMLAttributes {
/**
@@ -1435,6 +1439,14 @@ export namespace Components {
*/
'mode'?: Mode;
/**
+ * Emitted when the button loses focus.
+ */
+ 'onIonBlur'?: (event: CustomEvent) => void;
+ /**
+ * Emitted when the button has focus.
+ */
+ 'onIonFocus'?: (event: CustomEvent) => void;
+ /**
* When using a router, it specifies the transition direction when navigating to another page using `href`.
*/
'routerDirection'?: RouterDirection;
@@ -1446,6 +1458,10 @@ export namespace Components {
* If true, the fab button will be translucent. Defaults to `false`.
*/
'translucent'?: boolean;
+ /**
+ * The type of the button. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
+ */
+ 'type'?: 'submit' | 'reset' | 'button';
}
interface IonFabList {
diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx
index 8cf84845f7e..5e3a36edc03 100644
--- a/core/src/components/button/button.tsx
+++ b/core/src/components/button/button.tsx
@@ -166,7 +166,6 @@ export class Button implements ComponentInterface {
}
render() {
-
const TagType = this.href === undefined ? 'button' : 'a';
const attrs = (TagType === 'button')
? { type: this.type }
diff --git a/core/src/components/fab-button/fab-button.ios.scss b/core/src/components/fab-button/fab-button.ios.scss
index 07afbc63a90..6f3e49bb6fa 100755
--- a/core/src/components/fab-button/fab-button.ios.scss
+++ b/core/src/components/fab-button/fab-button.ios.scss
@@ -10,7 +10,6 @@
}
:host(.activated) {
- --background: #{current-color(tint)};
--box-shadow: #{$fab-ios-box-shadow-activated};
--transform: #{$fab-ios-transform};
--transition: #{$fab-ios-transition-activated};
@@ -25,10 +24,10 @@
// --------------------------------------------------
: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};
+ --background: #{$fab-ios-list-button-background-color};
+ --color: #{$fab-ios-list-button-text-color};
+ --transition: #{transform 200ms ease 10ms,
+ opacity 200ms ease 10ms};
}
:host(.fab-button-in-list.activated) {
diff --git a/core/src/components/fab-button/fab-button.ios.vars.scss b/core/src/components/fab-button/fab-button.ios.vars.scss
index 08aa0ed94be..2c578aea79e 100755
--- a/core/src/components/fab-button/fab-button.ios.vars.scss
+++ b/core/src/components/fab-button/fab-button.ios.vars.scss
@@ -57,14 +57,5 @@ $fab-ios-list-button-icon-fill-color: $fab-ios-list-butt
/// @prop - Background color of the activated button in a list
$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;
-
-/// @prop - Speed curve of the transition of the transform and opacity of the button in a list
-$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;
diff --git a/core/src/components/fab-button/fab-button.md.scss b/core/src/components/fab-button/fab-button.md.scss
index 9f9e9ad5cf1..28101105597 100755
--- a/core/src/components/fab-button/fab-button.md.scss
+++ b/core/src/components/fab-button/fab-button.md.scss
@@ -6,9 +6,11 @@
:host {
--box-shadow: #{$fab-md-box-shadow};
- --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};
+ --transition: #{
+ box-shadow 300ms cubic-bezier(.4, 0, .2, 1),
+ background-color 300ms cubic-bezier(.4, 0, .2, 1),
+ color 300ms cubic-bezier(.4, 0, .2, 1)
+ };
}
:host(.activated) {
@@ -25,13 +27,15 @@
// --------------------------------------------------
: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-md-list-button-text-color};
+ --background: #{$fab-md-list-button-background-color};
+ --transition: #{
+ transform 200ms ease 10ms ease 10ms
+ opacity 200ms ease 10ms ease 10ms
+ box-shadow 300ms cubic-bezier(.4, 0, .2, 1)
+ background-color 300ms cubic-bezier(.4, 0, .2, 1)
+ color 300ms cubic-bezier(.4, 0, .2, 1)
+ };
}
:host(.fab-button-in-list.activated) {
diff --git a/core/src/components/fab-button/fab-button.md.vars.scss b/core/src/components/fab-button/fab-button.md.vars.scss
index d89f5b50b2f..7ad88066045 100755
--- a/core/src/components/fab-button/fab-button.md.vars.scss
+++ b/core/src/components/fab-button/fab-button.md.vars.scss
@@ -32,18 +32,3 @@ $fab-md-list-button-icon-fill-color: $fab-md-list-button-text-color
/// @prop - Background color of the activated button in a list
$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;
-
-/// @prop - Speed curve of the transition of the transform and opacity of the button in a list
-$fab-md-list-button-transition-timing-function: ease !default;
-
-/// @prop - Transition delay of the transform and opacity of the button in a list
-$fab-md-list-button-transition-delay: 10ms !default;
-
-/// @prop - Transition duration of the box-shadow and background-color of the button
-$fab-button-md-transition-duration: 300ms !default;
-
-/// @prop - Speed curve of the transition of the box-shadow and background-color of the button
-$fab-button-md-transition-timing-function: cubic-bezier(.4, 0, .2, 1) !default;
diff --git a/core/src/components/fab-button/fab-button.scss b/core/src/components/fab-button/fab-button.scss
index 3f8b60926d5..b930f959883 100755
--- a/core/src/components/fab-button/fab-button.scss
+++ b/core/src/components/fab-button/fab-button.scss
@@ -4,21 +4,56 @@
// --------------------------------------------------
: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)};
+ /**
+ * @prop --background: Background of the button
+ * @prop --background-activated: Background of the button when activated
+ * @prop --background-focused: Background of the button when focused
+ *
+ * @prop --color: Text color of the button
+ * @prop --color-activated: Text color of the button when activated
+ * @prop --color-focused: Text color of the button when focused
+ *
+ * @prop --width: Width of the button
+ * @prop --height: Height of the button
+ *
+ * @prop --transition: Transition of the button
+ *
+ * @prop --border-radius: Border radius of the button
+ * @prop --border-width: Border width of the button
+ * @prop --border-style: Border style of the button
+ * @prop --border-color: Border color of the button
+ *
+ * @prop --ripple-color: Color of the button ripple effect
+ *
+ * @prop --box-shadow: Box shadow of the button
+ *
+ * @prop --margin-top: Margin top of the button
+ * @prop --margin-end: Margin end of the button
+ * @prop --margin-bottom: Margin bottom of the button
+ * @prop --margin-start: Margin start of the button
+ *
+ * @prop --padding-top: Padding top of the button
+ * @prop --padding-end: Padding end of the button
+ * @prop --padding-bottom: Padding bottom of the button
+ * @prop --padding-start: Padding start of the button
+ */
+ --background: #{ion-color(primary, base)};
+ --background-activated: #{ion-color(primary, shade)};
+ --background-focused: #{ion-color(primary, shade)};
+ --color: #{ion-color(primary, contrast)};
+ --color-activated: #{ion-color(primary, contrast)};
+ --color-focused: var(--color-activated);
+ --width: #{$fab-size};
+ --height: var(--width);
+ --margin-start: calc((#{$fab-size} - var(--width)) / 2);
+ --margin-end: calc((#{$fab-size} - var(--width)) / 2);
+ --margin-top: calc((#{$fab-size} - var(--height)) / 2);
+ --margin-bottom: calc((#{$fab-size} - var(--height)) / 2);
--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);
+ --ripple-color: currentColor;
display: block;
- color: #{current-color(contrast)};
-
font-size: 14px;
text-align: center;
@@ -29,24 +64,34 @@
font-kerning: none;
}
-:host(.fab-button-disabled) {
- pointer-events: none;
+
+// FAB with Color
+// --------------------------------------------------
+
+// Default Button with Color
+:host(.ion-color) .button-native {
+ background: #{current-color(base)};
+ color: #{current-color(contrast)};
}
-:host(.activated) {
- --background: #{current-color(tint)};
+// Focused/Activated Button with Color
+:host(.ion-color.focused) .button-native,
+:host(.ion-color.activated) .button-native {
+ background: #{current-color(shade)};
+ color: #{current-color(contrast)};
}
.button-native {
- @include text-inherit();
@include border-radius(50%);
- @include margin(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
+ @include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
+ @include margin(var(--margin-top), var(--margin-end), var(--margin-bottom), var(--margin-start));
+ @include text-inherit();
display: block;
position: relative;
- width: var(--size);
- height: var(--size);
+ width: var(--width);
+ height: var(--height);
transform: var(--transform);
@@ -57,9 +102,11 @@
outline: none;
background: var(--background);
+
background-clip: padding-box;
+ color: var(--color);
- line-height: var(--size);
+ line-height: var(--heigh);
box-shadow: var(--box-shadow);
contain: strict;
@@ -97,11 +144,45 @@
}
+// FAB States
+// --------------------------------------------------
+
+// Activated / Pressed Button
+:host(.activated) .button-native {
+ background: var(--background-activated);
+ color: var(--color-activated);
+}
+
+// Focused Button
+:host(.focused) .button-native {
+ background: var(--background-focused);
+ color: var(--color-focused);
+}
+
+// Disabled Button
+:host(.fab-button-disabled) {
+ pointer-events: none;
+}
+
+.button-native[disabled] {
+ cursor: default;
+ opacity: .5;
+ pointer-events: none;
+}
+
+// FAB Content
+// --------------------------------------------------
+
+::slotted(ion-icon) {
+ line-height: 1;
+}
+
+
// FAB Mini
// --------------------------------------------------
:host([mini]) {
- --size: #{$fab-mini-size};
+ --width: #{$fab-mini-size};
}
// FAB Close Icon
diff --git a/core/src/components/fab-button/fab-button.tsx b/core/src/components/fab-button/fab-button.tsx
index eaef8ac89f4..fa97bbba49f 100755
--- a/core/src/components/fab-button/fab-button.tsx
+++ b/core/src/components/fab-button/fab-button.tsx
@@ -1,4 +1,4 @@
-import { Component, ComponentInterface, Element, Prop } from '@stencil/core';
+import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
import { Color, Mode, RouterDirection } from '../../interface';
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
@@ -12,10 +12,11 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
shadow: true
})
export class FabButton implements ComponentInterface {
+ @Element() el!: HTMLElement;
- @Prop({ context: 'window' }) win!: Window;
+ @State() keyFocus = false;
- @Element() el!: HTMLElement;
+ @Prop({ context: 'window' }) win!: Window;
/**
* The mode determines which platform styles to use.
@@ -40,6 +41,12 @@ export class FabButton implements ComponentInterface {
*/
@Prop() disabled = false;
+ /**
+ * Contains a URL or a URL fragment that the hyperlink points to.
+ * If this property is set, an anchor tag will be rendered.
+ */
+ @Prop() href?: string;
+
/**
* When using a router, it specifies the transition direction when navigating to
* another page using `href`.
@@ -47,10 +54,9 @@ export class FabButton implements ComponentInterface {
@Prop() routerDirection?: RouterDirection;
/**
- * Contains a URL or a URL fragment that the hyperlink points to.
- * If this property is set, an anchor tag will be rendered.
+ * If true, the fab button will show when in a fab-list.
*/
- @Prop() href?: string;
+ @Prop() show = false;
/**
* If true, the fab button will be translucent. Defaults to `false`.
@@ -58,9 +64,34 @@ export class FabButton implements ComponentInterface {
@Prop() translucent = false;
/**
- * If true, the fab button will show when in a fab-list.
+ * The type of the button.
+ * Possible values are: `"submit"`, `"reset"` and `"button"`.
+ * Default value is: `"button"`
*/
- @Prop() show = false;
+ @Prop() type: 'submit' | 'reset' | 'button' = 'button';
+
+ /**
+ * Emitted when the button has focus.
+ */
+ @Event() ionFocus!: EventEmitter;
+
+ /**
+ * Emitted when the button loses focus.
+ */
+ @Event() ionBlur!: EventEmitter;
+
+ private onFocus = () => {
+ this.ionFocus.emit();
+ }
+
+ private onKeyUp = () => {
+ this.keyFocus = true;
+ }
+
+ private onBlur = () => {
+ this.keyFocus = false;
+ this.ionBlur.emit();
+ }
hostData() {
const inList = hostContext('ion-fab-list', this.el);
@@ -73,19 +104,26 @@ export class FabButton implements ComponentInterface {
'fab-button-close-active': this.activated,
'fab-button-show': this.show,
'fab-button-disabled': this.disabled,
- 'fab-button-translucent': this.translucent
+ 'fab-button-translucent': this.translucent,
+ 'focused': this.keyFocus
}
};
}
render() {
const TagType = this.href === undefined ? 'button' : 'a';
+ const attrs = (TagType === 'button')
+ ? { type: this.type }
+ : { href: this.href };
return (
openURL(this.win, this.href, ev, this.routerDirection)}
>
diff --git a/core/src/components/fab-button/test/standalone/index.html b/core/src/components/fab-button/test/standalone/index.html
index 6c503e49bfe..b3165a0cc2e 100644
--- a/core/src/components/fab-button/test/standalone/index.html
+++ b/core/src/components/fab-button/test/standalone/index.html
@@ -14,6 +14,7 @@
Default
Default
+ Mini
diff --git a/core/src/components/fab-list/fab-list.scss b/core/src/components/fab-list/fab-list.scss
index 792c6d65dd7..1afdab726bc 100644
--- a/core/src/components/fab-list/fab-list.scss
+++ b/core/src/components/fab-list/fab-list.scss
@@ -22,7 +22,7 @@
}
::slotted(.fab-button-in-list) {
- --size: #{$fab-mini-size};
+ --width: #{$fab-mini-size};
transform: scale(0);
@@ -32,14 +32,14 @@
:host(.fab-list-side-top) ::slotted(.fab-button-in-list),
:host(.fab-list-side-bottom) ::slotted(.fab-button-in-list) {
- --padding-top: 5px;
- --padding-bottom: 5px;
+ --margin-top: 5px;
+ --margin-bottom: 5px;
}
:host(.fab-list-side-start) ::slotted(.fab-button-in-list),
:host(.fab-list-side-end) ::slotted(.fab-button-in-list) {
- --padding-start: 5px;
- --padding-end: 5px;
+ --margin-start: 5px;
+ --margin-end: 5px;
}
::slotted(.fab-button-in-list.fab-button-show) {