mirror of https://github.com/grafana/grafana.git
				
				
				
			Chore: Extract out dragHandle styles (#81280)
extract out dragHandle styles
This commit is contained in:
		
							parent
							
								
									e041055012
								
							
						
					
					
						commit
						43de30a09b
					
				| 
						 | 
				
			
			@ -1053,11 +1053,6 @@ exports[`better eslint`] = {
 | 
			
		|||
    "public/app/core/components/SharedPreferences/SharedPreferences.tsx:5381": [
 | 
			
		||||
      [0, 0, 0, "Styles should be written using objects.", "0"]
 | 
			
		||||
    ],
 | 
			
		||||
    "public/app/core/components/SplitPaneWrapper/SplitPaneWrapper.tsx:5381": [
 | 
			
		||||
      [0, 0, 0, "Styles should be written using objects.", "0"],
 | 
			
		||||
      [0, 0, 0, "Styles should be written using objects.", "1"],
 | 
			
		||||
      [0, 0, 0, "Styles should be written using objects.", "2"]
 | 
			
		||||
    ],
 | 
			
		||||
    "public/app/core/components/TagFilter/TagFilter.tsx:5381": [
 | 
			
		||||
      [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
 | 
			
		||||
      [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
import { css, cx } from '@emotion/css';
 | 
			
		||||
 | 
			
		||||
import { GrafanaTheme2 } from '@grafana/data';
 | 
			
		||||
 | 
			
		||||
export const getDragStyles = (theme: GrafanaTheme2) => {
 | 
			
		||||
  const baseColor = theme.colors.emphasize(theme.colors.background.secondary, 0.15);
 | 
			
		||||
  const hoverColor = theme.colors.primary.border;
 | 
			
		||||
  const clickTargetSize = theme.spacing(2);
 | 
			
		||||
  const handlebarThickness = 4;
 | 
			
		||||
  const handlebarWidth = 200;
 | 
			
		||||
 | 
			
		||||
  const dragHandleBase = css({
 | 
			
		||||
    position: 'relative',
 | 
			
		||||
 | 
			
		||||
    '&:before': {
 | 
			
		||||
      content: '""',
 | 
			
		||||
      position: 'absolute',
 | 
			
		||||
      transition: theme.transitions.create('border-color'),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    '&:after': {
 | 
			
		||||
      background: baseColor,
 | 
			
		||||
      content: '""',
 | 
			
		||||
      position: 'absolute',
 | 
			
		||||
      left: '50%',
 | 
			
		||||
      top: '50%',
 | 
			
		||||
      transition: theme.transitions.create('background'),
 | 
			
		||||
      transform: 'translate(-50%, -50%)',
 | 
			
		||||
      borderRadius: theme.shape.radius.pill,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    '&:hover': {
 | 
			
		||||
      '&:before': {
 | 
			
		||||
        borderColor: hoverColor,
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      '&:after': {
 | 
			
		||||
        background: hoverColor,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    dragHandleVertical: cx(
 | 
			
		||||
      dragHandleBase,
 | 
			
		||||
      css({
 | 
			
		||||
        cursor: 'col-resize',
 | 
			
		||||
        width: clickTargetSize,
 | 
			
		||||
 | 
			
		||||
        '&:before': {
 | 
			
		||||
          borderRight: '1px solid transparent',
 | 
			
		||||
          height: '100%',
 | 
			
		||||
          left: '50%',
 | 
			
		||||
          transform: 'translateX(-50%)',
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        '&:after': {
 | 
			
		||||
          height: handlebarWidth,
 | 
			
		||||
          width: handlebarThickness,
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
    ),
 | 
			
		||||
    dragHandleHorizontal: cx(
 | 
			
		||||
      dragHandleBase,
 | 
			
		||||
      css({
 | 
			
		||||
        height: clickTargetSize,
 | 
			
		||||
        cursor: 'row-resize',
 | 
			
		||||
 | 
			
		||||
        '&:before': {
 | 
			
		||||
          borderTop: '1px solid transparent',
 | 
			
		||||
          top: '50%',
 | 
			
		||||
          transform: 'translateY(-50%)',
 | 
			
		||||
          width: '100%',
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        '&:after': {
 | 
			
		||||
          height: handlebarThickness,
 | 
			
		||||
          width: handlebarWidth,
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
    ),
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ import { selectors } from '@grafana/e2e-selectors';
 | 
			
		|||
import { useStyles2 } from '../../themes';
 | 
			
		||||
import { t } from '../../utils/i18n';
 | 
			
		||||
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
 | 
			
		||||
import { getDragStyles } from '../DragHandle/DragHandle';
 | 
			
		||||
import { IconButton } from '../IconButton/IconButton';
 | 
			
		||||
import { Text } from '../Text/Text';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +66,7 @@ export function Drawer({
 | 
			
		|||
 | 
			
		||||
  const styles = useStyles2(getStyles);
 | 
			
		||||
  const sizeStyles = useStyles2(getSizeStyles, size, drawerWidth ?? width);
 | 
			
		||||
  const dragStyles = useStyles2(getDragStyles);
 | 
			
		||||
 | 
			
		||||
  const overlayRef = React.useRef(null);
 | 
			
		||||
  const { dialogProps, titleProps } = useDialog({}, overlayRef);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +118,11 @@ export function Drawer({
 | 
			
		|||
          ref={overlayRef}
 | 
			
		||||
        >
 | 
			
		||||
          {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
 | 
			
		||||
          <div className={styles.resizer} onMouseDown={onMouseDown} onTouchStart={onTouchStart} />
 | 
			
		||||
          <div
 | 
			
		||||
            className={cx(dragStyles.dragHandleVertical, styles.resizer)}
 | 
			
		||||
            onMouseDown={onMouseDown}
 | 
			
		||||
            onTouchStart={onTouchStart}
 | 
			
		||||
          />
 | 
			
		||||
          {typeof title === 'string' && (
 | 
			
		||||
            <div className={cx(styles.header, Boolean(tabs) && styles.headerWithTabs)}>
 | 
			
		||||
              <div className={styles.actions}>
 | 
			
		||||
| 
						 | 
				
			
			@ -338,46 +344,11 @@ const getStyles = (theme: GrafanaTheme2) => {
 | 
			
		|||
      margin: theme.spacing(1, -1, -3, -3),
 | 
			
		||||
    }),
 | 
			
		||||
    resizer: css({
 | 
			
		||||
      width: 8,
 | 
			
		||||
      top: 0,
 | 
			
		||||
      left: -4,
 | 
			
		||||
      left: theme.spacing(-1),
 | 
			
		||||
      bottom: 0,
 | 
			
		||||
      position: 'absolute',
 | 
			
		||||
      cursor: 'col-resize',
 | 
			
		||||
      zIndex: theme.zIndex.modal,
 | 
			
		||||
 | 
			
		||||
      '&::after': {
 | 
			
		||||
        background: theme.colors.emphasize(theme.colors.background.secondary, 0.15),
 | 
			
		||||
        content: '""',
 | 
			
		||||
        position: 'absolute',
 | 
			
		||||
        left: '50%',
 | 
			
		||||
        top: '50%',
 | 
			
		||||
        transition: '0.2s background ease-in-out',
 | 
			
		||||
        transform: 'translate(-50%, -50%)',
 | 
			
		||||
        borderRadius: theme.shape.radius.default,
 | 
			
		||||
        height: '200px',
 | 
			
		||||
        width: '4px',
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      '&::before': {
 | 
			
		||||
        content: '""',
 | 
			
		||||
        position: 'absolute',
 | 
			
		||||
        transition: '0.2s border-color ease-in-out',
 | 
			
		||||
        borderRight: '2px solid transparent',
 | 
			
		||||
        height: '100%',
 | 
			
		||||
        left: '50%',
 | 
			
		||||
        transform: 'translateX(-50%)',
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      '&:hover': {
 | 
			
		||||
        '&::before': {
 | 
			
		||||
          borderColor: theme.colors.primary.border,
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        '&::after': {
 | 
			
		||||
          background: theme.colors.primary.border,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,6 +264,7 @@ export { Avatar } from './UsersIndicator/Avatar';
 | 
			
		|||
// Export this until we've figured out a good approach to inline form styles.
 | 
			
		||||
export { InlineFormLabel } from './FormLabel/FormLabel';
 | 
			
		||||
export { Divider } from './Divider/Divider';
 | 
			
		||||
export { getDragStyles } from './DragHandle/DragHandle';
 | 
			
		||||
 | 
			
		||||
export { LayoutItemContext, type LayoutItemContextProps } from './Layout/LayoutItemContext';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ import React, { createRef, MutableRefObject, PureComponent } from 'react';
 | 
			
		|||
import SplitPane, { Split } from 'react-split-pane';
 | 
			
		||||
 | 
			
		||||
import { GrafanaTheme2 } from '@grafana/data';
 | 
			
		||||
import { getDragStyles } from '@grafana/ui';
 | 
			
		||||
import { config } from 'app/core/config';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +75,7 @@ export class SplitPaneWrapper extends PureComponent<React.PropsWithChildren<Prop
 | 
			
		|||
 | 
			
		||||
    // Limit options pane width to 90% of screen.
 | 
			
		||||
    const styles = getStyles(config.theme2, splitVisible);
 | 
			
		||||
    const dragStyles = getDragStyles(config.theme2);
 | 
			
		||||
 | 
			
		||||
    // Need to handle when width is relative. ie a percentage of the viewport
 | 
			
		||||
    const paneSizePx =
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +97,10 @@ export class SplitPaneWrapper extends PureComponent<React.PropsWithChildren<Prop
 | 
			
		|||
        maxSize={maxSize}
 | 
			
		||||
        size={splitVisible ? paneSizePx : 0}
 | 
			
		||||
        primary={splitVisible ? primary : 'second'}
 | 
			
		||||
        resizerClassName={splitOrientation === 'horizontal' ? styles.resizerH : styles.resizerV}
 | 
			
		||||
        resizerClassName={cx(
 | 
			
		||||
          styles.resizer,
 | 
			
		||||
          splitOrientation === 'horizontal' ? dragStyles.dragHandleHorizontal : dragStyles.dragHandleVertical
 | 
			
		||||
        )}
 | 
			
		||||
        onDragStarted={() => this.onDragStarted()}
 | 
			
		||||
        onDragFinished={(size) => this.onDragFinished(size)}
 | 
			
		||||
        style={parentStyle}
 | 
			
		||||
| 
						 | 
				
			
			@ -109,83 +114,12 @@ export class SplitPaneWrapper extends PureComponent<React.PropsWithChildren<Prop
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
const getStyles = (theme: GrafanaTheme2, hasSplit: boolean) => {
 | 
			
		||||
  const handleColor = theme.v1.palette.blue95;
 | 
			
		||||
  const paneSpacing = theme.spacing(2);
 | 
			
		||||
 | 
			
		||||
  const resizer = css`
 | 
			
		||||
    position: relative;
 | 
			
		||||
    display: ${hasSplit ? 'block' : 'none'};
 | 
			
		||||
 | 
			
		||||
    &::before {
 | 
			
		||||
      content: '';
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      transition: 0.2s border-color ease-in-out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &::after {
 | 
			
		||||
      background: ${theme.components.panel.borderColor};
 | 
			
		||||
      content: '';
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      left: 50%;
 | 
			
		||||
      top: 50%;
 | 
			
		||||
      transition: 0.2s background ease-in-out;
 | 
			
		||||
      transform: translate(-50%, -50%);
 | 
			
		||||
      border-radius: ${theme.shape.radius.default};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &:hover {
 | 
			
		||||
      &::before {
 | 
			
		||||
        border-color: ${handleColor};
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &::after {
 | 
			
		||||
        background: ${handleColor};
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  `;
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    splitPane: css({
 | 
			
		||||
      overflow: 'visible !important',
 | 
			
		||||
    }),
 | 
			
		||||
    resizerV: cx(
 | 
			
		||||
      resizer,
 | 
			
		||||
      css`
 | 
			
		||||
        cursor: col-resize;
 | 
			
		||||
        width: ${paneSpacing};
 | 
			
		||||
 | 
			
		||||
        &::before {
 | 
			
		||||
          border-right: 1px solid transparent;
 | 
			
		||||
          height: 100%;
 | 
			
		||||
          left: 50%;
 | 
			
		||||
          transform: translateX(-50%);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &::after {
 | 
			
		||||
          height: 200px;
 | 
			
		||||
          width: 4px;
 | 
			
		||||
        }
 | 
			
		||||
      `
 | 
			
		||||
    ),
 | 
			
		||||
    resizerH: cx(
 | 
			
		||||
      resizer,
 | 
			
		||||
      css`
 | 
			
		||||
        height: ${paneSpacing};
 | 
			
		||||
        cursor: row-resize;
 | 
			
		||||
        margin-left: ${paneSpacing};
 | 
			
		||||
 | 
			
		||||
        &::before {
 | 
			
		||||
          border-top: 1px solid transparent;
 | 
			
		||||
          top: 50%;
 | 
			
		||||
          transform: translateY(-50%);
 | 
			
		||||
          width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &::after {
 | 
			
		||||
          height: 4px;
 | 
			
		||||
          width: 200px;
 | 
			
		||||
        }
 | 
			
		||||
      `
 | 
			
		||||
    ),
 | 
			
		||||
    resizer: css({
 | 
			
		||||
      display: hasSplit ? 'block' : 'none',
 | 
			
		||||
    }),
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import React from 'react';
 | 
			
		|||
 | 
			
		||||
// Services & Utils
 | 
			
		||||
import { GrafanaTheme2 } from '@grafana/data';
 | 
			
		||||
import { useStyles2, useTheme2 } from '@grafana/ui';
 | 
			
		||||
import { getDragStyles, useStyles2, useTheme2 } from '@grafana/ui';
 | 
			
		||||
 | 
			
		||||
export interface Props {
 | 
			
		||||
  width: number;
 | 
			
		||||
| 
						 | 
				
			
			@ -17,13 +17,14 @@ export function ExploreDrawer(props: Props) {
 | 
			
		|||
  const { width, children, onResize } = props;
 | 
			
		||||
  const theme = useTheme2();
 | 
			
		||||
  const styles = useStyles2(getStyles);
 | 
			
		||||
  const dragStyles = getDragStyles(theme);
 | 
			
		||||
  const drawerWidth = `${width + 31.5}px`;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Resizable
 | 
			
		||||
      className={cx(styles.fixed, styles.container, styles.drawerActive)}
 | 
			
		||||
      defaultSize={{ width: drawerWidth, height: `${theme.components.horizontalDrawer.defaultHeight}px` }}
 | 
			
		||||
      handleClasses={{ top: styles.rzHandle }}
 | 
			
		||||
      handleClasses={{ top: dragStyles.dragHandleHorizontal }}
 | 
			
		||||
      enable={{
 | 
			
		||||
        top: true,
 | 
			
		||||
        right: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,18 +72,4 @@ const getStyles = (theme: GrafanaTheme2) => ({
 | 
			
		|||
    opacity: 1,
 | 
			
		||||
    animation: `0.5s ease-out ${drawerSlide(theme)}`,
 | 
			
		||||
  }),
 | 
			
		||||
  rzHandle: css({
 | 
			
		||||
    background: theme.colors.secondary.main,
 | 
			
		||||
    transition: '0.3s background ease-in-out',
 | 
			
		||||
    position: 'relative',
 | 
			
		||||
    width: '200px !important',
 | 
			
		||||
    height: '7px !important',
 | 
			
		||||
    left: 'calc(50% - 100px) !important',
 | 
			
		||||
    top: '-4px !important',
 | 
			
		||||
    cursor: 'grab',
 | 
			
		||||
    borderRadius: theme.shape.radius.pill,
 | 
			
		||||
    ['&:hover']: {
 | 
			
		||||
      background: theme.colors.secondary.shade,
 | 
			
		||||
    },
 | 
			
		||||
  }),
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue