Grafana/ui: Add Space component (#81145)

* Grafana/ui: Add Space component

* Add responsive styles and prop docs

* Use the Box component

* Docs

* Replace the component from grafana/experimental

* Update story

* Tweak docs

* Adjust docs
This commit is contained in:
Alex Khomenko 2024-01-25 07:59:24 +01:00 committed by GitHub
parent 05eb4fcd7f
commit f154b2b855
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 146 additions and 73 deletions

View File

@ -7,7 +7,7 @@ import { useStyles2 } from '../../../themes';
import { AlignItems, FlexProps, JustifyContent } from '../types';
import { ResponsiveProp, getResponsiveStyle } from '../utils/responsiveness';
type Display = 'flex' | 'block' | 'inline' | 'none';
type Display = 'flex' | 'block' | 'inline' | 'inline-block' | 'none';
export type BackgroundColor = keyof GrafanaTheme2['colors']['background'] | 'error' | 'success' | 'warning' | 'info';
export type BorderStyle = 'solid' | 'dashed';
export type BorderColor = keyof GrafanaTheme2['colors']['border'] | 'error' | 'success' | 'warning' | 'info';

View File

@ -0,0 +1,22 @@
import { Meta, ArgTypes } from '@storybook/blocks';
import { Space } from './Space';
<Meta title="MDX|Space" component={Space} />
# Space
The `Space` component is a component used to add space between elements. Horizontal space is added using the `h` prop, while vertical space is added using the `v` prop. When adding horizontal space between inline or inline-block elements, the `layout` props should be set to `inline`, otherwise the `block` value of the prop can be used.
### Usage
#### When to use
Use the `Space` component to add space between elements that cannot be spaced using flex or grid layout.
#### When not to use
Do not use the `Space` component to add space between elements inside the `Stack` component. Instead, use the `gap` prop on the `Stack` component.
### Props
<ArgTypes of={Space} />

View File

@ -0,0 +1,70 @@
import { StoryFn, Meta } from '@storybook/react';
import React from 'react';
import { SpacingTokenControl } from '../../utils/storybook/themeStorybookControls';
import { Box } from './Box/Box';
import { Space } from './Space';
import mdx from './Space.mdx';
const meta: Meta<typeof Space> = {
title: 'General/Layout/Space',
component: Space,
parameters: {
docs: {
page: mdx,
},
},
argTypes: {
v: SpacingTokenControl,
h: SpacingTokenControl,
},
};
export default meta;
export const Horizontal: StoryFn<typeof Space> = (args) => {
return (
<div style={{ display: 'flex' }}>
<Box borderStyle={'solid'} padding={1}>
Box without space
</Box>
<Box borderStyle={'solid'} padding={1}>
Box with space on the right
</Box>
<Space {...args} />
<Box borderStyle={'solid'} padding={1}>
Box without space
</Box>
</div>
);
};
Horizontal.args = {
v: 0,
h: 2,
layout: 'inline',
};
export const Vertical: StoryFn<typeof Space> = (args) => {
return (
<div>
<Box borderStyle={'solid'} padding={1}>
Box without space
</Box>
<Box borderStyle={'solid'} padding={1}>
Box with bottom space
</Box>
<Space {...args} />
<Box borderStyle={'solid'} padding={1}>
Box without space
</Box>
</div>
);
};
Vertical.args = {
v: 2,
h: 0,
layout: 'block',
};

View File

@ -0,0 +1,26 @@
import React from 'react';
import { ThemeSpacingTokens } from '@grafana/data';
import { Box } from './Box/Box';
import { ResponsiveProp } from './utils/responsiveness';
export interface SpaceProps {
/**
* The amount of vertical space to use.
*/
v?: ResponsiveProp<ThemeSpacingTokens>;
/**
* The amount of horizontal space to use.
*/
h?: ResponsiveProp<ThemeSpacingTokens>;
/**
* The layout of the space. If set to `inline`, the component will behave like an inline-block element,
* otherwise it will behave like a block element.
*/
layout?: 'block' | 'inline';
}
export const Space = ({ v = 0, h = 0, layout }: SpaceProps) => {
return <Box paddingRight={h} paddingBottom={v} display={layout === 'inline' ? 'inline-block' : 'block'} />;
};

View File

@ -213,6 +213,7 @@ export { Text } from './Text/Text';
export { Box } from './Layout/Box/Box';
export { Stack } from './Layout/Stack/Stack';
export { Grid } from './Layout/Grid/Grid';
export { Space } from './Layout/Space';
export { Label } from './Forms/Label';
export { Field, type FieldProps } from './Forms/Field';

View File

@ -3,8 +3,7 @@ import { sortBy } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Space } from '@grafana/experimental';
import { Text, Box, Button, useStyles2 } from '@grafana/ui';
import { Text, Box, Button, useStyles2, Space } from '@grafana/ui';
import { SlideDown } from 'app/core/components/Animations/SlideDown';
import { Trans, t } from 'app/core/internationalization';
import { getBackendSrv } from 'app/core/services/backend_srv';

