Canvas: Implement new constraint system (#47911)

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
Nathan Marrs
2022-04-20 09:59:49 -07:00
committed by GitHub
parent c1f766a374
commit d442608eb9
12 changed files with 315 additions and 250 deletions

View File

@@ -38,7 +38,6 @@ export class LayerElementListEditor extends PureComponent<Props> {
const newElementOptions = item.getNewOptions() as CanvasElementOptions;
newElementOptions.type = item.id;
const newElement = new ElementState(item, newElementOptions, layer);
newElement.updateSize(newElement.width, newElement.height);
newElement.updateData(layer.scene.context);
layer.elements.push(newElement);
layer.scene.save();

View File

@@ -1,18 +1,32 @@
import React, { FC } from 'react';
import { Button, Field, HorizontalGroup, InlineField, InlineFieldRow } from '@grafana/ui';
import { StandardEditorProps } from '@grafana/data';
import { PanelOptions } from '../models.gen';
import { useObservable } from 'react-use';
import { Subject } from 'rxjs';
import { Field, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui';
import { SelectableValue, StandardEditorProps } from '@grafana/data';
import { PanelOptions } from '../models.gen';
import { CanvasEditorOptions } from './elementEditor';
import { Anchor, Placement } from 'app/features/canvas';
import { HorizontalConstraint, Placement, VerticalConstraint } from 'app/features/canvas';
import { NumberInput } from 'app/features/dimensions/editors/NumberInput';
const anchors: Array<keyof Anchor> = ['top', 'left', 'bottom', 'right'];
const places: Array<keyof Placement> = ['top', 'left', 'bottom', 'right', 'width', 'height'];
export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, PanelOptions>> = ({ item }) => {
const horizontalOptions: Array<SelectableValue<HorizontalConstraint>> = [
{ label: 'Left', value: HorizontalConstraint.Left },
{ label: 'Right', value: HorizontalConstraint.Right },
{ label: 'Left and right', value: HorizontalConstraint.LeftRight },
];
const verticalOptions: Array<SelectableValue<VerticalConstraint>> = [
{ label: 'Top', value: VerticalConstraint.Top },
{ label: 'Bottom', value: VerticalConstraint.Bottom },
{ label: 'Top and bottom', value: VerticalConstraint.TopBottom },
];
export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, PanelOptions>> = ({
item,
onChange,
}) => {
const settings = item.settings;
// Will force a rerender whenever the subject changes
@@ -26,28 +40,39 @@ export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, P
if (!element) {
return <div>???</div>;
}
const { placement } = element;
const { options } = element;
const { placement, constraint: layout } = options;
const onHorizontalConstraintChange = (h: SelectableValue<HorizontalConstraint>) => {
element.options.constraint!.horizontal = h.value;
element.setPlacementFromConstraint();
settings.scene.revId++;
settings.scene.save(true);
};
const onVerticalConstraintChange = (v: SelectableValue<VerticalConstraint>) => {
element.options.constraint!.vertical = v.value;
element.setPlacementFromConstraint();
settings.scene.revId++;
settings.scene.save(true);
};
return (
<div>
<HorizontalGroup>
{anchors.map((a) => (
<Button
key={a}
size="sm"
variant={element.anchor[a] ? 'primary' : 'secondary'}
onClick={() => settings.scene.toggleAnchor(element, a)}
>
{a}
</Button>
))}
</HorizontalGroup>
<VerticalGroup>
<Select options={verticalOptions} onChange={onVerticalConstraintChange} value={layout?.vertical} />
<Select
options={horizontalOptions}
onChange={onHorizontalConstraintChange}
value={options.constraint?.horizontal}
/>
</VerticalGroup>
<br />
<Field label="Position">
<>
{places.map((p) => {
const v = placement[p];
const v = placement![p];
if (v == null) {
return null;
}

View File

@@ -84,7 +84,7 @@ export function getElementEditor(opts: CanvasEditorOptions): NestedPanelOptions<
category: ['Layout'],
id: 'content',
path: '__', // not used
name: 'Anchor',
name: 'Constraints',
editor: PlacementEditor,
settings: opts,
});

View File

@@ -81,7 +81,7 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions<LayerEdi
category: ['Layout'],
id: 'content',
path: '__', // not used
name: 'Anchor',
name: 'Constraints',
editor: PlacementEditor,
settings: {
scene: opts.scene,