react-native-molecules 0.5.0-beta.10 → 0.5.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,23 @@
1
1
  import { getRegisteredComponentWithFallback } from '../../core';
2
- import TextInputDefault from './TextInput';
2
+ import TextInputDefault, {
3
+ TextInputIcon,
4
+ TextInputLabel,
5
+ TextInputLeft,
6
+ TextInputOutline,
7
+ TextInputRight,
8
+ TextInputSupportingText,
9
+ } from './TextInput';
10
+
11
+ const TextInputBase = getRegisteredComponentWithFallback('TextInput', TextInputDefault);
3
12
 
4
- export const TextInput = getRegisteredComponentWithFallback('TextInput', TextInputDefault);
13
+ export const TextInput = Object.assign(TextInputBase, {
14
+ Label: TextInputLabel,
15
+ Left: TextInputLeft,
16
+ Right: TextInputRight,
17
+ Icon: TextInputIcon,
18
+ Outline: TextInputOutline,
19
+ SupportingText: TextInputSupportingText,
20
+ });
5
21
 
6
22
  export {
7
23
  type ElementProps as TextInputElementProps,
@@ -9,4 +25,4 @@ export {
9
25
  type Props as TextInputProps,
10
26
  } from './TextInput';
11
27
  export type * from './types';
12
- export { styles as textInputStyles } from './utils';
28
+ export { TextInputContext } from './utils';
@@ -1,37 +1,96 @@
1
- import type { ReactElement, RefObject } from 'react';
1
+ import type { ReactElement, ReactNode, RefObject } from 'react';
2
2
  import type {
3
3
  Animated,
4
- BlurEvent,
5
- ColorValue,
6
- FocusEvent,
4
+ GestureResponderEvent,
5
+ LayoutChangeEvent,
6
+ PressableProps,
7
7
  StyleProp,
8
8
  TextInput as NativeTextInput,
9
+ TextProps,
9
10
  TextStyle,
11
+ ViewStyle,
10
12
  } from 'react-native';
11
13
 
14
+ import type { IconProps } from '../Icon';
12
15
  import type { Props as TextInputProps } from './TextInput';
13
16
 
14
17
  export type TextInputLabelProp = string | ReactElement;
15
18
 
19
+ // States for compound component context
20
+ export type TextInputStates =
21
+ | 'disabled'
22
+ | 'focused'
23
+ | 'hovered'
24
+ | 'hoveredAndFocused'
25
+ | 'errorFocusedAndHovered'
26
+ | 'error'
27
+ | 'errorFocused'
28
+ | 'errorHovered'
29
+ | 'errorDisabled'
30
+ | 'default';
31
+
32
+ // Context type for compound components
33
+ export type TextInputContextType = {
34
+ // Variants
35
+ variant: TextInputVariant;
36
+ size: TextInputSize;
37
+ state: TextInputStates;
38
+
39
+ // State flags
40
+ disabled: boolean;
41
+ error: boolean;
42
+ focused: boolean;
43
+ hovered: boolean;
44
+ hasValue: boolean;
45
+ hasLabel: boolean;
46
+ required: boolean;
47
+ multiline: boolean;
48
+
49
+ // Layout
50
+ labelLayout: { measured: boolean; width: number; height: number };
51
+ leftElementLayout: { measured: boolean; width: number; height: number };
52
+ onLayoutLabel: (e: LayoutChangeEvent) => void;
53
+ onLayoutLeftElement: (e: LayoutChangeEvent) => void;
54
+
55
+ // Refs and handlers
56
+ forceFocus: () => void;
57
+ };
58
+
59
+ // Compound component props
60
+ export type TextInputLabelCompoundProps = TextProps & {
61
+ children: TextInputLabelProp;
62
+ floatingStyle?: StyleProp<TextStyle>;
63
+ maxFontSizeMultiplier?: number;
64
+ };
65
+
66
+ export type TextInputElementCompoundProps = Omit<PressableProps, 'onPress'> & {
67
+ onPress?: null | ((event: GestureResponderEvent, forceFocus: () => void) => void) | undefined;
68
+ children: ReactNode;
69
+ style?: StyleProp<ViewStyle>;
70
+ onLayout?: (e: LayoutChangeEvent) => void;
71
+ };
72
+
73
+ export type TextInputIconCompoundProps = Omit<IconProps, 'color'> & {
74
+ color?: string;
75
+ };
76
+
77
+ export type TextInputSupportingTextCompoundProps = {
78
+ children: string;
79
+ style?: StyleProp<TextStyle>;
80
+ };
81
+
82
+ export type TextInputOutlineCompoundProps = {
83
+ style?: StyleProp<ViewStyle>;
84
+ };
85
+
16
86
  export type TextInputSize = 'lg' | 'md' | 'sm';
17
87
 
18
88
  export type TextInputVariant = 'flat' | 'outlined' | 'plain';
19
89
 
20
- export type RenderProps = {
90
+ export type RenderProps = Omit<TextInputProps, 'ref'> & {
21
91
  ref: RefObject<NativeTextInput | null>;
22
- onChangeText?: (a: string) => void;
23
- placeholder?: string;
24
- placeholderTextColor?: ColorValue;
25
- editable?: boolean;
26
- selectionColor?: string;
27
- onFocus?: (args: FocusEvent) => void;
28
- onBlur?: (args: BlurEvent) => void;
29
- underlineColorAndroid?: string;
30
- style: any;
31
- multiline?: boolean;
32
92
  size?: TextInputSize;
33
93
  numberOfLines?: number;
34
- value?: string;
35
94
  adjustsFontSizeToFit?: boolean;
36
95
  testID?: string;
37
96
  };
@@ -54,17 +113,7 @@ export type InputBaseProps = {
54
113
  onChangeText?: (value: string) => void;
55
114
  onLayoutAnimatedText: (args: any) => void;
56
115
  componentStyles: Record<string, any>;
57
- } & Omit<
58
- TextInputProps,
59
- | 'style'
60
- | 'activeOutlineColor'
61
- | 'activeUnderlineColor'
62
- | 'underlineColor'
63
- | 'outlineColor'
64
- | 'placeholderTextColor'
65
- | 'selectionColor'
66
- | 'containerStyle'
67
- >;
116
+ } & Omit<TextInputProps, 'style' | 'placeholderTextColor' | 'selectionColor' | 'containerStyle'>;
68
117
 
69
118
  export type InputLabelProps = {
70
119
  baseLabelTranslateX: number;
@@ -1,9 +1,30 @@
1
+ import { createContext } from 'react';
1
2
  import { StyleSheet } from 'react-native-unistyles';
2
3
 
3
4
  import {
4
5
  getRegisteredComponentStylesWithFallback,
5
6
  getRegisteredComponentUtilsWithFallback,
6
7
  } from '../../core';
8
+ import type { TextInputContextType, TextInputStates } from './types';
9
+
10
+ export const TextInputContext = createContext<TextInputContextType>({
11
+ variant: 'outlined',
12
+ size: 'sm',
13
+ state: 'default' as TextInputStates,
14
+ disabled: false,
15
+ error: false,
16
+ focused: false,
17
+ hovered: false,
18
+ hasValue: false,
19
+ hasLabel: false,
20
+ required: false,
21
+ multiline: false,
22
+ labelLayout: { measured: false, width: 0, height: 0 },
23
+ leftElementLayout: { measured: false, width: 0, height: 0 },
24
+ onLayoutLabel: () => {},
25
+ onLayoutLeftElement: () => {},
26
+ forceFocus: () => {},
27
+ });
7
28
 
8
29
  export type States =
9
30
  | 'disabled'
@@ -41,58 +62,12 @@ export const getInputMinHeight = getRegisteredComponentUtilsWithFallback(
41
62
  'getInputMinHeight',
42
63
  );
43
64
 
65
+ // Main TextInput component styles
44
66
  const textInputStylesDefault = StyleSheet.create(theme => ({
45
67
  root: {
46
- variants: {
47
- variant: {
48
- outlined: {},
49
- },
50
- state: {
51
- focused: {
52
- ...({
53
- activeColor: theme.colors.primary,
54
- } as Record<string, any>),
55
- },
56
- hovered: {},
57
- hoveredAndFocused: {
58
- ...({
59
- activeColor: theme.colors.primary,
60
- } as Record<string, any>),
61
- },
62
- disabled: {},
63
- error: {
64
- ...({
65
- activeColor: theme.colors.error,
66
- } as Record<string, any>),
67
- },
68
- errorFocused: {
69
- ...({
70
- activeColor: theme.colors.error,
71
- } as Record<string, any>),
72
- },
73
- errorFocusedAndHovered: {
74
- ...({
75
- activeColor: theme.colors.error,
76
- } as Record<string, any>),
77
- },
78
- errorDisabled: {
79
- ...({
80
- activeColor: theme.colors.error,
81
- } as Record<string, any>),
82
- },
83
- errorHovered: {},
84
- },
85
- size: {
86
- lg: {},
87
- md: {},
88
- sm: {},
89
- },
90
- },
91
- },
92
-
93
- container: {
94
68
  flexDirection: 'row',
95
69
  paddingHorizontal: theme.spacings['4'],
70
+
96
71
  variants: {
97
72
  variant: {
98
73
  outlined: {
@@ -116,68 +91,100 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
116
91
  },
117
92
  ],
118
93
  },
119
- leftElement: {
120
- color: theme.colors.onSurfaceVariant,
121
- iconSize: 20,
122
- marginRight: theme.spacings['3'],
123
- marginLeft: theme.spacings._1,
124
- justifyContent: 'center',
125
94
 
126
- state: {
127
- disabled: {
128
- color: theme.colors.onSurface,
129
- opacity: 0.38,
130
- },
131
- error: {
132
- color: theme.colors.onSurfaceVariant,
133
- },
134
- errorFocused: {
135
- color: theme.colors.onSurfaceVariant,
136
- },
137
- errorFocusedAndHovered: {
138
- color: theme.colors.onSurfaceVariant,
139
- },
140
- errorDisabled: {
141
- color: theme.colors.onSurfaceVariant,
142
- opacity: 0.38,
143
- },
144
- errorHovered: {
145
- color: theme.colors.onSurfaceVariant,
146
- },
95
+ input: {
96
+ color: theme.colors.onSurface,
97
+ ...theme.typescale.bodyLarge,
98
+ flexGrow: 1,
99
+
100
+ _web: {
101
+ outline: 'none',
147
102
  },
148
- },
149
- rightElement: {
150
- color: theme.colors.onSurfaceVariant,
151
- iconSize: 24,
152
- marginRight: theme.spacings._1,
153
- marginLeft: theme.spacings['3'],
154
- justifyContent: 'center',
155
103
 
156
104
  variants: {
105
+ size: {
106
+ lg: {
107
+ ...theme.typescale.bodyExtraLarge,
108
+ },
109
+ md: {
110
+ ...theme.typescale.bodyLarge,
111
+ },
112
+ sm: {
113
+ ...theme.typescale.bodyMedium,
114
+ },
115
+ },
116
+ variant: {
117
+ flat: {
118
+ paddingTop: 12,
119
+ },
120
+ },
121
+
157
122
  state: {
158
123
  disabled: {
159
124
  color: theme.colors.onSurface,
160
125
  opacity: 0.38,
161
126
  },
162
127
  error: {
163
- color: theme.colors.error,
128
+ color: theme.colors.onSurface,
164
129
  },
165
130
  errorFocused: {
166
- color: theme.colors.error,
131
+ color: theme.colors.onSurface,
167
132
  },
168
133
  errorFocusedAndHovered: {
169
- color: theme.colors.error,
134
+ color: theme.colors.onSurface,
170
135
  },
171
136
  errorDisabled: {
172
- color: theme.colors.error,
137
+ color: theme.colors.onSurface,
173
138
  opacity: 0.38,
174
139
  },
175
140
  errorHovered: {
176
- color: theme.colors.onErrorContainer,
141
+ color: theme.colors.onSurface,
177
142
  },
178
143
  },
179
144
  },
180
145
  },
146
+
147
+ placeholder: {
148
+ color: theme.colors.onSurfaceVariant,
149
+ },
150
+
151
+ stateLayer: {
152
+ borderTopLeftRadius: theme.shapes.corner.extraSmall,
153
+ borderTopRightRadius: theme.shapes.corner.extraSmall,
154
+ variants: {
155
+ variant: {},
156
+ state: {},
157
+ },
158
+ compoundVariants: [
159
+ {
160
+ variant: 'flat',
161
+ state: 'hovered',
162
+ styles: {
163
+ backgroundColor: theme.colors.stateLayer.hover.onSurface,
164
+ },
165
+ },
166
+ {
167
+ variant: 'flat',
168
+ state: 'errorHovered',
169
+ styles: {
170
+ backgroundColor: theme.colors.stateLayer.hover.onSurface,
171
+ },
172
+ },
173
+ ],
174
+ },
175
+
176
+ inputWrapper: {
177
+ paddingTop: 0,
178
+ paddingBottom: 0,
179
+ flexGrow: 1,
180
+ flexShrink: 1,
181
+ },
182
+ }));
183
+
184
+ export const styles = getRegisteredComponentStylesWithFallback('TextInput', textInputStylesDefault);
185
+
186
+ // TextInput.Label styles
187
+ const textInputLabelStylesDefault = StyleSheet.create(theme => ({
181
188
  floatingLabel: {
182
189
  variants: {
183
190
  variant: {
@@ -187,11 +194,12 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
187
194
  },
188
195
  },
189
196
  },
197
+
190
198
  labelText: {
191
199
  position: 'absolute',
192
200
  left: 0,
193
201
  color: theme.colors.onSurfaceVariant,
194
- typescale: theme.typescale.bodyLarge,
202
+ ...theme.typescale.bodyLarge,
195
203
 
196
204
  variants: {
197
205
  size: {
@@ -250,51 +258,95 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
250
258
  },
251
259
  },
252
260
  },
253
- inputText: {
254
- color: theme.colors.onSurface,
255
- ...theme.typescale.bodyLarge,
256
- flexGrow: 1,
261
+ }));
262
+
263
+ export const textInputLabelStyles = getRegisteredComponentStylesWithFallback(
264
+ 'TextInputLabel',
265
+ textInputLabelStylesDefault,
266
+ );
267
+
268
+ // TextInput.Left styles
269
+ const textInputLeftStylesDefault = StyleSheet.create(theme => ({
270
+ leftElement: {
271
+ color: theme.colors.onSurfaceVariant,
272
+ marginRight: theme.spacings['3'],
273
+ marginLeft: theme.spacings._1,
274
+ justifyContent: 'center',
257
275
 
258
276
  variants: {
259
- size: {
260
- lg: {
261
- ...theme.typescale.bodyExtraLarge,
277
+ state: {
278
+ disabled: {
279
+ color: theme.colors.onSurface,
280
+ opacity: 0.38,
262
281
  },
263
- md: {
264
- ...theme.typescale.bodyLarge,
282
+ error: {
283
+ color: theme.colors.onSurfaceVariant,
265
284
  },
266
- sm: {
267
- ...theme.typescale.bodyMedium,
285
+ errorFocused: {
286
+ color: theme.colors.onSurfaceVariant,
287
+ },
288
+ errorFocusedAndHovered: {
289
+ color: theme.colors.onSurfaceVariant,
290
+ },
291
+ errorDisabled: {
292
+ color: theme.colors.onSurfaceVariant,
293
+ opacity: 0.38,
294
+ },
295
+ errorHovered: {
296
+ color: theme.colors.onSurfaceVariant,
268
297
  },
269
298
  },
270
- variant: {
271
- flat: {},
272
- },
299
+ },
300
+ },
301
+ }));
302
+
303
+ export const textInputLeftStyles = getRegisteredComponentStylesWithFallback(
304
+ 'TextInputLeft',
305
+ textInputLeftStylesDefault,
306
+ );
273
307
 
308
+ // TextInput.Right styles
309
+ const textInputRightStylesDefault = StyleSheet.create(theme => ({
310
+ rightElement: {
311
+ color: theme.colors.onSurfaceVariant,
312
+ marginRight: theme.spacings._1,
313
+ marginLeft: theme.spacings['3'],
314
+ justifyContent: 'center',
315
+
316
+ variants: {
274
317
  state: {
275
318
  disabled: {
276
319
  color: theme.colors.onSurface,
277
320
  opacity: 0.38,
278
321
  },
279
322
  error: {
280
- color: theme.colors.onSurface,
323
+ color: theme.colors.error,
281
324
  },
282
325
  errorFocused: {
283
- color: theme.colors.onSurface,
326
+ color: theme.colors.error,
284
327
  },
285
328
  errorFocusedAndHovered: {
286
- color: theme.colors.onSurface,
329
+ color: theme.colors.error,
287
330
  },
288
331
  errorDisabled: {
289
- color: theme.colors.onSurface,
332
+ color: theme.colors.error,
290
333
  opacity: 0.38,
291
334
  },
292
335
  errorHovered: {
293
- color: theme.colors.onSurface,
336
+ color: theme.colors.onErrorContainer,
294
337
  },
295
338
  },
296
339
  },
297
340
  },
341
+ }));
342
+
343
+ export const textInputRightStyles = getRegisteredComponentStylesWithFallback(
344
+ 'TextInputRight',
345
+ textInputRightStylesDefault,
346
+ );
347
+
348
+ // TextInput.SupportingText styles
349
+ const textInputSupportingTextStylesDefault = StyleSheet.create({
298
350
  supportingText: {
299
351
  variants: {
300
352
  state: {
@@ -307,9 +359,15 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
307
359
  },
308
360
  },
309
361
  },
310
- placeholder: {
311
- color: theme.colors.onSurfaceVariant,
312
- },
362
+ });
363
+
364
+ export const textInputSupportingTextStyles = getRegisteredComponentStylesWithFallback(
365
+ 'TextInputSupportingText',
366
+ textInputSupportingTextStylesDefault,
367
+ );
368
+
369
+ // TextInput.Outline styles
370
+ const textInputOutlineStylesDefault = StyleSheet.create(theme => ({
313
371
  outline: {
314
372
  position: 'absolute',
315
373
  left: 0,
@@ -322,7 +380,8 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
322
380
  variants: {
323
381
  variant: {
324
382
  outlined: {
325
- borderRadius: theme.shapes.corner.extraSmall,
383
+ // this will be inherited from root
384
+ // borderRadius: theme.shapes.corner.extraSmall,
326
385
  borderColor: theme.colors.outline,
327
386
  borderWidth: 1,
328
387
  },
@@ -399,6 +458,7 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
399
458
  },
400
459
  ],
401
460
  },
461
+
402
462
  activeIndicator: {
403
463
  variants: {
404
464
  variant: {
@@ -489,24 +549,7 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
489
549
  },
490
550
  ],
491
551
  },
492
- stateLayer: {
493
- compoundVariants: [
494
- {
495
- variant: 'flat',
496
- state: 'hovered',
497
- styles: {
498
- backgroundColor: theme.colors.stateLayer.hover.onSurface,
499
- },
500
- },
501
- {
502
- variant: 'flat',
503
- state: 'errorHovered',
504
- styles: {
505
- backgroundColor: theme.colors.stateLayer.hover.onSurface,
506
- },
507
- },
508
- ],
509
- },
552
+
510
553
  underline: {
511
554
  position: 'absolute',
512
555
  left: 0,
@@ -515,23 +558,60 @@ const textInputStylesDefault = StyleSheet.create(theme => ({
515
558
  height: 1,
516
559
  zIndex: 1,
517
560
  },
518
- labelContainer: {
519
- paddingTop: 0,
520
- paddingBottom: 0,
521
- flexGrow: 1,
522
- flexShrink: 1,
523
- },
524
- patchContainer: {
525
- height: 24,
526
- zIndex: 2,
527
- },
528
561
  }));
529
562
 
530
- export const styles = getRegisteredComponentStylesWithFallback('TextInput', textInputStylesDefault);
563
+ export const textInputOutlineStyles = getRegisteredComponentStylesWithFallback(
564
+ 'TextInputOutline',
565
+ textInputOutlineStylesDefault,
566
+ );
531
567
 
532
- export const inputLabelStyles = StyleSheet.create({
533
- labelContainer: {
534
- zIndex: 3,
535
- justifyContent: 'center',
568
+ // TextInput.Icon styles
569
+ const textInputIconStylesDefault = StyleSheet.create(theme => ({
570
+ root: {
571
+ variants: {
572
+ state: {
573
+ default: {
574
+ color: theme.colors.onSurfaceVariant,
575
+ },
576
+ focused: {
577
+ color: theme.colors.onSurfaceVariant,
578
+ },
579
+ hovered: {
580
+ color: theme.colors.onSurfaceVariant,
581
+ },
582
+ hoveredAndFocused: {
583
+ color: theme.colors.onSurfaceVariant,
584
+ },
585
+ disabled: {
586
+ color: theme.colors.onSurface,
587
+ opacity: 0.38,
588
+ },
589
+ error: {
590
+ color: theme.colors.error,
591
+ },
592
+ errorFocused: {
593
+ color: theme.colors.error,
594
+ },
595
+ errorFocusedAndHovered: {
596
+ color: theme.colors.error,
597
+ },
598
+ errorDisabled: {
599
+ color: theme.colors.error,
600
+ opacity: 0.38,
601
+ },
602
+ errorHovered: {
603
+ color: theme.colors.onErrorContainer,
604
+ },
605
+ },
606
+ position: {
607
+ left: {},
608
+ right: {},
609
+ },
610
+ },
536
611
  },
537
- });
612
+ }));
613
+
614
+ export const textInputIconStyles = getRegisteredComponentStylesWithFallback(
615
+ 'TextInputIcon',
616
+ textInputIconStylesDefault,
617
+ );
@@ -26,10 +26,11 @@ const TimePickerField = (
26
26
  withModal = true,
27
27
  style,
28
28
  onBlur: onBlurProp,
29
- modalProps = {},
30
- iconButtonProps = {},
29
+ modalProps,
30
+ iconButtonProps,
31
31
  disabled,
32
32
  onFocus: onFocusProp,
33
+ children,
33
34
  ...rest
34
35
  }: Props,
35
36
  ref: any,
@@ -143,9 +144,10 @@ const TimePickerField = (
143
144
  onFocus={onFocus}
144
145
  onChangeText={onChangeText}
145
146
  style={componentStyles}
146
- onBlur={onBlur}
147
- right={rightElement}
148
- />
147
+ onBlur={onBlur}>
148
+ <TextInput.Right>{rightElement}</TextInput.Right>
149
+ {children}
150
+ </TextInput>
149
151
  );
150
152
  };
151
153
 
@@ -61,7 +61,7 @@ const TouchableRipple = (
61
61
  }: Props,
62
62
  ref: any,
63
63
  ) => {
64
- const disabled = disabledProp || !rest.onPress;
64
+ const disabled = disabledProp;
65
65
 
66
66
  const componentStyles = touchableRippleStyles;
67
67