diff --git a/packages/grafana-ui/src/themes/GlobalStyles/utilityClasses.ts b/packages/grafana-ui/src/themes/GlobalStyles/utilityClasses.ts index f931952116c..ac14021ea41 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/utilityClasses.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/utilityClasses.ts @@ -2,6 +2,37 @@ import { css } from '@emotion/react'; import { GrafanaTheme2 } from '@grafana/data'; +function buttonBackgroundMixin( + startColor: string, + endColor: string, + textColor = '#fff', + textShadow = '0px 1px 0 rgba(0, 0, 0, 0.1)' +) { + return { + backgroundColor: startColor, + backgroundImage: `linear-gradient(to bottom, ${startColor}, ${endColor})`, + backgroundRepeat: 'repeat-x', + color: textColor, + textShadow: textShadow, + borderColor: startColor, + + // in these cases the gradient won't cover the background, so we override + '&:hover, &:focus, &:active, &.active, &.disabled, &[disabled]': { + color: textColor, + backgroundImage: 'none', + backgroundColor: startColor, + }, + }; +} + +function buttonSizeMixin(paddingY: string, paddingX: string, fontSize: string, borderRadius: string) { + return { + padding: `${paddingY} ${paddingX}`, + fontSize: fontSize, + borderRadius: borderRadius, + }; +} + export function getUtilityClassStyles(theme: GrafanaTheme2) { return css({ '.highlight-word': { @@ -38,5 +69,73 @@ export function getUtilityClassStyles(theme: GrafanaTheme2) { justifyContent: 'center', justifyItems: 'center', }, + '.btn': { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + fontWeight: theme.typography.fontWeightMedium, + lineHeight: theme.typography.body.lineHeight, + textAlign: 'center', + verticalAlign: 'middle', + cursor: 'pointer', + border: 'none', + height: `${theme.spacing.gridSize * theme.components.height.md}px`, + ...buttonSizeMixin( + theme.spacing(0), + theme.spacing(2), + `${theme.typography.fontSize}px`, + theme.shape.radius.default + ), + + '&, &:active, &.active': { + '&:focus, &.focus': { + outline: 'none', + }, + }, + '&:focus, &:hover': { + textDecoration: 'none', + }, + '&.focus': { + textDecoration: 'none', + }, + '&:active, &.active': { + backgroundImage: 'none', + outline: 0, + }, + '&.disabled, &[disabled], &:disabled': { + cursor: 'not-allowed', + opacity: 0.65, + boxShadow: 'none', + pointerEvents: 'none', + }, + }, + '.btn-small': { + ...buttonSizeMixin(theme.spacing(0.5), theme.spacing(1), theme.typography.size.sm, theme.shape.radius.default), + height: `${theme.spacing.gridSize * theme.components.height.sm}px`, + }, + // Deprecated, only used by old plugins + '.btn-mini': { + ...buttonSizeMixin(theme.spacing(0.5), theme.spacing(1), theme.typography.size.sm, theme.shape.radius.default), + height: `${theme.spacing.gridSize * theme.components.height.sm}px`, + }, + '.btn-success, .btn-primary': { + ...buttonBackgroundMixin(theme.colors.primary.main, theme.colors.primary.shade), + }, + '.btn-danger': { + ...buttonBackgroundMixin(theme.colors.error.main, theme.colors.error.shade), + }, + '.btn-secondary': { + ...buttonBackgroundMixin(theme.colors.secondary.main, theme.colors.secondary.shade, theme.colors.text.primary), + }, + '.btn-inverse': { + ...buttonBackgroundMixin( + theme.isDark ? theme.v1.palette.dark6 : theme.v1.palette.gray5, + theme.isDark ? theme.v1.palette.dark5 : theme.v1.palette.gray4, + theme.colors.text.primary + ), + '&': { + boxShadow: 'none', + }, + }, }); } diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 524357a008c..cd1f36c9bfc 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -8,7 +8,6 @@ @import 'utils/widths'; // COMPONENTS -@import 'components/buttons'; @import 'components/dropdown'; // ANGULAR diff --git a/public/sass/components/_buttons.scss b/public/sass/components/_buttons.scss deleted file mode 100644 index 5af22a2a797..00000000000 --- a/public/sass/components/_buttons.scss +++ /dev/null @@ -1,415 +0,0 @@ -@use 'sass:color'; -@use 'sass:map'; - -// Gradient Bar Colors for buttons and alerts -@mixin gradientBar($primaryColor, $secondaryColor, $text-color: #fff, $textShadow: 0 -1px 0 rgba(0, 0, 0, 0.25)) { - background-color: color.mix($primaryColor, $secondaryColor, 60%); - background-image: linear-gradient(to bottom, $primaryColor, $secondaryColor); // Standard, IE10 - background-repeat: repeat-x; - color: $text-color; - text-shadow: $textShadow; - border-color: $primaryColor; -} - -@mixin hover { - @if $enable-hover-media-query { - // See Media Queries Level 4: http://drafts.csswg.org/mediaqueries/#hover - // Currently shimmed by https://github.com/twbs/mq4-hover-shim - @media (hover: hover) { - &:hover { - @content; - } - } - } @else { - &:hover { - @content; - } - } -} - -@mixin hover-focus { - @if $enable-hover-media-query { - &:focus { - @content; - } - @include hover { - @content; - } - } @else { - &:focus, - &:hover { - @content; - } - } -} - -// Button backgrounds -// ------------------ -@mixin buttonBackground($startColor, $endColor, $text-color: #fff, $textShadow: 0px 1px 0 rgba(0, 0, 0, 0.1)) { - // gradientBar will set the background to a pleasing blend of these, to support IE<=9 - @include gradientBar($startColor, $endColor, $text-color, $textShadow); - - // in these cases the gradient won't cover the background, so we override - &:hover, - &:focus, - &:active, - &.active, - &.disabled, - &[disabled] { - color: $text-color; - background-image: none; - background-color: $startColor; - } -} - -// Button sizes -@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { - padding: $padding-y $padding-x; - font-size: $font-size; - //box-shadow: inset 0 (-$padding-y/3) rgba(0,0,0,0.15); - - border-radius: $border-radius; -} - -@mixin button-outline-variant($color) { - color: $white; - background-image: none; - background-color: transparent; - border: 1px solid $white; - - @include hover { - color: $white; - background-color: $color; - } - - &:focus, - &.focus { - color: $white; - background-color: $color; - } - - &:active, - &.active, - .open > &.dropdown-toggle { - color: $white; - background-color: $color; - - &:hover, - &:focus, - &.focus { - color: $white; - background-color: color.adjust($color, $lightness: -17%); - border-color: color.adjust($color, $lightness: -25%); - } - } - - &.disabled, - &:disabled { - &:focus, - &.focus { - border-color: color.adjust($color, $lightness: 20%); - } - @include hover { - border-color: color.adjust($color, $lightness: 20%); - } - } -} - -// -// Buttons -// -------------------------------------------------- - -// Base styles -// -------------------------------------------------- - -// Core -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - font-weight: $btn-font-weight; - line-height: $btn-line-height; - font-size: $font-size-base; - text-align: center; - vertical-align: middle; - cursor: pointer; - border: none; - height: $height-md + px; - - @include button-size($btn-padding-y, $space-md, $font-size-base, $border-radius-sm); - - &, - &:active, - &.active { - &:focus, - &.focus { - outline: none; - } - } - - @include hover-focus { - text-decoration: none; - } - &.focus { - text-decoration: none; - } - - &:active, - &.active { - background-image: none; - outline: 0; - } - - &.disabled, - &[disabled], - &:disabled { - cursor: $cursor-disabled; - opacity: 0.65; - box-shadow: none; - pointer-events: none; - } - - &--radius-left-0 { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - - &--radius-right-0 { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } -} - -// Button Sizes -// -------------------------------------------------- - -// Large -.btn-large { - @include button-size($btn-padding-y-lg, $space-lg, $font-size-lg, $border-radius-sm); - font-weight: normal; - height: $height-lg + px; - - .gicon { - //font-size: 31px; - margin-right: $space-sm; - filter: brightness(100); - } -} - -.btn-small { - @include button-size($btn-padding-y-sm, $space-sm, $font-size-sm, $border-radius-sm); - height: $height-sm + px; -} - -// Deprecated, only used by old plugins -.btn-mini { - @include button-size($btn-padding-y-sm, $space-sm, $font-size-sm, $border-radius-sm); - height: #{height-sm}px; -} - -.btn-link { - color: $btn-link-color; - background: transparent; -} - -// Set the backgrounds -// ------------------------- -.btn-success, -.btn-primary { - @include buttonBackground($btn-primary-bg, $btn-primary-bg-hl); -} - -.btn-secondary { - @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); -} - -// Danger and error appear as red -.btn-danger { - @include buttonBackground($btn-danger-bg, $btn-danger-bg-hl); -} - -// Info appears as a neutral blue -.btn-secondary { - @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl, $text-color); - // Inverse appears as dark gray -} -.btn-inverse { - @include buttonBackground($btn-inverse-bg, $btn-inverse-bg-hl, $btn-inverse-text-color, $btn-inverse-text-shadow); - //background: $card-background; - /* stylelint-disable-next-line */ - & { - box-shadow: $card-shadow; - } - //border: 1px solid $tight-form-func-highlight-bg; -} - -.btn-transparent { - background-color: transparent; -} - -.btn-outline-primary { - @include button-outline-variant($btn-primary-bg); -} -.btn-outline-secondary { - @include button-outline-variant($btn-secondary-bg-hl); -} -.btn-outline-inverse { - @include button-outline-variant($btn-inverse-bg); -} -.btn-outline-danger { - @include button-outline-variant($btn-danger-bg); -} - -.btn-outline-disabled { - @include button-outline-variant($gray-1); - /* stylelint-disable-next-line */ - & { - box-shadow: none; - cursor: default; - } - - &:hover, - &:active, - &:active:hover, - &:focus { - color: $gray-1; - background-color: transparent; - border-color: $gray-1; - } -} - -// Extra padding -.btn-p-x-2 { - padding-left: 20px; - padding-right: 20px; -} - -// No horizontal padding -.btn-p-x-0 { - padding-left: 0; - padding-right: 0; -} - -// External services -// Usage: -//
Button text
- -$btn-service-icon-width: 35px; -.btn-service { - position: relative; -} - -@each $service, $data in $external-services { - $serviceBgColor: map.get($data, bgColor); - $serviceBorderColor: map.get($data, borderColor); - - .btn-service--#{$service} { - background-color: $serviceBgColor; - border: 1px solid $serviceBorderColor; - - .btn-service-icon { - font-size: 24px; // Override - border-right: 1px solid $serviceBorderColor; - } - } -} - -.btn-service-icon { - position: absolute; - left: 0; - height: 100%; - top: 0; - padding-left: $space-sm; - padding-right: $space-sm; - width: $btn-service-icon-width; - text-align: center; - - &::before { - position: relative; - top: 4px; - } -} - -.btn-service--grafanacom { - .btn-service-icon { - background-image: url(../img/grafana_mask_icon_white.svg); - background-repeat: no-repeat; - background-position: 50%; - background-size: 60%; - } -} - -.btn-service--azuread { - .btn-service-icon { - background-image: url(../img/microsoft_auth_icon.svg); - background-repeat: no-repeat; - background-position: 50%; - background-size: 60%; - } -} - -.btn-service--okta { - .btn-service-icon { - background-image: url(../img/okta_logo_white.png); - background-repeat: no-repeat; - background-position: 50%; - background-size: 60%; - } -} - -//Toggle button - -.toggle-btn { - background: $input-label-bg; - color: $text-color-weak; - box-shadow: $card-shadow; - - &:first-child { - border-radius: 2px 0 0 2px; - margin: 0; - } - &:last-child { - border-radius: 0 2px 2px 0; - margin-left: 0 !important; - } - - &.active { - background-color: color.adjust($input-label-bg, $lightness: 5%); - color: $link-color; - &:hover { - cursor: default; - } - } -} - -//Button animations - -.btn-loading span { - animation-name: blink; - animation-duration: 1.4s; - animation-iteration-count: infinite; - animation-fill-mode: both; -} - -.btn-loading span:nth-child(2) { - animation-delay: 0.2s; -} - -.btn-loading span:nth-child(3) { - animation-delay: 0.4s; -} - -@keyframes blink { - 0% { - opacity: 0.2; - font-size: 14; - } - 20% { - opacity: 1; - font-size: 18; - } - 100% { - opacity: 0.2; - font-size: 14; - } -}