From bfa3eeadc6a8528922f994ff104e913de69cba34 Mon Sep 17 00:00:00 2001 From: mkpaz Date: Thu, 29 Sep 2022 13:03:13 +0400 Subject: [PATCH] Improve button style - Use opacity for hover effect - Add color transition for focused effect - Add separate hover effect for SplitMenuButton arrow - Add button color customization example --- .../sampler/page/components/ButtonPage.java | 33 +++++++++++- styles/src/components/_button.scss | 54 ++++++++++--------- styles/src/components/_menu-button.scss | 37 ++++++++++++- styles/src/nord-dark.scss | 2 +- styles/src/settings/_color-vars.scss | 2 + 5 files changed, 99 insertions(+), 29 deletions(-) diff --git a/sampler/src/main/java/atlantafx/sampler/page/components/ButtonPage.java b/sampler/src/main/java/atlantafx/sampler/page/components/ButtonPage.java index 76dbb8b..af837ad 100755 --- a/sampler/src/main/java/atlantafx/sampler/page/components/ButtonPage.java +++ b/sampler/src/main/java/atlantafx/sampler/page/components/ButtonPage.java @@ -4,6 +4,7 @@ package atlantafx.sampler.page.components; import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.Page; import atlantafx.sampler.page.SampleBlock; +import atlantafx.sampler.theme.CSSFragment; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.ContentDisplay; @@ -12,6 +13,7 @@ import javafx.scene.layout.HBox; import javafx.scene.shape.Circle; import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.javafx.FontIcon; +import org.kordamp.ikonli.material2.Material2AL; import static atlantafx.base.theme.Styles.*; import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP; @@ -45,7 +47,9 @@ public class ButtonPage extends AbstractPage { grid.add(sizeSample(), 1, 2); grid.add(roundedSample(), 0, 3); - grid.add(disabledSample(), 1, 3); + grid.add(customColorSample(), 1, 3); + + grid.add(disabledSample(), 0, 4); setUserContent(grid); } @@ -198,6 +202,33 @@ public class ButtonPage extends AbstractPage { return new SampleBlock("Size", content); } + private SampleBlock customColorSample() { + var btn = new Button("DO SOMETHING!"); + btn.getStyleClass().addAll(SUCCESS, LARGE); + btn.setStyle(""" + -color-button-bg: linear-gradient(to bottom right, -color-success-emphasis, darkblue); + -color-button-bg-hover: -color-button-bg; + -color-button-bg-focused: -color-button-bg; + -color-button-bg-pressed: -color-button-bg; + """); + + var iconBtn = new Button("", new FontIcon(Material2AL.FAVORITE)); + iconBtn.getStyleClass().addAll("favorite-button", BUTTON_CIRCLE, FLAT, DANGER); + new CSSFragment(""" + .favorite-button.button >.ikonli-font-icon { + -fx-fill: linear-gradient(to bottom right, pink, -color-danger-emphasis); + -fx-icon-color: linear-gradient(to bottom right, pink, -color-danger-emphasis); + -fx-font-size: 32px; + -fx-icon-size: 32px; + } + """).addTo(iconBtn); + + var content = new HBox(BLOCK_HGAP, btn, iconBtn); + content.setAlignment(Pos.CENTER_LEFT); + + return new SampleBlock("Custom Color", content); + } + private SampleBlock disabledSample() { var basicBtn = new Button("Basic"); basicBtn.setDisable(true); diff --git a/styles/src/components/_button.scss b/styles/src/components/_button.scss index 9b3eb00..5b67161 100755 --- a/styles/src/components/_button.scss +++ b/styles/src/components/_button.scss @@ -10,67 +10,67 @@ $color-fg: -color-fg-default !default; $color-border: -color-border-default !default; $color-bg-hover: if(cfg.$darkMode, -color-base-6, -color-base-1) !default; -$color-fg-hover: -color-button-fg !default; +$color-fg-hover: -color-button-fg !default; $color-border-hover: -color-button-border !default; -$color-bg-focused: -color-button-bg !default; -$color-fg-focused: -color-button-fg !default; +$color-bg-focused: -color-button-bg !default; +$color-fg-focused: -color-button-fg !default; $color-border-focused: -color-accent-emphasis !default; -$color-bg-pressed: if(cfg.$darkMode, -color-base-7, -color-base-2) !default; +$color-bg-pressed: -color-bg-subtle !default; $color-fg-pressed: -color-button-fg !default; -$color-border-pressed: transparent !default; +$color-border-pressed: transparent !default; // accent $color-accent-bg: -color-accent-emphasis !default; $color-accent-fg: -color-fg-emphasis !default; $color-accent-border: -color-accent-emphasis !default; -$color-accent-bg-hover: -color-accent-6 !default; +$color-accent-bg-hover: -color-accent-emphasis !default; $color-accent-fg-hover: -color-fg-emphasis !default; $color-accent-border-hover: -color-accent-emphasis !default; -$color-accent-bg-focused: -color-accent-emphasis !default; +$color-accent-bg-focused: -color-accent-6 !default; $color-accent-fg-focused: -color-fg-emphasis !default; $color-accent-border-focused: -color-accent-emphasis !default; -$color-accent-bg-pressed: -color-accent-6 !default; -$color-accent-fg-pressed: -color-fg-emphasis !default; -$color-accent-border-pressed: transparent !default; +$color-accent-bg-pressed: -color-accent-emphasis !default; +$color-accent-fg-pressed: -color-fg-emphasis !default; +$color-accent-border-pressed: transparent !default; // success $color-success-bg: -color-success-emphasis !default; $color-success-fg: -color-fg-emphasis !default; $color-success-border: -color-success-emphasis !default; -$color-success-bg-hover: if(cfg.$darkMode, -color-success-6, -color-success-5) !default; +$color-success-bg-hover: -color-success-emphasis !default; $color-success-fg-hover: -color-fg-emphasis !default; $color-success-border-hover: -color-success-emphasis !default; -$color-success-bg-focused: -color-success-emphasis !default; +$color-success-bg-focused: if(cfg.$darkMode, -color-success-6, -color-success-5) !default; $color-success-fg-focused: -color-fg-emphasis !default; $color-success-border-focused: -color-success-emphasis !default; -$color-success-bg-pressed: if(cfg.$darkMode, -color-success-6, -color-success-5) !default; -$color-success-fg-pressed: -color-fg-emphasis !default; -$color-success-border-pressed: transparent !default; +$color-success-bg-pressed: -color-success-emphasis !default; +$color-success-fg-pressed: -color-fg-emphasis !default; +$color-success-border-pressed: transparent !default; // danger $color-danger-bg: -color-danger-emphasis !default; $color-danger-fg: -color-fg-emphasis !default; $color-danger-border: -color-danger-emphasis !default; -$color-danger-bg-hover: -color-danger-6 !default; +$color-danger-bg-hover: -color-danger-emphasis !default; $color-danger-fg-hover: -color-fg-emphasis !default; $color-danger-border-hover: -color-danger-emphasis !default; -$color-danger-bg-focused: -color-danger-emphasis !default; +$color-danger-bg-focused: -color-danger-6 !default; $color-danger-fg-focused: -color-fg-emphasis !default; $color-danger-border-focused: -color-danger-emphasis !default; -$color-danger-bg-pressed: -color-danger-6 !default; -$color-danger-fg-pressed: -color-fg-emphasis !default; -$color-danger-border-pressed: transparent !default; +$color-danger-bg-pressed: -color-danger-emphasis !default; +$color-danger-fg-pressed: -color-fg-emphasis !default; +$color-danger-border-pressed: transparent !default; // flat $color-flat-fg: -color-fg-default !default; @@ -86,15 +86,18 @@ $color-flat-danger-fg: -color-danger-fg !default; $color-flat-danger-bg-hover: -color-danger-subtle !default; // outlined -$color-accent-outlined-fg: -color-accent-fg !default; +$color-accent-outlined-fg: -color-accent-fg !default; $color-accent-outlined-bg-hover: $color-accent-bg-hover !default; -$color-success-outlined-fg: -color-success-fg !default; +$color-success-outlined-fg: -color-success-fg !default; $color-success-outlined-bg-hover: $color-success-bg-hover !default; -$color-danger-outlined-fg: -color-danger-fg !default; +$color-danger-outlined-fg: -color-danger-fg !default; $color-danger-outlined-bg-hover: $color-danger-bg-hover !default; +// opacity level for hover effect +$opacity-hover: 0.9 !default; + // basic style is shared with Button, ToggleButton and MenuButton @mixin base() { @@ -295,11 +298,11 @@ $color-danger-outlined-bg-hover: $color-danger-bg-hover !default; -color-button-bg-hover: $color-flat-bg-hover; -color-button-fg-hover: -color-button-fg; - -color-button-border-hover: transparent; + -color-button-border-hover: $color-flat-bg-hover; -color-button-bg-focused: -color-button-bg; -color-button-fg-focused: -color-button-fg; - -color-button-border-focused: transparent; + -color-button-border-focused: -color-button-bg; -color-button-bg-pressed: -color-button-bg; -color-button-fg-pressed: -color-button-fg; @@ -314,6 +317,7 @@ $color-danger-outlined-bg-hover: $color-danger-bg-hover !default; &:hover { -fx-background-color: -color-button-border-hover, -color-button-bg-hover; -fx-text-fill: -color-button-fg-hover; + -fx-opacity: $opacity-hover; &:focused { -fx-background-color: -color-button-border-focused, -color-button-bg-hover; diff --git a/styles/src/components/_menu-button.scss b/styles/src/components/_menu-button.scss index 35bf9c6..45f41c9 100644 --- a/styles/src/components/_menu-button.scss +++ b/styles/src/components/_menu-button.scss @@ -53,13 +53,16 @@ $separator-width: 0.75px !default; &:hover { -fx-background-color: -color-button-border-hover, -color-button-bg-hover; + -fx-opacity: button.$opacity-hover; >.label { -fx-text-fill: -color-button-fg-hover; } - >.arrow-button>.arrow { - -fx-background-color: -color-button-fg-hover; + >.arrow-button { + >.arrow { + -fx-background-color: -color-button-fg-hover; + } } #{cfg.$font-icon-selector} { @@ -122,6 +125,7 @@ $separator-width: 0.75px !default; } .menu-button { + // #tweak/no-arrow &.no-arrow { >.arrow-button { @@ -142,6 +146,35 @@ $separator-width: 0.75px !default; -fx-padding: cfg.$padding-y calc(cfg.$padding-x / 2) cfg.$padding-y cfg.$padding-x; } + &:hover, + &:focused:hover { + >.arrow-button { + -fx-background-color: -color-neutral-emphasis-plus; + -fx-background-insets: cfg.$border-width; + -fx-background-radius: cfg.$border-radius; + -fx-border-color: transparent; + -fx-opacity: 0.75; + + >.arrow { + -fx-background-color: -color-fg-emphasis; + -fx-opacity: 1.0; + } + } + } + + &:default:hover, + &.accent:hover, + &.success:hover, + &.danger:hover { + >.arrow-button { + -fx-background-color: -color-fg-emphasis; + + >.arrow { + -fx-background-color: -color-button-bg-hover; + } + } + } + &.button-outlined:hover, &.button-outlined:focused { >.arrow-button { diff --git a/styles/src/nord-dark.scss b/styles/src/nord-dark.scss index d2c01de..b712220 100755 --- a/styles/src/nord-dark.scss +++ b/styles/src/nord-dark.scss @@ -100,7 +100,7 @@ $nord16: #B48EAD; // hsl(311, 20.2, 63.1) $border-subtle: scale.$base-8, $shadow-default: scale.$dark, - $neutral-emphasisPlus: scale.$base-7, + $neutral-emphasisPlus: scale.$base-6, $neutral-emphasis: scale.$base-7, $neutral-muted: color.change(scale.$base-7, $alpha: 0.4), $neutral-subtle: color.change(scale.$base-7, $alpha: 0.2), diff --git a/styles/src/settings/_color-vars.scss b/styles/src/settings/_color-vars.scss index a7f2c7b..5e19bf4 100644 --- a/styles/src/settings/_color-vars.scss +++ b/styles/src/settings/_color-vars.scss @@ -18,6 +18,8 @@ $border-muted: lighten(scale.$base-2, 0.03) !default; $border-subtle: color.change(scale.$dark, $alpha: 0.15) !default; $shadow-default: scale.$base-2 !default; +// neutral is used by the .split-menu-button, +// note that you should maintain some contrast between neutral and canvas.subtle $neutral-emphasisPlus: scale.$base-9 !default; $neutral-emphasis: scale.$base-5 !default; $neutral-muted: color.change(scale.$base-3, $alpha: 0.2) !default;