forked from platypush/platypush
[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:
parent
e17abc34c1
commit
485a1db3d3
2 changed files with 128 additions and 9 deletions
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="floating-btn" :class="className">
|
<div class="floating-btn" :class="classes">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
|
:class="glow ? 'with-glow' : ''"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:title="title"
|
:title="title"
|
||||||
@click="$emit('click', $event)">
|
@click="$emit('click', $event)">
|
||||||
|
@ -14,7 +15,6 @@
|
||||||
import Icon from "@/components/elements/Icon";
|
import Icon from "@/components/elements/Icon";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FloatingButton",
|
|
||||||
components: {Icon},
|
components: {Icon},
|
||||||
emits: ["click"],
|
emits: ["click"],
|
||||||
|
|
||||||
|
@ -35,11 +35,49 @@ export default {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
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: {
|
computed: {
|
||||||
className() {
|
classes() {
|
||||||
return this.class
|
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>
|
<style lang="scss" scoped>
|
||||||
.floating-btn {
|
.floating-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
&.left {
|
||||||
margin: auto 1em 1em auto;
|
left: 0;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
right: 0;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.top {
|
||||||
|
top: 0;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bottom {
|
||||||
|
bottom: 0;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background: $tile-bg !important;
|
background: $tile-bg !important;
|
||||||
color: $tile-fg !important;
|
color: $tile-fg !important;
|
||||||
width: 4em;
|
width: $floating-btn-size;
|
||||||
height: 4em;
|
height: $floating-btn-size;
|
||||||
border-radius: 2em;
|
border-radius: 2em;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -72,6 +127,20 @@ export default {
|
||||||
color: $disabled-fg !important;
|
color: $disabled-fg !important;
|
||||||
cursor: not-allowed;
|
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) {
|
:deep(button) {
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue