form.stories.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. import PropTypes from 'prop-types';
  2. import React from 'react';
  3. import {
  4. Form as LegacyForm,
  5. TextField as LegacyTextField,
  6. PasswordField,
  7. BooleanField,
  8. } from 'app/components/forms';
  9. import {Panel} from 'app/components/panels';
  10. import {action} from '@storybook/addon-actions';
  11. import {boolean} from '@storybook/addon-knobs';
  12. import {storiesOf} from '@storybook/react';
  13. import {withInfo} from '@storybook/addon-info';
  14. import DatePickerField from 'app/views/settings/components/forms/datePickerField';
  15. import Form from 'app/views/settings/components/forms/form';
  16. import FormField from 'app/views/settings/components/forms/formField';
  17. import NewBooleanField from 'app/views/settings/components/forms/booleanField';
  18. import RadioField from 'app/views/settings/components/forms/radioField';
  19. import RadioGroup from 'app/views/settings/components/forms/controls/radioGroup';
  20. import RangeField from 'app/views/settings/components/forms/rangeField';
  21. import RangeSlider from 'app/views/settings/components/forms/controls/rangeSlider';
  22. import SelectField from 'app/views/settings/components/forms/selectField';
  23. import Switch from 'app/components/switch';
  24. import TextField from 'app/views/settings/components/forms/textField';
  25. class UndoButton extends React.Component {
  26. handleClick(e) {
  27. e.preventDefault();
  28. this.context.form.undo();
  29. }
  30. render() {
  31. return (
  32. <button type="button" onClick={this.handleClick.bind(this)}>
  33. Undo
  34. </button>
  35. );
  36. }
  37. }
  38. UndoButton.contextTypes = {
  39. form: PropTypes.object,
  40. };
  41. // eslint-disable-next-line
  42. storiesOf('Forms|Old/Form', module)
  43. .add('empty', withInfo('Empty form')(() => <LegacyForm onSubmit={action('submit')} />))
  44. .add(
  45. 'with Cancel',
  46. withInfo('Adds a "Cancel" button when `onCancel` is defined')(() => (
  47. <LegacyForm onCancel={action('cancel')} onSubmit={action('submit')} />
  48. ))
  49. )
  50. .add(
  51. 'save on blur and undo',
  52. withInfo('Saves on blur and has undo')(() => (
  53. <LegacyForm saveOnBlur allowUndo>
  54. <LegacyTextField
  55. name="name"
  56. label="Team Name"
  57. placeholder="e.g. Operations, Web, Desktop"
  58. required
  59. />
  60. <LegacyTextField name="slug" label="Short name" placeholder="e.g. api-team" />
  61. <UndoButton />
  62. </LegacyForm>
  63. ))
  64. );
  65. storiesOf('Forms|Form', module).add(
  66. 'default',
  67. withInfo(
  68. 'Use the knobs to see how the different field props that can be used affect the form layout.'
  69. )(() => {
  70. const fieldProps = {
  71. alignRight: boolean('Align right', false),
  72. required: boolean('Required', false),
  73. visible: boolean('Visible', true),
  74. disabled: boolean('Disabled', false),
  75. flexibleControlStateSize: boolean('Flexible Control State Size', true),
  76. inline: boolean('Inline (Label and Control on same line)', true),
  77. stacked: boolean(
  78. 'Stacked (Fields are on top of each other without a border)',
  79. true
  80. ),
  81. };
  82. return (
  83. <Form>
  84. <TextField
  85. name="textfieldflexiblecontrol"
  86. label="Text Field With Flexible Control State Size"
  87. placeholder="Type text and then delete it"
  88. {...fieldProps}
  89. />
  90. <NewBooleanField name="field" label="New Boolean Field" {...fieldProps} />
  91. <RadioField
  92. name="radio"
  93. label="Radio Field"
  94. choices={[
  95. ['choice_one', 'Choice One'],
  96. ['choice_two', 'Choice Two'],
  97. ['choice_three', 'Choice Three'],
  98. ]}
  99. {...fieldProps}
  100. />
  101. <SelectField
  102. name="select"
  103. label="Select Field"
  104. choices={[
  105. ['choice_one', 'Choice One'],
  106. ['choice_two', 'Choice Two'],
  107. ['choice_three', 'Choice Three'],
  108. ]}
  109. {...fieldProps}
  110. />
  111. <RangeField
  112. name="rangeField"
  113. label="Range Field"
  114. min={1}
  115. max={10}
  116. step={1}
  117. value={1}
  118. formatLabel={value => {
  119. return `${value} Toaster Strudle${value > 1 ? 's' : ''}`;
  120. }}
  121. {...fieldProps}
  122. />
  123. </Form>
  124. );
  125. })
  126. );
  127. storiesOf('Forms|Old/Fields', module)
  128. .add(
  129. 'PasswordField',
  130. withInfo({
  131. text: 'Password input',
  132. propTablesExclude: [LegacyForm],
  133. })(() => (
  134. <LegacyForm>
  135. <PasswordField hasSavedValue name="password" label="password" />
  136. </LegacyForm>
  137. ))
  138. )
  139. .add(
  140. 'BooleanField',
  141. withInfo({
  142. text: 'Boolean field (i.e. checkbox)',
  143. propTablesExclude: [LegacyForm],
  144. })(() => (
  145. <LegacyForm>
  146. <BooleanField name="field" />
  147. </LegacyForm>
  148. ))
  149. );
  150. storiesOf('Forms|Fields', module)
  151. .add(
  152. 'TextField',
  153. withInfo({
  154. text: 'Simple text input',
  155. propTablesExclude: [Form],
  156. })(() => (
  157. <Panel>
  158. <Form initialData={{context: {location: 'cat'}}}>
  159. <TextField
  160. name="simpletextfieldvalue"
  161. label="Simple Text Field with Value"
  162. placeholder="Simple Text Field"
  163. defaultValue="With a value present"
  164. />
  165. <TextField
  166. name="simpletextfieldplaceholder"
  167. label="Simple Text Field with Placeholder"
  168. placeholder="This is placeholder text"
  169. />
  170. <TextField
  171. name="simpletextfieldvaluedisabled"
  172. label="Disabled - Simple Text Field with Value"
  173. placeholder="Simple Text Field"
  174. defaultValue="With a value present"
  175. disabled
  176. />
  177. <TextField
  178. name="simpletextfieldplaceholderdisabled"
  179. label="Disabled - Simple Text Field with Placeholder"
  180. placeholder="This is placeholder text in a disabled field"
  181. disabled
  182. />
  183. <TextField
  184. name="textfieldwithreturnsubmit"
  185. label="Text Field With Return Submit"
  186. placeholder="Type here to show the return button"
  187. showReturnButton
  188. />
  189. <TextField
  190. name="textfieldflexiblecontrol"
  191. label="Text Field With Flexible Control State Size"
  192. placeholder="Type text and then delete it"
  193. required
  194. flexibleControlStateSize
  195. />
  196. <TextField
  197. name="textfielddisabled"
  198. label="Text field with disabled reason"
  199. placeholder="I am disabled"
  200. disabled
  201. disabledReason="This is the reason this field is disabled"
  202. />
  203. </Form>
  204. </Panel>
  205. ))
  206. )
  207. .add(
  208. 'BooleanField',
  209. withInfo({
  210. text: 'Boolean field (i.e. checkbox)',
  211. propTablesExclude: [Form],
  212. })(() => (
  213. <Form>
  214. <NewBooleanField name="field" label="New Boolean Field" />
  215. </Form>
  216. ))
  217. )
  218. .add(
  219. 'DatePickerField',
  220. withInfo({
  221. text: 'Date picker field with a popup calendar picker (for a single date)',
  222. propTablesExclude: [Form],
  223. })(() => (
  224. <Form>
  225. <DatePickerField name="field" label="Date Picker Field" />
  226. </Form>
  227. ))
  228. )
  229. .add(
  230. 'RadioField',
  231. withInfo({
  232. text: 'Radio field',
  233. propTablesExclude: [Form],
  234. })(() => (
  235. <Form>
  236. <RadioField
  237. name="radio"
  238. label="Radio Field"
  239. choices={[
  240. ['choice_one', 'Choice One'],
  241. ['choice_two', 'Choice Two'],
  242. ['choice_three', 'Choice Three'],
  243. ]}
  244. />
  245. </Form>
  246. ))
  247. )
  248. .add(
  249. 'SelectField',
  250. withInfo({
  251. text: 'Select Field',
  252. propTablesExclude: [Form],
  253. })(() => (
  254. <Form>
  255. <SelectField
  256. name="select"
  257. label="Select Field"
  258. choices={[
  259. ['choice_one', 'Choice One'],
  260. ['choice_two', 'Choice Two'],
  261. ['choice_three', 'Choice Three'],
  262. ]}
  263. />
  264. </Form>
  265. ))
  266. )
  267. .add(
  268. 'SelectField multiple',
  269. withInfo({
  270. text: 'Select Control w/ multiple',
  271. propTablesExclude: [Form],
  272. })(() => (
  273. <Form>
  274. <SelectField
  275. name="select"
  276. label="Multi Select"
  277. multiple={true}
  278. choices={[
  279. ['choice_one', 'Choice One'],
  280. ['choice_two', 'Choice Two'],
  281. ['choice_three', 'Choice Three'],
  282. ]}
  283. />
  284. </Form>
  285. ))
  286. )
  287. .add(
  288. 'Non-inline field',
  289. withInfo({
  290. text: 'Radio Group used w/ FormField',
  291. propTablesExclude: [Form],
  292. })(() => (
  293. <Form>
  294. <FormField name="radio" label="Radio Field" inline={false}>
  295. {({value, label, onChange}) => (
  296. <RadioGroup
  297. onChange={onChange}
  298. label={label}
  299. value={value}
  300. choices={[
  301. ['choice_one', 'Choice One'],
  302. ['choice_two', 'Choice Two'],
  303. ['choice_three', 'Choice Three'],
  304. ]}
  305. />
  306. )}
  307. </FormField>
  308. </Form>
  309. ))
  310. )
  311. .add(
  312. 'RangeSlider',
  313. withInfo('Range slider')(() => (
  314. <div style={{backgroundColor: '#fff', padding: 20}}>
  315. <RangeSlider
  316. name="rangeField"
  317. min={1}
  318. max={10}
  319. step={1}
  320. value={1}
  321. formatLabel={value => {
  322. return `${value} Toaster Strudle${value > 1 ? 's' : ''}`;
  323. }}
  324. />
  325. </div>
  326. ))
  327. )
  328. .add(
  329. 'Without a parent Form',
  330. withInfo('New form fields used withing having a parent Form')(() => {
  331. return (
  332. <div>
  333. <TextField
  334. name="simpletextfield"
  335. label="Simple Text Field"
  336. placeholder="Simple Text Field"
  337. onChange={action('TextField onChange')}
  338. />
  339. <NewBooleanField
  340. name="field"
  341. label="New Boolean Field"
  342. onChange={action('BooleanField onChange')}
  343. />
  344. <RadioField
  345. name="radio"
  346. label="Radio Field"
  347. onChange={action('RadioField onChange')}
  348. choices={[
  349. ['choice_one', 'Choice One'],
  350. ['choice_two', 'Choice Two'],
  351. ['choice_three', 'Choice Three'],
  352. ]}
  353. />
  354. <Switch id="test" />
  355. </div>
  356. );
  357. })
  358. );