From 69f8b32dc0e85ab096cd00916191f2871a52bf8c Mon Sep 17 00:00:00 2001 From: Tima Gixe <60817786+timagixe@users.noreply.github.com> Date: Tue, 27 Sep 2022 14:19:00 +0300 Subject: [PATCH] Storybook: add controls to `Segment` story (#55264) --- .../src/components/Segment/Segment.story.tsx | 44 +++++++++++- .../components/Segment/SegmentAsync.story.tsx | 72 ++++++++++++++++++- .../components/Segment/SegmentInput.story.tsx | 40 ++++++++++- 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/packages/grafana-ui/src/components/Segment/Segment.story.tsx b/packages/grafana-ui/src/components/Segment/Segment.story.tsx index 3adccc35ee8..7b0b43dd127 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.story.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.story.tsx @@ -1,9 +1,11 @@ import { action } from '@storybook/addon-actions'; -import { ComponentMeta } from '@storybook/react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; import React, { useState } from 'react'; import { Segment, Icon, SegmentSection } from '@grafana/ui'; +import { SegmentSyncProps } from './Segment'; + const AddButton = ( @@ -149,4 +151,44 @@ export const HtmlAttributes = () => { ); }; +export const Basic: ComponentStory>> = ( + args: SegmentSyncProps +) => { + const [value, setValue] = useState(args.value); + + const props: SegmentSyncProps = { + ...args, + value, + onChange: ({ value }) => { + setValue(value); + action('onChange fired')(value); + }, + onExpandedChange: (expanded) => action('onExpandedChange fired')({ expanded }), + }; + + return ( + + {...props} /> + + ); +}; + +Basic.parameters = { + controls: { + exclude: ['onChange', 'onExpandedChange', 'Component', 'className', 'value'], + }, +}; + +Basic.args = { + value: undefined, + options, + inputMinWidth: 0, + allowCustomValue: false, + placeholder: 'Placeholder text', + disabled: false, + autofocus: false, + allowEmptyValue: false, + inputPlaceholder: 'Start typing...', +}; + export default meta; diff --git a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx index 85944612494..dc2eade4b0d 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx @@ -1,11 +1,13 @@ import { action } from '@storybook/addon-actions'; -import { ComponentMeta } from '@storybook/react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; import React, { useState } from 'react'; import { AsyncState } from 'react-use/lib/useAsync'; import { SelectableValue } from '@grafana/data'; import { SegmentAsync, Icon, SegmentSection } from '@grafana/ui'; +import { SegmentAsyncProps } from './SegmentAsync'; + const AddButton = ( @@ -202,4 +204,72 @@ export const HtmlAttributes = () => { ); }; +export const Basic: ComponentStory>> = ( + args: SegmentAsyncProps +) => { + const [value, setValue] = useState(args.value); + + const props: SegmentAsyncProps = { + ...args, + value, + loadOptions: async (query = '') => { + action('loadOptions fired')({ query }); + const result = await loadOptions(options); + if (query) { + return result.filter((data) => data.label?.includes(query)); + } + return loadOptions(options); + }, + onChange: ({ value }) => { + setValue(value); + action('onChange fired')(value); + }, + onExpandedChange: (expanded) => action('onExpandedChange fired')({ expanded }), + noOptionMessageHandler: (state) => { + action('noOptionMessageHandler fired')(state); + if (state.loading) { + return 'Loading...'; + } + if (state.error) { + return 'Failed to load options'; + } + if (!Array.isArray(state.value) || state.value.length === 0) { + return 'No options found'; + } + return ''; + }, + }; + + return ( + + {...props} /> + + ); +}; + +Basic.parameters = { + controls: { + exclude: [ + 'value', + 'loadOptions', + 'onChange', + 'noOptionMessageHandler', + 'Component', + 'className', + 'onExpandedChange', + ], + }, +}; + +Basic.args = { + inputMinWidth: 0, + allowCustomValue: false, + reloadOptionsOnChange: false, + placeholder: 'Placeholder text', + disabled: false, + autofocus: false, + allowEmptyValue: false, + inputPlaceholder: 'Start typing...', +}; + export default meta; diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx index 72a461c76de..9e14cf25818 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx @@ -1,9 +1,11 @@ import { action } from '@storybook/addon-actions'; -import { ComponentMeta } from '@storybook/react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; import React, { useState } from 'react'; import { SegmentInput, Icon, SegmentSection } from '@grafana/ui'; +import { SegmentInputProps } from './SegmentInput'; + const SegmentFrame = ({ children }: any) => ( <> {children} @@ -97,4 +99,40 @@ export const InputWithAutoFocus = () => { ); }; +export const Basic: ComponentStory>> = ( + args: SegmentInputProps +) => { + const [value, setValue] = useState(args.value); + + const props: SegmentInputProps = { + ...args, + value, + onChange: (value) => { + setValue(value); + action('onChange fired')({ value }); + }, + onExpandedChange: (expanded) => action('onExpandedChange fired')({ expanded }), + }; + + return ( + + {...props} /> + + ); +}; + +Basic.parameters = { + controls: { + exclude: ['value', 'onChange', 'Component', 'className', 'onExpandedChange'], + }, +}; + +Basic.args = { + value: 'Initial input value', + placeholder: 'Placeholder text', + disabled: false, + autofocus: false, + inputPlaceholder: 'Start typing...', +}; + export default meta;