@ecohouse/ui 0.1.2 → 0.1.4

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.
Files changed (74) hide show
  1. package/dist/index.cjs +1734 -155
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +287 -13
  4. package/dist/index.d.ts +287 -13
  5. package/dist/index.js +1720 -159
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/components/Avatar/Avatar.stories.tsx +133 -0
  9. package/src/components/Avatar/Avatar.tsx +389 -0
  10. package/src/components/Avatar/index.ts +2 -0
  11. package/src/components/Button/Button.tsx +106 -88
  12. package/src/components/Checkbox/Checkbox.stories.tsx +112 -0
  13. package/src/components/Checkbox/Checkbox.tsx +150 -0
  14. package/src/components/Checkbox/index.ts +2 -0
  15. package/src/components/Input/Input.stories.tsx +11 -40
  16. package/src/components/Input/Input.tsx +58 -54
  17. package/src/components/Input/index.ts +1 -1
  18. package/src/components/Select/Select.stories.tsx +196 -0
  19. package/src/components/Select/Select.tsx +851 -0
  20. package/src/components/Select/index.ts +2 -0
  21. package/src/components/Textarea/Textarea.stories.tsx +71 -0
  22. package/src/components/Textarea/Textarea.tsx +241 -0
  23. package/src/components/Textarea/index.ts +2 -0
  24. package/src/components/Toggle/Toggle.stories.tsx +100 -0
  25. package/src/components/Toggle/Toggle.tsx +176 -0
  26. package/src/components/Toggle/index.ts +2 -0
  27. package/src/components/index.ts +16 -1
  28. package/src/icons/Calendar/CalendarIcon.tsx +21 -0
  29. package/src/icons/Calendar/CalendarIcon.web.tsx +27 -0
  30. package/src/icons/Calendar/calendarPath.ts +3 -0
  31. package/src/icons/Calendar/index.ts +1 -0
  32. package/src/icons/Check/CheckIcon.tsx +26 -0
  33. package/src/icons/Check/CheckIcon.web.tsx +32 -0
  34. package/src/icons/Check/checkPath.ts +2 -0
  35. package/src/icons/Check/index.ts +1 -0
  36. package/src/icons/ChevronDown/ChevronDownIcon.tsx +30 -0
  37. package/src/icons/ChevronDown/ChevronDownIcon.web.tsx +36 -0
  38. package/src/icons/ChevronDown/chevronDownPath.ts +2 -0
  39. package/src/icons/ChevronDown/index.ts +1 -0
  40. package/src/icons/Heart/HeartIcon.tsx +23 -0
  41. package/src/icons/Heart/HeartIcon.web.tsx +29 -0
  42. package/src/icons/Heart/heartPath.ts +3 -0
  43. package/src/icons/Heart/index.ts +1 -0
  44. package/src/icons/HelpCircle/HelpCircleIcon.tsx +25 -0
  45. package/src/icons/HelpCircle/HelpCircleIcon.web.tsx +31 -0
  46. package/src/icons/HelpCircle/helpCirclePath.ts +3 -0
  47. package/src/icons/HelpCircle/index.ts +1 -0
  48. package/src/icons/LayoutGrid/LayoutGridIcon.tsx +25 -0
  49. package/src/icons/LayoutGrid/LayoutGridIcon.web.tsx +31 -0
  50. package/src/icons/LayoutGrid/index.ts +1 -0
  51. package/src/icons/LayoutGrid/layoutGridPath.ts +3 -0
  52. package/src/icons/LogOut/LogOutIcon.tsx +21 -0
  53. package/src/icons/LogOut/LogOutIcon.web.tsx +27 -0
  54. package/src/icons/LogOut/index.ts +1 -0
  55. package/src/icons/LogOut/logOutPath.ts +3 -0
  56. package/src/icons/Search/SearchIcon.tsx +37 -0
  57. package/src/icons/Search/SearchIcon.web.tsx +43 -0
  58. package/src/icons/Search/index.ts +1 -0
  59. package/src/icons/Search/searchPath.ts +5 -0
  60. package/src/icons/Settings/SettingsIcon.tsx +21 -0
  61. package/src/icons/Settings/SettingsIcon.web.tsx +27 -0
  62. package/src/icons/Settings/index.ts +1 -0
  63. package/src/icons/Settings/settingsPath.ts +3 -0
  64. package/src/icons/Video/VideoIcon.tsx +24 -0
  65. package/src/icons/Video/VideoIcon.web.tsx +30 -0
  66. package/src/icons/Video/index.ts +1 -0
  67. package/src/icons/Video/videoPath.ts +5 -0
  68. package/src/icons/index.ts +10 -0
  69. package/src/icons/registry.ts +24 -3
  70. package/src/index.ts +31 -3
  71. package/src/theme/colors.ts +1 -0
  72. package/src/theme/index.ts +8 -1
  73. package/src/theme/typography.ts +77 -2
  74. package/src/utils/mergeRefs.ts +20 -0
