@webority-technologies/mobile 0.0.9 → 0.0.10
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.
- package/lib/commonjs/components/Input/Input.js +10 -2
- package/lib/module/components/Input/Input.js +10 -2
- package/lib/typescript/commonjs/components/Input/Input.d.ts +10 -0
- package/lib/typescript/commonjs/theme/types.d.ts +7 -1
- package/lib/typescript/module/components/Input/Input.d.ts +10 -0
- package/lib/typescript/module/theme/types.d.ts +7 -1
- package/package.json +1 -1
|
@@ -59,7 +59,8 @@ const Input = exports.Input = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
|
|
|
59
59
|
leftIcon,
|
|
60
60
|
rightIcon,
|
|
61
61
|
size = 'md',
|
|
62
|
-
variant
|
|
62
|
+
variant: variantProp,
|
|
63
|
+
labelMode: labelModeProp,
|
|
63
64
|
required = false,
|
|
64
65
|
maxLength,
|
|
65
66
|
format,
|
|
@@ -80,13 +81,20 @@ const Input = exports.Input = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
|
|
|
80
81
|
...sizeMap[size],
|
|
81
82
|
...(theme.components.input?.[size] ?? {})
|
|
82
83
|
};
|
|
84
|
+
|
|
85
|
+
// Per-call-site prop wins; otherwise theme defaults; otherwise library defaults.
|
|
86
|
+
const variant = variantProp ?? theme.components.input?.defaultVariant ?? 'outlined';
|
|
87
|
+
const labelMode = labelModeProp ?? theme.components.input?.defaultLabelMode ?? 'float';
|
|
83
88
|
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
84
89
|
const [isPasswordVisible, setIsPasswordVisible] = (0, _react.useState)(false);
|
|
85
90
|
const hasValue = typeof value === 'string' && value.length > 0;
|
|
86
91
|
const hasError = typeof error === 'string' && error.length > 0;
|
|
87
92
|
const isEditable = !disabled && editable !== false;
|
|
88
93
|
const shouldFloat = isFocused || hasValue;
|
|
89
|
-
|
|
94
|
+
// Floating label only when explicitly opted into via labelMode='float' AND the
|
|
95
|
+
// field is single-line. labelMode='top' OR multiline both force a static label
|
|
96
|
+
// above the field — the staticLabel branch below handles both.
|
|
97
|
+
const showFloatingLabel = Boolean(label) && !multiline && labelMode === 'float';
|
|
90
98
|
|
|
91
99
|
// Animations
|
|
92
100
|
const focusAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
@@ -52,7 +52,8 @@ const Input = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
52
52
|
leftIcon,
|
|
53
53
|
rightIcon,
|
|
54
54
|
size = 'md',
|
|
55
|
-
variant
|
|
55
|
+
variant: variantProp,
|
|
56
|
+
labelMode: labelModeProp,
|
|
56
57
|
required = false,
|
|
57
58
|
maxLength,
|
|
58
59
|
format,
|
|
@@ -73,13 +74,20 @@ const Input = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
73
74
|
...sizeMap[size],
|
|
74
75
|
...(theme.components.input?.[size] ?? {})
|
|
75
76
|
};
|
|
77
|
+
|
|
78
|
+
// Per-call-site prop wins; otherwise theme defaults; otherwise library defaults.
|
|
79
|
+
const variant = variantProp ?? theme.components.input?.defaultVariant ?? 'outlined';
|
|
80
|
+
const labelMode = labelModeProp ?? theme.components.input?.defaultLabelMode ?? 'float';
|
|
76
81
|
const [isFocused, setIsFocused] = useState(false);
|
|
77
82
|
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
78
83
|
const hasValue = typeof value === 'string' && value.length > 0;
|
|
79
84
|
const hasError = typeof error === 'string' && error.length > 0;
|
|
80
85
|
const isEditable = !disabled && editable !== false;
|
|
81
86
|
const shouldFloat = isFocused || hasValue;
|
|
82
|
-
|
|
87
|
+
// Floating label only when explicitly opted into via labelMode='float' AND the
|
|
88
|
+
// field is single-line. labelMode='top' OR multiline both force a static label
|
|
89
|
+
// above the field — the staticLabel branch below handles both.
|
|
90
|
+
const showFloatingLabel = Boolean(label) && !multiline && labelMode === 'float';
|
|
83
91
|
|
|
84
92
|
// Animations
|
|
85
93
|
const focusAnim = useRef(createAnimatedValue(0)).current;
|
|
@@ -3,6 +3,7 @@ import { TextInput } from 'react-native';
|
|
|
3
3
|
import type { BlurEvent, FocusEvent, StyleProp, TextInputProps, TextStyle, ViewStyle } from 'react-native';
|
|
4
4
|
export type InputSize = 'sm' | 'md' | 'lg';
|
|
5
5
|
export type InputVariant = 'outlined' | 'filled';
|
|
6
|
+
export type InputLabelMode = 'float' | 'top';
|
|
6
7
|
export interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
7
8
|
label?: string;
|
|
8
9
|
placeholder?: string;
|
|
@@ -18,6 +19,15 @@ export interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
|
18
19
|
rightIcon?: React.ReactNode;
|
|
19
20
|
size?: InputSize;
|
|
20
21
|
variant?: InputVariant;
|
|
22
|
+
/**
|
|
23
|
+
* - `'float'` (default): Material-Design floating label that animates from
|
|
24
|
+
* inside the field to the top border on focus / when there's a value.
|
|
25
|
+
* - `'top'`: classic static label rendered above the field with no animation.
|
|
26
|
+
* Use for forms that want the label permanently visible.
|
|
27
|
+
*
|
|
28
|
+
* Theme override: `theme.components.input.defaultLabelMode`.
|
|
29
|
+
*/
|
|
30
|
+
labelMode?: InputLabelMode;
|
|
21
31
|
required?: boolean;
|
|
22
32
|
maxLength?: number;
|
|
23
33
|
/**
|
|
@@ -295,9 +295,15 @@ export interface RadioTokens extends Partial<Record<ComponentSizeKey, RadioSizeT
|
|
|
295
295
|
borderWidth?: number;
|
|
296
296
|
labelGap?: number;
|
|
297
297
|
}
|
|
298
|
+
export interface InputComponentTokens extends Partial<Record<ComponentSizeKey, InputSizeTokens>> {
|
|
299
|
+
/** Default `variant` when caller doesn't pass one. Library default: 'outlined'. */
|
|
300
|
+
defaultVariant?: 'outlined' | 'filled';
|
|
301
|
+
/** Default `labelMode` when caller doesn't pass one. Library default: 'float'. */
|
|
302
|
+
defaultLabelMode?: 'float' | 'top';
|
|
303
|
+
}
|
|
298
304
|
export interface ComponentTokens {
|
|
299
305
|
button?: Partial<Record<ComponentSizeKey, ButtonSizeTokens>>;
|
|
300
|
-
input?:
|
|
306
|
+
input?: InputComponentTokens;
|
|
301
307
|
searchBar?: Partial<Record<ComponentSizeKey, SearchBarSizeTokens>> & {
|
|
302
308
|
cancelButtonWidth?: number;
|
|
303
309
|
};
|
|
@@ -3,6 +3,7 @@ import { TextInput } from 'react-native';
|
|
|
3
3
|
import type { BlurEvent, FocusEvent, StyleProp, TextInputProps, TextStyle, ViewStyle } from 'react-native';
|
|
4
4
|
export type InputSize = 'sm' | 'md' | 'lg';
|
|
5
5
|
export type InputVariant = 'outlined' | 'filled';
|
|
6
|
+
export type InputLabelMode = 'float' | 'top';
|
|
6
7
|
export interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
7
8
|
label?: string;
|
|
8
9
|
placeholder?: string;
|
|
@@ -18,6 +19,15 @@ export interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
|
18
19
|
rightIcon?: React.ReactNode;
|
|
19
20
|
size?: InputSize;
|
|
20
21
|
variant?: InputVariant;
|
|
22
|
+
/**
|
|
23
|
+
* - `'float'` (default): Material-Design floating label that animates from
|
|
24
|
+
* inside the field to the top border on focus / when there's a value.
|
|
25
|
+
* - `'top'`: classic static label rendered above the field with no animation.
|
|
26
|
+
* Use for forms that want the label permanently visible.
|
|
27
|
+
*
|
|
28
|
+
* Theme override: `theme.components.input.defaultLabelMode`.
|
|
29
|
+
*/
|
|
30
|
+
labelMode?: InputLabelMode;
|
|
21
31
|
required?: boolean;
|
|
22
32
|
maxLength?: number;
|
|
23
33
|
/**
|
|
@@ -295,9 +295,15 @@ export interface RadioTokens extends Partial<Record<ComponentSizeKey, RadioSizeT
|
|
|
295
295
|
borderWidth?: number;
|
|
296
296
|
labelGap?: number;
|
|
297
297
|
}
|
|
298
|
+
export interface InputComponentTokens extends Partial<Record<ComponentSizeKey, InputSizeTokens>> {
|
|
299
|
+
/** Default `variant` when caller doesn't pass one. Library default: 'outlined'. */
|
|
300
|
+
defaultVariant?: 'outlined' | 'filled';
|
|
301
|
+
/** Default `labelMode` when caller doesn't pass one. Library default: 'float'. */
|
|
302
|
+
defaultLabelMode?: 'float' | 'top';
|
|
303
|
+
}
|
|
298
304
|
export interface ComponentTokens {
|
|
299
305
|
button?: Partial<Record<ComponentSizeKey, ButtonSizeTokens>>;
|
|
300
|
-
input?:
|
|
306
|
+
input?: InputComponentTokens;
|
|
301
307
|
searchBar?: Partial<Record<ComponentSizeKey, SearchBarSizeTokens>> & {
|
|
302
308
|
cancelButtonWidth?: number;
|
|
303
309
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority-technologies/mobile",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Beautiful, animated, accessible React Native components plus API/auth/logging/network/storage utilities for Webority projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|