1import * as React from 'react'
2import * as Sb from '../stories/storybook'
3import Button from './button'
4import Input, {Props} from './input'
5import Box from './box'
6import {globalStyles} from '../styles'
7
8const onKeyDown = Sb.action('onKeyDown')
9const onKeyUp = Sb.action('onKeyUp')
10const onEnterKeyDown = Sb.action('onEnterKeyDown')
11
12const commonProps: Props = {
13  onBlur: Sb.action('onBlur'),
14  onChangeText: Sb.action('onChangeText'),
15  onClick: Sb.action('onClick'),
16  onEnterKeyDown: () => onEnterKeyDown(),
17  onFocus: Sb.action('onFocus'),
18  onKeyDown: e => onKeyDown(e.key),
19  onKeyUp: e => onKeyUp(e.key),
20}
21
22type TestInputProps = {
23  multiline: boolean
24}
25
26class TestInput extends React.Component<TestInputProps> {
27  _input: Input | null = null
28
29  _setInput = (ref: Input | null) => {
30    this._input = ref
31  }
32
33  _replaceText = (textToInsert: string) => {
34    if (this._input) {
35      this._input.transformText(({text, selection}) => {
36        const newText = text.slice(0, selection?.start ?? 0) + textToInsert + text.slice(selection?.end ?? 0)
37        const pos = selection?.start ?? 0 + textToInsert.length
38        return {
39          selection: {
40            end: pos,
41            start: pos,
42          },
43          text: newText,
44        }
45      })
46    }
47  }
48
49  _replaceFoo = () => {
50    this._replaceText('foo')
51    onEnterKeyDown()
52  }
53
54  render() {
55    return (
56      <Box
57        style={{
58          ...globalStyles.flexBoxColumn,
59          alignItems: 'center',
60          width: 420,
61        }}
62      >
63        <Input
64          {...commonProps}
65          multiline={this.props.multiline}
66          onEnterKeyDown={this._replaceFoo}
67          uncontrolled={true}
68          ref={this._setInput}
69        />
70        <Button label='Insert "foo" (enter)' onClick={this._replaceFoo} />
71      </Box>
72    )
73  }
74}
75
76const load = () => {
77  Sb.storiesOf('Common/Input', module)
78    .addDecorator(Sb.scrollViewDecorator)
79    .add('Empty (uncontrolled)', () => <TestInput multiline={false} />)
80    .add('Empty (multiline) (uncontrolled)', () => <TestInput multiline={true} />)
81    .add('Filled', () => <Input {...commonProps} value="Hello, World!" />)
82    .add('Filled Centered', () => (
83      <Box
84        style={{
85          ...globalStyles.flexBoxColumn,
86          alignItems: 'center',
87          backgroundColor: 'yellow',
88          width: 420,
89        }}
90      >
91        <Input {...commonProps} value="Hello, World!" />
92      </Box>
93    ))
94    .add('Filled Stretched', () => (
95      <Box
96        style={{
97          ...globalStyles.flexBoxColumn,
98          alignItems: 'stretch',
99          backgroundColor: 'green',
100          width: 420,
101        }}
102      >
103        <Input {...commonProps} value="Hello, World!" />
104      </Box>
105    ))
106    .add('Filled style override', () => (
107      <Input {...commonProps} value="Hello, World!" style={{backgroundColor: 'red'}} />
108    ))
109    .add('Filled input style override', () => (
110      <Input {...commonProps} value="Hello, World!" inputStyle={{backgroundColor: 'red'}} />
111    ))
112    .add('No underline', () => <Input {...commonProps} hideUnderline={true} />)
113    .add('Hint empty', () => <Input {...commonProps} hintText="hint" />)
114    .add('Floating label empty', () => <Input {...commonProps} floatingHintTextOverride="floating" />)
115    .add('Single line', () => <Input {...commonProps} />)
116    .add('Auto cap none', () => <Input {...commonProps} autoCapitalize="none" />)
117    .add('Auto cap words', () => <Input {...commonProps} autoCapitalize="words" />)
118    .add('Auto cap sentences', () => <Input {...commonProps} autoCapitalize="sentences" />)
119    .add('Auto cap characters', () => <Input {...commonProps} autoCapitalize="characters" />)
120    .add('Autocorrect', () => <Input {...commonProps} autoCorrect={true} />)
121    .add('Password', () => <Input {...commonProps} type="password" />)
122    .add('Floating label filled', () => (
123      <Input {...commonProps} floatingHintTextOverride="Hello..." value="Hello, World!" />
124    ))
125    .add('Floating label filled error', () => (
126      <Input
127        {...commonProps}
128        floatingHintTextOverride="Hello..."
129        value="Hello, World!"
130        errorText="Check your spelling"
131      />
132    ))
133    .add('Error styled', () => (
134      <Input
135        {...commonProps}
136        floatingHintTextOverride="Hello..."
137        value="Hello, World!"
138        errorText="Check your spelling"
139        errorStyle={{
140          backgroundColor: 'blue',
141          padding: 20,
142        }}
143      />
144    ))
145    .add('Visible password', () => (
146      <Input {...commonProps} type="passwordVisible" floatingHintTextOverride="shh..." value="secret" />
147    ))
148    .add('Floating Label Hint Empty', () => (
149      <Input {...commonProps} hintText="Hello!" floatingHintTextOverride="Hello..." />
150    ))
151    .add('Multi Label Styled', () => (
152      <Input
153        {...commonProps}
154        hintText="Hello!"
155        multiline={true}
156        value="multi styled"
157        inputStyle={{color: 'blue'}}
158      />
159    ))
160    .add('Hint Multiline Empty', () => (
161      <Input
162        {...commonProps}
163        hintText="This is a very long hint that will hopefully wrap to two lines or more more more!"
164        multiline={true}
165      />
166    ))
167    .add('Long Multiline', () => (
168      <Input
169        {...commonProps}
170        value="This is a very long text that will hopefully wrap to two lines or more more more! or more or more or more or more or more or more or more or more or more or more or more or more or more or more!"
171        multiline={true}
172      />
173    ))
174    .add('Long Multiline rowsMax1', () => (
175      <Input
176        {...commonProps}
177        value="This is a very long text that will hopefully wrap to two lines or more more more! or more or more or more or more or more or more or more or more or more or more or more or more or more or more!"
178        multiline={true}
179        rowsMax={1}
180      />
181    ))
182    .add('Long Multiline rowsMax2', () => (
183      <Input
184        {...commonProps}
185        value="This is a very long text that will hopefully wrap to two lines or more more more! or more or more or more or more or more or more or more or more or more or more or more or more or more or more!"
186        multiline={true}
187        rowsMax={2}
188      />
189    ))
190    .add('Long Multiline rowsMax4', () => (
191      <Input
192        {...commonProps}
193        value="This is a very long text that will hopefully wrap to two laxes or more more more! or more or more or more or more or more or more or more or more or more or more or more or more or more or more!"
194        multiline={true}
195        rowsMax={4}
196      />
197    ))
198    .add('Long Multiline rowsMin2Max4 small', () => (
199      <Input {...commonProps} value="This is a small text" multiline={true} rowsMin={2} rowsMax={4} />
200    ))
201    .add('Long Multiline rowsMin2Max4 long', () => (
202      <Input
203        {...commonProps}
204        value="This is a very long text that will hopefully wrap to two lines or more more more! or more or more or more or more or more or more or more or more or more or more or more or more or more or more!"
205        multiline={true}
206        rowsMin={2}
207        rowsMax={4}
208      />
209    ))
210    .add('Long Multiline rowsMin1', () => (
211      <Input {...commonProps} value="This is a small text" multiline={true} rowsMin={1} />
212    ))
213    .add('Long Multiline rowsMin2', () => (
214      <Input {...commonProps} value="This is a small text" multiline={true} rowsMin={2} />
215    ))
216    .add('Long Multiline rowsMin4', () => (
217      <Input {...commonProps} value="This is a small text" multiline={true} rowsMin={4} />
218    ))
219    .add('Multiline error', () => (
220      <Input
221        {...commonProps}
222        value="This is a multiline with error"
223        multiline={true}
224        errorText="this is an error"
225      />
226    ))
227    .add('Floating Label Multiline Empty', () => (
228      <Input {...commonProps} floatingHintTextOverride="Hello..." multiline={true} />
229    ))
230    .add('Floating Label Multiline Filled', () => (
231      <Input {...commonProps} floatingHintTextOverride="Hello..." multiline={true} value="Hello, World!" />
232    ))
233    .add('Floating Label Multiline Filled Long', () => (
234      <Input
235        {...commonProps}
236        floatingHintTextOverride="Hello..."
237        multiline={true}
238        value={'Hello,\nMy name is Max\nHow are you?'}
239      />
240    ))
241    .add('Small Empty', () => <Input {...commonProps} small={true} smallLabel="Small:" />)
242    .add('Small Filled', () => (
243      <Input {...commonProps} small={true} value="Hello, World!" smallLabel="Small:" />
244    ))
245    .add('Small styled', () => (
246      <Input
247        {...commonProps}
248        small={true}
249        value="Hello, World!"
250        smallLabel="Small:"
251        inputStyle={{color: 'blue'}}
252      />
253    ))
254    .add('Small Hint Empty', () => (
255      <Input {...commonProps} small={true} smallLabel="Small:" hintText="Hello..." />
256    ))
257    .add('Small Label Empty', () => <Input {...commonProps} small={true} hintText="Hello..." />)
258    .add('Small Label Styled', () => (
259      <Input
260        {...commonProps}
261        small={true}
262        smallLabel="Styled:"
263        smallLabelStyle={{backgroundColor: 'blue'}}
264        hintText="Hello..."
265      />
266    ))
267    .add('Small Hint Error', () => (
268      <Input
269        {...commonProps}
270        small={true}
271        smallLabel="Small:"
272        value="has an error"
273        hintText="Hello..."
274        errorText="this is invisible in the small input"
275      />
276    ))
277}
278
279export default load
280