View File

@ -1,8 +1,7 @@
import React, { useState } from 'react';
import { Space } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Alert, ConfirmModal, Text } from '@grafana/ui';
import { Alert, ConfirmModal, Text, Space } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { useGetAffectedItemsQuery } from '../../api/browseDashboardsAPI';

View File

@ -1,7 +1,6 @@
import React, { useState } from 'react';
import { Space } from '@grafana/experimental';
import { Alert, Button, Field, Modal, Text } from '@grafana/ui';
import { Alert, Button, Field, Modal, Text, Space } from '@grafana/ui';
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
import { t, Trans } from 'app/core/internationalization';

View File

@ -2,7 +2,8 @@ import React, { useCallback, useEffect, useState } from 'react';
import { useAsync } from 'react-use';
import { QueryEditorProps } from '@grafana/data';
import { EditorMode, Space } from '@grafana/experimental';
import { EditorMode } from '@grafana/experimental';
import { Space } from '@grafana/ui';
import { SqlDatasource } from '../datasource/SqlDatasource';
import { applyQueryDefaults } from '../defaults';

View File

@ -3,9 +3,9 @@ import { useCopyToClipboard } from 'react-use';
import { v4 as uuidv4 } from 'uuid';
import { SelectableValue } from '@grafana/data';
import { EditorField, EditorHeader, EditorMode, EditorRow, FlexItem, InlineSelect, Space } from '@grafana/experimental';
import { EditorField, EditorHeader, EditorMode, EditorRow, FlexItem, InlineSelect } from '@grafana/experimental';
import { reportInteraction } from '@grafana/runtime';
import { Button, InlineSwitch, RadioButtonGroup, Tooltip } from '@grafana/ui';
import { Button, InlineSwitch, RadioButtonGroup, Tooltip, Space } from '@grafana/ui';
import { QueryWithDefaults } from '../defaults';
import { SQLQuery, QueryFormat, QueryRowFilter, QUERY_FORMAT_OPTIONS, DB, SQLDialect } from '../types';

View File

@ -2,8 +2,8 @@ import { uniqueId } from 'lodash';
import React, { useCallback } from 'react';
import { SelectableValue, toOption } from '@grafana/data';
import { EditorField, InputGroup, Space } from '@grafana/experimental';
import { Input, RadioButtonGroup, Select } from '@grafana/ui';
import { EditorField, InputGroup } from '@grafana/experimental';
import { Input, RadioButtonGroup, Select, Space } from '@grafana/ui';
import { SQLExpression } from '../../types';
import { setPropertyField } from '../../utils/sql.utils';

View File

