= (args) => {
+ return (
+
+
+ Box without space
+
+
+ Box with space on the right
+
+
+
+ Box without space
+
+
+ );
+};
+
+Horizontal.args = {
+ v: 0,
+ h: 2,
+ layout: 'inline',
+};
+
+export const Vertical: StoryFn = (args) => {
+ return (
+
+
+ Box without space
+
+
+ Box with bottom space
+
+
+
+ Box without space
+
+
+ );
+};
+
+Vertical.args = {
+ v: 2,
+ h: 0,
+ layout: 'block',
+};
diff --git a/packages/grafana-ui/src/components/Layout/Space.tsx b/packages/grafana-ui/src/components/Layout/Space.tsx
new file mode 100644
index 00000000000..6e3c53ed2ee
--- /dev/null
+++ b/packages/grafana-ui/src/components/Layout/Space.tsx
@@ -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;
+ /**
+ * The amount of horizontal space to use.
+ */
+ h?: ResponsiveProp;
+ /**
+ * 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 ;
+};
diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts
index 9325c425d40..c72282e0940 100644
--- a/packages/grafana-ui/src/components/index.ts
+++ b/packages/grafana-ui/src/components/index.ts
@@ -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';
diff --git a/public/app/core/components/AccessControl/Permissions.tsx b/public/app/core/components/AccessControl/Permissions.tsx
index 2b4f53aa7a3..de6a240b5d0 100644
--- a/public/app/core/components/AccessControl/Permissions.tsx
+++ b/public/app/core/components/AccessControl/Permissions.tsx
@@ -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';
diff --git a/public/app/features/browse-dashboards/components/BrowseActions/DeleteModal.tsx b/public/app/features/browse-dashboards/components/BrowseActions/DeleteModal.tsx
index 6a4a1604712..a45d6446934 100644
--- a/public/app/features/browse-dashboards/components/BrowseActions/DeleteModal.tsx
+++ b/public/app/features/browse-dashboards/components/BrowseActions/DeleteModal.tsx
@@ -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';
diff --git a/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.tsx b/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.tsx
index f36cbfd5bc5..366d3c3208c 100644
--- a/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.tsx
+++ b/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.tsx
@@ -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';
diff --git a/public/app/features/plugins/sql/components/QueryEditor.tsx b/public/app/features/plugins/sql/components/QueryEditor.tsx
index 25c4e4779ff..cfefaf37935 100644
--- a/public/app/features/plugins/sql/components/QueryEditor.tsx
+++ b/public/app/features/plugins/sql/components/QueryEditor.tsx
@@ -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';
diff --git a/public/app/features/plugins/sql/components/QueryHeader.tsx b/public/app/features/plugins/sql/components/QueryHeader.tsx
index 0450a67ebc4..c27c7a018c6 100644
--- a/public/app/features/plugins/sql/components/QueryHeader.tsx
+++ b/public/app/features/plugins/sql/components/QueryHeader.tsx
@@ -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';
diff --git a/public/app/features/plugins/sql/components/visual-query-builder/OrderByRow.tsx b/public/app/features/plugins/sql/components/visual-query-builder/OrderByRow.tsx
index 58c8ce3158a..224f7e5c3fc 100644
--- a/public/app/features/plugins/sql/components/visual-query-builder/OrderByRow.tsx
+++ b/public/app/features/plugins/sql/components/visual-query-builder/OrderByRow.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryEditor.tsx b/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryEditor.tsx
index 3e9b85d3fd4..8813d33f026 100644
--- a/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryEditor.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/AdvancedMulti.tsx b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/AdvancedMulti.tsx
index baa5389d05e..fa4d7f68def 100644
--- a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/AdvancedMulti.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/AdvancedMulti.tsx
@@ -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 {
resources: T[];
diff --git a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/NestedEntry.tsx b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/NestedEntry.tsx
index 6d843e2f18b..5b0bea5e2e1 100644
--- a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/NestedEntry.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/NestedEntry.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/ResourcePicker.tsx b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/ResourcePicker.tsx
index e4771a40216..0afb25e760f 100644
--- a/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/ResourcePicker.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/ResourcePicker/ResourcePicker.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/azuremonitor/components/Space.tsx b/public/app/plugins/datasource/azuremonitor/components/Space.tsx
deleted file mode 100644
index d8fac61c838..00000000000
--- a/public/app/plugins/datasource/azuremonitor/components/Space.tsx
+++ /dev/null
@@ -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 ;
-};
-
-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',
- },
- ]),
-});
diff --git a/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.tsx b/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.tsx
index 34b8141bcfd..94a2e1b281a 100644
--- a/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor/AnnotationQueryEditor.tsx
index a88bdf61eb4..cd8c3517e52 100644
--- a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor/AnnotationQueryEditor.tsx
+++ b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor/AnnotationQueryEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/cloudwatch/components/QueryEditor/MetricsQueryEditor/MetricsQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/QueryEditor/MetricsQueryEditor/MetricsQueryEditor.tsx
index 83c0a2f6ef7..884f9d373fd 100644
--- a/public/app/plugins/datasource/cloudwatch/components/QueryEditor/MetricsQueryEditor/MetricsQueryEditor.tsx
+++ b/public/app/plugins/datasource/cloudwatch/components/QueryEditor/MetricsQueryEditor/MetricsQueryEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LogGroupsSelector.tsx b/public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LogGroupsSelector.tsx
index 225f56e8432..d1720065ddd 100644
--- a/public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LogGroupsSelector.tsx
+++ b/public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LogGroupsSelector.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx
index 9139a6d5463..5b2eb4a5e89 100644
--- a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx
+++ b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/prometheus/components/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/AnnotationQueryEditor.tsx
index dc89036e1d1..0cbaf5978cd 100644
--- a/public/app/plugins/datasource/prometheus/components/AnnotationQueryEditor.tsx
+++ b/public/app/plugins/datasource/prometheus/components/AnnotationQueryEditor.tsx
@@ -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';
diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
index be1d98957d0..a0016b986e8 100644
--- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
+++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
@@ -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';