[UI] Several improvements to the FloatingButton component.

- Added support for multiple element classes.

- Added `glow` property.

- Added support for absolute initial positioning.

- Added dynamic button size.

- Added FloatingButtons component to support groups of floating buttons.
This commit is contained in:
Fabio Manganiello 2024-09-05 01:31:32 +02:00
parent e17abc34c1
commit 485a1db3d3
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
2 changed files with 128 additions and 9 deletions

View file

@ -1,7 +1,8 @@
<template>
<div class="floating-btn" :class="className">
<div class="floating-btn" :class="classes">
<button type="button"
class="btn btn-primary"
:class="glow ? 'with-glow' : ''"
:disabled="disabled"
:title="title"
@click="$emit('click', $event)">
@ -14,7 +15,6 @@
import Icon from "@/components/elements/Icon";
export default {
name: "FloatingButton",
components: {Icon},
emits: ["click"],
@ -35,11 +35,49 @@ export default {
title: {
type: String,
},
left: {
type: Boolean,
default: false,
},
right: {
type: Boolean,
default: true,
},
top: {
type: Boolean,
default: false,
},
bottom: {
type: Boolean,
default: true,
},
glow: {
type: Boolean,
default: false,
},
},
computed: {
className() {
return this.class
classes() {
const classes = {}
if (this.left) {
classes.left = true
} else {
classes.right = true
}
if (this.top) {
classes.top = true
} else {
classes.bottom = true
}
if (this.class?.length) {
classes[this.class] = true
}
return classes
}
}
}
@ -48,15 +86,32 @@ export default {
<style lang="scss" scoped>
.floating-btn {
position: absolute;
bottom: 0;
&.left {
left: 0;
margin-left: 1em;
}
&.right {
right: 0;
margin: auto 1em 1em auto;
margin-right: 1em;
}
&.top {
top: 0;
margin-top: 1em;
}
&.bottom {
bottom: 0;
margin-bottom: 1em;
}
button {
background: $tile-bg !important;
color: $tile-fg !important;
width: 4em;
height: 4em;
width: $floating-btn-size;
height: $floating-btn-size;
border-radius: 2em;
border: none !important;
padding: 0;
@ -72,6 +127,20 @@ export default {
color: $disabled-fg !important;
cursor: not-allowed;
}
&.with-glow {
&:not(:disabled) {
@extend .glow;
background: $default-bg-3 !important;
color: $ok-fg !important;
box-shadow: 0 0 1px 1px $selected-fg !important;
&:hover {
box-shadow: 0 0 1px 1px $active-glow-bg-2 !important;
color: $play-btn-fg !important;
}
}
}
}
:deep(button) {

View file

@ -0,0 +1,50 @@
<template>
<div class="floating-btns" :class="{direction: direction}">
<slot />
</div>
</template>
<script>
export default {
emits: ["click"],
props: {
direction: {
type: String,
default: "row",
},
size: {
type: String,
default: "4em",
},
},
computed: {
buttons() {
return this.$el.querySelectorAll(".floating-btn")
},
},
mounted() {
const buttons = Array.from(this.buttons)
let offset = 0
buttons.forEach((button, index) => {
const size = button.offsetWidth
const styleOffset = `calc(${offset}px + (${index} * 1em))`
if (this.direction === "row") {
if (!parseFloat(getComputedStyle(button).left))
button.style.left = styleOffset
else
button.style.right = styleOffset
} else {
if (!parseFloat(getComputedStyle(button).top))
button.style.top = styleOffset
else
button.style.bottom = styleOffset
}
offset += size
})
},
}
</script>