Skip to content

Commit

Permalink
Docs: Add styling.md with guide to Emotion at Grafana (grafana#19411)
Browse files Browse the repository at this point in the history
* Add styling.md with guide to emotion

* Update style_guides/styling.md

* Update style_guides/styling.md

* Update style_guides/styling.md

* Update PR guide

* Add stylesFactory helper function

* Simplify styles creator signature

* Make styles factory deps optional

* Update typing

* First batch of updates

* Remove unused import

* Update tests
  • Loading branch information
dprokop authored Sep 26, 2019
1 parent a3008ff commit 75b21c7
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 185 deletions.
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Whether you are contributing or doing code review, first read and understand htt
### Low-level checks

- [ ] The pull request contains a title that explains it. It follows [PR and commit messages guidelines](#Pull-Requests-titles-and-message).
- [ ] The pull request contains necessary links to issues.
- [ ] The pull request contains necessary links to issues.
- [ ] The pull request contains commits with messages that are small and understandable. It follows [PR and commit messages guidelines](#Pull-Requests-titles-and-message).
- [ ] The pull request does not contain magic strings or numbers that could be replaced with an `Enum` or `const` instead.

Expand All @@ -58,6 +58,8 @@ Whether you are contributing or doing code review, first read and understand htt
- [ ] The pull request does not contain uses of `any` or `{}` without comments describing why.
- [ ] The pull request does not contain large React components that could easily be split into several smaller components.
- [ ] The pull request does not contain back end calls directly from components, use actions and Redux instead.
- [ ] The pull request follows our [styling with Emotion convention](./style_guides/styling.md)
> We still use a lot of SASS, but any new CSS work should be using or migrating existing code to Emotion
#### Redux specific checks (skip if your pull request does not contain Redux changes)

Expand Down
72 changes: 33 additions & 39 deletions packages/grafana-ui/src/components/BigValue/BigValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getColorFromHexRgbOrName } from '../../utils';

// Types
import { Themeable } from '../../types';
import { stylesFactory } from '../../themes/stylesFactory';

export interface BigValueSparkline {
data: any[][]; // [[number,number]]
Expand All @@ -31,6 +32,33 @@ export interface Props extends Themeable {
className?: string;
}

const getStyles = stylesFactory(() => {
return {
wrapper: css`
position: 'relative';
display: 'table';
`,
title: css`
line-height: 1;
text-align: 'center';
z-index: 1;
display: 'block';
width: '100%';
position: 'absolute';
`,
value: css`
line-height: 1;
text-align: 'center';
z-index: 1;
display: 'table-cell';
vertical-align: 'middle';
position: 'relative';
font-size: '3em';
font-weight: 500;
`,
};
});

/*
* This visualization is still in POC state, needed more tests & better structure
*/
Expand Down Expand Up @@ -122,46 +150,12 @@ export class BigValue extends PureComponent<Props> {

render() {
const { height, width, value, prefix, suffix, sparkline, backgroundColor, onClick, className } = this.props;

const styles = getStyles();
return (
<div
className={cx(
css({
position: 'relative',
display: 'table',
}),
className
)}
style={{ width, height, backgroundColor }}
onClick={onClick}
>
{value.title && (
<div
className={css({
lineHeight: 1,
textAlign: 'center',
zIndex: 1,
display: 'block',
width: '100%',
position: 'absolute',
})}
>
{value.title}
</div>
)}

<span
className={css({
lineHeight: 1,
textAlign: 'center',
zIndex: 1,
display: 'table-cell',
verticalAlign: 'middle',
position: 'relative',
fontSize: '3em',
fontWeight: 500, // TODO: $font-weight-semi-bold
})}
>
<div className={cx(styles.wrapper, className)} style={{ width, height, backgroundColor }} onClick={onClick}>
{value.title && <div className={styles.title}>{value.title}</div>}

<span className={styles.value}>
{this.renderText(prefix, '0px 2px 0px 0px')}
{this.renderText(value)}
{this.renderText(suffix)}
Expand Down
13 changes: 10 additions & 3 deletions packages/grafana-ui/src/components/Button/AbstractButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import tinycolor from 'tinycolor2';
import { css, cx } from 'emotion';
import { Themeable, GrafanaTheme } from '../../types';
import { selectThemeVariant } from '../../themes/selectThemeVariant';
import { stylesFactory } from '../../themes/stylesFactory';

export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'inverse' | 'transparent';

Expand Down Expand Up @@ -49,7 +50,13 @@ const buttonVariantStyles = (
}
`;

const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonVariant, withIcon: boolean) => {
interface StyleDeps {
theme: GrafanaTheme;
size: ButtonSize;
variant: ButtonVariant;
withIcon: boolean;
}
const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }: StyleDeps) => {
const borderRadius = theme.border.radius.sm;
let padding,
background,
Expand Down Expand Up @@ -155,7 +162,7 @@ const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonV
filter: brightness(100);
`,
};
};
});

export const AbstractButton: React.FunctionComponent<AbstractButtonProps> = ({
renderAs,
Expand All @@ -167,7 +174,7 @@ export const AbstractButton: React.FunctionComponent<AbstractButtonProps> = ({
children,
...otherProps
}) => {
const buttonStyles = getButtonStyles(theme, size, variant, !!icon);
const buttonStyles = getButtonStyles({ theme, size, variant, withIcon: !!icon });
const nonHtmlProps = {
theme,
size,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Themeable, GrafanaTheme } from '../../types/theme';
import { selectThemeVariant } from '../../themes/selectThemeVariant';
import { css, cx } from 'emotion';
import { stylesFactory } from '../../themes';

export interface CallToActionCardProps extends Themeable {
message?: string | JSX.Element;
Expand All @@ -10,7 +11,7 @@ export interface CallToActionCardProps extends Themeable {
className?: string;
}

const getCallToActionCardStyles = (theme: GrafanaTheme) => ({
const getCallToActionCardStyles = stylesFactory((theme: GrafanaTheme) => ({
wrapper: css`
label: call-to-action-card;
padding: ${theme.spacing.lg};
Expand All @@ -28,7 +29,7 @@ const getCallToActionCardStyles = (theme: GrafanaTheme) => ({
footer: css`
margin-top: ${theme.spacing.lg};
`,
});
}));

export const CallToActionCard: React.FunctionComponent<CallToActionCardProps> = ({
message,
Expand Down
7 changes: 4 additions & 3 deletions packages/grafana-ui/src/components/Collapse/Collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { css, cx } from 'emotion';

import { GrafanaTheme } from '../../types/theme';
import { selectThemeVariant } from '../../themes/selectThemeVariant';
import { ThemeContext } from '../../themes/index';
import { ThemeContext } from '../../themes/ThemeContext';
import { stylesFactory } from '../../themes/stylesFactory';

const getStyles = (theme: GrafanaTheme) => ({
const getStyles = stylesFactory((theme: GrafanaTheme) => ({
collapse: css`
label: collapse;
margin-top: ${theme.spacing.sm};
Expand Down Expand Up @@ -79,7 +80,7 @@ const getStyles = (theme: GrafanaTheme) => ({
font-size: ${theme.typography.heading.h6};
box-shadow: ${selectThemeVariant({ light: 'none', dark: '1px 1px 4px rgb(45, 45, 45)' }, theme.type)};
`,
});
}));

interface Props {
isOpen: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useContext, useRef } from 'react';
import { css, cx } from 'emotion';
import useClickAway from 'react-use/lib/useClickAway';
import { GrafanaTheme, selectThemeVariant, ThemeContext } from '../../index';
import { stylesFactory } from '../../themes/stylesFactory';
import { Portal, List } from '../index';
import { LinkTarget } from '@grafana/data';

Expand All @@ -26,7 +27,7 @@ export interface ContextMenuProps {
renderHeader?: () => JSX.Element;
}

const getContextMenuStyles = (theme: GrafanaTheme) => {
const getContextMenuStyles = stylesFactory((theme: GrafanaTheme) => {
const linkColor = selectThemeVariant(
{
light: theme.colors.dark2,
Expand Down Expand Up @@ -146,7 +147,7 @@ const getContextMenuStyles = (theme: GrafanaTheme) => {
top: 4px;
`,
};
};
});

export const ContextMenu: React.FC<ContextMenuProps> = React.memo(({ x, y, onClose, items, renderHeader }) => {
const theme = useContext(ThemeContext);
Expand Down
29 changes: 16 additions & 13 deletions packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { DataLink } from '@grafana/data';
import { FormField, Switch } from '../index';
import { VariableSuggestion } from './DataLinkSuggestions';
import { css } from 'emotion';
import { ThemeContext } from '../../themes/index';
import { ThemeContext, stylesFactory } from '../../themes/index';
import { DataLinkInput } from './DataLinkInput';
import { GrafanaTheme } from '../../types';

interface DataLinkEditorProps {
index: number;
Expand All @@ -15,9 +16,21 @@ interface DataLinkEditorProps {
onRemove: (link: DataLink) => void;
}

const getStyles = stylesFactory((theme: GrafanaTheme) => ({
listItem: css`
margin-bottom: ${theme.spacing.sm};
`,
infoText: css`
padding-bottom: ${theme.spacing.md};
margin-left: 66px;
color: ${theme.colors.textWeak};
`,
}));

export const DataLinkEditor: React.FC<DataLinkEditorProps> = React.memo(
({ index, value, onChange, onRemove, suggestions, isLast }) => {
const theme = useContext(ThemeContext);
const styles = getStyles(theme);
const [title, setTitle] = useState(value.title);

const onUrlChange = (url: string, callback?: () => void) => {
Expand All @@ -39,18 +52,8 @@ export const DataLinkEditor: React.FC<DataLinkEditorProps> = React.memo(
onChange(index, { ...value, targetBlank: !value.targetBlank });
};

const listItemStyle = css`
margin-bottom: ${theme.spacing.sm};
`;

const infoTextStyle = css`
padding-bottom: ${theme.spacing.md};
margin-left: 66px;
color: ${theme.colors.textWeak};
`;

return (
<div className={listItemStyle}>
<div className={styles.listItem}>
<div className="gf-form gf-form--inline">
<FormField
className="gf-form--grow"
Expand All @@ -76,7 +79,7 @@ export const DataLinkEditor: React.FC<DataLinkEditorProps> = React.memo(
`}
/>
{isLast && (
<div className={infoTextStyle}>
<div className={styles.infoText}>
With data links you can reference data variables like series name, labels and values. Type CMD+Space,
CTRL+Space, or $ to open variable suggestions.
</div>
Expand Down
31 changes: 16 additions & 15 deletions packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useMemo, useCallback, useContext, useRef, RefObject } from 'react';
import React, { useState, useMemo, useContext, useRef, RefObject } from 'react';
import { VariableSuggestion, VariableOrigin, DataLinkSuggestions } from './DataLinkSuggestions';
import { ThemeContext, DataLinkBuiltInVars, makeValue } from '../../index';
import { SelectionReference } from './SelectionReference';
Expand All @@ -12,6 +12,8 @@ import { css, cx } from 'emotion';

import { SlatePrism } from '../../slate-plugins';
import { SCHEMA } from '../../utils/slate';
import { stylesFactory } from '../../themes';
import { GrafanaTheme } from '../../types';

const modulo = (a: number, n: number) => a - n * Math.floor(a / n);

Expand All @@ -28,26 +30,25 @@ const plugins = [
}),
];

const getStyles = stylesFactory((theme: GrafanaTheme) => ({
editor: css`
.token.builtInVariable {
color: ${theme.colors.queryGreen};
}
.token.variable {
color: ${theme.colors.queryKeyword};
}
`,
}));

export const DataLinkInput: React.FC<DataLinkInputProps> = ({ value, onChange, suggestions }) => {
const editorRef = useRef<Editor>() as RefObject<Editor>;
const theme = useContext(ThemeContext);
const styles = getStyles(theme);
const [showingSuggestions, setShowingSuggestions] = useState(false);
const [suggestionsIndex, setSuggestionsIndex] = useState(0);
const [linkUrl, setLinkUrl] = useState<Value>(makeValue(value));

const getStyles = useCallback(() => {
return {
editor: css`
.token.builtInVariable {
color: ${theme.colors.queryGreen};
}
.token.variable {
color: ${theme.colors.queryKeyword};
}
`,
};
}, [theme]);

// Workaround for https://github.com/ianstormtaylor/slate/issues/2927
const stateRef = useRef({ showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange });
stateRef.current = { showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange };
Expand Down Expand Up @@ -155,7 +156,7 @@ export const DataLinkInput: React.FC<DataLinkInputProps> = ({ value, onChange, s
onBlur={onUrlBlur}
onKeyDown={(event, _editor, next) => onKeyDown(event as KeyboardEvent, next)}
plugins={plugins}
className={getStyles().editor}
className={styles.editor}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, { useRef, useContext, useMemo } from 'react';
import useClickAway from 'react-use/lib/useClickAway';
import { List } from '../index';
import tinycolor from 'tinycolor2';
import { stylesFactory } from '../../themes';

export enum VariableOrigin {
Series = 'series',
Expand All @@ -28,7 +29,7 @@ interface DataLinkSuggestionsProps {
onClose?: () => void;
}

const getStyles = (theme: GrafanaTheme) => {
const getStyles = stylesFactory((theme: GrafanaTheme) => {
const wrapperBg = selectThemeVariant(
{
light: theme.colors.white,
Expand Down Expand Up @@ -129,7 +130,7 @@ const getStyles = (theme: GrafanaTheme) => {
color: ${itemDocsColor};
`,
};
};
});

export const DataLinkSuggestions: React.FC<DataLinkSuggestionsProps> = ({ suggestions, ...otherProps }) => {
const ref = useRef(null);
Expand Down
Loading

0 comments on commit 75b21c7

Please sign in to comment.