123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import { css } from '@emotion/css';
- import React from 'react';
- import { GrafanaTheme2 } from '@grafana/data/src';
- import { IconButton, useStyles2 } from '@grafana/ui/src';
- import { HorizontalConstraint, Placement, QuickPlacement, VerticalConstraint } from 'app/features/canvas';
- import { ElementState } from 'app/features/canvas/runtime/element';
- import { CanvasEditorOptions } from './elementEditor';
- type Props = {
- onPositionChange: (value: number | undefined, placement: keyof Placement) => void;
- element: ElementState;
- settings: CanvasEditorOptions;
- };
- export const QuickPositioning = ({ onPositionChange, element, settings }: Props) => {
- const styles = useStyles2(getStyles);
- const onQuickPositioningChange = (position: QuickPlacement) => {
- const defaultConstraint = { vertical: VerticalConstraint.Top, horizontal: HorizontalConstraint.Left };
- const originalConstraint = { ...element.options.constraint };
- element.options.constraint = defaultConstraint;
- element.setPlacementFromConstraint();
- switch (position) {
- case QuickPlacement.Top:
- onPositionChange(0, 'top');
- break;
- case QuickPlacement.Bottom:
- onPositionChange(getRightBottomPosition(element.options.placement?.height ?? 0, 'bottom'), 'top');
- break;
- case QuickPlacement.VerticalCenter:
- onPositionChange(getCenterPosition(element.options.placement?.height ?? 0, 'v'), 'top');
- break;
- case QuickPlacement.Left:
- onPositionChange(0, 'left');
- break;
- case QuickPlacement.Right:
- onPositionChange(getRightBottomPosition(element.options.placement?.width ?? 0, 'right'), 'left');
- break;
- case QuickPlacement.HorizontalCenter:
- onPositionChange(getCenterPosition(element.options.placement?.width ?? 0, 'h'), 'left');
- break;
- }
- element.options.constraint = originalConstraint;
- element.setPlacementFromConstraint();
- };
- // Basing this on scene will mean that center is based on root for the time being
- const getCenterPosition = (elementSize: number, align: 'h' | 'v') => {
- const sceneSize = align === 'h' ? settings.scene.width : settings.scene.height;
- return (sceneSize - elementSize) / 2;
- };
- const getRightBottomPosition = (elementSize: number, align: 'right' | 'bottom') => {
- const sceneSize = align === 'right' ? settings.scene.width : settings.scene.height;
- return sceneSize - elementSize;
- };
- return (
- <div className={styles.buttonGroup}>
- <IconButton
- name={'horizontal-align-left'}
- onClick={() => onQuickPositioningChange(QuickPlacement.Left)}
- className={styles.button}
- size={'lg'}
- tooltip={'Align left'}
- />
- <IconButton
- name={'horizontal-align-center'}
- onClick={() => onQuickPositioningChange(QuickPlacement.HorizontalCenter)}
- className={styles.button}
- size={'lg'}
- tooltip={'Align horizontal centers'}
- />
- <IconButton
- name={'horizontal-align-right'}
- onClick={() => onQuickPositioningChange(QuickPlacement.Right)}
- className={styles.button}
- size={'lg'}
- tooltip={'Align right'}
- />
- <IconButton
- name={'vertical-align-top'}
- onClick={() => onQuickPositioningChange(QuickPlacement.Top)}
- size={'lg'}
- tooltip={'Align top'}
- />
- <IconButton
- name={'vertical-align-center'}
- onClick={() => onQuickPositioningChange(QuickPlacement.VerticalCenter)}
- className={styles.button}
- size={'lg'}
- tooltip={'Align vertical centers'}
- />
- <IconButton
- name={'vertical-align-bottom'}
- onClick={() => onQuickPositioningChange(QuickPlacement.Bottom)}
- className={styles.button}
- size={'lg'}
- tooltip={'Align bottom'}
- />
- </div>
- );
- };
- const getStyles = (theme: GrafanaTheme2) => ({
- buttonGroup: css`
- display: flex;
- flex-wrap: wrap;
- padding: 12px 0 12px 0;
- `,
- button: css`
- margin-left: 5px;
- margin-right: 5px;
- `,
- });
|