@vellira-ui/react-native 2.42.0 → 2.43.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.
Files changed (2) hide show
  1. package/dist/index.js +187 -110
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Children, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
2
2
  import { Check, ChevronDown, Close, Search } from "@vellira-ui/icons";
3
- import { AccessibilityInfo, ActivityIndicator, Animated, Dimensions, Easing, FlatList, Modal as Modal$1, Pressable, ScrollView, StyleSheet, Text, TextInput, View, findNodeHandle, useWindowDimensions } from "react-native";
3
+ import { AccessibilityInfo, ActivityIndicator, Animated, Dimensions, Easing, FlatList, Modal as Modal$1, Platform, Pressable, ScrollView, StyleSheet, Text, TextInput, View, findNodeHandle, useWindowDimensions } from "react-native";
4
4
  import { darkTheme, highContrastTheme, lightTheme } from "@vellira-ui/tokens";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/managers/FloatingManager/useNativeFloatingPosition.ts
@@ -586,14 +586,19 @@ const createStyles$21 = (theme) => StyleSheet.create({
586
586
  borderTopLeftRadius: theme.tokens.radius.lg,
587
587
  borderTopRightRadius: theme.tokens.radius.lg,
588
588
  borderWidth: 1,
589
- shadowColor: "#000000",
590
- shadowOffset: {
591
- width: 0,
592
- height: -4
593
- },
594
- shadowOpacity: .24,
595
- shadowRadius: 16,
596
- elevation: 12
589
+ ...Platform.select({
590
+ web: { boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.24)" },
591
+ default: {
592
+ shadowColor: "#000000",
593
+ shadowOffset: {
594
+ width: 0,
595
+ height: -4
596
+ },
597
+ shadowOpacity: .24,
598
+ shadowRadius: 16,
599
+ elevation: 12
600
+ }
601
+ })
597
602
  },
598
603
  sheetMenu: {
599
604
  width: "100%",
@@ -640,6 +645,8 @@ const createStyles$21 = (theme) => StyleSheet.create({
640
645
  });
641
646
  //#endregion
642
647
  //#region src/components/Dropdown/Content/DropdownContent.tsx
648
+ const nativePointerEventsBoxNone$1 = Platform.OS === "web" ? void 0 : { pointerEvents: "box-none" };
649
+ const webPointerEventsBoxNone$1 = Platform.OS === "web" ? { pointerEvents: "box-none" } : void 0;
643
650
  function DropdownContent({ isOpen, children, onClose, color = "primary", contentStyle, accessibilityLabel, presentation, searchable = false, searchValue = "", searchPlaceholder = "Search actions...", searchAccessibilityLabel, onSearchChange }) {
644
651
  const { theme } = useTheme();
645
652
  const styles = useThemeStyles(createStyles$21);
@@ -667,7 +674,7 @@ function DropdownContent({ isOpen, children, onClose, color = "primary", content
667
674
  Animated.timing(animation, {
668
675
  toValue: 1,
669
676
  duration: isSheet ? 220 : 160,
670
- useNativeDriver: true
677
+ useNativeDriver: Platform.OS !== "web"
671
678
  }).start();
672
679
  }, [
673
680
  animation,
@@ -701,8 +708,12 @@ function DropdownContent({ isOpen, children, onClose, color = "primary", content
701
708
  children: /* @__PURE__ */ jsxs(View, {
702
709
  style: [styles.modalRoot, styles[presentation]],
703
710
  children: [/* @__PURE__ */ jsx(Animated.View, {
704
- pointerEvents: "box-none",
705
- style: [styles.backdrop, backdropAnimatedStyle],
711
+ ...nativePointerEventsBoxNone$1,
712
+ style: [
713
+ styles.backdrop,
714
+ backdropAnimatedStyle,
715
+ webPointerEventsBoxNone$1
716
+ ],
706
717
  children: /* @__PURE__ */ jsx(Pressable, {
707
718
  accessibilityRole: "button",
708
719
  accessibilityLabel: "Close menu",
@@ -1067,7 +1078,7 @@ function DropdownTrigger({ asChild = false, label, trigger, children, icon, arro
1067
1078
  Animated.timing(rotateAnim, {
1068
1079
  toValue: isOpen ? 1 : 0,
1069
1080
  duration: 180,
1070
- useNativeDriver: true
1081
+ useNativeDriver: Platform.OS !== "web"
1071
1082
  }).start();
1072
1083
  }, [isOpen, rotateAnim]);
1073
1084
  const arrowRotate = rotateAnim.interpolate({
@@ -1224,6 +1235,11 @@ function DropdownRoot({ children, label = "Menu", trigger, icon, arrowIcon, show
1224
1235
  AccessibilityInfo.announceForAccessibility(`${menuAccessibilityLabel} opened`);
1225
1236
  }, [isOpen, menuAccessibilityLabel]);
1226
1237
  const focusTrigger = useCallback(() => {
1238
+ if (Platform.OS === "web") {
1239
+ const triggerNode = triggerRef.current;
1240
+ if (triggerNode && typeof triggerNode === "object" && "focus" in triggerNode && typeof triggerNode.focus === "function") triggerNode.focus();
1241
+ return;
1242
+ }
1227
1243
  if (typeof findNodeHandle !== "function") return;
1228
1244
  const handle = findNodeHandle(triggerRef.current);
1229
1245
  if (handle && AccessibilityInfo.setAccessibilityFocus) AccessibilityInfo.setAccessibilityFocus(handle);
@@ -1492,14 +1508,19 @@ const createStyles$13 = (theme) => StyleSheet.create({ content: {
1492
1508
  borderColor: theme.components.modal.content.border,
1493
1509
  borderRadius: theme.components.modal.content.radius,
1494
1510
  borderWidth: theme.components.modal.content.borderWidth,
1495
- shadowColor: theme.tokens.shadows.lg.color,
1496
- shadowOffset: {
1497
- width: theme.tokens.shadows.lg.x,
1498
- height: theme.tokens.shadows.lg.y
1499
- },
1500
- shadowOpacity: theme.tokens.shadows.lg.opacity,
1501
- shadowRadius: theme.tokens.shadows.lg.blur,
1502
- elevation: theme.tokens.shadows.lg.elevation
1511
+ ...Platform.select({
1512
+ web: { boxShadow: `${theme.tokens.shadows.lg.x}px ${theme.tokens.shadows.lg.y}px ${theme.tokens.shadows.lg.blur}px ${theme.tokens.shadows.lg.color}` },
1513
+ default: {
1514
+ shadowColor: theme.tokens.shadows.lg.color,
1515
+ shadowOffset: {
1516
+ width: theme.tokens.shadows.lg.x,
1517
+ height: theme.tokens.shadows.lg.y
1518
+ },
1519
+ shadowOpacity: theme.tokens.shadows.lg.opacity,
1520
+ shadowRadius: theme.tokens.shadows.lg.blur,
1521
+ elevation: theme.tokens.shadows.lg.elevation
1522
+ }
1523
+ })
1503
1524
  } });
1504
1525
  //#endregion
1505
1526
  //#region src/components/Modal/Content/ModalContent.tsx
@@ -1736,6 +1757,8 @@ const indicatorSizeBySize = {
1736
1757
  md: 8,
1737
1758
  lg: 10
1738
1759
  };
1760
+ const nativePointerEventsNone$5 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
1761
+ const webPointerEventsNone$5 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
1739
1762
  const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: disabledProp = false, required: requiredProp = false, size: sizeProp, color: colorProp, onCheckedChange, label, description, icon, error, accessibilityLabel, accessibilityHint, containerStyle, labelStyle, descriptionStyle, errorStyle, style, ...rest }, ref) => {
1740
1763
  const { theme } = useTheme();
1741
1764
  const styles = createStyles$10(theme);
@@ -1815,9 +1838,10 @@ const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: di
1815
1838
  onPress: handlePress,
1816
1839
  style: resolvePressableStyle,
1817
1840
  children: (state) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(View, {
1818
- pointerEvents: "none",
1841
+ ...nativePointerEventsNone$5,
1819
1842
  style: [
1820
1843
  styles.control,
1844
+ webPointerEventsNone$5,
1821
1845
  {
1822
1846
  width: controlSize,
1823
1847
  height: controlSize,
@@ -1846,8 +1870,8 @@ const Radio = forwardRef(({ value, checked, defaultChecked = false, disabled: di
1846
1870
  resolvedDisabled && styles.indicatorDisabled
1847
1871
  ] }))
1848
1872
  }), (label || description) && /* @__PURE__ */ jsxs(View, {
1849
- pointerEvents: "none",
1850
- style: styles.content,
1873
+ ...nativePointerEventsNone$5,
1874
+ style: [styles.content, webPointerEventsNone$5],
1851
1875
  children: [label && (typeof label === "string" ? /* @__PURE__ */ jsx(Text, {
1852
1876
  style: [
1853
1877
  styles.label,
@@ -3250,6 +3274,10 @@ const createTriggerStyles = (theme) => StyleSheet.create({
3250
3274
  //#endregion
3251
3275
  //#region src/components/Select/Trigger/SelectTrigger.tsx
3252
3276
  const SelectTriggerSlot = createSelectSlot("trigger", "Select.Trigger");
3277
+ const nativePointerEventsNone$4 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
3278
+ const nativePointerEventsBoxNone = Platform.OS === "web" ? void 0 : { pointerEvents: "box-none" };
3279
+ const webPointerEventsNone$4 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
3280
+ const webPointerEventsBoxNone = Platform.OS === "web" ? { pointerEvents: "box-none" } : void 0;
3253
3281
  function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color = "primary", variant = "outline", disabled = false, required = false, hasError = false, hasValue = false, loading = false, clearable = false, startIcon, endIcon, prefix, suffix, accessibilityLabel, accessibilityHint, nativeID, accessibilityLabelledBy, ariaDescribedBy, triggerStyle, textStyle, onPress, onClear }) {
3254
3282
  const { theme } = useTheme();
3255
3283
  const styles = useThemeStyles(createTriggerStyles);
@@ -3257,6 +3285,16 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3257
3285
  const triggerState = isOpen ? palette.focus : palette.default;
3258
3286
  const resolvedIconSize = size === "lg" ? 18 : 16;
3259
3287
  const showClearButton = clearable && hasValue && !disabled && !loading;
3288
+ const openRingStyle = Platform.OS === "web" ? { boxShadow: `0 0 0 3px ${theme.components.select[color].ring}` } : {
3289
+ shadowColor: theme.components.select[color].ring,
3290
+ shadowOffset: {
3291
+ width: 0,
3292
+ height: 0
3293
+ },
3294
+ shadowOpacity: .16,
3295
+ shadowRadius: 6,
3296
+ elevation: 1
3297
+ };
3260
3298
  const triggerWithClearStyle = {
3261
3299
  sm: styles.triggerWithClearSm,
3262
3300
  md: styles.triggerWithClearMd,
@@ -3323,16 +3361,7 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3323
3361
  },
3324
3362
  styles[size],
3325
3363
  showClearButton && triggerWithClearStyle[size],
3326
- isOpen && {
3327
- shadowColor: theme.components.select[color].ring,
3328
- shadowOffset: {
3329
- width: 0,
3330
- height: 0
3331
- },
3332
- shadowOpacity: .16,
3333
- shadowRadius: 6,
3334
- elevation: 1
3335
- },
3364
+ isOpen && openRingStyle,
3336
3365
  hasError && { borderColor: theme.components.select.trigger.error.border },
3337
3366
  disabled && {
3338
3367
  backgroundColor: theme.components.select.trigger.disabled.bg,
@@ -3342,8 +3371,8 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3342
3371
  ],
3343
3372
  children: [
3344
3373
  startIcon && /* @__PURE__ */ jsx(View, {
3345
- pointerEvents: "none",
3346
- style: styles.startIcon,
3374
+ ...nativePointerEventsNone$4,
3375
+ style: [styles.startIcon, webPointerEventsNone$4],
3347
3376
  accessibilityElementsHidden: true,
3348
3377
  importantForAccessibility: "no",
3349
3378
  children: renderIcon(startIcon)
@@ -3365,8 +3394,8 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3365
3394
  size: "small",
3366
3395
  color: iconColor
3367
3396
  }) : showClearButton ? null : endIcon ? /* @__PURE__ */ jsx(View, {
3368
- pointerEvents: "none",
3369
- style: styles.endIcon,
3397
+ ...nativePointerEventsNone$4,
3398
+ style: [styles.endIcon, webPointerEventsNone$4],
3370
3399
  accessibilityElementsHidden: true,
3371
3400
  importantForAccessibility: "no",
3372
3401
  children: renderIcon(endIcon)
@@ -3382,8 +3411,12 @@ function SelectTrigger({ displayText, isPlaceholder, isOpen, size = "md", color
3382
3411
  })
3383
3412
  ]
3384
3413
  }), showClearButton && /* @__PURE__ */ jsx(View, {
3385
- pointerEvents: "box-none",
3386
- style: [styles.clearButtonContainer, clearButtonContainerStyle[size]],
3414
+ ...nativePointerEventsBoxNone,
3415
+ style: [
3416
+ styles.clearButtonContainer,
3417
+ clearButtonContainerStyle[size],
3418
+ webPointerEventsBoxNone
3419
+ ],
3387
3420
  children: /* @__PURE__ */ jsx(Pressable, {
3388
3421
  accessibilityRole: "button",
3389
3422
  accessibilityLabel: "Clear selection",
@@ -3712,6 +3745,8 @@ const COLLAPSED_SIZE = 8;
3712
3745
  const LINE_ANIMATION_DURATION = 360;
3713
3746
  const SURFACE_ANIMATION_DURATION = 220;
3714
3747
  const easing = Easing?.bezier?.(.22, 1, .36, 1) ?? ((value) => value);
3748
+ const nativePointerEventsNone$3 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
3749
+ const webPointerEventsNone$3 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
3715
3750
  const animateValue = (value, toValue, duration) => Animated.timing(value, {
3716
3751
  toValue,
3717
3752
  duration,
@@ -3868,21 +3903,26 @@ const TabsIndicator = ({ children, style }) => {
3868
3903
  return [
3869
3904
  baseStyle,
3870
3905
  {
3871
- top: 0,
3872
- left: 0,
3906
+ top: -1,
3907
+ left: -1,
3873
3908
  width,
3874
3909
  height,
3875
3910
  backgroundColor: palette.segmented.active.bg,
3876
3911
  borderColor: palette.segmented.active.border,
3877
3912
  borderRadius: theme.tokens.radius.lg,
3878
3913
  borderWidth: 1,
3879
- shadowColor: "#181521",
3880
- shadowOffset: {
3881
- width: 0,
3882
- height: 1
3883
- },
3884
- shadowOpacity: .06,
3885
- shadowRadius: 2,
3914
+ ...Platform.select({
3915
+ web: { boxShadow: "0 1px 2px rgba(24, 21, 33, 0.06)" },
3916
+ default: {
3917
+ shadowColor: "#181521",
3918
+ shadowOffset: {
3919
+ width: 0,
3920
+ height: 1
3921
+ },
3922
+ shadowOpacity: .06,
3923
+ shadowRadius: 2
3924
+ }
3925
+ }),
3886
3926
  transform: [{ translateX }, { translateY }]
3887
3927
  },
3888
3928
  style
@@ -3907,8 +3947,8 @@ const TabsIndicator = ({ children, style }) => {
3907
3947
  return /* @__PURE__ */ jsx(Animated.View, {
3908
3948
  accessibilityElementsHidden: true,
3909
3949
  importantForAccessibility: "no-hide-descendants",
3910
- pointerEvents: "none",
3911
- style: indicatorStyle,
3950
+ ...nativePointerEventsNone$3,
3951
+ style: [indicatorStyle, webPointerEventsNone$3],
3912
3952
  children
3913
3953
  });
3914
3954
  };
@@ -3925,6 +3965,7 @@ const createStyles$6 = (theme) => StyleSheet.create({
3925
3965
  marginBottom: theme.tokens.spacing[6]
3926
3966
  },
3927
3967
  listSegmented: {
3968
+ gap: theme.tokens.spacing[1],
3928
3969
  padding: 2,
3929
3970
  backgroundColor: theme.components.tabs.list.segmentedBg,
3930
3971
  borderColor: theme.components.tabs.list.border,
@@ -4011,6 +4052,8 @@ const createStyles$5 = (theme) => StyleSheet.create({
4011
4052
  paddingHorizontal: 0
4012
4053
  },
4013
4054
  tabSegmented: {
4055
+ flex: 1,
4056
+ minWidth: 0,
4014
4057
  minHeight: 32,
4015
4058
  paddingVertical: 5,
4016
4059
  borderRadius: theme.tokens.radius.lg
@@ -4408,6 +4451,8 @@ const useTooltipContext = () => {
4408
4451
  TooltipContext.displayName = "TooltipContext";
4409
4452
  //#endregion
4410
4453
  //#region src/components/Tooltip/Arrow/TooltipArrow.tsx
4454
+ const nativePointerEventsNone$2 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
4455
+ const webPointerEventsNone$2 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
4411
4456
  const TooltipArrow = ({ style }) => {
4412
4457
  const { theme } = useTheme();
4413
4458
  const tooltip = useTooltipContext();
@@ -4427,16 +4472,20 @@ const TooltipArrow = ({ style }) => {
4427
4472
  marginLeft: -size / 2
4428
4473
  };
4429
4474
  return /* @__PURE__ */ jsx(View, {
4430
- pointerEvents: "none",
4431
- style: [{
4432
- position: "absolute",
4433
- width: size,
4434
- height: size,
4435
- backgroundColor: theme.components.tooltip.arrow.bg,
4436
- transform: [{ rotate: "45deg" }],
4437
- [staticSide]: -size / 2,
4438
- ...crossAxisStyle
4439
- }, style]
4475
+ ...nativePointerEventsNone$2,
4476
+ style: [
4477
+ {
4478
+ position: "absolute",
4479
+ width: size,
4480
+ height: size,
4481
+ backgroundColor: theme.components.tooltip.arrow.bg,
4482
+ transform: [{ rotate: "45deg" }],
4483
+ [staticSide]: -size / 2,
4484
+ ...crossAxisStyle
4485
+ },
4486
+ webPointerEventsNone$2,
4487
+ style
4488
+ ]
4440
4489
  });
4441
4490
  };
4442
4491
  TooltipArrow.displayName = "Tooltip.Arrow";
@@ -4455,14 +4504,19 @@ const createStyles$3 = (theme) => StyleSheet.create({
4455
4504
  borderColor: theme.components.tooltip.content.border,
4456
4505
  borderRadius: theme.components.tooltip.content.radius,
4457
4506
  borderWidth: theme.components.tooltip.content.borderWidth,
4458
- shadowColor: theme.tokens.shadows.md.color,
4459
- shadowOffset: {
4460
- width: theme.tokens.shadows.md.x,
4461
- height: theme.tokens.shadows.md.y
4462
- },
4463
- shadowOpacity: theme.tokens.shadows.md.opacity,
4464
- shadowRadius: theme.tokens.shadows.md.blur,
4465
- elevation: theme.tokens.shadows.md.elevation
4507
+ ...Platform.select({
4508
+ web: { boxShadow: `${theme.tokens.shadows.md.x}px ${theme.tokens.shadows.md.y}px ${theme.tokens.shadows.md.blur}px ${theme.tokens.shadows.md.color}` },
4509
+ default: {
4510
+ shadowColor: theme.tokens.shadows.md.color,
4511
+ shadowOffset: {
4512
+ width: theme.tokens.shadows.md.x,
4513
+ height: theme.tokens.shadows.md.y
4514
+ },
4515
+ shadowOpacity: theme.tokens.shadows.md.opacity,
4516
+ shadowRadius: theme.tokens.shadows.md.blur,
4517
+ elevation: theme.tokens.shadows.md.elevation
4518
+ }
4519
+ })
4466
4520
  },
4467
4521
  text: {
4468
4522
  flexShrink: 1,
@@ -4475,16 +4529,19 @@ const createStyles$3 = (theme) => StyleSheet.create({
4475
4529
  });
4476
4530
  //#endregion
4477
4531
  //#region src/components/Tooltip/Content/TooltipContent.tsx
4478
- const TooltipContent = ({ children, forceMount = false, style, textStyle }) => {
4532
+ const nativePointerEventsNone$1 = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
4533
+ const webPointerEventsNone$1 = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
4534
+ const TooltipContent = ({ children, forceMount = false, withArrow = false, style, textStyle }) => {
4479
4535
  const styles = useThemeStyles(createStyles$3);
4480
4536
  const tooltip = useTooltipContext();
4481
4537
  const visible = tooltip.open && !tooltip.disabled;
4482
4538
  if (!forceMount && !visible) return null;
4483
- const bubble = /* @__PURE__ */ jsx(View, {
4539
+ const bubble = /* @__PURE__ */ jsxs(View, {
4484
4540
  nativeID: tooltip.contentId,
4485
- pointerEvents: "none",
4541
+ ...nativePointerEventsNone$1,
4486
4542
  style: [
4487
4543
  styles.bubble,
4544
+ webPointerEventsNone$1,
4488
4545
  {
4489
4546
  top: tooltip.position.top,
4490
4547
  left: tooltip.position.left
@@ -4493,10 +4550,10 @@ const TooltipContent = ({ children, forceMount = false, style, textStyle }) => {
4493
4550
  style
4494
4551
  ],
4495
4552
  onLayout: tooltip.onFloatingLayout,
4496
- children: Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx(Text, {
4553
+ children: [Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx(Text, {
4497
4554
  style: [styles.text, textStyle],
4498
4555
  children: child
4499
- }) : child)
4556
+ }) : child), withArrow && /* @__PURE__ */ jsx(TooltipArrow, {})]
4500
4557
  });
4501
4558
  if (!visible) return bubble;
4502
4559
  return /* @__PURE__ */ jsx(Modal$1, {
@@ -4708,14 +4765,19 @@ const createStyles$2 = (theme) => StyleSheet.create({
4708
4765
  disabled: { borderColor: theme.components.button.disabled.border },
4709
4766
  focused: {
4710
4767
  borderColor: theme.semantic.focus.ring.color,
4711
- shadowColor: theme.semantic.focus.ring.color,
4712
- shadowOffset: {
4713
- width: 0,
4714
- height: 0
4715
- },
4716
- shadowOpacity: .18,
4717
- shadowRadius: 8,
4718
- elevation: 2
4768
+ ...Platform.select({
4769
+ web: { boxShadow: `0 0 0 4px ${theme.semantic.focus.ring.color}` },
4770
+ default: {
4771
+ shadowColor: theme.semantic.focus.ring.color,
4772
+ shadowOffset: {
4773
+ width: 0,
4774
+ height: 0
4775
+ },
4776
+ shadowOpacity: .18,
4777
+ shadowRadius: 8,
4778
+ elevation: 2
4779
+ }
4780
+ })
4719
4781
  },
4720
4782
  pressed: { transform: [{ scale: .98 }] }
4721
4783
  });
@@ -5204,26 +5266,36 @@ const createStyles = (theme) => StyleSheet.create({
5204
5266
  color: theme.components.input.focus.fg,
5205
5267
  backgroundColor: theme.components.input.focus.bg,
5206
5268
  borderColor: theme.components.input.focus.border,
5207
- shadowColor: resolveRingColor(theme.components.input.focus.ring),
5208
- shadowOffset: {
5209
- width: 0,
5210
- height: 0
5211
- },
5212
- shadowOpacity: .18,
5213
- shadowRadius: 6,
5214
- elevation: 1
5269
+ ...Platform.select({
5270
+ web: { boxShadow: `0 0 0 3px ${resolveRingColor(theme.components.input.focus.ring)}` },
5271
+ default: {
5272
+ shadowColor: resolveRingColor(theme.components.input.focus.ring),
5273
+ shadowOffset: {
5274
+ width: 0,
5275
+ height: 0
5276
+ },
5277
+ shadowOpacity: .18,
5278
+ shadowRadius: 6,
5279
+ elevation: 1
5280
+ }
5281
+ })
5215
5282
  },
5216
5283
  error: { borderColor: theme.components.input.error.border },
5217
5284
  errorFocused: {
5218
5285
  borderColor: theme.components.input.error.border,
5219
- shadowColor: resolveRingColor(theme.components.input.error.ring),
5220
- shadowOffset: {
5221
- width: 0,
5222
- height: 0
5223
- },
5224
- shadowOpacity: .2,
5225
- shadowRadius: 6,
5226
- elevation: 1
5286
+ ...Platform.select({
5287
+ web: { boxShadow: `0 0 0 3px ${resolveRingColor(theme.components.input.error.ring)}` },
5288
+ default: {
5289
+ shadowColor: resolveRingColor(theme.components.input.error.ring),
5290
+ shadowOffset: {
5291
+ width: 0,
5292
+ height: 0
5293
+ },
5294
+ shadowOpacity: .2,
5295
+ shadowRadius: 6,
5296
+ elevation: 1
5297
+ }
5298
+ })
5227
5299
  },
5228
5300
  readOnly: {
5229
5301
  color: theme.components.input.readOnly.fg,
@@ -5286,6 +5358,8 @@ const applyMask = (value, mask) => {
5286
5358
  if (!mask) return value;
5287
5359
  return typeof mask === "function" ? mask(value) : applyPatternMask(value, mask);
5288
5360
  };
5361
+ const nativePointerEventsNone = Platform.OS === "web" ? void 0 : { pointerEvents: "none" };
5362
+ const webPointerEventsNone = Platform.OS === "web" ? { pointerEvents: "none" } : void 0;
5289
5363
  const Input = forwardRef(({ label, description, value, defaultValue, onValueChange, placeholder, size, error, invalid = false, disabled = false, required = false, loading = false, readOnly = false, type = "text", startIcon, endIcon, startIconTone = "default", endIconTone = "default", clearIcon, clearIconTone = "danger", iconSize, containerStyle, inputStyle, keyboardType, secureTextEntry, autoCapitalize, autoCorrect, onBlur, onFocus, accessibilityLabel, accessibilityHint, testID, autoFocus, maxLength, clearable, onClear, color = "primary", variant = "outline", revealPassword = false, showCounter: _showCounter, mask, format, parse, ...props }, ref) => {
5290
5364
  const { theme } = useTheme();
5291
5365
  const styles = useThemeStyles(createStyles);
@@ -5306,6 +5380,16 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5306
5380
  const isRequired = required || !hasOwnField && Boolean(field?.required);
5307
5381
  const isReadOnly = readOnly || loading;
5308
5382
  const placeholderTextColor = isDisabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : inputState.placeholder;
5383
+ const focusedRingStyle = Platform.OS === "web" ? { boxShadow: `0 0 0 3px ${inputColorPalette.ring}` } : {
5384
+ shadowColor: inputColorPalette.ring,
5385
+ shadowOffset: {
5386
+ width: 0,
5387
+ height: 0
5388
+ },
5389
+ shadowOpacity: .18,
5390
+ shadowRadius: 6,
5391
+ elevation: 1
5392
+ };
5309
5393
  const isPassword = type === "password";
5310
5394
  const [isPasswordRevealed, setIsPasswordRevealed] = useState(false);
5311
5395
  const resolvedIconSize = iconSize ?? 16;
@@ -5338,8 +5422,8 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5338
5422
  style: styles.inputWrapper,
5339
5423
  children: [
5340
5424
  startIcon && /* @__PURE__ */ jsx(View, {
5341
- pointerEvents: "none",
5342
- style: styles.leftIcon,
5425
+ ...nativePointerEventsNone,
5426
+ style: [styles.leftIcon, webPointerEventsNone],
5343
5427
  accessibilityElementsHidden: true,
5344
5428
  importantForAccessibility: "no",
5345
5429
  children: cloneElement(startIcon, {
@@ -5385,14 +5469,7 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5385
5469
  color: inputPalette.focus.fg,
5386
5470
  backgroundColor: inputPalette.focus.bg,
5387
5471
  borderColor: inputPalette.focus.border,
5388
- shadowColor: inputColorPalette.ring,
5389
- shadowOffset: {
5390
- width: 0,
5391
- height: 0
5392
- },
5393
- shadowOpacity: .18,
5394
- shadowRadius: 6,
5395
- elevation: 1
5472
+ ...focusedRingStyle
5396
5473
  },
5397
5474
  isInvalid && styles.error,
5398
5475
  isFocused && isInvalid && !isDisabled && !isReadOnly && styles.errorFocused,
@@ -5424,8 +5501,8 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5424
5501
  children: isPasswordRevealed ? "Hide" : "Show"
5425
5502
  })
5426
5503
  }) : showRightIcon && endIcon && /* @__PURE__ */ jsx(View, {
5427
- pointerEvents: "none",
5428
- style: styles.rightIcon,
5504
+ ...nativePointerEventsNone,
5505
+ style: [styles.rightIcon, webPointerEventsNone],
5429
5506
  accessibilityElementsHidden: true,
5430
5507
  importantForAccessibility: "no",
5431
5508
  children: cloneElement(endIcon, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellira-ui/react-native",
3
- "version": "2.42.0",
3
+ "version": "2.43.0",
4
4
  "description": "React Native components for Vellira Design System",
5
5
  "author": "Roman Bakurov",
6
6
  "license": "MIT",