refactor(fab): combine boolean position attributes to string props

fixes #13596
This commit is contained in:
Brandy Carney
2018-03-07 17:31:05 -05:00
parent dc8b363ea8
commit cc365f829d
8 changed files with 203 additions and 73 deletions

View File

@ -79,7 +79,7 @@ The `small` and `large` attributes are now combined under the `size` attribute.
| Old Property | New Property | Property Behavior |
| --------------------------- | ------------ | --------------------------- |
| `small`, `large` | `size` | Sets the button size. |
| `small`, `large` | `size` | Sets the button size. |
| `clear`, `outline`, `solid` | `fill` | Sets the button fill style. |
| `full`, `block`             | `expand` | Sets the button width. |
@ -253,7 +253,7 @@ Buttons inside of an `<ion-fab>` container should now be written as an `<ion-fab
**New Usage Example:**
```html
<ion-fab top right edge>
<ion-fab vertical="top" horizontal="right" edge>
<ion-fab-button>
<ion-icon name="add"></ion-icon>
</ion-fab-button>
@ -274,9 +274,52 @@ Buttons inside of an `<ion-fab>` container should now be written as an `<ion-fab
</ion-fab>
```
### Attributes Renamed
The mutually exclusive boolean attributes to position the fab have been combined into two single string attributes.
The attributes to align the fab horizontally are now combined under the `horizontal` attribute and the attributes to align the fab vertically are now combined under the `vertical` attribute:
| Old Property | New Property | Property Behavior |
|--------------|----------------------|-------------------------------------------------------------------------|
| left | `horizontal="left"` | Positions to the left of the viewport. |
| right | `horizontal="right"` | Positions to the right of the viewport. |
| center | `horizontal="center"`| Positions to the center of the viewport. |
| start | `horizontal="start"` | Positions to the left of the viewport in LTR, and to the right in RTL. |
| end | `horizontal="end"` | Positions to the right of the viewport in LTR, and to the left in RTL. |
| top | `vertical="top"` | Positions at the top of the viewport. |
| bottom | `vertical="bottom"` | Positions at the bottom of the viewport. |
| middle | `vertical="center"` | Positions at the center of the viewport. |
_Note that `middle` has been changed to `center` for the vertical positioning._
**Old Usage Example:**
```html
<ion-fab top right edge>
<!-- fab buttons and lists -->
</ion-fab>
<ion-fab center middle>
<!-- fab buttons and lists -->
</ion-fab>
```
**New Usage Example:**
```html
<ion-fab vertical="top" horizontal="right" edge>
<!-- fab buttons and lists -->
</ion-fab>
<ion-fab vertical="center" horizontal="center">
<!-- fab buttons and lists -->
</ion-fab>
```
### Fixed Content
The `<ion-fab>` container was previously placed inside of the fixed content by default. Now, any fixed content should go inside of the `<ion-fixed>` container.
The `<ion-fab>` container was previously placed inside of the fixed content by default. Now, any fixed content should use the `fixed` slot.
**Old Usage Example:**
@ -292,11 +335,9 @@ The `<ion-fab>` container was previously placed inside of the fixed content by d
**New Usage Example:**
```html
<ion-fixed>
<ion-fab top right edge>
<!-- fab buttons and lists -->
</ion-fab>
</ion-fixed>
<ion-fab vertical="top" horizontal="right" edge slot="fixed">
<!-- fab buttons and lists -->
</ion-fab>
<ion-content>
Scrollable Content
</ion-content>

View File

@ -937,7 +937,9 @@ declare global {
}
namespace JSXElements {
export interface IonFabAttributes extends HTMLAttributes {
edge?: boolean;
horizontal?: 'left' | 'right' | 'center' | 'start' | 'end';
vertical?: 'top' | 'center' | 'bottom';
}
}
}

View File

@ -6,66 +6,69 @@
ion-fab {
position: absolute;
z-index: $z-index-fixed-content;
}
&[center] {
@include position(null, null, null, 50%);
@include margin-horizontal(-$fab-size / 2, null);
// FAB Horizontal Positioning
// --------------------------------------------------
.fab-horizontal-left {
// scss-lint:disable PropertySpelling
@include multi-dir() {
left: $fab-content-margin;
left: calc(#{$fab-content-margin} + constant(safe-area-inset-left));
left: calc(#{$fab-content-margin} + env(safe-area-inset-left));
}
}
&[middle] {
@include margin(-$fab-size / 2, null, null, null);
.fab-horizontal-right {
// scss-lint:disable PropertySpelling
@include multi-dir() {
right: $fab-content-margin;
top: 50%;
right: calc(#{$fab-content-margin} + constant(safe-area-inset-right));
right: calc(#{$fab-content-margin} + env(safe-area-inset-right));
}
}
&[top] {
top: $fab-content-margin;
}
.fab-horizontal-center {
@include position(null, null, null, 50%);
@include margin-horizontal(-$fab-size / 2, null);
}
&[right] {
// scss-lint:disable PropertySpelling
@include multi-dir() {
right: $fab-content-margin;
}
.fab-horizontal-start {
@include position-horizontal($fab-content-margin, null);
@include safe-position-horizontal($fab-content-margin, null);
}
@include multi-dir() {
right: calc(#{$fab-content-margin} + constant(safe-area-inset-right));
right: calc(#{$fab-content-margin} + env(safe-area-inset-right));
}
}
&[end] {
@include position-horizontal(null, $fab-content-margin);
@include safe-position-horizontal(null, $fab-content-margin);
}
&[bottom] {
bottom: $fab-content-margin;
}
&[left] {
// scss-lint:disable PropertySpelling
@include multi-dir() {
left: $fab-content-margin;
}
.fab-horizontal-end {
@include position-horizontal(null, $fab-content-margin);
@include safe-position-horizontal(null, $fab-content-margin);
}
@include multi-dir() {
left: calc(#{$fab-content-margin} + constant(safe-area-inset-left));
left: calc(#{$fab-content-margin} + env(safe-area-inset-left));
}
}
// FAB Vertical Positioning
// --------------------------------------------------
&[start] {
@include position-horizontal($fab-content-margin, null);
@include safe-position-horizontal($fab-content-margin, null);
}
.fab-vertical-top {
top: $fab-content-margin;
&[top][edge] {
&.fab-edge {
top: -$fab-size / 2;
}
}
&[bottom][edge] {
.fab-vertical-bottom {
bottom: $fab-content-margin;
&.fab-edge {
bottom: -$fab-size / 2;
}
}
.fab-vertical-center {
@include margin(-$fab-size / 2, null, null, null);
top: 50%;
}

View File

@ -1,4 +1,4 @@
import { Component, Element, Method, State } from '@stencil/core';
import { Component, Element, Method, Prop, State } from '@stencil/core';
@Component({
@ -10,6 +10,26 @@ export class Fab {
@State() activated = false;
/**
* Where to align the fab horizontally in the viewport.
* Possible values are: `"left"`, `"right"`, `"center"`, `"start"`, `"end"`.
*/
@Prop() horizontal: 'left' | 'right' | 'center' | 'start' | 'end';
/**
* Where to align the fab vertically in the viewport.
* Possible values are: `"top"`, `"center"`, `"bottom"`.
*/
@Prop() vertical: 'top' | 'center' | 'bottom';
/**
* If true, the fab will display on the edge of the header if
* `vertical` is `"top"`, and on the edge of the footer if
* it is `"bottom"`. Should be used with a `fixed` slot.
*/
@Prop() edge: boolean;
/**
* Close an active FAB list container
*/
@ -22,6 +42,16 @@ export class Fab {
this.activated = !this.activated;
}
hostData() {
return {
class: {
[`fab-horizontal-${this.horizontal}`]: this.horizontal,
[`fab-vertical-${this.vertical}`]: this.vertical,
['fab-edge']: this.edge
}
};
}
render() {
const fab = this.el.querySelector('ion-fab-button');
if (fab) {

View File

@ -98,6 +98,60 @@ The fab should have one main fab button. Fabs can also contain fab lists which c
<!-- Auto Generated Below -->
## Properties
#### edge
boolean
If true, the fab will display on the edge of the header if
`vertical` is `"top"`, and on the edge of the footer if
it is `"bottom"`. Should be used with a `fixed` slot.
#### horizontal
Where to align the fab horizontally in the viewport.
Possible values are: `"left"`, `"right"`, `"center"`, `"start"`, `"end"`.
#### vertical
Where to align the fab vertically in the viewport.
Possible values are: `"top"`, `"center"`, `"bottom"`.
## Attributes
#### edge
boolean
If true, the fab will display on the edge of the header if
`vertical` is `"top"`, and on the edge of the footer if
it is `"bottom"`. Should be used with a `fixed` slot.
#### horizontal
Where to align the fab horizontally in the viewport.
Possible values are: `"left"`, `"right"`, `"center"`, `"start"`, `"end"`.
#### vertical
Where to align the fab vertically in the viewport.
Possible values are: `"top"`, `"center"`, `"bottom"`.
## Methods
#### close()

View File

@ -23,7 +23,7 @@
<ion-button>Test</ion-button>
<ion-fab-button>FAB</ion-fab-button>
<ion-fab top right edge id="fab1" slot="fixed">
<ion-fab vertical="top" horizontal="right" edge id="fab1" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab1')" mini class="e2eFabTopRight"><ion-icon name="add"></ion-icon></ion-fab-button>
<ion-fab-list>
<ion-fab-button onclick="openSocial('facebook', 'fab1')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -33,7 +33,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom right edge id="fab2" slot="fixed">
<ion-fab vertical="bottom" horizontal="right" edge id="fab2" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab2')" color="dark" class="e2eFabBottomRight"><ion-icon name="arrow-dropleft"></ion-icon></ion-fab-button>
<ion-fab-list side="left">
<ion-fab-button onclick="openSocial('facebook', 'fab2')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -43,7 +43,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab top left id="fab3" slot="fixed">
<ion-fab vertical="top" horizontal="left" id="fab3" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab3')" color="secondary" class="e2eFabTopLeft"><ion-icon name="arrow-dropright"></ion-icon></ion-fab-button>
<ion-fab-list side="right">
<ion-fab-button onclick="openSocial('facebook', 'fab3')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -53,7 +53,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom left id="fab4" slot="fixed">
<ion-fab vertical="bottom" horizontal="left" id="fab4" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab4')" color="light" class="e2eFabBottomLeft"><ion-icon name="arrow-dropup"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('facebook', 'fab4')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -63,7 +63,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab center middle id="fab5" slot="fixed">
<ion-fab vertical="center" horizontal="center" id="fab5" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab5')" class="e2eFabCenter"><ion-icon name="md-share"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('vimeo', 'fab5')" color="primary"><ion-icon name="logo-vimeo"></ion-icon></ion-fab-button>
@ -79,7 +79,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab right middle slot="fixed">
<ion-fab horizontal="right" vertical="center" slot="fixed">
<ion-fab-button color="danger" onclick="add()"><ion-icon name="add"></ion-icon></ion-fab-button>
</ion-fab>
</ion-content>

View File

@ -13,7 +13,7 @@
<f></f>
<ion-fab-button>FAB</ion-fab-button>
<ion-fab top right id="fab1" slot="fixed">
<ion-fab vertical="top" horizontal="right" id="fab1" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab1')" mini class="e2eFabTopRight"><ion-icon name="add"></ion-icon></ion-fab-button>
<ion-fab-list>
<ion-fab-button onclick="openSocial('facebook', 'fab1')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -23,7 +23,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom right id="fab2" slot="fixed">
<ion-fab vertical="bottom" horizontal="right" id="fab2" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab2')" color="dark" class="e2eFabBottomRight"><ion-icon name="arrow-dropleft"></ion-icon></ion-fab-button>
<ion-fab-list side="left">
<ion-fab-button onclick="openSocial('facebook', 'fab2')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -33,7 +33,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab top left id="fab3" slot="fixed">
<ion-fab vertical="top" horizontal="left" id="fab3" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab3')" color="secondary" class="e2eFabTopLeft"><ion-icon name="arrow-dropright"></ion-icon></ion-fab-button>
<ion-fab-list side="right">
<ion-fab-button onclick="openSocial('facebook', 'fab3')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -43,7 +43,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom left id="fab4" slot="fixed">
<ion-fab vertical="bottom" horizontal="left" id="fab4" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab4')" color="light" class="e2eFabBottomLeft"><ion-icon name="arrow-dropup"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('facebook', 'fab4')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -53,7 +53,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab center middle id="fab5" slot="fixed">
<ion-fab vertical="center" horizontal="center" id="fab5" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab5')" class="e2eFabCenter"><ion-icon name="md-share"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('vimeo', 'fab5')" color="primary"><ion-icon name="logo-vimeo"></ion-icon></ion-fab-button>
@ -69,7 +69,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab right middle slot="fixed">
<ion-fab horizontal="right" vertical="center" slot="fixed">
<ion-fab-button color="danger" onclick="add()"><ion-icon name="add"></ion-icon></ion-fab-button>
</ion-fab>

View File

@ -32,7 +32,7 @@
<pre id="log" style="right:10px; bottom:50px; text-shadow: 0 0 2px rgba(0, 0, 0, 0.24);" slot="fixed">log</pre>
<ion-button>Test</ion-button>
<ion-fab top right edge id="fab1" slot="fixed">
<ion-fab vertical="top" horizontal="right" edge id="fab1" slot="fixed">
<ion-fab-button translucent onclick="clickMainFAB('fab1')" mini class="e2eFabTopRight"><ion-icon name="add"></ion-icon></ion-fab-button>
<ion-fab-list>
<ion-fab-button translucent onclick="openSocial('facebook', 'fab1')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -42,7 +42,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom right edge id="fab2" slot="fixed">
<ion-fab vertical="bottom" horizontal="right" edge id="fab2" slot="fixed">
<ion-fab-button translucent onclick="clickMainFAB('fab2')" color="dark" class="e2eFabBottomRight"><ion-icon name="arrow-dropleft"></ion-icon></ion-fab-button>
<ion-fab-list side="left">
<ion-fab-button translucent onclick="openSocial('facebook', 'fab2')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -52,7 +52,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab top left id="fab3" slot="fixed">
<ion-fab vertical="top" horizontal="left" id="fab3" slot="fixed">
<ion-fab-button translucent onclick="clickMainFAB('fab3')" color="secondary" class="e2eFabTopLeft"><ion-icon name="arrow-dropright"></ion-icon></ion-fab-button>
<ion-fab-list side="right">
<ion-fab-button translucent onclick="openSocial('facebook', 'fab3')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -62,7 +62,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab bottom left id="fab4" slot="fixed">
<ion-fab vertical="bottom" horizontal="left" id="fab4" slot="fixed">
<ion-fab-button translucent onclick="clickMainFAB('fab4')" color="light" class="e2eFabBottomLeft"><ion-icon name="arrow-dropup"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button translucent onclick="openSocial('facebook', 'fab4')"><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
@ -72,7 +72,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab center middle id="fab5" slot="fixed">
<ion-fab horizontal="center" vertical="center" id="fab5" slot="fixed">
<ion-fab-button translucent onclick="clickMainFAB('fab5')" class="e2eFabCenter"><ion-icon name="md-share"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button translucent onclick="openSocial('vimeo', 'fab5')" color="primary"><ion-icon name="logo-vimeo"></ion-icon></ion-fab-button>
@ -88,7 +88,7 @@
</ion-fab-list>
</ion-fab>
<ion-fab right middle slot="fixed">
<ion-fab horizontal="right" vertical="center" slot="fixed">
<ion-fab-button translucent color="danger" onclick="add()"><ion-icon name="add"></ion-icon></ion-fab-button>
</ion-fab>
</ion-content>