@@ -1,4 +1,4 @@
1
- import { useRef, type ComponentRef, type ReactNode } from "react";
1
+ import { forwardRef, useMemo, useRef, type ComponentRef, type ReactNode } from "react";
2
2
  import {
3
3
  Platform,
4
4
  StyleSheet,
@@ -8,16 +8,21 @@ import {
8
8
  type GestureResponderEvent,
9
9
  type StyleProp,
10
10
  type TextStyle,
11
+ type TouchableOpacityProps,
11
12
  type ViewStyle,
12
13
  } from "react-native";
13
14
  import { ArrowRightIcon } from "../../icons";
14
15
  import { buttonTypography, colors } from "../../theme";
16
+ import { mergeRefs } from "../../utils/mergeRefs";
15
17
  import { useApplyWebClassName } from "../../utils/useApplyWebClassName";
16
18
 
17
19
  export type ButtonVariant = "primary" | "secondary";
18
20
  export type ButtonSize = "lg" | "sm";
19
21
 
20
- export interface ButtonProps {
22
+ export interface ButtonProps extends Omit<
23
+ TouchableOpacityProps,
24
+ "onPress" | "disabled" | "style" | "children"
25
+ > {
21
26
  title?: string;
22
27
  children?: ReactNode;
23
28
  onPress: (event: GestureResponderEvent) => void;
@@ -81,99 +86,112 @@ const sizeConfig = {
81
86
  },
82
87
  } as const satisfies Record<ButtonSize, Record<string, unknown>>;
83
88
 
84
- export function Button({
85
- title,
86
- children,
87
- onPress,
88
- disabled = false,
89
- variant = "primary",
90
- size = "lg",
91
- showIcon = false,
92
- icon,
93
- style,
94
- textStyle,
95
- className,
96
- textClassName,
97
- }: ButtonProps) {
98
- const containerRef = useRef<ComponentRef<typeof TouchableOpacity>>(null);
99
- const textRef = useRef<ComponentRef<typeof Text>>(null);
100
- const preset = variantConfig[variant];
101
- const metrics = sizeConfig[size];
89
+ export const Button = forwardRef<ComponentRef<typeof TouchableOpacity>, ButtonProps>(
90
+ function Button(
91
+ {
92
+ title,
93
+ children,
94
+ onPress,
95
+ disabled = false,
96
+ variant = "primary",
97
+ size = "lg",
98
+ showIcon = false,
99
+ icon,
100
+ style,
101
+ textStyle,
102
+ className,
103
+ textClassName,
104
+ accessibilityLabel,
105
+ ...rest
106
+ },
107
+ forwardedRef,
108
+ ) {
109
+ const containerRef = useRef<ComponentRef<typeof TouchableOpacity>>(null);
110
+ const textRef = useRef<ComponentRef<typeof Text>>(null);
111
+ const preset = variantConfig[variant];
112
+ const metrics = sizeConfig[size];
102
113
 
103
- const label = typeof children !== "undefined" ? children : title;
104
- const hasCustomChildren = typeof children !== "undefined";
105
- const customIcon = icon != null && typeof icon !== "boolean" ? icon : undefined;
106
- const hasIcon = showIcon || icon === true || customIcon != null;
107
- const resolvedContainerClassName = className?.trim() || undefined;
114
+ const label = typeof children !== "undefined" ? children : title;
115
+ const hasCustomChildren = typeof children !== "undefined";
116
+ const customIcon = icon != null && typeof icon !== "boolean" ? icon : undefined;
117
+ const hasIcon = showIcon || icon === true || customIcon != null;
118
+ const resolvedContainerClassName = className?.trim() || undefined;
119
+ const resolvedAccessibilityLabel =
120
+ accessibilityLabel ?? (typeof label === "string" ? label : undefined);
108
121
 
109
- useApplyWebClassName(containerRef, resolvedContainerClassName);
110
- useApplyWebClassName(textRef, textClassName);
122
+ const setContainerRef = useMemo(() => mergeRefs(containerRef, forwardedRef), [forwardedRef]);
111
123
 
112
- const iconNode = customIcon ?? (
113
- <ArrowRightIcon size={metrics.iconSize} color={preset.iconColor} />
114
- );
124
+ useApplyWebClassName(containerRef, resolvedContainerClassName);
125
+ useApplyWebClassName(textRef, textClassName);
115
126
 
116
- const containerStyle = [
117
- styles.base,
118
- {
119
- minHeight: metrics.minHeight,
120
- borderRadius: metrics.borderRadius,
121
- backgroundColor: preset.backgroundColor,
122
- paddingTop: metrics.paddingVertical,
123
- paddingBottom: metrics.paddingVertical,
124
- paddingLeft: metrics.paddingLeft,
125
- paddingRight: hasIcon ? metrics.paddingRightWithIcon : metrics.paddingRight,
126
- gap: hasIcon ? metrics.gap : 0,
127
- },
128
- disabled && styles.disabled,
129
- style,
130
- ];
127
+ const iconNode = customIcon ?? (
128
+ <ArrowRightIcon size={metrics.iconSize} color={preset.iconColor} />
129
+ );
131
130
 
132
- const labelStyle = [
133
- styles.label,
134
- metrics.text,
135
- { color: preset.textColor },
136
- Platform.OS === "android" ? styles.labelAndroid : null,
137
- !hasIcon && styles.labelCentered,
138
- textStyle,
139
- ];
131
+ const containerStyle = [
132
+ styles.base,
133
+ {
134
+ minHeight: metrics.minHeight,
135
+ borderRadius: metrics.borderRadius,
136
+ backgroundColor: preset.backgroundColor,
137
+ paddingTop: metrics.paddingVertical,
138
+ paddingBottom: metrics.paddingVertical,
139
+ paddingLeft: metrics.paddingLeft,
140
+ paddingRight: hasIcon ? metrics.paddingRightWithIcon : metrics.paddingRight,
141
+ gap: hasIcon ? metrics.gap : 0,
142
+ },
143
+ disabled && styles.disabled,
144
+ style,
145
+ ];
140
146
 
141
- return (
142
- <TouchableOpacity
143
- ref={containerRef}
144
- style={containerStyle}
145
- onPress={onPress}
146
- disabled={disabled}
147
- activeOpacity={0.7}
148
- accessibilityRole="button"
149
- accessibilityState={{ disabled }}
150
- >
151
- {hasCustomChildren ? (
152
- children
153
- ) : (
154
- <Text ref={textRef} style={labelStyle}>
155
- {label}
156
- </Text>
157
- )}
147
+ const labelStyle = [
148
+ styles.label,
149
+ metrics.text,
150
+ { color: preset.textColor },
151
+ Platform.OS === "android" ? styles.labelAndroid : null,
152
+ !hasIcon && styles.labelCentered,
153
+ textStyle,
154
+ ];
158
155
 
159
- {hasIcon ? (
160
- <View
161
- style={[
162
- styles.iconContainer,
163
- {
164
- width: metrics.iconContainerSize,
165
- height: metrics.iconContainerSize,
166
- borderRadius: metrics.iconContainerSize / 2,
167
- backgroundColor: preset.iconBadgeBackgroundColor,
168
- },
169
- ]}
170
- >
171
- {iconNode}
172
- </View>
173
- ) : null}
174
- </TouchableOpacity>
175
- );
176
- }
156
+ return (
157
+ <TouchableOpacity
158
+ {...rest}
159
+ ref={setContainerRef}
160
+ style={containerStyle}
161
+ onPress={onPress}
162
+ disabled={disabled}
163
+ activeOpacity={0.7}
164
+ accessibilityRole="button"
165
+ accessibilityLabel={resolvedAccessibilityLabel}
166
+ accessibilityState={{ disabled }}
167
+ >
168
+ {hasCustomChildren ? (
169
+ children
170
+ ) : (
171
+ <Text ref={textRef} style={labelStyle}>
172
+ {label}
173
+ </Text>
174
+ )}
175
+
176
+ {hasIcon ? (
177
+ <View
178
+ style={[
179
+ styles.iconContainer,
180
+ {
181
+ width: metrics.iconContainerSize,
182
+ height: metrics.iconContainerSize,
183
+ borderRadius: metrics.iconContainerSize / 2,
184
+ backgroundColor: preset.iconBadgeBackgroundColor,
185
+ },
186
+ ]}
187
+ >
188
+ {iconNode}
189
+ </View>
190
+ ) : null}
191
+ </TouchableOpacity>
192
+ );
193
+ },
194
+ );
177
195
 
178
196
  const styles = StyleSheet.create({
179
197
  base: {
@@ -0,0 +1,112 @@
1
+ import { useState } from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react-vite";
3
+ import { fn } from "storybook/test";
4
+ import { View, StyleSheet, Text } from "react-native";
5
+ import { Checkbox } from "./Checkbox";
6
+ import { colors } from "../../theme";
7
+
8
+ const meta = {
9
+ title: "Components/Checkbox",
10
+ component: Checkbox,
11
+ args: {
12
+ defaultValue: false,
13
+ disabled: false,
14
+ variant: "default",
15
+ onValueChange: fn(),
16
+ },
17
+ argTypes: {
18
+ variant: {
19
+ control: "select",
20
+ options: ["default", "light"],
21
+ },
22
+ onValueChange: { action: "valueChange" },
23
+ },
24
+ parameters: {
25
+ backgrounds: { default: "black" },
26
+ },
27
+ } satisfies Meta<typeof Checkbox>;
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ export const Default: Story = {};
33
+
34
+ export const Checked: Story = {
35
+ args: { defaultValue: true },
36
+ };
37
+
38
+ export const Light: Story = {
39
+ args: { variant: "light" },
40
+ };
41
+
42
+ export const LightChecked: Story = {
43
+ args: { variant: "light", defaultValue: true },
44
+ };
45
+
46
+ export const Disabled: Story = {
47
+ args: { disabled: true },
48
+ };
49
+
50
+ export const DisabledChecked: Story = {
51
+ args: { disabled: true, defaultValue: true },
52
+ };
53
+
54
+ export const WithLabel: Story = {
55
+ args: { label: "Label", defaultValue: true },
56
+ };
57
+
58
+ function ControlledCheckbox() {
59
+ const [value, setValue] = useState(false);
60
+
61
+ return (
62
+ <View style={storyStyles.row}>
63
+ <Checkbox value={value} onValueChange={setValue} label="Controlled" />
64
+ <Text style={storyStyles.meta}>{value ? "Checked" : "Unchecked"}</Text>
65
+ </View>
66
+ );
67
+ }
68
+
69
+ export const Controlled: Story = {
70
+ render: () => <ControlledCheckbox />,
71
+ };
72
+
73
+ /** Matches the design matrix: checked on top, unchecked below; light then default. */
74
+ export const AllStates: Story = {
75
+ render: () => (
76
+ <View style={storyStyles.matrix}>
77
+ <View style={storyStyles.matrixRow}>
78
+ <Checkbox variant="light" defaultValue />
79
+ <Checkbox variant="light" defaultValue disabled />
80
+ <Checkbox variant="default" defaultValue />
81
+ <Checkbox variant="default" defaultValue disabled />
82
+ </View>
83
+ <View style={storyStyles.matrixRow}>
84
+ <Checkbox variant="light" />
85
+ <Checkbox variant="light" disabled />
86
+ <Checkbox variant="default" />
87
+ <Checkbox variant="default" disabled />
88
+ </View>
89
+ </View>
90
+ ),
91
+ };
92
+
93
+ const storyStyles = StyleSheet.create({
94
+ matrix: {
95
+ gap: 16,
96
+ alignItems: "flex-start",
97
+ },
98
+ matrixRow: {
99
+ flexDirection: "row",
100
+ alignItems: "center",
101
+ gap: 16,
102
+ },
103
+ row: {
104
+ flexDirection: "row",
105
+ alignItems: "center",
106
+ gap: 12,
107
+ },
108
+ meta: {
109
+ color: colors.grey100,
110
+ fontSize: 12,
111
+ },
112
+ });
@@ -0,0 +1,150 @@
1
+ import { forwardRef, useMemo, useRef, useState, type ComponentRef, type ReactNode } from "react";
2
+ import {
3
+ Pressable,
4
+ StyleSheet,
5
+ Text,
6
+ View,
7
+ type PressableProps,
8
+ type StyleProp,
9
+ type TextStyle,
10
+ type ViewStyle,
11
+ } from "react-native";
12
+ import { CheckIcon } from "../../icons";
13
+ import { colors, inputTypography } from "../../theme";
14
+ import { mergeRefs } from "../../utils/mergeRefs";
15
+ import { useApplyWebClassName } from "../../utils/useApplyWebClassName";
16
+
17
+ export type CheckboxVariant = "default" | "light";
18
+
19
+ export interface CheckboxProps extends Omit<
20
+ PressableProps,
21
+ "onPress" | "disabled" | "style" | "children" | "hitSlop"
22
+ > {
23
+ value?: boolean;
24
+ defaultValue?: boolean;
25
+ onValueChange?: (value: boolean) => void;
26
+ disabled?: boolean;
27
+ variant?: CheckboxVariant;
28
+ label?: string;
29
+ children?: ReactNode;
30
+ style?: StyleProp<ViewStyle>;
31
+ labelStyle?: StyleProp<TextStyle>;
32
+ className?: string;
33
+ hitSlop?: PressableProps["hitSlop"];
34
+ }
35
+
36
+ const BOX_SIZE = 20;
37
+ const BOX_RADIUS = 6;
38
+ const CHECK_SIZE = 12;
39
+ const CHECK_STROKE = 2.5;
40
+
41
+ const variantChrome: Record<CheckboxVariant, { backgroundColor: string; borderColor: string }> = {
42
+ default: {
43
+ backgroundColor: colors.dark,
44
+ borderColor: colors.grey700,
45
+ },
46
+ light: {
47
+ backgroundColor: colors.grey700,
48
+ borderColor: colors.grey500,
49
+ },
50
+ };
51
+
52
+ export const Checkbox = forwardRef<ComponentRef<typeof Pressable>, CheckboxProps>(function Checkbox(
53
+ {
54
+ value,
55
+ defaultValue = false,
56
+ onValueChange,
57
+ disabled = false,
58
+ variant = "default",
59
+ label,
60
+ children,
61
+ style,
62
+ labelStyle,
63
+ className,
64
+ hitSlop = 8,
65
+ accessibilityLabel,
66
+ ...rest
67
+ },
68
+ forwardedRef,
69
+ ) {
70
+ const containerRef = useRef<ComponentRef<typeof Pressable>>(null);
71
+ const isControlled = typeof value === "boolean";
72
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
73
+ const isActive = isControlled ? value : uncontrolledValue;
74
+
75
+ const chrome = variantChrome[variant];
76
+ const labelContent = children ?? label;
77
+ const resolvedAccessibilityLabel =
78
+ accessibilityLabel ?? (typeof labelContent === "string" ? labelContent : undefined);
79
+ const setContainerRef = useMemo(() => mergeRefs(containerRef, forwardedRef), [forwardedRef]);
80
+
81
+ useApplyWebClassName(containerRef, className);
82
+
83
+ const handlePress = () => {
84
+ if (disabled) return;
85
+ const next = !isActive;
86
+ if (!isControlled) setUncontrolledValue(next);
87
+ onValueChange?.(next);
88
+ };
89
+
90
+ return (
91
+ <Pressable
92
+ {...rest}
93
+ ref={setContainerRef}
94
+ onPress={handlePress}
95
+ disabled={disabled}
96
+ hitSlop={hitSlop}
97
+ accessibilityRole="checkbox"
98
+ accessibilityLabel={resolvedAccessibilityLabel}
99
+ accessibilityState={{ checked: isActive, disabled }}
100
+ style={[styles.root, disabled && styles.disabled, style]}
101
+ >
102
+ <View
103
+ style={[
104
+ styles.box,
105
+ {
106
+ backgroundColor: chrome.backgroundColor,
107
+ borderColor: chrome.borderColor,
108
+ },
109
+ ]}
110
+ >
111
+ {isActive ? (
112
+ <CheckIcon size={CHECK_SIZE} color={colors.primary} strokeWidth={CHECK_STROKE} />
113
+ ) : null}
114
+ </View>
115
+
116
+ {labelContent != null && labelContent !== false ? (
117
+ typeof labelContent === "string" || typeof labelContent === "number" ? (
118
+ <Text style={[styles.label, labelStyle]}>{labelContent}</Text>
119
+ ) : (
120
+ labelContent
121
+ )
122
+ ) : null}
123
+ </Pressable>
124
+ );
125
+ });
126
+
127
+ const styles = StyleSheet.create({
128
+ root: {
129
+ flexDirection: "row",
130
+ alignItems: "center",
131
+ alignSelf: "flex-start",
132
+ gap: 10,
133
+ },
134
+ disabled: {
135
+ opacity: 0.5,
136
+ },
137
+ box: {
138
+ width: BOX_SIZE,
139
+ height: BOX_SIZE,
140
+ borderRadius: BOX_RADIUS,
141
+ borderWidth: 1,
142
+ alignItems: "center",
143
+ justifyContent: "center",
144
+ flexShrink: 0,
145
+ },
146
+ label: {
147
+ ...inputTypography.field,
148
+ color: colors.white,
149
+ },
150
+ });
@@ -0,0 +1,2 @@
1
+ export { Checkbox } from "./Checkbox";
2
+ export type { CheckboxProps, CheckboxVariant } from "./Checkbox";
@@ -15,14 +15,14 @@ const meta = {
15
15
  size: "lg",
16
16
  showLeftIcon: true,
17
17
  showRightIcon: true,
18
+ disabled: false,
19
+ error: false,
18
20
  onChangeText: fn(),
19
21
  onRightIconPress: fn(),
20
22
  },
21
23
  argTypes: {
22
- state: {
23
- control: "select",
24
- options: ["default", "filled", "active", "error", "disabled"],
25
- },
24
+ disabled: { control: "boolean" },
25
+ error: { control: "boolean" },
26
26
  size: {
27
27
  control: "select",
28
28
  options: ["lg", "sm"],
@@ -33,24 +33,18 @@ const meta = {
33
33
  export default meta;
34
34
  type Story = StoryObj<typeof meta>;
35
35
 
36
- export const Default: Story = {
37
- args: { state: "default" },
38
- };
36
+ export const Default: Story = {};
39
37
 
40
38
  export const Filled: Story = {
41
- args: { state: "filled", value: "Filled value" },
42
- };
43
-
44
- export const Active: Story = {
45
- args: { state: "active" },
39
+ args: { value: "Filled value" },
46
40
  };
47
41
 
48
42
  export const Error: Story = {
49
- args: { state: "error", hint: "Hint" },
43
+ args: { error: true, hint: "Hint" },
50
44
  };
51
45
 
52
46
  export const Disabled: Story = {
53
- args: { state: "disabled", value: "Disabled value" },
47
+ args: { disabled: true, value: "Disabled value" },
54
48
  };
55
49
 
56
50
  export const WithoutIcons: Story = {
@@ -64,46 +58,23 @@ export const WithoutLabelAndHint: Story = {
64
58
  export const AllStates: Story = {
65
59
  render: () => (
66
60
  <View style={storyStyles.column}>
61
+ <Input label="Label" hint="Hint" showLeftIcon showRightIcon placeholder="placeholder" />
67
62
  <Input
68
63
  label="Label"
69
64
  hint="Hint"
70
65
  showLeftIcon
71
66
  showRightIcon
72
67
  placeholder="placeholder"
73
- state="default"
74
- />
75
- <Input
76
- label="Label"
77
- hint="Hint"
78
- showLeftIcon
79
- showRightIcon
80
- placeholder="placeholder"
81
- state="filled"
82
68
  value="Filled value"
83
69
  />
70
+ <Input label="Label" hint="Hint" showLeftIcon showRightIcon placeholder="placeholder" error />
84
71
  <Input
85
72
  label="Label"
86
73
  hint="Hint"
87
74
  showLeftIcon
88
75
  showRightIcon
89
76
  placeholder="placeholder"
90
- state="active"
91
- />
92
- <Input
93
- label="Label"
94
- hint="Hint"
95
- showLeftIcon
96
- showRightIcon
97
- placeholder="placeholder"
98
- state="error"
99
- />
100
- <Input
101
- label="Label"
102
- hint="Hint"
103
- showLeftIcon
104
- showRightIcon
105
- placeholder="placeholder"
106
- state="disabled"
77
+ disabled
107
78
  value="Disabled value"
108
79
  />
109
80
  </View>