Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fab-button): position is correct with custom sizes #28195

Merged
merged 8 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/components/fab-button/fab-button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
// --------------------------------------------------

:host(.fab-button-small) {
@include margin(($fab-size - $fab-small-size) * 0.5);
@include margin($fab-button-small-margin);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was always 8px, so I just made it its own variable

$fab-size: 56
$fab-small-size: 40

(56 - 40) * 0.5 = 16 * 0.5 = 8


width: #{$fab-small-size};
height: #{$fab-small-size};
Expand Down
2 changes: 2 additions & 0 deletions core/src/components/fab-button/fab-button.vars.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ $fab-small-size: 40px !default;

/// @prop - Border radius of the FAB button
$fab-border-radius: 50% !default;

$fab-button-small-margin: 8px !default;;
10 changes: 5 additions & 5 deletions core/src/components/fab-list/fab-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// --------------------------------------------------

:host {
@include margin($fab-size + $fab-list-margin, 0);
@include margin(calc(100% + #{$fab-list-margin}), 0);

display: none;
position: absolute;
Expand All @@ -13,8 +13,8 @@
flex-direction: column;
align-items: center;

min-width: $fab-size;
min-height: $fab-size;
min-width: $fab-small-size + ($fab-button-small-margin * 2);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These evaluate to the same value. However, the purpose of this is so the list is aligned with the parent FAB button. I decided to make this a bit more verbose so its clear where 56px is coming from. I originally thought that this was a bug since small FAB buttons can be 40px until I realized we were trying to account for the small FAB button margin too.

min-height: $fab-small-size + ($fab-button-small-margin * 2);
}

:host(.fab-list-active) {
Expand Down Expand Up @@ -59,14 +59,14 @@
}

:host(.fab-list-side-start) {
@include margin(0, $fab-size + $fab-list-margin);
@include margin(0, calc(100% + #{$fab-list-margin}));
@include position-horizontal(null, 0);

flex-direction: row-reverse;
}

:host(.fab-list-side-end) {
@include margin(0, $fab-size + $fab-list-margin);
@include margin(0, calc(100% + #{$fab-list-margin}));
@include position(null, null, null, 0);

flex-direction: row;
Expand Down
51 changes: 44 additions & 7 deletions core/src/components/fab/fab.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
@import "./fab.vars";
@import "../fab-list/fab-list.vars";

// Floating Action Button Container
// --------------------------------------------------

:host {
position: absolute;

width: fit-content;
height: fit-content;

z-index: $z-index-fixed-content;
}

Expand All @@ -14,8 +18,8 @@
// --------------------------------------------------

:host(.fab-horizontal-center) {
@include position(null, null, null, 50%);
@include margin-horizontal(-$fab-size * 0.5, null);
@include position(null, 0px, null, 0px);
@include margin(null, auto);
}

:host(.fab-horizontal-start) {
Expand All @@ -39,21 +43,54 @@
}

:host(.fab-vertical-top.fab-edge) {
top: -$fab-size * 0.5;
top: 0px;
}

:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button) {
margin-top: -50%;
}

:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button.fab-button-small) {
margin-top: calc((-100% + $fab-button-small-margin * 2) / 2);
}

:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-end) {
@include margin(-50%, null, null, null);
}

:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom) {
@include margin(calc(50% + #{$fab-list-margin}) null, null, null);
}

:host(.fab-vertical-bottom) {
bottom: $fab-content-margin;
}

:host(.fab-vertical-bottom.fab-edge) {
bottom: -$fab-size * 0.5;
bottom: 0;
}

:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button) {
margin-bottom: -50%;
}

:host(.fab-vertical-center) {
@include margin(-$fab-size * 0.5, null, null, null);
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button.fab-button-small) {
margin-bottom: calc((-100% + $fab-button-small-margin * 2) / 2);
}

:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-end) {
@include margin(null, null, -50%, null);
}

:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom) {
@include margin(null, null, calc(50% + #{$fab-list-margin}) null);
}

top: 50%;
:host(.fab-vertical-center) {
@include position(0px, null, 0px, null);
@include margin(auto, null);
}
181 changes: 181 additions & 0 deletions core/src/components/fab/test/testing/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Floating Action Button - Basic</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>

<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Floating Action Button - Basic</ion-title>
</ion-toolbar>
</ion-header>

<ion-content class="ion-padding" id="content" fullscreen>
<f></f>
<f></f>

<ion-button>Test</ion-button>
<ion-fab-button disabled href="#path" onclick="throw 'no clickable'">FAB</ion-fab-button>

<ion-fab vertical="top" horizontal="end" edge id="fab1" slot="fixed">
<ion-fab-button size="small" class="e2eFabTopRight">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-list>
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>

<ion-fab vertical="bottom" horizontal="start" edge id="fab2" slot="fixed">
<ion-fab-button color="dark" class="e2eFabBottomRight" disabled>
<ion-icon name="arrow-up-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="start">
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>

<ion-fab vertical="top" horizontal="start" id="fab3" slot="fixed">
<ion-fab-button color="secondary" class="e2eFabTopLeft">
<ion-icon name="arrow-forward-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="end">
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>

<ion-fab vertical="center" horizontal="center" id="fab5" slot="fixed">
<ion-fab-button class="e2eFabCenter">
<ion-icon name="share"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button color="primary">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button color="light">
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="bottom">
<ion-fab-button color="secondary">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button color="dark">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="start">
<ion-fab-button color="light">
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
<ion-fab-button color="primary">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="end">
<ion-fab-button color="dark">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button color="secondary">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>

<ion-fab horizontal="end" vertical="bottom" slot="fixed">
<ion-fab-button color="danger" onclick="add()">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>

<ion-footer>
<ion-toolbar>
<ion-buttons slot="secondary">
<ion-button onclick="closeLists()">Close</ion-button>
</ion-buttons>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>

<script>
function insertAfter(el, referenceNode) {
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}

function add() {
var newEle = document.createElement('f');
var ref = document.querySelector('f');
insertAfter(newEle, ref);
}

function closeLists() {
var fabs = document.querySelectorAll('ion-fab');

for (var i = 0; i < fabs.length; i++) {
fabs[i].activated = false;
}
}
</script>

<style>
f {
display: block;
margin: 15px auto;
max-width: 150px;
height: 150px;
background: blue;
}

f:last-of-type {
background: yellow;
}
</style>
</ion-app>
</body>
</html>