|
|
|
|
@ -1,11 +1,22 @@ |
|
|
|
|
import React, { useState } from 'react'; |
|
|
|
|
import { boolean, text, select, number } from '@storybook/addon-knobs'; |
|
|
|
|
import { Story, Meta } from '@storybook/react'; |
|
|
|
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; |
|
|
|
|
import mdx from './Input.mdx'; |
|
|
|
|
import { getAvailableIcons, IconName } from '../../types'; |
|
|
|
|
import { KeyValue } from '@grafana/data'; |
|
|
|
|
import { Field, Icon, Button, Input } from '@grafana/ui'; |
|
|
|
|
|
|
|
|
|
const prefixSuffixOpts = { |
|
|
|
|
None: null, |
|
|
|
|
Text: '$', |
|
|
|
|
...getAvailableIcons().reduce<KeyValue<string>>((prev, c) => { |
|
|
|
|
return { |
|
|
|
|
...prev, |
|
|
|
|
[`Icon: ${c}`]: `icon-${c}`, |
|
|
|
|
}; |
|
|
|
|
}, {}), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
|
title: 'Forms/Input', |
|
|
|
|
component: Input, |
|
|
|
|
@ -14,47 +25,50 @@ export default { |
|
|
|
|
docs: { |
|
|
|
|
page: mdx, |
|
|
|
|
}, |
|
|
|
|
knobs: { |
|
|
|
|
disable: true, |
|
|
|
|
}, |
|
|
|
|
controls: { |
|
|
|
|
exclude: ['prefix', 'suffix', 'addonBefore', 'addonAfter'], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export const Simple = () => { |
|
|
|
|
const prefixSuffixOpts = { |
|
|
|
|
None: null, |
|
|
|
|
Text: '$', |
|
|
|
|
...getAvailableIcons().reduce<KeyValue<string>>((prev, c) => { |
|
|
|
|
return { |
|
|
|
|
...prev, |
|
|
|
|
[`Icon: ${c}`]: `icon-${c}`, |
|
|
|
|
}; |
|
|
|
|
}, {}), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const BEHAVIOUR_GROUP = 'Behaviour props'; |
|
|
|
|
// ---
|
|
|
|
|
const type = select( |
|
|
|
|
'Type', |
|
|
|
|
{ |
|
|
|
|
text: 'text', |
|
|
|
|
password: 'password', |
|
|
|
|
number: 'number', |
|
|
|
|
args: { |
|
|
|
|
type: 'text', |
|
|
|
|
width: 40, |
|
|
|
|
prefixVisible: '', |
|
|
|
|
suffixVisible: '', |
|
|
|
|
invalid: false, |
|
|
|
|
loading: false, |
|
|
|
|
}, |
|
|
|
|
argTypes: { |
|
|
|
|
prefixVisible: { |
|
|
|
|
control: { |
|
|
|
|
type: 'select', |
|
|
|
|
options: prefixSuffixOpts, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
'text', |
|
|
|
|
BEHAVIOUR_GROUP |
|
|
|
|
); |
|
|
|
|
const disabled = boolean('Disabled', false, BEHAVIOUR_GROUP); |
|
|
|
|
const invalid = boolean('Invalid', false, BEHAVIOUR_GROUP); |
|
|
|
|
const loading = boolean('Loading', false, BEHAVIOUR_GROUP); |
|
|
|
|
suffixVisible: { |
|
|
|
|
control: { |
|
|
|
|
type: 'select', |
|
|
|
|
options: prefixSuffixOpts, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
type: { |
|
|
|
|
control: { |
|
|
|
|
type: 'select', |
|
|
|
|
options: ['text', 'number', 'password'], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// validation: { name: 'Validation regex (will do a partial match if you do not anchor it)' },
|
|
|
|
|
width: { control: { type: 'range', min: 10, max: 200, step: 10 } }, |
|
|
|
|
}, |
|
|
|
|
} as Meta; |
|
|
|
|
|
|
|
|
|
const VISUAL_GROUP = 'Visual options'; |
|
|
|
|
// ---
|
|
|
|
|
const width = number('Width', 0, undefined, VISUAL_GROUP); |
|
|
|
|
const placeholder = text('Placeholder', 'Enter your name here...', VISUAL_GROUP); |
|
|
|
|
const before = boolean('Addon before', false, VISUAL_GROUP); |
|
|
|
|
const after = boolean('Addon after', false, VISUAL_GROUP); |
|
|
|
|
export const Simple: Story = (args) => { |
|
|
|
|
const addonAfter = <Button variant="secondary">Load</Button>; |
|
|
|
|
const addonBefore = <div style={{ display: 'flex', alignItems: 'center', padding: '5px' }}>Input</div>; |
|
|
|
|
const prefix = select('Prefix', prefixSuffixOpts, null, VISUAL_GROUP); |
|
|
|
|
const suffix = select('Suffix', prefixSuffixOpts, null, VISUAL_GROUP); |
|
|
|
|
const prefix = args.prefixVisible; |
|
|
|
|
const suffix = args.suffixVisible; |
|
|
|
|
let prefixEl: any = prefix; |
|
|
|
|
if (prefix && prefix.match(/icon-/g)) { |
|
|
|
|
prefixEl = <Icon name={prefix.replace(/icon-/g, '') as IconName} />; |
|
|
|
|
@ -64,45 +78,35 @@ export const Simple = () => { |
|
|
|
|
suffixEl = <Icon name={suffix.replace(/icon-/g, '') as IconName} />; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const CONTAINER_GROUP = 'Container options'; |
|
|
|
|
// ---
|
|
|
|
|
const containerWidth = number( |
|
|
|
|
'Container width', |
|
|
|
|
300, |
|
|
|
|
{ |
|
|
|
|
range: true, |
|
|
|
|
min: 100, |
|
|
|
|
max: 500, |
|
|
|
|
step: 10, |
|
|
|
|
}, |
|
|
|
|
CONTAINER_GROUP |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div style={{ width: containerWidth }}> |
|
|
|
|
<Input |
|
|
|
|
disabled={disabled} |
|
|
|
|
width={width} |
|
|
|
|
prefix={prefixEl} |
|
|
|
|
invalid={invalid} |
|
|
|
|
suffix={suffixEl} |
|
|
|
|
loading={loading} |
|
|
|
|
addonBefore={before && addonBefore} |
|
|
|
|
addonAfter={after && addonAfter} |
|
|
|
|
type={type} |
|
|
|
|
placeholder={placeholder} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
<Input |
|
|
|
|
disabled={args.disabled} |
|
|
|
|
width={args.width} |
|
|
|
|
prefix={prefixEl} |
|
|
|
|
invalid={args.invalid} |
|
|
|
|
suffix={suffixEl} |
|
|
|
|
loading={args.loading} |
|
|
|
|
addonBefore={args.before && addonBefore} |
|
|
|
|
addonAfter={args.after && addonAfter} |
|
|
|
|
type={args.type} |
|
|
|
|
placeholder={args.placeholder} |
|
|
|
|
/> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
Simple.args = { |
|
|
|
|
disabled: false, |
|
|
|
|
before: false, |
|
|
|
|
after: false, |
|
|
|
|
placeholder: 'Enter your name here...', |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export const WithFieldValidation = () => { |
|
|
|
|
export const WithFieldValidation: Story = (args) => { |
|
|
|
|
const [value, setValue] = useState(''); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div> |
|
|
|
|
<Field invalid={value === ''} error={value === '' ? 'This input is required' : ''}> |
|
|
|
|
<Input value={value} onChange={(e) => setValue(e.currentTarget.value)} /> |
|
|
|
|
<Input value={value} onChange={(e) => setValue(e.currentTarget.value)} {...args} /> |
|
|
|
|
</Field> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
|