@ -4,7 +4,7 @@ import React, { useCallback, useMemo, useState } from 'react';
import { QueryEditorProps } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Alert, Button, CodeEditor } from '@grafana/ui';
import { Alert, Button, CodeEditor, Space } from '@grafana/ui';
import AzureMonitorDatasource from '../../datasource';
import {
@ -20,7 +20,6 @@ import LogsQueryEditor from '../LogsQueryEditor';
import { AzureCheatSheetModal } from '../LogsQueryEditor/AzureCheatSheetModal';
import NewMetricsQueryEditor from '../MetricsQueryEditor/MetricsQueryEditor';
import { QueryHeader } from '../QueryHeader';
import { Space } from '../Space';
import TracesQueryEditor from '../TracesQueryEditor';
import usePreparedQuery from './usePreparedQuery';

View File

@ -1,10 +1,9 @@
import React, { useState } from 'react';
import { Collapse } from '@grafana/ui';
import { Collapse, Space } from '@grafana/ui';
import { selectors } from '../../e2e/selectors';
import { AzureMonitorResource } from '../../types';
import { Space } from '../Space';
export interface ResourcePickerProps<T> {
resources: T[];

View File

@ -1,9 +1,7 @@
import { cx } from '@emotion/css';
import React, { useCallback, useEffect } from 'react';
import { Checkbox, IconButton, useStyles2, useTheme2 } from '@grafana/ui';
import { Space } from '../Space';
import { Checkbox, IconButton, useStyles2, useTheme2, Space } from '@grafana/ui';
import { EntryIcon } from './EntryIcon';
import getStyles from './styles';

View File

@ -2,13 +2,12 @@ import { cx } from '@emotion/css';
import React, { useCallback, useEffect, useState } from 'react';
import { useEffectOnce } from 'react-use';
import { Alert, Button, LoadingPlaceholder, Modal, useStyles2 } from '@grafana/ui';
import { Alert, Button, LoadingPlaceholder, Modal, useStyles2, Space } from '@grafana/ui';
import { selectors } from '../../e2e/selectors';
import ResourcePickerData, { ResourcePickerQueryType } from '../../resourcePicker/resourcePickerData';
import { AzureMonitorResource } from '../../types';
import messageFromError from '../../utils/messageFromError';
import { Space } from '../Space';
import AdvancedMulti from './AdvancedMulti';
import NestedRow from './NestedRow';

View File

@ -1,38 +0,0 @@
import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
export interface SpaceProps {
v?: number;
h?: number;
layout?: 'block' | 'inline';
}
export const Space = (props: SpaceProps) => {
const styles = useStyles2(getStyles, props);
return <span className={cx(styles.wrapper)} />;
};
Space.defaultProps = {
v: 0,
h: 0,
layout: 'block',
};
const getStyles = (theme: GrafanaTheme2, props: SpaceProps) => ({
wrapper: css([
{
paddingRight: theme.spacing(props.h ?? 0),
paddingBottom: theme.spacing(props.v ?? 0),
},
props.layout === 'inline' && {
display: 'inline-block',
},
props.layout === 'block' && {
display: 'block',
},
]),
});

View File

@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
import { useEffectOnce } from 'react-use';
import { SelectableValue } from '@grafana/data';
import { Alert, Field, Select } from '@grafana/ui';
import { Alert, Field, Select, Space } from '@grafana/ui';
import DataSource from '../../datasource';
import { selectors } from '../../e2e/selectors';
@ -12,7 +12,6 @@ import { AzureMonitorOption, AzureMonitorQuery, AzureQueryType } from '../../typ
import useLastError from '../../utils/useLastError';
import ArgQueryEditor from '../ArgQueryEditor';
import LogsQueryEditor from '../LogsQueryEditor';
import { Space } from '../Space';
import GrafanaTemplateVariableFnInput from './GrafanaTemplateVariableFn';

View File

@ -1,8 +1,8 @@
import React, { ChangeEvent } from 'react';
import { QueryEditorProps } from '@grafana/data';
import { EditorField, EditorHeader, EditorRow, EditorSwitch, InlineSelect, Space } from '@grafana/experimental';
import { Alert, Input } from '@grafana/ui';
import { EditorField, EditorHeader, EditorRow, EditorSwitch, InlineSelect } from '@grafana/experimental';
import { Alert, Input, Space } from '@grafana/ui';
import { CloudWatchDatasource } from '../../datasource';
import { isCloudWatchAnnotationQuery } from '../../guards';

View File

@ -1,8 +1,8 @@
import React, { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { QueryEditorProps, SelectableValue } from '@grafana/data';
import { EditorField, EditorRow, InlineSelect, Space } from '@grafana/experimental';
import { ConfirmModal, Input, RadioButtonGroup } from '@grafana/ui';
import { EditorField, EditorRow, InlineSelect } from '@grafana/experimental';
import { ConfirmModal, Input, RadioButtonGroup, Space } from '@grafana/ui';
import { CloudWatchDatasource } from '../../../datasource';
import useMigratedMetricsQuery from '../../../migrations/useMigratedMetricsQuery';

View File

@ -1,8 +1,8 @@
import React, { useEffect, useMemo, useState } from 'react';
import { SelectableValue } from '@grafana/data';
import { EditorField, Space } from '@grafana/experimental';
import { Button, Checkbox, Icon, Label, LoadingPlaceholder, Modal, Select, useStyles2 } from '@grafana/ui';
import { EditorField } from '@grafana/experimental';
import { Button, Checkbox, Icon, Label, LoadingPlaceholder, Modal, Select, Space, useStyles2 } from '@grafana/ui';
import { DescribeLogGroupsRequest, ResourceResponse, LogGroupResponse } from '../../../resources/types';
import { LogGroup } from '../../../types';

View File

@ -4,9 +4,9 @@ import { usePrevious } from 'react-use';
import { CoreApp, LoadingState } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { EditorHeader, EditorRows, FlexItem, Space, Stack } from '@grafana/experimental';
import { EditorHeader, EditorRows, FlexItem } from '@grafana/experimental';
import { config, reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal } from '@grafana/ui';
import { Button, ConfirmModal, Space, Stack } from '@grafana/ui';
import { QueryEditorModeToggle } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle';
import { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch';
import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types';

View File

@ -2,8 +2,8 @@ import React from 'react';
import { AnnotationQuery } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { EditorField, EditorRow, EditorRows, EditorSwitch, Space } from '@grafana/experimental';
import { AutoSizeInput, Input } from '@grafana/ui';
import { EditorField, EditorRow, EditorRows, EditorSwitch } from '@grafana/experimental';
import { AutoSizeInput, Input, Space } from '@grafana/ui';
import { PromQueryCodeEditor } from '../querybuilder/components/PromQueryCodeEditor';
import { PromQuery } from '../types';

View File

@ -3,9 +3,9 @@ import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react';
import { CoreApp, LoadingState, SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { EditorHeader, EditorRows, FlexItem, Space } from '@grafana/experimental';
import { EditorHeader, EditorRows, FlexItem } from '@grafana/experimental';
import { reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal } from '@grafana/ui';
import { Button, ConfirmModal, Space } from '@grafana/ui';
import { PromQueryEditorProps } from '../../components/types';
import { PromQueryFormat } from '../../dataquery.gen';