Checkbox: Updates to look and feel and using new theme (#33310)

* Checkbox: Updates to look and feel and using new theme

* A few more theme fixes

* Removed comments

* Updated snapshot
This commit is contained in:
Torkel Ödegaard 2021-04-23 14:40:06 +02:00 committed by GitHub
parent b6cfb65e40
commit e6a9654d0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 99 additions and 144 deletions

View File

@ -13,7 +13,7 @@ export function createShadows(colors: ThemeColors): ThemeShadows {
return {
z1: '0px 1px 2px rgba(24, 26, 27, 0.75)',
z2: '0px 4px 8px rgba(24, 26, 27, 0.75)',
z3: '0px 10px 20px #181A1B',
z3: '0px 10px 20px rgb(20,20,20)',
};
}

View File

@ -171,27 +171,18 @@ export function createV1Theme(theme: Omit<GrafanaThemeV2, 'v1'>): GrafanaTheme {
// Next-gen forms functional colors
formLabel: theme.colors.text.primary,
formDescription: theme.colors.text.secondary,
formInputBg: basicColors.gray05,
formInputBgDisabled: basicColors.gray10,
formInputBorder: borders.border2,
formInputBorderHover: basicColors.gray33,
formInputBorderActive: basicColors.blue95,
formInputBorderInvalid: basicColors.red88,
formInputPlaceholderText: textColors.textFaint,
formInputText: basicColors.gray85,
formInputDisabledText: basicColors.gray70,
formFocusOutline: basicColors.blue77,
formValidationMessageText: basicColors.white,
formValidationMessageBg: basicColors.red88,
formSwitchBg: basicColors.gray25,
formSwitchBgActive: basicColors.blue95,
formSwitchBgHover: basicColors.gray33,
formSwitchBgActiveHover: basicColors.blue80,
formSwitchBgDisabled: basicColors.gray25,
formSwitchDot: basicColors.gray15,
formCheckboxBgChecked: basicColors.blue95,
formCheckboxBgCheckedHover: basicColors.blue80,
formCheckboxCheckmark: basicColors.gray25,
formInputBg: theme.components.input.background,
formInputBgDisabled: theme.colors.action.disabledBackground,
formInputBorder: theme.components.input.borderColor,
formInputBorderHover: theme.components.input.borderHover,
formInputBorderActive: theme.colors.primary.border,
formInputBorderInvalid: theme.colors.error.border,
formInputPlaceholderText: theme.colors.text.disabled,
formInputText: theme.components.input.text,
formInputDisabledText: theme.colors.action.disabledText,
formFocusOutline: theme.colors.primary.main,
formValidationMessageText: theme.colors.error.contrastText,
formValidationMessageBg: theme.colors.error.main,
};
return {

View File

@ -234,15 +234,6 @@ export interface GrafanaTheme extends GrafanaThemeCommons {
formInputPlaceholderText: string;
formValidationMessageText: string;
formValidationMessageBg: string;
formSwitchBg: string;
formSwitchBgActive: string;
formSwitchBgActiveHover: string;
formSwitchBgHover: string;
formSwitchBgDisabled: string;
formSwitchDot: string;
formCheckboxBgChecked: string;
formCheckboxBgCheckedHover: string;
formCheckboxCheckmark: string;
};
shadows: {
listItem: string;

View File

@ -1,9 +1,9 @@
import React, { HTMLProps, useCallback } from 'react';
import { GrafanaTheme } from '@grafana/data';
import { GrafanaThemeV2 } from '@grafana/data';
import { getLabelStyles } from './Label';
import { useTheme, stylesFactory } from '../../themes';
import { useTheme2, stylesFactory } from '../../themes';
import { css, cx } from '@emotion/css';
import { focusCss } from '../../themes/mixins';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
export interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
label?: string;
@ -11,29 +11,30 @@ export interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, 'value'
value?: boolean;
}
export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
export const getCheckboxStyles = stylesFactory((theme: GrafanaThemeV2) => {
const labelStyles = getLabelStyles(theme);
const checkboxSize = '16px';
return {
label: cx(
labelStyles.label,
css`
padding-left: ${theme.spacing.formSpacingBase}px;
padding-left: ${theme.spacing(1)};
white-space: nowrap;
cursor: pointer;
`
),
description: cx(
labelStyles.description,
css`
line-height: ${theme.typography.lineHeight.sm};
padding-left: ${theme.spacing.formSpacingBase}px;
line-height: ${theme.typography.bodySmall.lineHeight};
padding-left: ${theme.spacing(1)};
`
),
wrapper: css`
position: relative;
padding-left: ${checkboxSize};
vertical-align: middle;
height: ${theme.spacing.lg};
height: ${theme.spacing(3)};
`,
input: css`
position: absolute;
@ -42,8 +43,14 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
width: 100%;
height: 100%;
opacity: 0;
&:focus + span {
${focusCss(theme)}
&:focus + span,
&:focus-visible + span {
${getFocusStyles(theme)}
}
&:focus:not(:focus-visible) + span {
${getMouseFocusStyles(theme)}
}
/**
@ -53,11 +60,11 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
* */
&:checked + span {
background: blue;
background: ${theme.colors.formCheckboxBgChecked};
background: ${theme.colors.primary.main};
border: none;
&:hover {
background: ${theme.colors.formCheckboxBgCheckedHover};
background: ${theme.colors.primary.shade};
}
&:after {
@ -67,7 +74,7 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
top: 1px;
width: 6px;
height: 12px;
border: solid ${theme.colors.formCheckboxCheckmark};
border: solid ${theme.colors.primary.contrastText};
border-width: 0 3px 3px 0;
transform: rotate(45deg);
}
@ -77,17 +84,17 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
display: inline-block;
width: ${checkboxSize};
height: ${checkboxSize};
border-radius: ${theme.border.radius.sm};
margin-right: ${theme.spacing.formSpacingBase}px;
background: ${theme.colors.formInputBg};
border: 1px solid ${theme.colors.formInputBorder};
border-radius: ${theme.shape.borderRadius()};
margin-right: ${theme.spacing(1)};
background: ${theme.components.input.background};
border: 1px solid ${theme.components.input.borderColor};
position: absolute;
top: 2px;
left: 0;
&:hover {
cursor: pointer;
border-color: ${theme.colors.formInputBorderHover};
border-color: ${theme.components.input.borderHover};
}
`,
};
@ -95,7 +102,7 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme) => {
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
({ label, description, value, onChange, disabled, className, ...inputProps }, ref) => {
const theme = useTheme();
const theme = useTheme2();
const handleOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
if (onChange) {

View File

@ -1,9 +1,8 @@
import React from 'react';
import { useTheme, stylesFactory } from '../../themes';
import { GrafanaTheme } from '@grafana/data';
import { useTheme2, stylesFactory } from '../../themes';
import { GrafanaThemeV2 } from '@grafana/data';
import { css, cx } from '@emotion/css';
import { Icon } from '../Icon/Icon';
import tinycolor from 'tinycolor2';
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
children: React.ReactNode;
@ -11,16 +10,15 @@ export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>
category?: string[];
}
export const getLabelStyles = stylesFactory((theme: GrafanaTheme) => {
export const getLabelStyles = stylesFactory((theme: GrafanaThemeV2) => {
return {
label: css`
label: Label;
font-size: ${theme.typography.size.sm};
font-weight: ${theme.typography.weight.semibold};
font-weight: ${theme.typography.fontWeightMedium};
line-height: 1.25;
margin: ${theme.spacing.formLabelMargin};
padding: ${theme.spacing.formLabelPadding};
color: ${theme.colors.formLabel};
margin-bottom: ${theme.spacing(0.5)};
color: ${theme.colors.text.primary};
max-width: 480px;
`,
labelContent: css`
@ -29,28 +27,25 @@ export const getLabelStyles = stylesFactory((theme: GrafanaTheme) => {
`,
description: css`
label: Label-description;
color: ${theme.colors.formDescription};
color: ${theme.colors.text.secondary};
font-size: ${theme.typography.size.sm};
font-weight: ${theme.typography.weight.regular};
margin-top: ${theme.spacing.xxs};
font-weight: ${theme.typography.fontWeightRegular};
margin-top: ${theme.spacing(0.25)};
display: block;
`,
categories: css`
label: Label-categories;
color: ${theme.isLight
? tinycolor(theme.colors.formLabel).lighten(10).toHexString()
: tinycolor(theme.colors.formLabel).darken(10).toHexString()};
display: inline-flex;
align-items: center;
`,
chevron: css`
margin: 0 ${theme.spacing.xxs};
margin: 0 ${theme.spacing(0.25)};
`,
};
});
export const Label: React.FC<LabelProps> = ({ children, description, className, category, ...labelProps }) => {
const theme = useTheme();
const theme = useTheme2();
const styles = getLabelStyles(theme);
const categories = category?.map((c, i) => {
return (

View File

@ -14,7 +14,7 @@ export const getFormStyles = stylesFactory(
console.warn('getFormStyles is deprecated');
return {
label: getLabelStyles(theme.v1),
label: getLabelStyles(theme),
legend: getLegendStyles(theme.v1),
fieldValidationMessage: getFieldValidationMessageStyles(theme.v1),
button: getButtonStyles({
@ -23,7 +23,7 @@ export const getFormStyles = stylesFactory(
size: options.size,
}),
input: getInputStyles({ theme, invalid: options.invalid }),
checkbox: getCheckboxStyles(theme.v1),
checkbox: getCheckboxStyles(theme),
};
}
);

View File

@ -1,7 +1,7 @@
import React, { PropsWithChildren } from 'react';
import { css, cx } from '@emotion/css';
import { GrafanaTheme, SelectableValue, getTimeZoneInfo } from '@grafana/data';
import { useTheme } from '../../../themes/ThemeContext';
import { GrafanaThemeV2, SelectableValue, getTimeZoneInfo } from '@grafana/data';
import { useTheme2 } from '../../../themes/ThemeContext';
import { stylesFactory } from '../../../themes/stylesFactory';
import { Icon } from '../../Icon/Icon';
import { TimeZoneOffset } from './TimeZoneOffset';
@ -24,7 +24,7 @@ export interface SelectableZone extends SelectableValue<string> {
export const WideTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props, ref) => {
const { children, innerProps, data, isSelected, isFocused } = props;
const theme = useTheme();
const theme = useTheme2();
const styles = getStyles(theme);
const timestamp = Date.now();
const containerStyles = cx(styles.container, isFocused && styles.containerFocused);
@ -56,7 +56,7 @@ export const WideTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props, re
export const CompactTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props, ref) => {
const { children, innerProps, data, isSelected, isFocused } = props;
const theme = useTheme();
const theme = useTheme2();
const styles = getStyles(theme);
const timestamp = Date.now();
const containerStyles = cx(styles.container, isFocused && styles.containerFocused);
@ -93,9 +93,7 @@ export const CompactTimeZoneOption: React.FC<PropsWithChildren<Props>> = (props,
);
};
const getStyles = stylesFactory((theme: GrafanaTheme) => {
const offsetHoverBg = theme.isDark ? theme.palette.gray05 : theme.palette.white;
const getStyles = stylesFactory((theme: GrafanaThemeV2) => {
return {
container: css`
display: flex;
@ -104,34 +102,18 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
flex-shrink: 0;
white-space: nowrap;
cursor: pointer;
border-left: 2px solid transparent;
padding: 6px 8px 4px;
&:hover {
background: ${theme.colors.dropdownOptionHoverBg};
span.${offsetClassName} {
background: ${offsetHoverBg};
}
background: ${theme.colors.action.hover};
}
`,
containerFocused: css`
background: ${theme.colors.dropdownOptionHoverBg};
border-image: linear-gradient(#f05a28 30%, #fbca0a 99%);
border-image-slice: 1;
border-style: solid;
border-top: 0;
border-right: 0;
border-bottom: 0;
border-left-width: 2px;
span.${offsetClassName} {
background: ${offsetHoverBg};
}
background: ${theme.colors.action.hover};
`,
body: css`
display: flex;
font-weight: ${theme.typography.weight.semibold};
font-weight: ${theme.typography.fontWeightMedium};
flex-direction: column;
flex-grow: 1;
`,

View File

@ -200,11 +200,11 @@ $btn-active-box-shadow: 0px 0px 4px rgba(234, 161, 51, 0.6);
// Forms
// -------------------------
$input-bg: $white;
$input-bg-disabled: $gray-5;
$input-bg: ${theme.components.input.background};
$input-bg-disabled: ${theme.colors.action.disabledBackground};
$input-color: ${theme.v1.colors.formInputText};
$input-border-color: ${theme.v1.colors.formInputBorder};
$input-color: ${theme.components.input.text};
$input-border-color: ${theme.components.input.borderColor};
$input-box-shadow: none;
$input-border-focus: ${theme.v1.palette.blue95};
$input-box-shadow-focus: ${theme.v1.palette.blue95};

View File

@ -2,7 +2,7 @@
exports[`Render should render component 1`] = `
<div
className="panel-container css-ozhi9g"
className="panel-container css-e4b3m6"
>
<AddPanelWidgetHandle
onCancel={[Function]}
@ -15,7 +15,7 @@ exports[`Render should render component 1`] = `
"libraryPanelsWrapper": "css-18m13of",
"noMargin": "css-u023fv",
"panelSearchInput": "css-2ug8g3",
"wrapper": "css-ozhi9g",
"wrapper": "css-e4b3m6",
}
}
>

View File

@ -1,7 +1,6 @@
import React, { FunctionComponent, useEffect, useState } from 'react';
import { LegacyForms } from '@grafana/ui';
import { AnnotationQuery } from '@grafana/data';
const { Switch } = LegacyForms;
import { InlineField, InlineSwitch } from '@grafana/ui';
interface Props {
annotations: AnnotationQuery[];
@ -22,16 +21,10 @@ export const Annotations: FunctionComponent<Props> = ({ annotations, onAnnotatio
<>
{visibleAnnotations.map((annotation: any) => {
return (
<div
key={annotation.name}
className={annotation.enable ? 'submenu-item' : 'submenu-item annotation-disabled'}
>
<Switch
label={annotation.name}
className="gf-form"
checked={annotation.enable}
onChange={() => onAnnotationChanged(annotation)}
/>
<div key={annotation.name} className={'submenu-item'}>
<InlineField label={annotation.name}>
<InlineSwitch checked={annotation.enable} onChange={() => onAnnotationChanged(annotation)} />
</InlineField>
</div>
);
})}

View File

@ -110,7 +110,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
width: 100%;
&:hover {
background: ${theme.colors.formCheckboxBgCheckedHover};
background: ${theme.colors.bgBlue1};
color: ${theme.colors.text};
}
`,

View File

@ -1,7 +1,7 @@
import React, { forwardRef, HTMLAttributes } from 'react';
import { cx, css } from '@emotion/css';
import { GrafanaTheme } from '@grafana/data';
import { useTheme } from '@grafana/ui';
import { GrafanaThemeV2 } from '@grafana/data';
import { useTheme2 } from '@grafana/ui';
// @ts-ignore
import Highlighter from 'react-highlight-words';
@ -22,7 +22,7 @@ export interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
export const LokiLabel = forwardRef<HTMLElement, Props>(
({ name, value, hidden, facets, onClick, className, loading, searchTerm, active, style, ...rest }, ref) => {
const theme = useTheme();
const theme = useTheme2();
const styles = getLabelStyles(theme);
const searchWords = searchTerm ? [searchTerm] : [];
@ -64,47 +64,47 @@ export const LokiLabel = forwardRef<HTMLElement, Props>(
LokiLabel.displayName = 'LokiLabel';
const getLabelStyles = (theme: GrafanaTheme) => ({
const getLabelStyles = (theme: GrafanaThemeV2) => ({
base: css`
cursor: pointer;
font-size: ${theme.typography.size.sm};
line-height: ${theme.typography.lineHeight.xs};
background-color: ${theme.colors.bg3};
line-height: ${theme.typography.bodySmall.lineHeight};
background-color: ${theme.colors.background.secondary};
vertical-align: baseline;
color: ${theme.colors.text};
white-space: nowrap;
text-shadow: none;
padding: ${theme.spacing.xs};
border-radius: ${theme.border.radius.md};
margin-right: ${theme.spacing.sm};
margin-bottom: ${theme.spacing.xs};
padding: ${theme.spacing(0.5)};
border-radius: ${theme.shape.borderRadius()};
margin-right: ${theme.spacing(1)};
margin-bottom: ${theme.spacing(0.5)};
`,
loading: css`
font-weight: ${theme.typography.weight.semibold};
background-color: ${theme.colors.formSwitchBgHover};
color: ${theme.palette.gray98};
font-weight: ${theme.typography.fontWeightMedium};
background-color: ${theme.colors.primary.shade};
color: ${theme.colors.text.primary};
animation: pulse 3s ease-out 0s infinite normal forwards;
@keyframes pulse {
0% {
color: ${theme.colors.textSemiWeak};
color: ${theme.colors.text.primary};
}
50% {
color: ${theme.colors.textFaint};
color: ${theme.colors.text.secondary};
}
100% {
color: ${theme.colors.textSemiWeak};
color: ${theme.colors.text.disabled};
}
}
`,
active: css`
font-weight: ${theme.typography.weight.semibold};
background-color: ${theme.colors.formSwitchBgActive};
color: ${theme.colors.formSwitchDot};
font-weight: ${theme.typography.fontWeightMedium};
background-color: ${theme.colors.primary.main};
color: ${theme.colors.primary.contrastText};
`,
matchHighLight: css`
background: inherit;
color: ${theme.palette.yellow};
background-color: rgba(${theme.palette.yellow}, 0.1);
color: ${theme.colors.primary.text};
background-color: ${theme.colors.primary.transparent};
`,
hidden: css`
opacity: 0.6;

View File

@ -263,7 +263,7 @@ $side-menu-header-color: rgb(201, 209, 217);
// -------------------------
$menu-dropdown-bg: #181b1f;
$menu-dropdown-hover-bg: rgba(201, 209, 217, 0.08);
$menu-dropdown-shadow: 0px 10px 20px #181A1B;
$menu-dropdown-shadow: 0px 10px 20px rgb(20,20,20);
// Tabs
// -------------------------
@ -296,7 +296,7 @@ $popover-bg: #181b1f;
$popover-color: rgb(201, 209, 217);
$popover-border-color: rgba(201, 209, 217, 0.10);
$popover-header-bg: #22252b;
$popover-shadow: 0px 10px 20px #181A1B;
$popover-shadow: 0px 10px 20px rgb(20,20,20);
$popover-help-bg: $tooltipBackground;
$popover-help-color: $text-color;

View File

@ -202,10 +202,10 @@ $btn-active-box-shadow: 0px 0px 4px rgba(234, 161, 51, 0.6);
// Forms
// -------------------------
$input-bg: $white;
$input-bg-disabled: $gray-5;
$input-bg: #fff;
$input-bg-disabled: rgba(36, 41, 46, 0.07);
$input-color: #c7d0d9;
$input-color: rgba(36, 41, 46, 1);
$input-border-color: rgba(36, 41, 46, 0.30);
$input-box-shadow: none;
$input-border-focus: #5794f2;

View File

@ -7,11 +7,6 @@
padding: 0 0 $space-sm 0;
}
.annotation-disabled,
.annotation-disabled a {
color: $link-color-disabled;
}
.annotation-segment {
padding: 8px 7px;

View File

@ -5,6 +5,7 @@
max-width: 100%;
line-height: 22px;
background-color: $input-bg;
border: 1px solid $input-border-color;
input {
display: inline-block;