@vellira-ui/react-native 2.20.0 → 2.22.0
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/README.md +14 -0
- package/dist/index.js +151 -25
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -55,6 +55,20 @@ export function Example() {
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
### Button Notes
|
|
59
|
+
|
|
60
|
+
Use `accessibilityLabel` for icon-only native buttons:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Search } from '@vellira-ui/icons';
|
|
64
|
+
|
|
65
|
+
<Button accessibilityLabel='Search' iconOnly leftIcon={<Search />} />;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Button icons are React elements from `@vellira-ui/icons`; the component injects
|
|
69
|
+
the current icon color and size. `loading` disables interaction and can replace
|
|
70
|
+
the visible label with `loadingText`.
|
|
71
|
+
|
|
58
72
|
## Testing
|
|
59
73
|
|
|
60
74
|
Run only native tests:
|
package/dist/index.js
CHANGED
|
@@ -1831,6 +1831,13 @@ Tooltip.displayName = "Tooltip";
|
|
|
1831
1831
|
import { cloneElement as cloneElement4, useState as useState7 } from "react";
|
|
1832
1832
|
import { ActivityIndicator, Pressable as Pressable11, Text as Text12 } from "react-native";
|
|
1833
1833
|
|
|
1834
|
+
// src/utils/devWarning.ts
|
|
1835
|
+
var devWarning = (condition, message) => {
|
|
1836
|
+
if ((typeof __DEV__ === "undefined" || __DEV__) && !condition) {
|
|
1837
|
+
console.warn(message);
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1834
1841
|
// src/primitives/Button/Button.styles.ts
|
|
1835
1842
|
import { StyleSheet as StyleSheet21 } from "react-native";
|
|
1836
1843
|
var fontWeight3 = (value) => value;
|
|
@@ -1861,6 +1868,16 @@ var createStyles21 = (theme) => StyleSheet21.create({
|
|
|
1861
1868
|
disabled: {
|
|
1862
1869
|
borderColor: theme.components.button.disabled.border
|
|
1863
1870
|
},
|
|
1871
|
+
focused: {
|
|
1872
|
+
borderColor: theme.semantic.focus.ring,
|
|
1873
|
+
shadowColor: theme.semantic.focus.ring,
|
|
1874
|
+
shadowOffset: {
|
|
1875
|
+
width: 0,
|
|
1876
|
+
height: 0
|
|
1877
|
+
},
|
|
1878
|
+
shadowOpacity: 0.35,
|
|
1879
|
+
shadowRadius: 4
|
|
1880
|
+
},
|
|
1864
1881
|
pressed: {
|
|
1865
1882
|
transform: [{ scale: 0.98 }]
|
|
1866
1883
|
}
|
|
@@ -1912,15 +1929,16 @@ function Button({
|
|
|
1912
1929
|
const config = sizeMap[size];
|
|
1913
1930
|
const variantTheme = theme.components.button[color][variant];
|
|
1914
1931
|
const [isPressed, setIsPressed] = useState7(false);
|
|
1932
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
1933
|
+
const [isFocused, setIsFocused] = useState7(false);
|
|
1915
1934
|
const isDisabled = disabled || loading;
|
|
1916
1935
|
const iconOnly = iconOnlyProp || !children && Boolean(leftIcon || rightIcon);
|
|
1917
1936
|
const content = loading && loadingText ? loadingText : children;
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
const stateTheme = isDisabled ? theme.components.button.disabled : isPressed ? variantTheme.pressed : variantTheme.default;
|
|
1937
|
+
devWarning(
|
|
1938
|
+
!iconOnly || Boolean(accessibilityLabel),
|
|
1939
|
+
"Button: icon-only buttons must provide an accessibilityLabel."
|
|
1940
|
+
);
|
|
1941
|
+
const stateTheme = isDisabled ? theme.components.button.disabled : isPressed ? variantTheme.pressed : isHovered ? variantTheme.hover : variantTheme.default;
|
|
1924
1942
|
const contentColor = stateTheme.fg;
|
|
1925
1943
|
const resolvedIconSize = iconSize ?? config.iconSize;
|
|
1926
1944
|
const renderIcon = (icon, iconColor) => {
|
|
@@ -1938,10 +1956,14 @@ function Button({
|
|
|
1938
1956
|
accessibilityRole: "button",
|
|
1939
1957
|
accessibilityState: { disabled: isDisabled, busy: loading },
|
|
1940
1958
|
accessibilityLabel: accessibilityLabel ?? (typeof content === "string" ? content : void 0),
|
|
1959
|
+
onBlur: () => setIsFocused(false),
|
|
1960
|
+
onFocus: () => setIsFocused(true),
|
|
1961
|
+
onHoverIn: () => setIsHovered(true),
|
|
1962
|
+
onHoverOut: () => setIsHovered(false),
|
|
1941
1963
|
onPressIn: () => setIsPressed(true),
|
|
1942
1964
|
onPressOut: () => setIsPressed(false),
|
|
1943
1965
|
style: ({ pressed }) => {
|
|
1944
|
-
const pressedTheme = !isDisabled && pressed ? variantTheme.pressed : stateTheme;
|
|
1966
|
+
const pressedTheme = !isDisabled && pressed ? variantTheme.pressed : !isDisabled && isHovered ? variantTheme.hover : stateTheme;
|
|
1945
1967
|
return [
|
|
1946
1968
|
styles.button,
|
|
1947
1969
|
{
|
|
@@ -1953,6 +1975,7 @@ function Button({
|
|
|
1953
1975
|
fullWidth && styles.fullWidth,
|
|
1954
1976
|
isDisabled && styles.disabled,
|
|
1955
1977
|
pressed && !isDisabled && styles.pressed,
|
|
1978
|
+
isFocused && !isDisabled && styles.focused,
|
|
1956
1979
|
style
|
|
1957
1980
|
];
|
|
1958
1981
|
},
|
|
@@ -2103,7 +2126,7 @@ Checkbox.displayName = "Checkbox";
|
|
|
2103
2126
|
|
|
2104
2127
|
// src/primitives/Input/Input.tsx
|
|
2105
2128
|
import { cloneElement as cloneElement5, forwardRef as forwardRef2, useState as useState8 } from "react";
|
|
2106
|
-
import { TextInput, View as View20 } from "react-native";
|
|
2129
|
+
import { Pressable as Pressable13, Text as Text14, TextInput, View as View20 } from "react-native";
|
|
2107
2130
|
|
|
2108
2131
|
// src/primitives/Input/Input.styles.ts
|
|
2109
2132
|
import { StyleSheet as StyleSheet23 } from "react-native";
|
|
@@ -2128,18 +2151,51 @@ var createStyles23 = (theme) => StyleSheet23.create({
|
|
|
2128
2151
|
borderRadius: theme.tokens.radius.md,
|
|
2129
2152
|
borderWidth: 1
|
|
2130
2153
|
},
|
|
2131
|
-
|
|
2154
|
+
inputWithLeftAdornment: {
|
|
2132
2155
|
paddingLeft: theme.tokens.spacing[5] + 20
|
|
2133
2156
|
},
|
|
2134
|
-
|
|
2157
|
+
inputWithRightAdornment: {
|
|
2158
|
+
paddingRight: theme.tokens.spacing[5] + 20
|
|
2159
|
+
},
|
|
2160
|
+
rightAdornment: {
|
|
2161
|
+
position: "absolute",
|
|
2162
|
+
right: theme.tokens.spacing[4],
|
|
2163
|
+
top: "50%",
|
|
2164
|
+
zIndex: 1,
|
|
2165
|
+
width: 20,
|
|
2166
|
+
height: 20,
|
|
2167
|
+
marginTop: -10,
|
|
2168
|
+
alignItems: "center",
|
|
2169
|
+
justifyContent: "center"
|
|
2170
|
+
},
|
|
2171
|
+
leftAdornment: {
|
|
2135
2172
|
position: "absolute",
|
|
2136
2173
|
left: theme.tokens.spacing[4],
|
|
2137
|
-
top:
|
|
2138
|
-
bottom: 0,
|
|
2174
|
+
top: "50%",
|
|
2139
2175
|
zIndex: 1,
|
|
2176
|
+
width: 20,
|
|
2177
|
+
height: 20,
|
|
2178
|
+
marginTop: -10,
|
|
2140
2179
|
alignItems: "center",
|
|
2141
2180
|
justifyContent: "center"
|
|
2142
2181
|
},
|
|
2182
|
+
clearButton: {
|
|
2183
|
+
position: "absolute",
|
|
2184
|
+
right: theme.tokens.spacing[4],
|
|
2185
|
+
top: "50%",
|
|
2186
|
+
zIndex: 1,
|
|
2187
|
+
width: 20,
|
|
2188
|
+
height: 20,
|
|
2189
|
+
marginTop: -10,
|
|
2190
|
+
borderRadius: 999,
|
|
2191
|
+
alignItems: "center",
|
|
2192
|
+
justifyContent: "center"
|
|
2193
|
+
},
|
|
2194
|
+
clearButtonText: {
|
|
2195
|
+
color: theme.components.input.icon.danger,
|
|
2196
|
+
fontSize: 16,
|
|
2197
|
+
lineHeight: 20
|
|
2198
|
+
},
|
|
2143
2199
|
sm: {
|
|
2144
2200
|
minHeight: 36,
|
|
2145
2201
|
paddingHorizontal: theme.tokens.spacing[3],
|
|
@@ -2169,6 +2225,11 @@ var createStyles23 = (theme) => StyleSheet23.create({
|
|
|
2169
2225
|
errorFocused: {
|
|
2170
2226
|
borderColor: theme.components.input.error.border
|
|
2171
2227
|
},
|
|
2228
|
+
readOnly: {
|
|
2229
|
+
color: theme.components.input.readOnly.fg,
|
|
2230
|
+
borderColor: theme.components.input.readOnly.border,
|
|
2231
|
+
backgroundColor: theme.components.input.readOnly.bg
|
|
2232
|
+
},
|
|
2172
2233
|
disabled: {
|
|
2173
2234
|
opacity: 1,
|
|
2174
2235
|
color: theme.components.input.disabled.fg,
|
|
@@ -2210,14 +2271,20 @@ var Input = forwardRef2(
|
|
|
2210
2271
|
({
|
|
2211
2272
|
label,
|
|
2212
2273
|
value,
|
|
2274
|
+
defaultValue,
|
|
2213
2275
|
onChange,
|
|
2214
2276
|
placeholder,
|
|
2215
2277
|
size = "md",
|
|
2216
2278
|
error,
|
|
2217
2279
|
disabled = false,
|
|
2218
2280
|
required = false,
|
|
2281
|
+
readOnly = false,
|
|
2219
2282
|
type = "text",
|
|
2220
|
-
|
|
2283
|
+
leftAdornment,
|
|
2284
|
+
rightAdornment,
|
|
2285
|
+
leftAdornmentTone = "default",
|
|
2286
|
+
rightAdornmentTone = "default",
|
|
2287
|
+
clearIcon,
|
|
2221
2288
|
iconSize,
|
|
2222
2289
|
containerStyle,
|
|
2223
2290
|
inputStyle,
|
|
@@ -2229,15 +2296,25 @@ var Input = forwardRef2(
|
|
|
2229
2296
|
onFocus,
|
|
2230
2297
|
accessibilityLabel,
|
|
2231
2298
|
accessibilityHint,
|
|
2299
|
+
testID,
|
|
2300
|
+
autoFocus,
|
|
2301
|
+
maxLength,
|
|
2302
|
+
clearable,
|
|
2303
|
+
onClear,
|
|
2232
2304
|
...props
|
|
2233
2305
|
}, ref) => {
|
|
2234
2306
|
const { theme } = useTheme();
|
|
2235
2307
|
const styles = useThemeStyles(createStyles23);
|
|
2236
2308
|
const [isFocused, setIsFocused] = useState8(false);
|
|
2237
|
-
const
|
|
2309
|
+
const [uncontrolledValue, setUncontrolledValue] = useState8(
|
|
2310
|
+
defaultValue ?? ""
|
|
2311
|
+
);
|
|
2312
|
+
const isControlled = value !== void 0;
|
|
2313
|
+
const currentValue = isControlled ? value : uncontrolledValue;
|
|
2314
|
+
const hasValue = currentValue !== "";
|
|
2315
|
+
const placeholderTextColor = disabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : getPlaceholderTextColor(theme);
|
|
2238
2316
|
const isPassword = type === "password";
|
|
2239
2317
|
const resolvedIconSize = iconSize ?? 16;
|
|
2240
|
-
const iconColor = disabled ? theme.components.input.disabled.fg : isFocused ? theme.components.input.focus.fg : theme.components.input.default.placeholder;
|
|
2241
2318
|
const handleFocus = (event) => {
|
|
2242
2319
|
setIsFocused(true);
|
|
2243
2320
|
onFocus?.(event);
|
|
@@ -2246,6 +2323,24 @@ var Input = forwardRef2(
|
|
|
2246
2323
|
setIsFocused(false);
|
|
2247
2324
|
onBlur?.(event);
|
|
2248
2325
|
};
|
|
2326
|
+
const handleChangeText = (nextValue) => {
|
|
2327
|
+
if (!isControlled) {
|
|
2328
|
+
setUncontrolledValue(nextValue);
|
|
2329
|
+
}
|
|
2330
|
+
onChange?.(nextValue);
|
|
2331
|
+
};
|
|
2332
|
+
const handleClear = () => {
|
|
2333
|
+
if (!isControlled) {
|
|
2334
|
+
setUncontrolledValue("");
|
|
2335
|
+
}
|
|
2336
|
+
onChange?.("");
|
|
2337
|
+
onClear?.();
|
|
2338
|
+
};
|
|
2339
|
+
const showClearButton = clearable && hasValue && !disabled && !readOnly;
|
|
2340
|
+
const showRightIcon = !showClearButton && Boolean(rightAdornment);
|
|
2341
|
+
const leftIconColor = disabled ? theme.components.input.disabled.icon : theme.components.input.icon[leftAdornmentTone];
|
|
2342
|
+
const rightIconColor = disabled ? theme.components.input.disabled.icon : theme.components.input.icon[rightAdornmentTone];
|
|
2343
|
+
const clearIconColor = disabled ? theme.components.input.disabled.icon : theme.components.input.icon.danger;
|
|
2249
2344
|
return /* @__PURE__ */ jsx25(
|
|
2250
2345
|
FormField,
|
|
2251
2346
|
{
|
|
@@ -2255,15 +2350,15 @@ var Input = forwardRef2(
|
|
|
2255
2350
|
disabled,
|
|
2256
2351
|
style: containerStyle,
|
|
2257
2352
|
children: /* @__PURE__ */ jsxs15(View20, { style: styles.inputWrapper, children: [
|
|
2258
|
-
|
|
2353
|
+
leftAdornment && /* @__PURE__ */ jsx25(
|
|
2259
2354
|
View20,
|
|
2260
2355
|
{
|
|
2261
2356
|
pointerEvents: "none",
|
|
2262
|
-
style: styles.
|
|
2357
|
+
style: styles.leftAdornment,
|
|
2263
2358
|
accessibilityElementsHidden: true,
|
|
2264
2359
|
importantForAccessibility: "no",
|
|
2265
|
-
children: cloneElement5(
|
|
2266
|
-
color:
|
|
2360
|
+
children: cloneElement5(leftAdornment, {
|
|
2361
|
+
color: leftIconColor,
|
|
2267
2362
|
size: resolvedIconSize
|
|
2268
2363
|
})
|
|
2269
2364
|
}
|
|
@@ -2273,16 +2368,19 @@ var Input = forwardRef2(
|
|
|
2273
2368
|
{
|
|
2274
2369
|
...props,
|
|
2275
2370
|
ref,
|
|
2276
|
-
value,
|
|
2277
|
-
|
|
2371
|
+
value: currentValue,
|
|
2372
|
+
onChangeText: handleChangeText,
|
|
2373
|
+
editable: !disabled && !readOnly,
|
|
2278
2374
|
placeholder,
|
|
2279
2375
|
keyboardType: keyboardType ?? keyboardTypeByInputType[type],
|
|
2280
2376
|
secureTextEntry: secureTextEntry ?? isPassword,
|
|
2281
2377
|
autoCapitalize: autoCapitalize ?? autoCapitalizeByInputType[type],
|
|
2282
2378
|
autoCorrect: autoCorrect ?? autoCorrectByInputType[type],
|
|
2283
|
-
onChangeText: onChange,
|
|
2284
2379
|
onBlur: handleBlur,
|
|
2285
2380
|
onFocus: handleFocus,
|
|
2381
|
+
autoFocus,
|
|
2382
|
+
maxLength,
|
|
2383
|
+
testID,
|
|
2286
2384
|
placeholderTextColor,
|
|
2287
2385
|
accessibilityLabel: accessibilityLabel ?? label,
|
|
2288
2386
|
accessibilityHint,
|
|
@@ -2291,13 +2389,41 @@ var Input = forwardRef2(
|
|
|
2291
2389
|
styles.input,
|
|
2292
2390
|
styles[size],
|
|
2293
2391
|
inputStyle,
|
|
2294
|
-
|
|
2295
|
-
|
|
2392
|
+
leftAdornment && styles.inputWithLeftAdornment,
|
|
2393
|
+
(showRightIcon || showClearButton) && styles.inputWithRightAdornment,
|
|
2394
|
+
isFocused && !disabled && !readOnly && styles.focused,
|
|
2296
2395
|
error && styles.error,
|
|
2297
|
-
isFocused && error && !disabled && styles.errorFocused,
|
|
2396
|
+
isFocused && error && !disabled && !readOnly && styles.errorFocused,
|
|
2397
|
+
readOnly && !disabled && styles.readOnly,
|
|
2298
2398
|
disabled && styles.disabled
|
|
2299
2399
|
]
|
|
2300
2400
|
}
|
|
2401
|
+
),
|
|
2402
|
+
showClearButton ? /* @__PURE__ */ jsx25(
|
|
2403
|
+
Pressable13,
|
|
2404
|
+
{
|
|
2405
|
+
accessibilityRole: "button",
|
|
2406
|
+
accessibilityLabel: "Clear input",
|
|
2407
|
+
hitSlop: 8,
|
|
2408
|
+
onPress: handleClear,
|
|
2409
|
+
style: styles.clearButton,
|
|
2410
|
+
children: clearIcon ? cloneElement5(clearIcon, {
|
|
2411
|
+
color: clearIconColor,
|
|
2412
|
+
size: resolvedIconSize
|
|
2413
|
+
}) : /* @__PURE__ */ jsx25(Text14, { style: styles.clearButtonText, children: "\xD7" })
|
|
2414
|
+
}
|
|
2415
|
+
) : showRightIcon && rightAdornment && /* @__PURE__ */ jsx25(
|
|
2416
|
+
View20,
|
|
2417
|
+
{
|
|
2418
|
+
pointerEvents: "none",
|
|
2419
|
+
style: styles.rightAdornment,
|
|
2420
|
+
accessibilityElementsHidden: true,
|
|
2421
|
+
importantForAccessibility: "no",
|
|
2422
|
+
children: cloneElement5(rightAdornment, {
|
|
2423
|
+
color: rightIconColor,
|
|
2424
|
+
size: resolvedIconSize
|
|
2425
|
+
})
|
|
2426
|
+
}
|
|
2301
2427
|
)
|
|
2302
2428
|
] })
|
|
2303
2429
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vellira-ui/react-native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "React Native components for Vellira Design System",
|
|
5
5
|
"author": "Roman Bakurov",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"react-native": ">=0.81"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@vellira-ui/core": "2.
|
|
39
|
-
"@vellira-ui/icons": "2.
|
|
40
|
-
"@vellira-ui/types": "2.
|
|
41
|
-
"@vellira-ui/tokens": "2.
|
|
38
|
+
"@vellira-ui/core": "2.22.0",
|
|
39
|
+
"@vellira-ui/icons": "2.22.0",
|
|
40
|
+
"@vellira-ui/types": "2.22.0",
|
|
41
|
+
"@vellira-ui/tokens": "2.22.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react": "^19.2.3",
|