diff --git a/packages/visx-annotation/src/components/EditableAnnotation.tsx b/packages/visx-annotation/src/components/EditableAnnotation.tsx index 8ebb0f9d8..f15cc2e85 100644 --- a/packages/visx-annotation/src/components/EditableAnnotation.tsx +++ b/packages/visx-annotation/src/components/EditableAnnotation.tsx @@ -11,6 +11,10 @@ export type EditableAnnotationProps = Pick; /** Optional circle props to set on the label drag handle. */ @@ -40,18 +44,20 @@ const defaultDragHandleProps = { }; export default function EditableAnnotation({ - x: subjectX = 0, - y: subjectY = 0, + canEditLabel = true, + canEditSubject = true, + children, dx: labelDx = 0, dy: labelDy = 0, - children, - width, height, - subjectDragHandleProps, labelDragHandleProps, - onDragStart, - onDragMove, onDragEnd, + onDragMove, + onDragStart, + subjectDragHandleProps, + width, + x: subjectX = 0, + y: subjectY = 0, }: EditableAnnotationProps) { // chicken before the egg, we need these to reference drag state // in drag callbacks which are defined before useDrag() state is available @@ -142,20 +148,22 @@ export default function EditableAnnotation({ fill="transparent" /> )} - + {canEditSubject && ( + + )} {labelDrag.isDragging && ( )} - + {canEditLabel && ( + + )} ); } diff --git a/packages/visx-annotation/test/EditableAnnotation.test.tsx b/packages/visx-annotation/test/EditableAnnotation.test.tsx index b72f49b0c..6f87cd7e2 100644 --- a/packages/visx-annotation/test/EditableAnnotation.test.tsx +++ b/packages/visx-annotation/test/EditableAnnotation.test.tsx @@ -1,11 +1,12 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Annotation, EditableAnnotation } from '../src'; +import { EditableAnnotationProps } from '../lib/components/EditableAnnotation'; describe('', () => { - function setup() { + function setup(props?: Partial) { return shallow( - +
, ); @@ -16,6 +17,10 @@ describe('', () => { it('should render two resize handles', () => { expect(setup().find('circle')).toHaveLength(2); }); + it('should render one resize handle if canEditLabel or canEditSubject are false', () => { + expect(setup({ canEditLabel: false }).find('circle')).toHaveLength(1); + expect(setup({ canEditSubject: false }).find('circle')).toHaveLength(1); + }); it('should render an Annotation', () => { expect(setup().find(Annotation)).toHaveLength(1); }); diff --git a/packages/visx-demo/src/sandboxes/visx-annotation/Example.tsx b/packages/visx-demo/src/sandboxes/visx-annotation/Example.tsx index 38f0079af..30e2ffaec 100644 --- a/packages/visx-demo/src/sandboxes/visx-annotation/Example.tsx +++ b/packages/visx-demo/src/sandboxes/visx-annotation/Example.tsx @@ -22,6 +22,8 @@ export default function Example({ width, height, compact = false }: AnnotationPr approxTooltipHeight, connectorType, data, + editLabelPosition, + editSubjectPosition, getDate, getStockValue, horizontalAnchor, @@ -51,6 +53,8 @@ export default function Example({ width, height, compact = false }: AnnotationPr y={annotationPosition.y} dx={annotationPosition.dx} dy={annotationPosition.dy} + canEditLabel={editLabelPosition} + canEditSubject={editSubjectPosition} onDragEnd={({ event, ...nextPosition }) => { // snap Annotation to the nearest data point const nearestDatum = findNearestDatum({ diff --git a/packages/visx-demo/src/sandboxes/visx-annotation/ExampleControls.tsx b/packages/visx-demo/src/sandboxes/visx-annotation/ExampleControls.tsx index 57a453285..a87fa43d3 100644 --- a/packages/visx-demo/src/sandboxes/visx-annotation/ExampleControls.tsx +++ b/packages/visx-demo/src/sandboxes/visx-annotation/ExampleControls.tsx @@ -19,6 +19,8 @@ type ProvidedProps = { approxTooltipHeight: number; connectorType: 'line' | 'elbow'; data: AppleStock[]; + editLabelPosition: boolean; + editSubjectPosition: boolean; getDate: (d: AppleStock) => number; getStockValue: (d: AppleStock) => number; horizontalAnchor?: 'left' | 'middle' | 'right'; @@ -62,7 +64,8 @@ export default function ExampleControls({ [height], ); - const [editAnnotation, setEditAnnotation] = useState(false); + const [editLabelPosition, setEditLabelPosition] = useState(false); + const [editSubjectPosition, setEditSubjectPosition] = useState(false); const [title, setTitle] = useState('Title'); const [subtitle, setSubtitle] = useState( compact ? 'Subtitle' : 'Subtitle with deets and deets and deets and deets', @@ -87,11 +90,14 @@ export default function ExampleControls({ return ( <> {children({ - AnnotationComponent: editAnnotation ? EditableAnnotation : Annotation, + AnnotationComponent: + editLabelPosition || editSubjectPosition ? EditableAnnotation : Annotation, annotationPosition, approxTooltipHeight, connectorType, data, + editLabelPosition, + editSubjectPosition, getDate, getStockValue, horizontalAnchor: horizontalAnchor === 'auto' ? undefined : horizontalAnchor, @@ -121,10 +127,19 @@ export default function ExampleControls({ +    +