From 047abc87c2ff3864f2e17b9fa107ca00bf411569 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Fri, 6 Dec 2019 10:24:34 +0100 Subject: [PATCH] UI: Segment Input (#20904) * Add input segment * Rename story * Cleanup * Fix lint error * More cleanup * Export ui component * Use measure text util --- .../src/components/Segment/Segment.tsx | 2 + .../src/components/Segment/SegmentAsync.tsx | 2 + .../components/Segment/SegmentInput.story.tsx | 29 +++++++++++ .../src/components/Segment/SegmentInput.tsx | 48 +++++++++++++++++++ .../src/components/Segment/index.ts | 1 + .../src/components/Segment/types.ts | 3 -- packages/grafana-ui/src/components/index.ts | 2 +- 7 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx create mode 100644 packages/grafana-ui/src/components/Segment/SegmentInput.tsx diff --git a/packages/grafana-ui/src/components/Segment/Segment.tsx b/packages/grafana-ui/src/components/Segment/Segment.tsx index 6aa78bd4830..fbdf617ad2f 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.tsx @@ -4,6 +4,8 @@ import { SelectableValue } from '@grafana/data'; import { SegmentSelect, useExpandableLabel, SegmentProps } from './'; export interface SegmentSyncProps extends SegmentProps { + value?: SelectableValue; + onChange: (item: SelectableValue) => void; options: Array>; } diff --git a/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx b/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx index ed595e3d6cb..2dd849bc25e 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx @@ -5,7 +5,9 @@ import { SelectableValue } from '@grafana/data'; import { useExpandableLabel, SegmentProps } from '.'; export interface SegmentAsyncProps extends SegmentProps { + value?: SelectableValue; loadOptions: (query?: string) => Promise>>; + onChange: (item: SelectableValue) => void; } export function SegmentAsync({ diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx new file mode 100644 index 00000000000..afe9b8060d5 --- /dev/null +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +const SegmentStories = storiesOf('UI/Segment/SegmentInput', module); +import { SegmentInput } from '.'; +import { UseState } from '../../utils/storybook/UseState'; + +SegmentStories.add('Segment Input', () => { + return ( + + {(value, updateValue) => ( + <> +
+
+ Segment Name +
+ { + updateValue(text as string); + action('Segment value changed')(text); + }} + /> +
+ + )} +
+ ); +}); diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.tsx new file mode 100644 index 00000000000..ebc026ff0e1 --- /dev/null +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.tsx @@ -0,0 +1,48 @@ +import React, { useRef, useState } from 'react'; +import { cx, css } from 'emotion'; +import useClickAway from 'react-use/lib/useClickAway'; +import { measureText } from '../../utils/measureText'; +import { useExpandableLabel, SegmentProps } from '.'; + +export interface SegmentInputProps extends SegmentProps { + value: string | number; + onChange: (text: string | number) => void; +} + +const FONT_SIZE = 14; + +export function SegmentInput({ + value, + onChange, + Component, + className, +}: React.PropsWithChildren>) { + const ref = useRef(null); + const [inputWidth, setInputWidth] = useState(measureText(value.toString(), FONT_SIZE).width); + const [Label, , expanded, setExpanded] = useExpandableLabel(false); + useClickAway(ref, () => setExpanded(false)); + + if (!expanded) { + return