diff --git a/.screenshots/cupertino-dark.png b/.screenshots/cupertino-dark.png new file mode 100644 index 0000000..24358a9 Binary files /dev/null and b/.screenshots/cupertino-dark.png differ diff --git a/.screenshots/cupertino-light.png b/.screenshots/cupertino-light.png new file mode 100644 index 0000000..0b760e6 Binary files /dev/null and b/.screenshots/cupertino-light.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 53925d6..e04706b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## [Unreleased] +### Features + +- (CSS) 🚀 New MacOS-like Cupertino theme in light and dark variants. + +### Improvements + +- (CSS) `Button` shadow support (`-color-button-shadow`). Only for themes compiled with the `button.$use-shadow` flag enabled. + +### Bugfixes + +- (CSS) Added border radius/shadow to `ComboBox` popup menu to match other controls. + ## [1.2.0] - 2023-02-11 This is a bugfix/maintenance release that also contains a few style improvements. diff --git a/README.md b/README.md index ef1d605..d5cb2ff 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@

Modern JavaFX CSS theme collection with additional controls.

-
-See the docs for more info. -
+

+See the docs for more info. +

Logo
diff --git a/base/src/main/java/atlantafx/base/theme/CupertinoDark.java b/base/src/main/java/atlantafx/base/theme/CupertinoDark.java new file mode 100644 index 0000000..24d6306 --- /dev/null +++ b/base/src/main/java/atlantafx/base/theme/CupertinoDark.java @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT */ + +package atlantafx.base.theme; + +import atlantafx.base.Preview; + +@Preview +public class CupertinoDark implements Theme { + + public CupertinoDark() { + // Default constructor + } + + @Override + public String getName() { + return "Cupertino Dark"; + } + + @Override + public String getUserAgentStylesheet() { + return "/atlantafx/base/theme/cupertino-dark.css"; + } + + @Override + public boolean isDarkMode() { + return true; + } +} diff --git a/base/src/main/java/atlantafx/base/theme/CupertinoLight.java b/base/src/main/java/atlantafx/base/theme/CupertinoLight.java new file mode 100644 index 0000000..61bd699 --- /dev/null +++ b/base/src/main/java/atlantafx/base/theme/CupertinoLight.java @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT */ + +package atlantafx.base.theme; + +import atlantafx.base.Preview; + +@Preview +public class CupertinoLight implements Theme { + + public CupertinoLight() { + // Default constructor + } + + @Override + public String getName() { + return "Cupertino Light"; + } + + @Override + public String getUserAgentStylesheet() { + return "/atlantafx/base/theme/cupertino-light.css"; + } + + @Override + public boolean isDarkMode() { + return false; + } +} diff --git a/docs/docs/assets/images/cupertino-dark.png b/docs/docs/assets/images/cupertino-dark.png new file mode 100644 index 0000000..24358a9 Binary files /dev/null and b/docs/docs/assets/images/cupertino-dark.png differ diff --git a/docs/docs/assets/images/cupertino-light.png b/docs/docs/assets/images/cupertino-light.png new file mode 100644 index 0000000..0b760e6 Binary files /dev/null and b/docs/docs/assets/images/cupertino-light.png differ diff --git a/docs/docs/index.md b/docs/docs/index.md index 7dcec52..4fb3d5f 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -34,21 +34,31 @@ Or download the latest build on the [releases page](https://github.com/mkpaz/atl ## Themes

- ![Image title](assets/images/primer-light.png){ width="800" } + ![Primer Light](assets/images/primer-light.png){ width="800" }
Primer Light
- ![Image title](assets/images/primer-dark.png){ width="800" } + ![Primer Dark](assets/images/primer-dark.png){ width="800" }
Primer Dark
- ![Image title](assets/images/nord-light.png){ width="800" } + ![Nord Light](assets/images/nord-light.png){ width="800" }
Nord Light
- ![Image title](assets/images/nord-dark.png){ width="800" } + ![Nord Dark](assets/images/nord-dark.png){ width="800" }
Nord Dark
+ +
+ ![Cupertino Light](assets/images/cupertino-light.png){ width="800" } +
Cupertino Light
+
+ +
+ ![Cupertino Dark](assets/images/cupertino-dark.png){ width="800" } +
Cupertino Dark
+
\ No newline at end of file diff --git a/sampler/src/main/java/atlantafx/sampler/page/components/TablePage.java b/sampler/src/main/java/atlantafx/sampler/page/components/TablePage.java index 70d5944..cfda274 100644 --- a/sampler/src/main/java/atlantafx/sampler/page/components/TablePage.java +++ b/sampler/src/main/java/atlantafx/sampler/page/components/TablePage.java @@ -16,6 +16,7 @@ import static javafx.collections.FXCollections.observableArrayList; import atlantafx.base.controls.CaptionMenuItem; import atlantafx.base.controls.Spacer; import atlantafx.base.controls.ToggleSwitch; +import atlantafx.base.theme.Styles; import atlantafx.base.theme.Tweaks; import atlantafx.sampler.fake.domain.Product; import atlantafx.sampler.page.AbstractPage; @@ -133,7 +134,7 @@ public class TablePage extends AbstractPage { var alignGroup = new ToggleGroup(); var alignLeftBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_LEFT)); - alignLeftBtn.getStyleClass().add(".left-pill"); + alignLeftBtn.getStyleClass().add(Styles.LEFT_PILL); alignLeftBtn.setToggleGroup(alignGroup); alignLeftBtn.setSelected(true); alignLeftBtn.setOnAction(e -> { @@ -143,7 +144,7 @@ public class TablePage extends AbstractPage { }); var alignCenterBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_CENTER)); - alignCenterBtn.getStyleClass().add(".center-pill"); + alignCenterBtn.getStyleClass().add(Styles.CENTER_PILL); alignCenterBtn.setToggleGroup(alignGroup); alignCenterBtn.selectedProperty().addListener((obs, old, val) -> { for (TableColumn c : table.getColumns()) { @@ -152,7 +153,7 @@ public class TablePage extends AbstractPage { }); var alignRightBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_RIGHT)); - alignRightBtn.getStyleClass().add(".right-pill"); + alignRightBtn.getStyleClass().add(Styles.RIGHT_PILL); alignRightBtn.setToggleGroup(alignGroup); alignRightBtn.selectedProperty().addListener((obs, old, val) -> { for (TableColumn c : table.getColumns()) { diff --git a/sampler/src/main/java/atlantafx/sampler/page/components/ToggleButtonPage.java b/sampler/src/main/java/atlantafx/sampler/page/components/ToggleButtonPage.java index 4273be3..009875a 100644 --- a/sampler/src/main/java/atlantafx/sampler/page/components/ToggleButtonPage.java +++ b/sampler/src/main/java/atlantafx/sampler/page/components/ToggleButtonPage.java @@ -75,7 +75,7 @@ public class ToggleButtonPage extends AbstractPage { var group = new ToggleGroup(); var prevBtn = new Button("\f", new FontIcon(Feather.CHEVRON_LEFT)); - prevBtn.getStyleClass().addAll(BUTTON_ICON, LEFT_PILL); + prevBtn.getStyleClass().addAll(BUTTON_ICON, LEFT_PILL, "toggle-button"); prevBtn.setOnAction(e -> { int selected = group.getToggles().indexOf(group.getSelectedToggle()); if (selected > 0) { @@ -84,7 +84,7 @@ public class ToggleButtonPage extends AbstractPage { }); var nextBtn = new Button("\f", new FontIcon(Feather.CHEVRON_RIGHT)); - nextBtn.getStyleClass().addAll(BUTTON_ICON, RIGHT_PILL); + nextBtn.getStyleClass().addAll(BUTTON_ICON, RIGHT_PILL, "toggle-button"); nextBtn.setContentDisplay(ContentDisplay.RIGHT); nextBtn.setOnAction(e -> { int selected = group.getToggles().indexOf(group.getSelectedToggle()); diff --git a/sampler/src/main/java/atlantafx/sampler/page/components/TreeTablePage.java b/sampler/src/main/java/atlantafx/sampler/page/components/TreeTablePage.java index f0bcaa1..c18c8df 100644 --- a/sampler/src/main/java/atlantafx/sampler/page/components/TreeTablePage.java +++ b/sampler/src/main/java/atlantafx/sampler/page/components/TreeTablePage.java @@ -15,6 +15,7 @@ import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP; import atlantafx.base.controls.CaptionMenuItem; import atlantafx.base.controls.Spacer; import atlantafx.base.controls.ToggleSwitch; +import atlantafx.base.theme.Styles; import atlantafx.base.theme.Tweaks; import atlantafx.sampler.fake.domain.Product; import atlantafx.sampler.page.AbstractPage; @@ -115,7 +116,7 @@ public class TreeTablePage extends AbstractPage { var alignGroup = new ToggleGroup(); var alignLeftBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_LEFT)); - alignLeftBtn.getStyleClass().add(".left-pill"); + alignLeftBtn.getStyleClass().add(Styles.LEFT_PILL); alignLeftBtn.setToggleGroup(alignGroup); alignLeftBtn.setSelected(true); alignLeftBtn.setOnAction(e -> { @@ -125,7 +126,7 @@ public class TreeTablePage extends AbstractPage { }); var alignCenterBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_CENTER)); - alignCenterBtn.getStyleClass().add(".center-pill"); + alignCenterBtn.getStyleClass().add(Styles.CENTER_PILL); alignCenterBtn.setToggleGroup(alignGroup); alignCenterBtn.selectedProperty().addListener((obs, old, val) -> { for (TreeTableColumn c : treeTable.getColumns()) { @@ -134,7 +135,7 @@ public class TreeTablePage extends AbstractPage { }); var alignRightBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_RIGHT)); - alignRightBtn.getStyleClass().add(".right-pill"); + alignRightBtn.getStyleClass().add(Styles.RIGHT_PILL); alignRightBtn.setToggleGroup(alignGroup); alignRightBtn.selectedProperty().addListener((obs, old, val) -> { for (TreeTableColumn c : treeTable.getColumns()) { diff --git a/sampler/src/main/java/atlantafx/sampler/theme/ThemeManager.java b/sampler/src/main/java/atlantafx/sampler/theme/ThemeManager.java index d926eb3..a18263f 100644 --- a/sampler/src/main/java/atlantafx/sampler/theme/ThemeManager.java +++ b/sampler/src/main/java/atlantafx/sampler/theme/ThemeManager.java @@ -5,6 +5,8 @@ package atlantafx.sampler.theme; import static atlantafx.sampler.Resources.getResource; import static java.nio.charset.StandardCharsets.UTF_8; +import atlantafx.base.theme.CupertinoDark; +import atlantafx.base.theme.CupertinoLight; import atlantafx.base.theme.NordDark; import atlantafx.base.theme.NordLight; import atlantafx.base.theme.PrimerDark; @@ -38,7 +40,9 @@ public final class ThemeManager { Resources.resolve("assets/styles/index.css") }; static final Set> PROJECT_THEMES = Set.of( - PrimerLight.class, PrimerDark.class, NordLight.class, NordDark.class + PrimerLight.class, PrimerDark.class, + NordLight.class, NordDark.class, + CupertinoLight.class, CupertinoDark.class ); private static final PseudoClass DARK = PseudoClass.getPseudoClass("dark"); diff --git a/sampler/src/main/java/atlantafx/sampler/theme/ThemeRepository.java b/sampler/src/main/java/atlantafx/sampler/theme/ThemeRepository.java index d94efbe..ba604e6 100644 --- a/sampler/src/main/java/atlantafx/sampler/theme/ThemeRepository.java +++ b/sampler/src/main/java/atlantafx/sampler/theme/ThemeRepository.java @@ -4,6 +4,8 @@ package atlantafx.sampler.theme; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; +import atlantafx.base.theme.CupertinoDark; +import atlantafx.base.theme.CupertinoLight; import atlantafx.base.theme.NordDark; import atlantafx.base.theme.NordLight; import atlantafx.base.theme.PrimerDark; @@ -34,7 +36,9 @@ public final class ThemeRepository { new SamplerTheme(new PrimerLight()), new SamplerTheme(new PrimerDark()), new SamplerTheme(new NordLight()), - new SamplerTheme(new NordDark()) + new SamplerTheme(new NordDark()), + new SamplerTheme(new CupertinoLight()), + new SamplerTheme(new CupertinoDark()) ); private final List externalThemes = new ArrayList<>(); diff --git a/sampler/src/main/resources/atlantafx/sampler/assets/styles/scss/layout/_main.scss b/sampler/src/main/resources/atlantafx/sampler/assets/styles/scss/layout/_main.scss index e96535c..c429563 100644 --- a/sampler/src/main/resources/atlantafx/sampler/assets/styles/scss/layout/_main.scss +++ b/sampler/src/main/resources/atlantafx/sampler/assets/styles/scss/layout/_main.scss @@ -84,7 +84,9 @@ } #sidebar { - -fx-border-color: -color-border-default; + // border is necessary when scrollbar is hidden + // e.g. when displaying search result + -fx-border-color: -color-border-subtle; -fx-border-width: 0 1px 0 0; >.scroll-pane { diff --git a/styles/pom.xml b/styles/pom.xml index ef3d51a..b6ac2f4 100755 --- a/styles/pom.xml +++ b/styles/pom.xml @@ -35,6 +35,8 @@ ${scss.inputDir}/primer-dark.scss:${css.outputDir}/primer-dark.css ${scss.inputDir}/nord-light.scss:${css.outputDir}/nord-light.css ${scss.inputDir}/nord-dark.scss:${css.outputDir}/nord-dark.css + ${scss.inputDir}/cupertino-light.scss:${css.outputDir}/cupertino-light.css + ${scss.inputDir}/cupertino-dark.scss:${css.outputDir}/cupertino-dark.css --no-source-map diff --git a/styles/src/components/_button.scss b/styles/src/components/_button.scss index e44bd9a..c2464d8 100755 --- a/styles/src/components/_button.scss +++ b/styles/src/components/_button.scss @@ -98,6 +98,10 @@ $color-danger-outlined-bg-hover: $color-danger-bg-hover !default; // opacity level for hover effect $opacity-hover: 0.9 !default; +// shadow +$use-shadow: false !default; +$color-shadow: -color-shadow-default !default; + // basic style is shared with Button, ToggleButton and MenuButton @mixin base() { @@ -118,6 +122,8 @@ $opacity-hover: 0.9 !default; -color-button-fg-pressed: $color-fg-pressed; -color-button-border-pressed: $color-border-pressed; + -color-button-shadow: $color-shadow; + -fx-background-color: -color-button-border, -color-button-bg; -fx-background-insets: 0, cfg.$border-width; -fx-background-radius: cfg.$border-radius, cfg.$inner-border-radius; @@ -125,6 +131,10 @@ $opacity-hover: 0.9 !default; -fx-text-fill: -color-button-fg; -fx-alignment: CENTER; + @if $use-shadow { + -fx-effect: dropshadow(gaussian, -color-button-shadow, 3px, -2, 0, 1); + } + #{cfg.$font-icon-selector} { -fx-icon-color: -color-button-fg; // Always add -fx-fill when styling font icons. There's at least one weird bug. @@ -137,6 +147,7 @@ $opacity-hover: 0.9 !default; &:disabled { -fx-opacity: cfg.$opacity-disabled; + -fx-effect: none; } &:show-mnemonics { @@ -160,16 +171,18 @@ $opacity-hover: 0.9 !default; &.button-circle { -fx-background-radius: 50; -fx-padding: 6px 8px 6px 8px; + -fx-effect: none; >.text { visibility: hidden; } } - // toggle button + // toggle button + input group &.left-pill { -fx-background-radius: cfg.$border-radius 0 0 cfg.$border-radius, cfg.$inner-border-radius 0 0 cfg.$inner-border-radius; -fx-background-insets: 0, cfg.$border-width 0 cfg.$border-width cfg.$border-width; + -fx-effect: none; &:hover, &:focused { @@ -180,6 +193,7 @@ $opacity-hover: 0.9 !default; &.center-pill { -fx-background-radius: 0; -fx-background-insets: 0, cfg.$border-width 0 cfg.$border-width 0; + -fx-effect: none; &:hover, &:focused { @@ -190,6 +204,7 @@ $opacity-hover: 0.9 !default; &.right-pill { -fx-background-radius: 0 cfg.$border-radius cfg.$border-radius 0, 0 cfg.$inner-border-radius cfg.$inner-border-radius 0; -fx-background-insets: 0, cfg.$border-width cfg.$border-width cfg.$border-width 0; + -fx-effect: none; &:hover, &:focused { @@ -307,6 +322,8 @@ $opacity-hover: 0.9 !default; -color-button-bg-pressed: -color-button-bg; -color-button-fg-pressed: -color-button-fg; -color-button-border-pressed: transparent; + + -fx-effect: none; } .button { diff --git a/styles/src/components/_checkbox.scss b/styles/src/components/_checkbox.scss index 148d1e3..3fb5303 100755 --- a/styles/src/components/_checkbox.scss +++ b/styles/src/components/_checkbox.scss @@ -3,9 +3,22 @@ @use "../settings/config" as cfg; @use "../settings/icons"; -$border-color: -color-border-default !default; -$indeterminate-color: -color-fg-muted !default; -$thickness: 1.5px !default; +$color-box: -color-bg-default !default; +$color-box-hover: -color-bg-subtle !default; +$color-box-selected: -color-accent-emphasis !default; +$color-box-indeterminate: -color-bg-default !default; + +$color-border: -color-border-default !default; +$color-border-hover: -color-fg-subtle !default; +$color-border-selected: -color-accent-emphasis !default; +$color-border-indeterminate: -color-border-default !default; + +$color-mark-selected: -color-fg-emphasis !default; +$color-mark-indeterminate: -color-fg-subtle !default; + +$border-width: 1.5px !default; +// $border-color: -color-border-default !default; +// $indeterminate-color: -color-fg-muted !default; .check-box { @@ -14,14 +27,14 @@ $thickness: 1.5px !default; -fx-label-padding: cfg.$checkbox-label-padding cfg.$checkbox-label-padding 0 cfg.$graphic-gap; >.box { - -fx-background-color: $border-color, -color-bg-default; - -fx-background-insets: 0, $thickness; + -fx-background-color: $color-border, $color-box; + -fx-background-insets: 0, $border-width; -fx-background-radius: cfg.$border-radius, cfg.$inner-border-radius; -fx-padding: cfg.$checkbox-mark-padding-y cfg.$checkbox-mark-padding-x cfg.$checkbox-mark-padding-y cfg.$checkbox-mark-padding-x; -fx-alignment: CENTER; >.mark { - -fx-background-color: -color-bg-default; // mark is hidden + -fx-background-color: $color-box; // mark is hidden @include icons.get("check", true); -fx-min-height: cfg.$checkbox-mark-size; -fx-max-height: cfg.$checkbox-mark-size; @@ -30,14 +43,16 @@ $thickness: 1.5px !default; } &:hover { - -fx-background-color: -color-fg-muted, -color-bg-subtle; + -fx-background-color: $color-border-hover, $color-box-hover; } } &:indeterminate { >.box { + -fx-background-color: $color-border-indeterminate, $color-box-indeterminate; + >.mark { - -fx-background-color: $indeterminate-color; + -fx-background-color: $color-mark-indeterminate; @include icons.get("minus", false); } } @@ -53,15 +68,15 @@ $thickness: 1.5px !default; &:selected { >.box { - -fx-background-color: -color-accent-emphasis, -color-accent-emphasis; + -fx-background-color: $color-border-selected, $color-box-selected; >.mark { - -fx-background-color: -color-fg-emphasis; + -fx-background-color: $color-mark-selected; } } } &:show-mnemonics>.mnemonic-underline { - -fx-stroke: $border-color; + -fx-stroke: -color-fg-muted; } } diff --git a/styles/src/components/_combo-box.scss b/styles/src/components/_combo-box.scss index 6c20d68..c61c747 100755 --- a/styles/src/components/_combo-box.scss +++ b/styles/src/components/_combo-box.scss @@ -1,25 +1,34 @@ // SPDX-License-Identifier: MIT @use "../settings/config" as cfg; +@use "../settings/effects"; @use "../settings/icons"; +$color-arrow-button-fg: -color-fg-muted !default; $color-list-bg: -color-bg-default !default; $color-list-bg-hover: if(cfg.$darkMode, -color-base-7, -color-base-1) !default; $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !default; +$color-list-fg: -color-fg-default !default; +$color-list-fg-hover: -color-fg-default !default; +$color-list-fg-selected: -color-fg-default !default; +$use-alt-icon: false !default; -@mixin _arrow() { - @include icons.get("arrow-drop-down", false); - -fx-background-color: -color-fg-muted; -} +@mixin _arrow($is-alt: false) { + @if $use-alt-icon { + $is-alt: not $is-alt; + } -// alt icon to make combo-box not to be confused with menu button, if matters -@mixin _alt-arrow() { - @include icons.get("unfold-more", false); + @if $is-alt { + @include icons.get("unfold-more", false); + } + @else { + @include icons.get("arrow-drop-down", false); + } } @mixin _combo-box-base() { -fx-background-color: -color-border-default, -color-bg-default; - -fx-background-insets: 0, 1; + -fx-background-insets: 0, cfg.$border-width; -fx-background-radius: cfg.$border-radius, cfg.$inner-border-radius; -fx-text-fill: -color-fg-default; -fx-alignment: CENTER; @@ -87,11 +96,12 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul >.arrow { @include _arrow(); + -fx-background-color: $color-arrow-button-fg; } } >.text-field { - -fx-background-insets: 0, 1 0 1 1; + -fx-background-insets: 0, cfg.$border-width 0 cfg.$border-width cfg.$border-width; -fx-background-radius: cfg.$border-radius 0 0 cfg.$border-radius, cfg.$inner-border-radius 0 0 cfg.$inner-border-radius; } @@ -110,14 +120,14 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul // #tweaks/alt-icon &.alt-icon { >.arrow-button>.arrow { - @include _alt-arrow(); + @include _arrow(true); } } } .combo-box { - // customise the ListCell that appears in the ComboBox button itself + // customize the ListCell that appears in the ComboBox button itself >.list-cell { -fx-background-color: transparent; -fx-text-fill: -color-fg-default; @@ -138,7 +148,10 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul >.list-view { -fx-background-color: -color-border-default, $color-list-bg; -fx-background-insets: 0, 1; + -fx-border-radius: cfg.$border-radius, cfg.$inner-border-radius; -fx-background-radius: cfg.$border-radius, cfg.$inner-border-radius; + -fx-padding: cfg.$popup-padding-y cfg.$popup-padding-x cfg.$popup-padding-y cfg.$popup-padding-x; + @include effects.shadow(-color-shadow-default, cfg.$popup-shadow-radius, cfg.$popup-shadow-spread); >.virtual-flow { >.clipped-container { @@ -148,16 +161,35 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul // to use the same values as ChoiceBox -fx-cell-size: 0; -fx-background-color: $color-list-bg; + -fx-background-radius: cfg.$border-radius, cfg.$inner-border-radius; -fx-padding: cfg.$menu-padding-y cfg.$menu-padding-x cfg.$menu-padding-y cfg.$menu-padding-x; -fx-graphic-text-gap: cfg.$graphic-gap; + -fx-text-fill: $color-list-fg; + + #{cfg.$font-icon-selector} { + -fx-icon-color: $color-list-fg; + -fx-fill: $color-list-fg; + } &:filled:hover { -fx-background-color: $color-list-bg-hover; + -fx-text-fill: $color-list-fg-hover; + + #{cfg.$font-icon-selector} { + -fx-icon-color: $color-list-fg-hover; + -fx-fill: $color-list-fg-hover; + } } &:filled:selected, &:filled:selected:hover { -fx-background-color: $color-list-bg-selected; + -fx-text-fill: $color-list-fg-selected; + + #{cfg.$font-icon-selector} { + -fx-icon-color: $color-list-fg-selected; + -fx-fill: $color-list-fg-selected; + } } } } @@ -191,6 +223,7 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul >.arrow { @include _arrow(); + -fx-background-color: $color-arrow-button-fg; } } @@ -217,7 +250,7 @@ $color-list-bg-selected: if(cfg.$darkMode, -color-base-6, -color-base-2) !defaul // #tweaks/alt-icon &.alt-icon { >.open-button>.arrow { - @include _alt-arrow(); + @include _arrow(true); } } } diff --git a/styles/src/components/_date-picker.scss b/styles/src/components/_date-picker.scss index d4468fa..8da93de 100755 --- a/styles/src/components/_date-picker.scss +++ b/styles/src/components/_date-picker.scss @@ -20,9 +20,11 @@ $color-today-bg: -color-accent-subtle !default; $color-today-fg: -color-accent-fg !default; $color-other-month-fg: -color-fg-subtle !default; $color-chrono-fg: -color-success-fg !default; +$color-icon: -color-fg-muted !default; $content-padding-x: 8px !default; $content-padding-y: 8px !default; +$day-cell-font-size: 1em !default; $month-year-font-size: 1.1em !default; $cell-padding-x: 4px !default; @@ -63,7 +65,7 @@ $chrono-cell-padding: 0.083333em $cell-padding-x 0.083333em 0.333333em !default; >.arrow { @include icons.get("calendar", true); - -fx-background-color: -color-fg-default; + -fx-background-color: $color-icon; -fx-padding: 0.416667em; // icon size } } @@ -136,12 +138,14 @@ $chrono-cell-padding: 0.083333em $cell-padding-x 0.083333em 0.333333em !default; -fx-opacity: 1.0; -fx-text-fill: -color-date-day-fg; -fx-cell-size: $cell-size; + -fx-font-size: $day-cell-font-size; } >.week-number-cell { -fx-padding: $cell-padding-y $cell-padding-x $cell-padding-y $cell-padding-x; -fx-background-color: -color-date-week-bg; -fx-text-fill: -color-date-week-fg; + -fx-font-size: $day-cell-font-size; } >.day-cell { diff --git a/styles/src/components/_menu-button.scss b/styles/src/components/_menu-button.scss index e74bc86..2c2a56a 100644 --- a/styles/src/components/_menu-button.scss +++ b/styles/src/components/_menu-button.scss @@ -4,6 +4,10 @@ @use "../settings/icons"; @use "button"; +$color-split-arrow-bg: -color-neutral-emphasis-plus !default; +$color-split-arrow-fg: -color-fg-emphasis !default; +$color-split-arrow-opacity: 0.75 !default; + $arrow-button-width: 0.5em !default; $separator-width: 0.75px !default; @@ -122,6 +126,13 @@ $separator-width: 0.75px !default; &.flat { @include button.flat(); } + + // prevent opacity from being applied twice + &:disabled { + >.label { + -fx-opacity: 1; + } + } } .menu-button { @@ -149,14 +160,14 @@ $separator-width: 0.75px !default; &:hover, &:focused:hover { >.arrow-button { - -fx-background-color: -color-neutral-emphasis-plus; + -fx-background-color: $color-split-arrow-bg; -fx-background-insets: cfg.$border-width; -fx-background-radius: cfg.$inner-border-radius; -fx-border-color: transparent; - -fx-opacity: 0.75; + -fx-opacity: $color-split-arrow-opacity; >.arrow { - -fx-background-color: -color-fg-emphasis; + -fx-background-color: $color-split-arrow-fg; -fx-opacity: 1.0; } } diff --git a/styles/src/components/_menu.scss b/styles/src/components/_menu.scss index e4c66e0..ffcd81d 100755 --- a/styles/src/components/_menu.scss +++ b/styles/src/components/_menu.scss @@ -11,8 +11,11 @@ $color-menubar-bg: -color-bg-subtle !default; $color-menubar-bg-hover: if(cfg.$darkMode, -color-base-6, -color-base-1) !default; + $color-menuitem-bg: -color-bg-default !default; $color-menuitem-bg-hover: if(cfg.$darkMode, -color-base-7, -color-base-1) !default; +$color-menuitem-fg: -color-fg-default !default; +$color-menuitem-fg-hover: -color-fg-default !default; $separator-padding: map-get(cfg.$separators, "small") !default; $menu-button-padding-x: cfg.$menu-padding-x - math.div(cfg.$menubar-padding-x, 2) !default; @@ -33,6 +36,7 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, -fx-background-insets: 0 0 cfg.$border-width 0; -fx-background-radius: cfg.$popup-radius; -fx-padding: $menu-button-padding-y $menu-button-padding-x $menu-button-padding-y $menu-button-padding-x; + -fx-effect: none; // reset padding of menu buttons when in menu bar >.label { @@ -65,7 +69,6 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, /////////////////////////////////////////////////////////////////////////////// .menu { - -fx-background-color: transparent; >.right-container { @@ -74,6 +77,15 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, -fx-background-color: -color-fg-muted; } } + + // #javafx-bug Not possible to maintain hover font color here due to commented + // styles applied always, even when menu is under cursor. + // &:hover { + // .menu-up-arrow, + // .menu-down-arrow { + // -fx-background-color: $color-menuitem-fg-hover; + // } + // } } // vertical (scroll) arrows appear if menu height exceeds container size @@ -121,11 +133,23 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, &:focused { -fx-background-color: $color-menuitem-bg-hover, $color-menuitem-bg-hover; + + >.label { + -fx-text-fill: $color-menuitem-fg-hover; + } + + >.right-container >.arrow { + -fx-background-color: $color-menuitem-fg-hover; + } + + #{cfg.$font-icon-selector} { + -fx-icon-color: $color-menuitem-fg-hover; + -fx-fill: $color-menuitem-fg-hover; + } } &:disabled { -fx-opacity: cfg.$opacity-disabled; - -fx-background-color: $color-menuitem-bg; } } @@ -139,6 +163,13 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, -fx-max-width: cfg.$checkbox-mark-size; } +.radio-menu-item:hover:checked>.left-container>.radio, +.radio-menu-item:focused:checked>.left-container>.radio, +.check-menu-item:hover:checked>.left-container>.check, +.check-menu-item:focused:checked>.left-container>.check { + -fx-background-color: $color-menuitem-fg-hover; +} + .caption-menu-item { -fx-padding: cfg.$menu-padding-y cfg.$menu-padding-x cfg.$menu-padding-y cfg.$menu-padding-x; @@ -146,6 +177,10 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, &:focused, &:pressed { -fx-background-color: transparent; + + >.label { + -fx-text-fill: -color-fg-muted; + } } >.label { @@ -175,7 +210,7 @@ $menu-button-padding-y: cfg.$menu-padding-y - math.div(cfg.$menubar-padding-y, &:hover { -fx-background-color: $color-menuitem-bg-hover; - -fx-text-fill: -color-fg-default; + -fx-text-fill: $color-menuitem-fg-hover; } } diff --git a/styles/src/components/_radio.scss b/styles/src/components/_radio.scss index 49ed785..6c95a5c 100755 --- a/styles/src/components/_radio.scss +++ b/styles/src/components/_radio.scss @@ -2,8 +2,10 @@ @use "../settings/config" as cfg; -$border-color: -color-border-default !default; -$thickness: 1.5px !default; +$color-border: -color-border-default !default; +$border-width: 1.5px !default; +$dot-width: 1px !default; +$dot-width-selected: 1px !default; .radio-button { @@ -13,15 +15,15 @@ $thickness: 1.5px !default; -fx-label-padding: cfg.$checkbox-label-padding cfg.$checkbox-label-padding 0 cfg.$graphic-gap; >.radio { - -fx-background-color: $border-color, -color-bg-default; - -fx-background-insets: 0, $thickness; + -fx-background-color: $color-border, -color-bg-default; + -fx-background-insets: 0, $border-width; -fx-background-radius: 1em; // large value to make sure this remains circular -fx-padding: cfg.$checkbox-mark-padding-y; -fx-alignment: CENTER; >.dot { -fx-background-color: transparent, transparent; - -fx-background-insets: 0, 1; + -fx-background-insets: 0, $dot-width; -fx-background-radius: 1em; // large value to make sure this remains circular -fx-min-height: cfg.$checkbox-mark-size; -fx-max-height: cfg.$checkbox-mark-size; @@ -48,11 +50,12 @@ $thickness: 1.5px !default; >.dot { -fx-background-color: -color-accent-emphasis, -color-fg-emphasis; + -fx-background-insets: 0, $dot-width-selected; } } } &:show-mnemonics>.mnemonic-underline { - -fx-stroke: $border-color; + -fx-stroke: -color-fg-muted; } } diff --git a/styles/src/components/_slider.scss b/styles/src/components/_slider.scss index f150a92..d7ac00d 100755 --- a/styles/src/components/_slider.scss +++ b/styles/src/components/_slider.scss @@ -22,6 +22,8 @@ $thumb-size: ( $thumb-radius: 10em !default; $thumb-border-width: 2px !default; +$thumb-effect: none !default; +$thumb-effect-large: none !default; // visual track height (or width) $track-size: ( @@ -50,8 +52,9 @@ $tick-minor-size: 3px !default; >.thumb { -fx-background-color: -color-slider-thumb-border, -color-slider-thumb; - -fx-background-insets: 0, 2px; + -fx-background-insets: 0, $thumb-border-width; -fx-background-radius: $thumb-radius; + -fx-effect: $thumb-effect; } >.track { @@ -93,11 +96,13 @@ $tick-minor-size: 3px !default; -fx-padding: map-get($thumb-size, "medium-h") 0 map-get($thumb-size, "medium-h") 0; -fx-background-insets: 0, calc(map-get($thumb-size, "medium-h") - map-get($track-size, "medium")) 0 calc(map-get($thumb-size, "medium-h") - map-get($track-size, "medium")) 0; + -fx-background-radius: $track-radius 0 0 $track-radius; } >.progress { -fx-background-radius: $track-radius; -fx-background-insets: 0, calc(map-get($thumb-size, "medium-h") - map-get($track-size, "medium")) 0 calc(map-get($thumb-size, "medium-h") - map-get($track-size, "medium")) 0; + -fx-background-radius: $track-radius 0 0 $track-radius; } } @@ -120,16 +125,17 @@ $tick-minor-size: 3px !default; &.large:horizontal { >.thumb { -fx-padding: map-get($thumb-size, "large-h") map-get($thumb-size, "large-w") map-get($thumb-size, "large-h") map-get($thumb-size, "smlargeall-w"); + -fx-effect: $thumb-effect-large; } >.track { -fx-padding: map-get($thumb-size, "large-h") 0 map-get($thumb-size, "large-h") 0; -fx-background-insets: 0, calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0 - calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0 + calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0; } >.progress { -fx-padding: map-get($thumb-size, "large-h") 0 map-get($thumb-size, "large-h") 0; -fx-background-insets: 0, calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0 - calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0 + calc(map-get($thumb-size, "large-h") - map-get($track-size, "large")) 0; } } diff --git a/styles/src/components/_spinner.scss b/styles/src/components/_spinner.scss index c735908..5992fab 100755 --- a/styles/src/components/_spinner.scss +++ b/styles/src/components/_spinner.scss @@ -3,7 +3,7 @@ @use "../settings/config" as cfg; @use "../settings/icons"; -$color-button-bg: -color-bg-subtle !default; +$color-button-bg: -color-bg-subtle !default; $color-button-fg: -color-fg-default !default; $color-button-hover: if(cfg.$darkMode, -color-base-6, -color-base-2) !default; $icon-padding-x: 0.25em !default; diff --git a/styles/src/components/_tab-pane.scss b/styles/src/components/_tab-pane.scss index de89588..cdd5c46 100755 --- a/styles/src/components/_tab-pane.scss +++ b/styles/src/components/_tab-pane.scss @@ -44,6 +44,8 @@ $tab-lr-label-padding-y-dense: 0.15em !default; $header-border-width: 2px !default; // floating tabs +$color-float-header-area: -color-bg-inset !default; + $color-float-bg: -color-bg-inset !default; $color-float-border: -color-border-default !default; @@ -229,7 +231,7 @@ $tab-float-width: 150px !default; &.floating { >.tab-header-area { - -fx-background-color: $color-float-border, $color-float-bg; + -fx-background-color: $color-float-border, $color-float-header-area; -fx-background-insets: 0, 0 0 $header-float-border-width 0; // NOTE: Floating TabPane doesn't have '.tab-header-background'. @@ -241,7 +243,7 @@ $tab-float-width: 150px !default; -fx-padding: $tab-padding-y 0 $tab-padding-y $tab-float-spacing; >.tab-container { - -fx-background-color: transparent; + -fx-background-color: $color-float-bg; -fx-background-insets: 0; -fx-background-radius: cfg.$border-radius; -fx-border-radius: cfg.$border-radius; diff --git a/styles/src/components/_toggle-button.scss b/styles/src/components/_toggle-button.scss index 9fc0b37..7b827fb 100644 --- a/styles/src/components/_toggle-button.scss +++ b/styles/src/components/_toggle-button.scss @@ -3,17 +3,21 @@ @use "../settings/config" as cfg; @use "button"; +$color-bg-selected: -color-accent-emphasis !default; +$color-fg-selected: -color-fg-emphasis !default; +$color-border-selected: -color-accent-emphasis !default; + .toggle-button { @include button.base(); - -color-button-bg-selected: -color-accent-emphasis; - -color-button-fg-selected: -color-fg-emphasis; + -color-button-bg-selected: $color-bg-selected; + -color-button-fg-selected: $color-fg-selected; -fx-padding: cfg.$padding-y cfg.$padding-x cfg.$padding-y cfg.$padding-x; &:selected, &:selected:focused { - -fx-background-color: -color-button-bg-selected; + -fx-background-color: $color-border-selected, -color-button-bg-selected; -fx-text-fill: -color-button-fg-selected; -fx-background-insets: 0; @@ -29,6 +33,14 @@ } } + &.left-pill, + &.center-pill, + &.right-pill { + @if button.$use-shadow { + -fx-effect: dropshadow(gaussian, -color-button-shadow, 3px, -2, 0, 1); + } + } + &:selected.left-pill:focused { -fx-background-insets: 0, cfg.$border-width; } diff --git a/styles/src/components/_toolbar.scss b/styles/src/components/_toolbar.scss index 15da490..c215525 100755 --- a/styles/src/components/_toolbar.scss +++ b/styles/src/components/_toolbar.scss @@ -26,6 +26,7 @@ $border-width: cfg.$border-width !default; >.split-menu-button { -color-button-bg: $color-bg; -fx-background-insets: 0; + -fx-effect: none; } .toggle-button { @@ -33,6 +34,7 @@ $border-width: cfg.$border-width !default; -color-button-bg-selected: $color-bg-selected; -color-button-fg-selected: -color-fg-default; -fx-background-insets: 0; + -fx-effect: none; } >.separator { @@ -40,6 +42,13 @@ $border-width: cfg.$border-width !default; } } + // When toolbar doesn't have enough size to place all elements, it creates additional + // menu button (the ToolBarOverflowMenu) and roughly hides all overflown elements + // in there. It's end-up as a normal button (or combo-box etc) inside a menu item, which + // is a very unlucky implementation that's pretty hard to style nicely. + // Given the very rare use case and the fact that the implementation is a complete non-sense, + // there are no reasons to support it. So, expect that hover, focused etc effects may not work + // inside the overflow menu. >.tool-bar-overflow-button { -fx-padding: 0 $padding-x 0 $spacing; @@ -47,6 +56,10 @@ $border-width: cfg.$border-width !default; @include icons.get("arrow-double-right", false); -fx-background-color: -color-fg-default; } + + .menu-item:hover { + -fx-background-color: transparent; + } } &:vertical { diff --git a/styles/src/cupertino-dark.scss b/styles/src/cupertino-dark.scss new file mode 100755 index 0000000..2945d9d --- /dev/null +++ b/styles/src/cupertino-dark.scss @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: MIT) + +@use "sass:color"; +@use "settings/utils" as utils; + +// IOS dark color palette +$systemBackground: rgba(0.0, 0.0, 0.0, 1.0); // #000000ff +$secondarySystemBackground: rgba(28.0, 28.0, 30.0, 1.0); // #1c1c1eff +$tertiarySystemBackground: rgba(44.0, 44.0, 46.0, 1.0); // #2c2c2eff +$systemGroupedBackground: rgba(0.0, 0.0, 0.0, 1.0); // #000000ff +$secondarySystemGroupedBackground: rgba(28.0, 28.0, 30.0, 1.0); // #1c1c1eff +$tertiarySystemGroupedBackground: rgba(44.0, 44.0, 46.0, 1.0); // #2c2c2eff +$systemFill: rgba(120.0, 120.0, 128.0, 0.36); // #7878805b +$secondarySystemFill: rgba(120.0, 120.0, 128.0, 0.32); // #78788051 +$tertiarySystemFill: rgba(118.0, 118.0, 128.0, 0.24); // #7676803d +$quaternarySystemFill: rgba(118.0, 118.0, 128.0, 0.18); // #7676802d +$systemBlue: rgba(10.0, 132.0, 255.0, 1.0); // #0a84ffff +$systemGreen: rgba(50.0, 215.0, 75.0, 1.0); // #32d74bff +$systemIndigo: rgba(94.0, 92.0, 230.0, 1.0); // #5e5ce6ff +$systemOrange: rgba(255.0, 159.0, 10.0, 1.0); // #ff9f0aff +$systemPink: rgba(255.0, 55.0, 95.0, 1.0); // #ff375fff +$systemPurple: rgba(191.0, 90.0, 242.0, 1.0); // #bf5af2ff +$systemRed: rgba(255.0, 69.0, 58.0, 1.0); // #ff453aff +$systemTeal: rgba(100.0, 210.0, 255.0, 1.0); // #64d2ffff +$systemYellow: rgba(255.0, 214.0, 10.0, 1.0); // #ffd60aff +$systemGray: rgba(142.0, 142.0, 147.0, 1.0); // #8e8e93ff +$systemGray2: rgba(99.0, 99.0, 102.0, 1.0); // #636366ff +$systemGray3: rgba(72.0, 72.0, 74.0, 1.0); // #48484aff +$systemGray4: rgba(58.0, 58.0, 60.0, 1.0); // #3a3a3cff +$systemGray5: rgba(44.0, 44.0, 46.0, 1.0); // #2c2c2eff +$systemGray6: rgba(28.0, 28.0, 30.0, 1.0); // #1c1c1eff + +$darkText: rgba(0.0, 0.0, 0.0, 1.0); // #000000ff +$lightText: rgba(255.0, 255.0, 255.0, 0.6); // #ffffff99 +$label: rgba(255.0, 255.0, 255.0, 1.0); // #ffffffff +$secondaryLabel: rgba(235.0, 235.0, 245.0, 0.6); // #ebebf599 +$tertiaryLabel: rgba(235.0, 235.0, 245.0, 0.3); // #ebebf54c +$quaternaryLabel: rgba(235.0, 235.0, 245.0, 0.18); // #ebebf52d +$placeholderText: rgba(235.0, 235.0, 245.0, 0.3); // #ebebf54c +$link: rgba(9.0, 132.0, 255.0, 1.0); // #0984ffff +$separator: rgba(84.0, 84.0, 88.0, 0.6); // #54545899 +$opaqueSeparator: rgba(56.0, 56.0, 58.0, 1.0); // #38383aff + +@forward "settings/color-scale" with ( + + $dark: $systemBackground, + $light: $label, + + $base-0: #f2f2f7ff, // the rest of the color shades + $base-1: #e5e5eaff, // are + $base-2: #d1d1d6ff, // from + $base-3: #aeaeb2ff, // the light palette + $base-4: $systemGray, + $base-5: $systemGray2, + $base-6: $systemGray3, + $base-7: $systemGray4, + $base-8: $systemGray5, + $base-9: $systemGray6, + + $accent-0: #c2e0ff, + $accent-1: #9dceff, + $accent-2: #78bbff, + $accent-3: #54a9ff, + $accent-4: #2f96ff, + $accent-5: $systemBlue, + $accent-6: #0970d9, + $accent-7: #075cb3, + $accent-8: #06498c, + $accent-9: #043566, + + $success-0: #ccf5d2, + $success-1: #adefb7, + $success-2: #8ee99c, + $success-3: #70e381, + $success-4: #51dd66, + $success-5: $systemGreen, + $success-6: #2bb740, + $success-7: #239735, + $success-8: #1c7629, + $success-9: #14561e, + + $warning-0: #ffe7c2, + $warning-1: #ffd99d, + $warning-2: #ffca78, + $warning-3: #ffbc54, + $warning-4: #ffad2f, + $warning-5: $systemOrange, + $warning-6: #d98709, + $warning-7: #b36f07, + $warning-8: #8c5706, + $warning-9: #664004, + + $danger-0: #ffd1ce, + $danger-1: #ffb5b0, + $danger-2: #ff9993, + $danger-3: #ff7d75, + $danger-4: #ff6158, + $danger-5: $systemRed, + $danger-6: #d93b31, + $danger-7: #b33029, + $danger-8: #8c2620, + $danger-9: #661c17 +); + +@use "settings/color-scale" as scale; + +@forward "settings/color-vars" with ( + + $fg-default: $label, + $fg-muted: scale.$base-3, + $fg-subtle: utils.flattenColor($systemGroupedBackground, $secondaryLabel), + $fg-onEmphasis: $label, + + $canvas-default: $secondarySystemGroupedBackground, + $canvas-overlay: $secondarySystemGroupedBackground, + $canvas-inset: #0b0b0c, // nothing good in default palette + $canvas-subtle: $tertiarySystemGroupedBackground, + + $border-default: scale.$base-6, + $border-muted: scale.$base-7, + $border-subtle: utils.flattenColor(scale.$base-9, color.change(scale.$base-0, $alpha: 0.1)), + $shadow-default: $systemGroupedBackground, + + $neutral-emphasisPlus: scale.$base-4, + $neutral-emphasis: scale.$base-4, + $neutral-muted: color.change(scale.$base-5, $alpha: 0.4), + $neutral-subtle: color.change(scale.$base-5, $alpha: 0.1), + + $accent-fg: scale.$accent-4, + $accent-emphasis: scale.$accent-5, + $accent-muted: color.change(scale.$accent-5, $alpha: 0.4), + $accent-subtle: color.change(scale.$accent-5, $alpha: 0.15), + + $success-fg: scale.$success-5, + $success-emphasis: scale.$success-6, + $success-muted: color.change(scale.$success-5, $alpha: 0.4), + $success-subtle: color.change(scale.$success-5, $alpha: 0.15), + + $warning-fg: scale.$warning-5, + $warning-emphasis: scale.$warning-6, + $warning-muted: color.change(scale.$warning-5, $alpha: 0.4), + $warning-subtle: color.change(scale.$warning-5, $alpha: 0.15), + + $danger-fg: scale.$danger-5, + $danger-emphasis: scale.$danger-5, + $danger-muted: color.change(scale.$danger-5, $alpha: 0.4), + $danger-subtle: color.change(scale.$danger-5, $alpha: 0.15) +); + +@forward "settings/config" with ( + $darkMode: true, + $padding-y: 6px, + $border-radius: 6px, + $checkbox-mark-size: 0.85em +); + +@use "general"; + +@forward "components/button" as button-* with ( + $color-bg: $secondarySystemGroupedBackground, + $color-success-bg-focused: -color-success-7, + $use-shadow: true +); + +@forward "components/checkbox" as checkbox-* with ( + $color-box-indeterminate: -color-accent-emphasis, + $color-border-indeterminate: -color-accent-emphasis, + $color-mark-indeterminate: -color-fg-emphasis +); + +@forward "components/combo-box" as combo-box-* with ( + $use-alt-icon: true, + $color-arrow-button-fg: -color-accent-fg, + $color-list-bg-hover: -color-accent-emphasis, + $color-list-bg-selected: -color-accent-emphasis, + $color-list-fg-hover: -color-fg-emphasis, + $color-list-fg-selected: -color-fg-emphasis +); + +@forward "components/data" as data-* with ( + $color-header-bg: -color-bg-default, + $color-header-fg: -color-fg-muted +); + +@forward "components/date-picker" as date-picker-* with ( + $cell-padding-x: 2px, + $cell-padding-y: 2px, + $cell-size: 2.5em, + $color-icon: -color-accent-fg, + $day-cell-font-size: 0.85em, + $day-name-font-size: 0.9em, + $month-year-font-size: 1em +); + +@forward "components/menu" as menu-* with ( + $color-menuitem-bg-hover: -color-accent-emphasis, + $color-menuitem-fg-hover: -color-fg-emphasis +); + +@forward "components/menu-button" as menu-button-* with ( + $color-split-arrow-bg: -color-accent-emphasis, + $color-split-arrow-fg: -color-fg-emphasis, + $color-split-arrow-opacity: 1.0 +); + +@forward "components/radio" as radio-* with ( + $dot-width-selected: 2px +); + +@forward "components/slider" as slider-* with ( + $thumb-border-width: 0.5px, + $thumb-effect: dropshadow(gaussian, -color-border-default, 3px, 0.25, 0, 1) +); + +@forward "components/spinner" as spinner-* with ( + $color-button-bg: -color-accent-emphasis, + $color-button-fg: -color-fg-emphasis, + $color-button-hover: -color-accent-3 +); + +@forward "components/split-pane" as split-pane-* with ( + $divider-thickness: 1px, + $grabber-length: 5px +); + +// There are two types of tabs on MacOS. Segmented button tabs and Safari tabs. +// The first one can't be implemented from TabPane with just CSS, so it's not supported. +// Safari tabs implemented as floating tabs. +@forward "components/tab-pane" as tab-pane-* with ( + $color-float-bg: -color-base-9, + $color-float-bg-selected: -color-base-6 +); + +@forward "components/toggle-button" as toggle-button-* with ( + $color-bg-selected: -color-accent-emphasis, + $color-fg-selected: -color-fg-emphasis, + $color-border-selected: scale.$accent-6 +); + +@use "components"; diff --git a/styles/src/cupertino-light.scss b/styles/src/cupertino-light.scss new file mode 100755 index 0000000..dac50c5 --- /dev/null +++ b/styles/src/cupertino-light.scss @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: MIT + +@use "sass:color"; +@use "settings/utils" as utils; + +// IOS light color palette +// Tint colors don't meet WCAG, but there's accessible (darker) pallette. +$systemBackground: rgba(255.0, 255.0, 255.0, 1.0); // #ffffffff +$secondarySystemBackground: rgba(242.0, 242.0, 247.0, 1.0); // #f2f2f7ff +$tertiarySystemBackground: rgba(255.0, 255.0, 255.0, 1.0); // #ffffffff +$systemGroupedBackground: rgba(242.0, 242.0, 247.0, 1.0); // #f2f2f7ff +$secondarySystemGroupedBackground: rgba(255.0, 255.0, 255.0, 1.0); // #ffffffff +$tertiarySystemGroupedBackground: rgba(242.0, 242.0, 247.0, 1.0); // #f2f2f7ff +$systemFill: rgba(120.0, 120.0, 128.0, 0.2); // #78788033 +$secondarySystemFill: rgba(120.0, 120.0, 128.0, 0.16); // #78788028 +$tertiarySystemFill: rgba(118.0, 118.0, 128.0, 0.12); // #7676801e +$quaternarySystemFill: rgba(116.0, 116.0, 128.0, 0.08); // #74748014 +$systemBlue: rgba(0.0, 122.0, 255.0, 1.0); // #007affff +$systemGreen: rgba(30.0, 195.0, 55.0, 1.0); // #1ec337ff +$systemIndigo: rgba(88.0, 86.0, 214.0, 1.0); // #5856d6ff +$systemOrange: rgba(255.0, 149.0, 0.0, 1.0); // #ff9500ff +$systemPink: rgba(255.0, 45.0, 85.0, 1.0); // #ff2d55ff +$systemPurple: rgba(175.0, 82.0, 222.0, 1.0); // #af52deff +$systemRed: rgba(255.0, 59.0, 48.0, 1.0); // #ff3b30ff +$systemTeal: rgba(90.0, 200.0, 250.0, 1.0); // #5ac8faff +$systemYellow: rgba(255.0, 204.0, 0.0, 1.0); // #ffcc00ff +$systemGray: rgba(142.0, 142.0, 147.0, 1.0); // #8e8e93ff +$systemGray2: rgba(174.0, 174.0, 178.0, 1.0); // #aeaeb2ff +$systemGray3: rgba(199.0, 199.0, 204.0, 1.0); // #c7c7ccff +$systemGray4: rgba(209.0, 209.0, 214.0, 1.0); // #d1d1d6ff +$systemGray5: rgba(229.0, 229.0, 234.0, 1.0); // #e5e5eaff +$systemGray6: rgba(242.0, 242.0, 247.0, 1.0); // #f2f2f7ff + +$darkText: rgba(0.0, 0.0, 0.0, 1.0); // #000000ff +$lightText: rgba(255.0, 255.0, 255.0, 0.6); // #ffffff99 +$label: rgba(0.0, 0.0, 0.0, 1.0); // #000000ff +$secondaryLabel: rgba(60.0, 60.0, 67.0, 0.6); // #3c3c4399 +$tertiaryLabel: rgba(60.0, 60.0, 67.0, 0.3); // #3c3c434c +$quaternaryLabel: rgba(60.0, 60.0, 67.0, 0.18); // #3c3c432d +$placeholderText: rgba(60.0, 60.0, 67.0, 0.3); // #3c3c434c +$link: rgba(0.0, 122.0, 255.0, 1.0); // #007affff +$separator: rgba(60.0, 60.0, 67.0, 0.29); // #3c3c4349 +$opaqueSeparator: rgba(198.0, 198.0, 200.0, 1.0); // #c6c6c8ff + +@forward "settings/color-scale" with ( + + $dark: $darkText, + $light: $systemBackground, + + $base-0: $systemGray6, + $base-1: $systemGray5, + $base-2: $systemGray4, + $base-3: $systemGray3, + $base-4: $systemGray2, + $base-5: $systemGray, + $base-6: #636366, // the rest of the color shades + $base-7: #48484A, // are + $base-8: #3A3A3C, // from + $base-9: #2C2C2E, // the dark palette + + $accent-0: #bfdeff, + $accent-1: #99caff, + $accent-2: #73b6ff, + $accent-3: #4da2ff, + $accent-4: #268eff, + $accent-5: $systemBlue, + $accent-6: #0068d9, + $accent-7: #0055b3, + $accent-8: #00438c, + $accent-9: #003166, + + $success-0: #c7f0cd, + $success-1: #a5e7af, + $success-2: #83de91, + $success-3: #62d573, + $success-4: #40cc55, + $success-5: $systemGreen, + $success-6: #1aa62f, + $success-7: #158927, + $success-8: #116b1e, + $success-9: #0c4e16, + + $warning-0: #ffe5bf, + $warning-1: #ffd599, + $warning-2: #ffc573, + $warning-3: #ffb54d, + $warning-4: #ffa526, + $warning-5: $systemOrange, + $warning-6: #d97f00, + $warning-7: #b36800, + $warning-8: #8c5200, + $warning-9: #663c00, + + $danger-0: #ffcecb, + $danger-1: #ffb1ac, + $danger-2: #ff938d, + $danger-3: #ff766e, + $danger-4: #ff584f, + $danger-5: $systemRed, + $danger-6: #d93229, + $danger-7: #b32922, + $danger-8: #8c201a, + $danger-9: #661813, +); + +@use "settings/color-scale" as scale; + +@forward "settings/color-vars" with ( + + $fg-default: $label, + $fg-muted: scale.$base-6, + $fg-subtle: utils.flattenColor($systemBackground, $secondaryLabel), + $fg-onEmphasis: scale.$light, + + $canvas-default: $systemBackground, + $canvas-overlay: $systemBackground, + $canvas-inset: $tertiarySystemGroupedBackground, + $canvas-subtle: $tertiarySystemGroupedBackground, + + $border-default: scale.$base-2, + $border-muted: lighten(scale.$base-2, 0.03), + $border-subtle: utils.flattenColor(scale.$light, color.change(scale.$dark, $alpha: 0.15)), + $shadow-default: scale.$base-2, + + $neutral-emphasisPlus: scale.$base-7, + $neutral-emphasis: scale.$base-6, + $neutral-muted: utils.flattenColor(scale.$light, color.change(scale.$base-5, $alpha: 0.4)), + $neutral-subtle: utils.flattenColor(scale.$light, color.change(scale.$base-5, $alpha: 0.1)), + + $accent-fg: scale.$accent-5, + $accent-emphasis: scale.$accent-5, + $accent-muted: utils.flattenColor(scale.$light, color.change(scale.$accent-5, $alpha: 0.4)), + $accent-subtle: utils.flattenColor(scale.$light, color.change(scale.$accent-5, $alpha: 0.1)), + + $success-fg: scale.$success-6, + $success-emphasis: scale.$success-5, + $success-muted: utils.flattenColor(scale.$light, color.change(scale.$success-5, $alpha: 0.4)), + $success-subtle: utils.flattenColor(scale.$light, color.change(scale.$success-5, $alpha: 0.1)), + + $warning-fg: scale.$warning-5, + $warning-emphasis: scale.$warning-6, + $warning-muted: utils.flattenColor(scale.$light, color.change(scale.$warning-5, $alpha: 0.4)), + $warning-subtle: utils.flattenColor(scale.$light, color.change(scale.$warning-5, $alpha: 0.1)), + + $danger-fg: scale.$danger-5, + $danger-emphasis: scale.$danger-5, + $danger-muted: utils.flattenColor(scale.$light, color.change(scale.$danger-5, $alpha: 0.4)), + $danger-subtle: utils.flattenColor(scale.$light, color.change(scale.$danger-5, $alpha: 0.15)) +); + +@forward "settings/config" with ( + $darkMode: false, + $padding-y: 6px, + $border-radius: 6px, + $checkbox-mark-size: 0.85em +); + +@use "general"; + +@forward "components/button" as button-* with ( + $color-bg: $systemBackground, + $color-success-bg-focused: -color-success-6, + $use-shadow: true +); + +@forward "components/checkbox" as checkbox-* with ( + $color-box-indeterminate: -color-accent-emphasis, + $color-border-indeterminate: -color-accent-emphasis, + $color-mark-indeterminate: -color-fg-emphasis +); + +@forward "components/combo-box" as combo-box-* with ( + $use-alt-icon: true, + $color-arrow-button-fg: -color-accent-fg, + $color-list-bg-hover: -color-accent-emphasis, + $color-list-bg-selected: -color-accent-emphasis, + $color-list-fg-hover: -color-fg-emphasis, + $color-list-fg-selected: -color-fg-emphasis +); + +@forward "components/data" as data-* with ( + $color-header-bg: -color-bg-default, + $color-header-fg: -color-fg-muted +); + +@forward "components/date-picker" as date-picker-* with ( + $cell-padding-x: 2px, + $cell-padding-y: 2px, + $cell-size: 2.5em, + $color-icon: -color-accent-fg, + $day-cell-font-size: 0.85em, + $day-name-font-size: 0.9em, + $month-year-font-size: 1em +); + +@forward "components/menu" as menu-* with ( + $color-menuitem-bg-hover: -color-accent-emphasis, + $color-menuitem-fg-hover: -color-fg-emphasis +); + +@forward "components/menu-button" as menu-button-* with ( + $color-split-arrow-bg: -color-accent-emphasis, + $color-split-arrow-fg: -color-fg-emphasis, + $color-split-arrow-opacity: 1.0 +); + +@forward "components/radio" as radio-* with ( + $dot-width-selected: 2px +); + +@forward "components/slider" as slider-* with ( + $color-thumb: -color-bg-default, + $color-thumb-border: -color-border-default, + $color-thumb-large: -color-bg-default, + $color-thumb-large-border: -color-border-default, + $thumb-border-width: 0.5px, + $thumb-effect: dropshadow(gaussian, -color-border-default, 3px, 0.25, 0, 1) +); + +@forward "components/split-pane" as split-pane-* with ( + $divider-thickness: 1px, + $grabber-length: 5px +); + +@forward "components/spinner" as spinner-* with ( + $color-button-bg: -color-accent-emphasis, + $color-button-fg: -color-fg-emphasis, + $color-button-hover: -color-accent-3 +); + +// There are two types of tabs on MacOS. Segmented button tabs and Safari tabs. +// The first one can't be implemented from TabPane with just CSS, so it's not supported. +// Safari tabs implemented as floating tabs. +@forward "components/tab-pane" as tab-pane-* with ( + $color-float-bg: -color-base-1, + $color-float-bg-selected: -color-base-3 +); + +@forward "components/toggle-button" as toggle-button-* with ( + $color-bg-selected: -color-accent-emphasis, + $color-fg-selected: -color-fg-emphasis, + $color-border-selected: scale.$accent-6 +); + +@use "components";