mirror of https://github.com/grafana/grafana.git
Grafana/ui: Unify flex shorthand props (#77768)
* Update flex props * Make the story external * Add ResponsiveProp
This commit is contained in:
parent
0ae3cd6fa5
commit
e286a3a652
|
|
@ -4,7 +4,7 @@ import React, { ElementType, forwardRef, PropsWithChildren } from 'react';
|
|||
import { GrafanaTheme2, ThemeSpacingTokens, ThemeShape, ThemeShadows } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { AlignItems, JustifyContent } from '../Stack/Stack';
|
||||
import { AlignItems, FlexProps, JustifyContent } from '../types';
|
||||
import { ResponsiveProp, getResponsiveStyle } from '../utils/responsiveness';
|
||||
|
||||
type Display = 'flex' | 'block' | 'inline' | 'none';
|
||||
|
|
@ -14,7 +14,7 @@ export type BorderColor = keyof GrafanaTheme2['colors']['border'] | 'error' | 's
|
|||
export type BorderRadius = keyof ThemeShape['radius'];
|
||||
export type BoxShadow = keyof ThemeShadows;
|
||||
|
||||
interface BoxProps extends Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'style'> {
|
||||
interface BoxProps extends FlexProps, Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'style'> {
|
||||
// Margin props
|
||||
/** Sets the property `margin` */
|
||||
margin?: ResponsiveProp<ThemeSpacingTokens>;
|
||||
|
|
@ -53,10 +53,6 @@ interface BoxProps extends Omit<React.HTMLAttributes<HTMLElement>, 'className' |
|
|||
borderRadius?: ResponsiveProp<BorderRadius>;
|
||||
|
||||
// Flex Props
|
||||
/** Sets the property `flex` */
|
||||
grow?: ResponsiveProp<number>;
|
||||
/** Sets the property `flex-shrink` */
|
||||
shrink?: ResponsiveProp<number>;
|
||||
alignItems?: ResponsiveProp<AlignItems>;
|
||||
justifyContent?: ResponsiveProp<JustifyContent>;
|
||||
gap?: ResponsiveProp<ThemeSpacingTokens>;
|
||||
|
|
@ -90,6 +86,8 @@ export const Box = forwardRef<HTMLElement, PropsWithChildren<BoxProps>>((props,
|
|||
backgroundColor,
|
||||
grow,
|
||||
shrink,
|
||||
basis,
|
||||
flex,
|
||||
borderColor,
|
||||
borderStyle,
|
||||
borderRadius,
|
||||
|
|
@ -120,6 +118,8 @@ export const Box = forwardRef<HTMLElement, PropsWithChildren<BoxProps>>((props,
|
|||
backgroundColor,
|
||||
grow,
|
||||
shrink,
|
||||
basis,
|
||||
flex,
|
||||
borderColor,
|
||||
borderStyle,
|
||||
borderRadius,
|
||||
|
|
@ -183,6 +183,8 @@ const getStyles = (
|
|||
backgroundColor: BoxProps['backgroundColor'],
|
||||
grow: BoxProps['grow'],
|
||||
shrink: BoxProps['shrink'],
|
||||
basis: BoxProps['basis'],
|
||||
flex: BoxProps['flex'],
|
||||
borderColor: BoxProps['borderColor'],
|
||||
borderStyle: BoxProps['borderStyle'],
|
||||
borderRadius: BoxProps['borderRadius'],
|
||||
|
|
@ -246,11 +248,17 @@ const getStyles = (
|
|||
backgroundColor: customBackgroundColor(val, theme),
|
||||
})),
|
||||
getResponsiveStyle(theme, grow, (val) => ({
|
||||
flex: val,
|
||||
flexGrow: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, shrink, (val) => ({
|
||||
flexShrink: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, basis, (val) => ({
|
||||
flexBasis: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, flex, (val) => ({
|
||||
flex: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, borderStyle, (val) => ({
|
||||
borderStyle: val,
|
||||
})),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import { ThemeSpacingTokens } from '@grafana/data';
|
|||
|
||||
import { useTheme2 } from '../../../themes';
|
||||
import { SpacingTokenControl } from '../../../utils/storybook/themeStorybookControls';
|
||||
import { JustifyContent, Wrap, Direction } from '../types';
|
||||
|
||||
import { Stack, JustifyContent, Wrap, Direction } from './Stack';
|
||||
import { Stack } from './Stack';
|
||||
import mdx from './Stack.mdx';
|
||||
|
||||
const Item = ({ color, text, height }: { color: string; text?: string | number; height?: string }) => {
|
||||
|
|
@ -1,59 +1,31 @@
|
|||
import { css } from '@emotion/css';
|
||||
import React, { CSSProperties } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2, ThemeSpacingTokens } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { AlignItems, Direction, FlexProps, JustifyContent, Wrap } from '../types';
|
||||
import { ResponsiveProp, getResponsiveStyle } from '../utils/responsiveness';
|
||||
|
||||
export type AlignItems =
|
||||
| 'stretch'
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'baseline'
|
||||
| 'start'
|
||||
| 'end'
|
||||
| 'self-start'
|
||||
| 'self-end';
|
||||
|
||||
export type JustifyContent =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'space-between'
|
||||
| 'space-around'
|
||||
| 'space-evenly'
|
||||
| 'start'
|
||||
| 'end'
|
||||
| 'left'
|
||||
| 'right';
|
||||
|
||||
export type Direction = 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
||||
|
||||
export type Wrap = 'nowrap' | 'wrap' | 'wrap-reverse';
|
||||
|
||||
interface StackProps extends Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'style'> {
|
||||
interface StackProps extends FlexProps, Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'style'> {
|
||||
gap?: ResponsiveProp<ThemeSpacingTokens>;
|
||||
alignItems?: ResponsiveProp<AlignItems>;
|
||||
justifyContent?: ResponsiveProp<JustifyContent>;
|
||||
direction?: ResponsiveProp<Direction>;
|
||||
wrap?: ResponsiveProp<Wrap>;
|
||||
children?: React.ReactNode;
|
||||
flexGrow?: ResponsiveProp<CSSProperties['flexGrow']>;
|
||||
}
|
||||
|
||||
export const Stack = React.forwardRef<HTMLDivElement, StackProps>(
|
||||
({ gap = 1, alignItems, justifyContent, direction, wrap, children, flexGrow, ...rest }, ref) => {
|
||||
const styles = useStyles2(getStyles, gap, alignItems, justifyContent, direction, wrap, flexGrow);
|
||||
export const Stack = React.forwardRef<HTMLDivElement, StackProps>((props, ref) => {
|
||||
const { gap = 1, alignItems, justifyContent, direction, wrap, children, grow, shrink, basis, flex, ...rest } = props;
|
||||
const styles = useStyles2(getStyles, gap, alignItems, justifyContent, direction, wrap, grow, shrink, basis, flex);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={styles.flex} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<div ref={ref} className={styles.flex} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
Stack.displayName = 'Stack';
|
||||
|
||||
|
|
@ -64,7 +36,10 @@ const getStyles = (
|
|||
justifyContent: StackProps['justifyContent'],
|
||||
direction: StackProps['direction'],
|
||||
wrap: StackProps['wrap'],
|
||||
flexGrow: StackProps['flexGrow']
|
||||
grow: StackProps['grow'],
|
||||
shrink: StackProps['shrink'],
|
||||
basis: StackProps['basis'],
|
||||
flex: StackProps['flex']
|
||||
) => {
|
||||
return {
|
||||
flex: css([
|
||||
|
|
@ -86,9 +61,18 @@ const getStyles = (
|
|||
getResponsiveStyle(theme, gap, (val) => ({
|
||||
gap: theme.spacing(val),
|
||||
})),
|
||||
getResponsiveStyle(theme, flexGrow, (val) => ({
|
||||
getResponsiveStyle(theme, grow, (val) => ({
|
||||
flexGrow: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, shrink, (val) => ({
|
||||
flexShrink: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, basis, (val) => ({
|
||||
flexBasis: val,
|
||||
})),
|
||||
getResponsiveStyle(theme, flex, (val) => ({
|
||||
flex: val,
|
||||
})),
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
import { ResponsiveProp } from './utils/responsiveness';
|
||||
|
||||
export type AlignItems =
|
||||
| 'stretch'
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'baseline'
|
||||
| 'start'
|
||||
| 'end'
|
||||
| 'self-start'
|
||||
| 'self-end';
|
||||
|
||||
export type JustifyContent =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'space-between'
|
||||
| 'space-around'
|
||||
| 'space-evenly'
|
||||
| 'start'
|
||||
| 'end'
|
||||
| 'left'
|
||||
| 'right';
|
||||
|
||||
export type Direction = 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
||||
export type Wrap = 'nowrap' | 'wrap' | 'wrap-reverse';
|
||||
|
||||
type FlexGrow = number;
|
||||
type FlexShrink = number;
|
||||
type FlexBasis = 'auto' | 'initial' | '0' | `${number}%` | `${number}px`;
|
||||
|
||||
// Support the following formats for the "flex" shorthand property:
|
||||
// - 1
|
||||
// - '1'
|
||||
// - '1 1'
|
||||
// - '1 1 0'
|
||||
// - '1 1 0px'
|
||||
// - '1 1 auto'
|
||||
type Flex = FlexGrow | `${FlexGrow}` | `${FlexGrow} ${FlexShrink}` | `${FlexGrow} ${FlexShrink} ${FlexBasis}`;
|
||||
|
||||
export type FlexProps = {
|
||||
/** Sets the property `flex-grow` */
|
||||
grow?: ResponsiveProp<FlexGrow>;
|
||||
/** Sets the property `flex-shrink` */
|
||||
shrink?: ResponsiveProp<FlexShrink>;
|
||||
/** Sets the property `flex-basis` */
|
||||
basis?: ResponsiveProp<FlexBasis>;
|
||||
/** Sets the property `flex` */
|
||||
flex?: ResponsiveProp<Flex>;
|
||||
};
|
||||
|
|
@ -59,7 +59,7 @@ const DashboardEmpty = ({ dashboard, canCreate }: Props) => {
|
|||
</Box>
|
||||
<Stack direction={{ xs: 'column', md: 'row' }} wrap="wrap" gap={4}>
|
||||
{config.featureToggles.vizAndWidgetSplit && (
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} grow={1}>
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} flex={1}>
|
||||
<Stack direction="column" alignItems="center" gap={1}>
|
||||
<Text element="h3" textAlignment="center" weight="medium">
|
||||
<Trans i18nKey="dashboard.empty.add-widget-header">Add a widget</Trans>
|
||||
|
|
@ -84,7 +84,7 @@ const DashboardEmpty = ({ dashboard, canCreate }: Props) => {
|
|||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} grow={1}>
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} flex={1}>
|
||||
<Stack direction="column" alignItems="center" gap={1}>
|
||||
<Text element="h3" textAlignment="center" weight="medium">
|
||||
<Trans i18nKey="dashboard.empty.add-library-panel-header">Import panel</Trans>
|
||||
|
|
@ -110,7 +110,7 @@ const DashboardEmpty = ({ dashboard, canCreate }: Props) => {
|
|||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} grow={1}>
|
||||
<Box borderColor="strong" borderStyle="dashed" padding={3} flex={1}>
|
||||
<Stack direction="column" alignItems="center" gap={1}>
|
||||
<Text element="h3" textAlignment="center" weight="medium">
|
||||
<Trans i18nKey="dashboard.empty.import-a-dashboard-header">Import a dashboard</Trans>
|
||||
|
|
|
|||
Loading…
Reference in New Issue