on master help sign in
feat: update indigo grid/flex to render arbitrary dom nodes
f011ffcMatt Condon (shrugs)
src/components/Grid.jsdeleted−30
@@ -1,30 +0,0 @@
1−import React from 'react';
2−import cn from 'classnames';
3−
4−function Grid({ className, ...rest }) {
5− return <div className={cn('grid12', className)} {...rest} />;
6−}
7−
8−Grid.Item = function GridItem({
9− full,
10− half,
11− third,
12− fourth,
13− className,
14− ...rest
15−}) {
16− return (
17− <div
18− className={cn(
19− full && `full`,
20− half && `half-${half}`,
21− third && `third-${third}`,
22− fourth && `fourth-${fourth}`,
23− className
24− )}
25− {...rest}
26− />
27− );
28−};
29−
30−export default Grid;
src/indigo-react/components/Flex.jsnew file+61
@@ -0,0 +1,61 @@
1+import React from 'react';
2+import cn from 'classnames';
3+
4+import getComponent from 'indigo-react/lib/getComponent';
5+
6+function Flex({
7+ as = 'div',
8+ row = false,
9+ wrap = false,
10+ col = false,
11+ align,
12+ justify,
13+ className,
14+ ...rest
15+}) {
16+ if (row && col) {
17+ throw new Error('Only one of row or col must be true, not both.');
18+ }
19+
20+ const Component = getComponent(as);
21+ return (
22+ <Component
23+ className={cn(
24+ 'flex',
25+ {
26+ 'flex-row': row,
27+ 'flex-col': col,
28+ 'flex-wrap': wrap,
29+ },
30+ {
31+ [`align-${align}`]: align,
32+ [`justify-${justify}`]: justify,
33+ },
34+ className
35+ )}
36+ {...rest}
37+ />
38+ );
39+}
40+
41+// flex can be boolean {true} or integer flex
42+Flex.Item = function FlexItem({ as = 'div', flex, className, ...rest }) {
43+ if (flex === true) {
44+ flex = 1;
45+ }
46+
47+ const Component = getComponent(as);
48+ return (
49+ <Component
50+ className={cn(
51+ {
52+ [`flex${flex}`]: flex,
53+ },
54+ className
55+ )}
56+ {...rest}
57+ />
58+ );
59+};
60+
61+export default Flex;
src/indigo-react/components/Grid.jsnew file+61
@@ -0,0 +1,61 @@
1+import React from 'react';
2+import cn from 'classnames';
3+
4+import getComponent from '../lib/getComponent';
5+
6+function Grid({ as = 'div', gap = 0, className, ...rest }) {
7+ const Component = getComponent(as);
8+ return (
9+ <Component
10+ className={cn('grid12', gap && `gap${gap}`, className)}
11+ {...rest}
12+ />
13+ );
14+}
15+
16+Grid.Item = function GridItem({
17+ as = 'div',
18+ full = false,
19+ half = 0,
20+ third = 0,
21+ fourth = 0,
22+ rows = [],
23+ cols = [],
24+ className,
25+ ...rest
26+}) {
27+ const Component = getComponent(as);
28+ return (
29+ <Component
30+ className={cn(
31+ {
32+ full,
33+ [`half-${half}`]: half,
34+ [`third-${third}`]: third,
35+ [`fourth-${fourth}`]: fourth,
36+ },
37+ {
38+ [`r${rows[0]}-${rows[1]}`]: rows.length === 2,
39+ [`c${cols[0]}-${cols[1]}`]: cols.length === 2,
40+ },
41+ className
42+ )}
43+ {...rest}
44+ />
45+ );
46+};
47+
48+Grid.Divider = function GridDivider({ vertical = false, className, ...rest }) {
49+ return (
50+ <div
51+ style={{
52+ height: vertical ? 'auto' : '1px',
53+ width: vertical ? '1px' : 'auto',
54+ }}
55+ className={cn('full', className || 'bg-gray2')}
56+ {...rest}
57+ />
58+ );
59+};
60+
61+export default Grid;
src/indigo-react/components/Input.js+26−12
@@ -1,7 +1,7 @@
1import React, { useCallback, useEffect, useMemo, useState } from 'react';
1import React, { useCallback, useEffect, useMemo, useState } from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3
3
4−import Grid from 'components/Grid';
4+import { Flex } from 'indigo-react';
5
5
6import { compose } from 'lib/lib';
6import { compose } from 'lib/lib';
7import { kDefaultValidator } from 'lib/validators';
7import { kDefaultValidator } from 'lib/validators';
@@ -124,6 +124,8 @@ export default function Input({
124 onPass,
124 onPass,
125 onError,
125 onError,
126 onFocus,
126 onFocus,
127+ onEnter,
128+ accessory,
127 disabled = false,
129 disabled = false,
128 mono = false,
130 mono = false,
129 autoFocus = false,
131 autoFocus = false,
@@ -137,6 +139,12 @@ export default function Input({
137 autoFocus: actuallyAutoFocus,
139 autoFocus: actuallyAutoFocus,
138 });
140 });
139
141
142+ // notify parent of enter keypress iff not disabled
143+ const onKeyPress = useCallback(
144+ e => !disabled && e.key === 'Enter' && onEnter && onEnter(),
145+ [disabled, onEnter]
146+ );
147+
140 // notify parent of value only when passing
148 // notify parent of value only when passing
141 useEffect(() => {
149 useEffect(() => {
142 pass && onValue && onValue(data);
150 pass && onValue && onValue(data);
@@ -158,15 +166,15 @@ export default function Input({
158 }, [focused, onFocus]);
166 }, [focused, onFocus]);
159
167
160 return (
168 return (
161− <Grid>
169+ <Flex col>
162− <Grid.Item full>
163− <label className="f6 lh-tall" htmlFor={name}>
170+ <Flex.Item as="label" className="f6 lh-tall" htmlFor={name}>
164− {label}
171+ {label}
165− </label>
172+ </Flex.Item>
166− </Grid.Item>
173+ <Flex row>
167− <Grid.Item full>
174+ <Flex.Item
168− <input
175+ as="input"
169 {...rest}
176 {...rest}
177+ cols={[1, accessory ? 11 : 13]}
170 className={cn(
178 className={cn(
171 'b b1 p3',
179 'b b1 p3',
172 { mono },
180 { mono },
@@ -189,12 +197,18 @@ export default function Input({
189 style={{
197 style={{
190 ...(disabled && { pointerEvents: 'none', cursor: 'not-allowed' }),
198 ...(disabled && { pointerEvents: 'none', cursor: 'not-allowed' }),
191 }}
199 }}
200+ onKeyPress={onKeyPress}
192 id={name}
201 id={name}
193− name={name}
194 autoFocus={actuallyAutoFocus}
202 autoFocus={actuallyAutoFocus}
195 {...bind}
203 {...bind}
204+ flex
196 />
205 />
197− </Grid.Item>
206+ {accessory && (
198− </Grid>
207+ <Flex.Item style={{ height: '45px', overflow: 'hidden' }}>
208+ {accessory}
209+ </Flex.Item>
210+ )}
211+ </Flex>
212+ </Flex>
199 );
213 );
200}
214}
src/indigo-react/lib/getComponent.jsnew file+1
@@ -0,0 +1 @@
1+export default as => as || 'div';