diff --git a/nymea-app/styles.qrc b/nymea-app/styles.qrc
index f45da24f..347c12f5 100644
--- a/nymea-app/styles.qrc
+++ b/nymea-app/styles.qrc
@@ -6,5 +6,7 @@
styles/dark/ApplicationWindow.qml
styles/dark/Page.qml
styles/dark/logo.svg
+ styles/dark/Button.qml
+ styles/light/Button.qml
diff --git a/nymea-app/styles/dark/ApplicationWindow.qml b/nymea-app/styles/dark/ApplicationWindow.qml
index 3654910b..6ace480d 100644
--- a/nymea-app/styles/dark/ApplicationWindow.qml
+++ b/nymea-app/styles/dark/ApplicationWindow.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.0
+import QtQuick 2.9
import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
diff --git a/nymea-app/styles/dark/Button.qml b/nymea-app/styles/dark/Button.qml
new file mode 100644
index 00000000..d52ac7b7
--- /dev/null
+++ b/nymea-app/styles/dark/Button.qml
@@ -0,0 +1,75 @@
+import QtQuick 2.9
+import QtQuick.Templates 2.2 as T
+import QtQuick.Controls.Material 2.2
+import QtQuick.Controls.Material.impl 2.2
+
+T.Button {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem.implicitWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ contentItem.implicitHeight + topPadding + bottomPadding)
+ baselineOffset: contentItem.y + contentItem.baselineOffset
+
+ // external vertical padding is 6 (to increase touch area)
+ padding: 12
+ leftPadding: padding - 4
+ rightPadding: padding - 4
+
+ Material.elevation: flat ? control.down || control.hovered ? 2 : 0
+ : control.down ? 8 : 2
+ Material.background: flat ? "transparent" : undefined
+
+ contentItem: Text {
+ text: control.text
+ font: control.font
+ color: app.primaryColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state
+ background: Rectangle {
+ implicitWidth: 64
+ implicitHeight: 40
+
+ // external vertical padding is 6 (to increase touch area)
+ y: 6
+ width: parent.width
+ height: parent.height - 12
+ radius: height / 2
+ color: !control.enabled ? control.Material.buttonDisabledColor :
+ control.highlighted ? control.Material.highlightedButtonColor : control.Material.accentColor
+
+ PaddedRectangle {
+ y: parent.height - 4
+ width: parent.width
+ height: 4
+ radius: 2
+ topPadding: -2
+ clip: true
+ visible: control.checkable && (!control.highlighted || control.flat)
+ color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor
+ }
+
+ // The layer is disabled when the button color is transparent so you can do
+ // Material.background: "transparent" and get a proper flat button without needing
+ // to set Material.elevation as well
+ layer.enabled: control.enabled && control.Material.buttonColor.a > 0
+ layer.effect: ElevationEffect {
+ elevation: control.Material.elevation
+ }
+
+ Ripple {
+ clipRadius: 2
+ width: parent.width
+ height: parent.height
+ pressed: control.pressed
+ anchor: control
+ active: control.down || control.visualFocus || control.hovered
+ color: control.Material.rippleColor
+ }
+ }
+}
diff --git a/nymea-app/styles/light/Button.qml b/nymea-app/styles/light/Button.qml
new file mode 100644
index 00000000..d52ac7b7
--- /dev/null
+++ b/nymea-app/styles/light/Button.qml
@@ -0,0 +1,75 @@
+import QtQuick 2.9
+import QtQuick.Templates 2.2 as T
+import QtQuick.Controls.Material 2.2
+import QtQuick.Controls.Material.impl 2.2
+
+T.Button {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem.implicitWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ contentItem.implicitHeight + topPadding + bottomPadding)
+ baselineOffset: contentItem.y + contentItem.baselineOffset
+
+ // external vertical padding is 6 (to increase touch area)
+ padding: 12
+ leftPadding: padding - 4
+ rightPadding: padding - 4
+
+ Material.elevation: flat ? control.down || control.hovered ? 2 : 0
+ : control.down ? 8 : 2
+ Material.background: flat ? "transparent" : undefined
+
+ contentItem: Text {
+ text: control.text
+ font: control.font
+ color: app.primaryColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state
+ background: Rectangle {
+ implicitWidth: 64
+ implicitHeight: 40
+
+ // external vertical padding is 6 (to increase touch area)
+ y: 6
+ width: parent.width
+ height: parent.height - 12
+ radius: height / 2
+ color: !control.enabled ? control.Material.buttonDisabledColor :
+ control.highlighted ? control.Material.highlightedButtonColor : control.Material.accentColor
+
+ PaddedRectangle {
+ y: parent.height - 4
+ width: parent.width
+ height: 4
+ radius: 2
+ topPadding: -2
+ clip: true
+ visible: control.checkable && (!control.highlighted || control.flat)
+ color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor
+ }
+
+ // The layer is disabled when the button color is transparent so you can do
+ // Material.background: "transparent" and get a proper flat button without needing
+ // to set Material.elevation as well
+ layer.enabled: control.enabled && control.Material.buttonColor.a > 0
+ layer.effect: ElevationEffect {
+ elevation: control.Material.elevation
+ }
+
+ Ripple {
+ clipRadius: 2
+ width: parent.width
+ height: parent.height
+ pressed: control.pressed
+ anchor: control
+ active: control.down || control.visualFocus || control.hovered
+ color: control.Material.rippleColor
+ }
+ }
+}