Skip to content

Commit 74fac39

Browse files
authored
feat(ui): input component
1 parent d0d610f commit 74fac39

File tree

10 files changed

+821
-2
lines changed

10 files changed

+821
-2
lines changed

src/framework/theme/type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
export enum Interaction {
22
ACTIVE = 'active',
3+
FOCUSED = 'focused',
34
}
45

56
export enum State {
67
CHECKED = 'checked',
78
SELECTED = 'selected',
89
DISABLED = 'disabled',
9-
FOCUSED = 'focused',
1010
}
1111

1212
export namespace Interaction {

src/framework/ui/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import {
77
ButtonGroup as ButtonGroupComponent,
88
Props as ButtonGroupProps,
99
} from './buttonGroup/buttonGroup.component';
10+
import {
11+
Input as InputComponent,
12+
Props as InputProps,
13+
} from './input/input.component';
1014
import {
1115
Text as TextComponent,
1216
Props as TextProps,
@@ -86,6 +90,7 @@ import {
8690

8791
const Button = styled<ButtonComponent, ButtonProps>(ButtonComponent);
8892
const ButtonGroup = styled<ButtonGroupComponent, ButtonGroupProps>(ButtonGroupComponent);
93+
const Input = styled<InputComponent, InputProps>(InputComponent);
8994
const Text = styled<TextComponent, TextProps>(TextComponent);
9095
const Radio = styled<RadioComponent, RadioProps>(RadioComponent);
9196
const RadioGroup = styled<RadioGroupComponent, RadioGroupProps>(RadioGroupComponent);
@@ -106,6 +111,7 @@ const Modal = styled<ModalComponent, ModalProps>(ModalComponent);
106111
export {
107112
Button,
108113
ButtonGroup,
114+
Input,
109115
Text,
110116
Layout,
111117
LayoutProps,
@@ -123,6 +129,7 @@ export {
123129
ViewPager,
124130
TabView,
125131
ButtonProps,
132+
InputProps,
126133
ButtonGroupProps,
127134
CheckBoxProps,
128135
TabProps,
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React from 'react';
2+
import {
3+
ImageProps,
4+
StyleSheet,
5+
TextInput,
6+
TextInputProps,
7+
View,
8+
} from 'react-native';
9+
import {
10+
Interaction,
11+
StyledComponentProps,
12+
StyleType,
13+
} from '@kitten/theme';
14+
import {
15+
InputFocusEvent,
16+
InputEndEditEvent,
17+
} from '../service/type';
18+
19+
interface InputProps {
20+
icon?: (style: StyleType) => React.ReactElement<ImageProps>;
21+
status?: string;
22+
disabled?: boolean;
23+
}
24+
25+
export type Props = InputProps & StyledComponentProps & TextInputProps;
26+
27+
export class Input extends React.Component<Props> {
28+
29+
private onFocus = (event: InputFocusEvent) => {
30+
this.props.dispatch([Interaction.FOCUSED]);
31+
32+
if (this.props.onFocus) {
33+
this.props.onFocus(event);
34+
}
35+
};
36+
37+
private onEndEditing = (event: InputEndEditEvent) => {
38+
this.props.dispatch([]);
39+
40+
if (this.props.onEndEditing) {
41+
this.props.onEndEditing(event);
42+
}
43+
};
44+
45+
private getComponentStyle = (style: StyleType): StyleType => {
46+
const { text, icon, ...container } = style;
47+
48+
return {
49+
container: container,
50+
text: text,
51+
icon: icon,
52+
};
53+
};
54+
55+
private getDerivedStyle = (style: StyleType): StyleType => {
56+
const {
57+
color,
58+
fontFamily,
59+
fontSize,
60+
fontStyle,
61+
fontWeight,
62+
letterSpacing,
63+
textAlign,
64+
...container
65+
} = style;
66+
67+
return {
68+
container: container,
69+
text: {
70+
color,
71+
fontFamily,
72+
fontSize,
73+
fontStyle,
74+
fontWeight,
75+
letterSpacing,
76+
textAlign,
77+
},
78+
};
79+
};
80+
81+
private renderImageElement = (style: StyleType): React.ReactElement<ImageProps> => {
82+
const { icon } = this.props;
83+
84+
return React.cloneElement(icon(style), { key: 0 });
85+
};
86+
87+
private renderComponentChildren = (style: StyleType): React.ReactNode => {
88+
const { icon } = this.props;
89+
90+
const hasIcon: boolean = icon !== undefined;
91+
92+
return [
93+
hasIcon ? this.renderImageElement(style) : undefined,
94+
];
95+
};
96+
97+
public render(): React.ReactElement<TextInputProps> {
98+
const { style, themedStyle, disabled, ...derivedProps } = this.props;
99+
100+
const derivedStyle: StyleType = this.getDerivedStyle(style);
101+
const componentStyle: StyleType = this.getComponentStyle(themedStyle);
102+
const componentChildren: React.ReactNode = this.renderComponentChildren(componentStyle.icon);
103+
104+
return (
105+
<View style={[componentStyle.container, derivedStyle.container, strictStyles.container]}>
106+
<TextInput
107+
{...derivedProps}
108+
editable={!disabled}
109+
onFocus={this.onFocus}
110+
onEndEditing={this.onEndEditing}
111+
style={[componentStyle.text, derivedStyle.text, strictStyles.text]}
112+
/>
113+
{componentChildren}
114+
</View>
115+
);
116+
}
117+
}
118+
119+
const strictStyles = StyleSheet.create({
120+
container: {
121+
flex: 1,
122+
flexDirection: 'row',
123+
},
124+
text: {
125+
flex: 1,
126+
},
127+
icon: {
128+
flexGrow: 1,
129+
},
130+
});

0 commit comments

Comments
 (0)