@vellira-ui/react-native 2.53.0 → 2.54.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 CHANGED
@@ -1,41 +1,24 @@
1
1
  # @vellira-ui/react-native
2
2
 
3
- React Native component package for Vellira.
3
+ React Native implementation of the Vellira design system.
4
4
 
5
- This package contains iOS-inspired native components built with React Native `StyleSheet`. Components use shared colors, typography, spacing, and radius from `@vellira-ui/tokens`, shared behavior from `@vellira-ui/core`, and renderer-neutral contracts from `@vellira-ui/types`.
6
-
7
- ## Components
8
-
9
- - Button
10
- - Checkbox
11
- - Input
12
- - FormField
13
- - Radio
14
- - RadioGroup
15
- - Select
16
- - Dropdown
17
- - Tabs
18
- - Tooltip
19
- - Modal
20
-
21
- Each public native component has React Native Storybook coverage and Vitest unit coverage.
22
-
23
- For detailed props, shared types, examples, and compound component APIs, see
24
- [Native Component API](./API.md).
5
+ It extends shared contracts from `@vellira-ui/types`, uses shared tokens from
6
+ `@vellira-ui/tokens`, shares renderer-neutral behavior through
7
+ `@vellira-ui/core`, and keeps native rendering, accessibility, layout, and
8
+ interaction behavior inside the React Native layer.
25
9
 
26
10
  ## Installation
27
11
 
12
+ Requires React and React Native.
13
+
28
14
  ```bash
29
15
  pnpm add @vellira-ui/react-native
30
16
  ```
31
17
 
32
- Peer dependencies:
33
-
34
- - `react`
35
- - `react-native`
36
-
37
18
  ## Usage
38
19
 
20
+ Use the components directly in your React Native application:
21
+
39
22
  ```tsx
40
23
  import { Button, Checkbox, Input } from '@vellira-ui/react-native';
41
24
  import { useState } from 'react';
@@ -47,7 +30,12 @@ export function Example() {
47
30
 
48
31
  return (
49
32
  <View style={{ gap: 16 }}>
50
- <Input label='Email' value={email} onValueChange={setEmail} />
33
+ <Input
34
+ label='Email'
35
+ value={email}
36
+ onValueChange={setEmail}
37
+ placeholder='name@example.com'
38
+ />
51
39
  <Checkbox
52
40
  label='Accept terms'
53
41
  description='Required to create an account.'
@@ -62,105 +50,56 @@ export function Example() {
62
50
  }
63
51
  ```
64
52
 
65
- ### Button Notes
66
-
67
- Use `accessibilityLabel` for icon-only native buttons:
68
-
69
- ```tsx
70
- import { Search } from '@vellira-ui/icons';
71
-
72
- <Button accessibilityLabel='Search' iconOnly iconStart={<Search />} />;
73
- ```
74
-
75
- Button icons are React elements from `@vellira-ui/icons`; the component injects
76
- the current icon color and size. `loading` disables interaction and can replace
77
- the visible label with `loadingText`.
78
-
79
- ### Checkbox Notes
80
-
81
- Use `description` for settings-style helper text when the checkbox is not
82
- wrapped in `FormField`. For checkbox rows without a visible label, provide
83
- `accessibilityLabel`.
84
-
85
- ### Select Notes
53
+ ## Components
86
54
 
87
- Use `Select` for one form value from a compact list, `RadioGroup` for a few
88
- visible choices, and `Dropdown` for action menus. Native `Select` opens a
89
- sheet, modal, or popover and renders options with a FlatList-backed native
90
- content surface.
55
+ ### Inputs
91
56
 
92
- ```tsx
93
- import { Select } from '@vellira-ui/react-native';
94
- import { useState } from 'react';
57
+ - Button
58
+ - Checkbox
59
+ - Input
60
+ - Radio
61
+ - RadioGroup
62
+ - Select
95
63
 
96
- export function RoleSelect() {
97
- const [role, setRole] = useState('editor');
64
+ ### Overlays
98
65
 
99
- return (
100
- <Select
101
- label='Role'
102
- value={role}
103
- onValueChange={(nextRole) => setRole(nextRole ?? '')}
104
- searchable
105
- clearable
106
- >
107
- <Select.Item value='admin' label='Admin' />
108
- <Select.Item value='editor' label='Editor' />
109
- <Select.Item value='viewer' label='Viewer' />
110
- </Select>
111
- );
112
- }
113
- ```
114
-
115
- ### Dropdown Notes
66
+ - Dropdown
67
+ - Tooltip
68
+ - Popover
69
+ - Modal
116
70
 
117
- Use `Dropdown` for contextual actions, not saved form values. Compose native
118
- menus with `Dropdown.Trigger`, `Dropdown.Content`, `Dropdown.Item`, groups,
119
- labels, and separators. Use `open`, `defaultOpen`, and `onOpenChange` for menu
120
- state. Use root `color` for the semantic trigger and menu palette, and
121
- `Dropdown.Item danger` for destructive commands.
71
+ ### Forms
122
72
 
123
- ```tsx
124
- import { Dropdown } from '@vellira-ui/react-native';
125
-
126
- <Dropdown color='primary' label='Actions'>
127
- <Dropdown.Content>
128
- <Dropdown.Label>File</Dropdown.Label>
129
- <Dropdown.Item value='duplicate' onSelect={duplicate}>
130
- Duplicate
131
- </Dropdown.Item>
132
- <Dropdown.Separator />
133
- <Dropdown.Item value='delete' danger onSelect={deleteFile}>
134
- Delete
135
- </Dropdown.Item>
136
- </Dropdown.Content>
137
- </Dropdown>;
138
- ```
73
+ - FormField
74
+ - Tabs
139
75
 
140
- ### FormField Notes
76
+ Every public component includes React Native Storybook stories and Vitest unit
77
+ tests.
141
78
 
142
- `FormField` is a presentational wrapper for custom native controls. Do not wrap
143
- components that already render their own field chrome, such as `Input`, `Select`
144
- or `RadioGroup`. The wrapped control should provide its own
145
- `accessibilityLabel`, role, disabled/editable state and interaction behavior.
146
- `FormField` only provides layout, text styling, required mark, disabled root
147
- state and polite error announcement.
79
+ For detailed props, shared types, examples, and compound component APIs, see
80
+ [Native Component API](./API.md).
148
81
 
149
- ## Testing
82
+ ## Infrastructure
150
83
 
151
- Run only native tests:
84
+ The package also exports native infrastructure used by components and
85
+ applications:
152
86
 
153
- ```bash
154
- pnpm --filter @vellira-ui/react-native test
155
- ```
87
+ - `Portal`
88
+ - `PortalProvider`
89
+ - `ThemeProvider`
90
+ - `useTheme`
91
+ - `nativeThemes`
156
92
 
157
- The native package uses Vitest with a lightweight local `react-native` mock. These tests validate component state, callbacks, accessibility props, and conditional rendering without requiring an iOS or Android simulator.
93
+ ## Documentation
158
94
 
159
- Native tests and test utilities are excluded from the package build through `tsconfig.json`.
95
+ - [Getting Started](https://docs.vellira.dev/start/getting-started)
96
+ - [React Native](https://docs.vellira.dev/react-native/)
97
+ - [Native Component API](./API.md)
160
98
 
161
99
  ## Storybook
162
100
 
163
- Native stories live next to components as `*.stories.tsx` and are consumed by `apps/native-storybook`.
101
+ Native stories live next to components as `*.stories.tsx` and are consumed by
102
+ `apps/native-storybook`.
164
103
 
165
104
  Run on-device Storybook from the workspace root:
166
105
 
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { Dropdown } from './components/Dropdown';
2
2
  export type { DropdownContentProps, DropdownEmptyProps, DropdownGroupProps, DropdownItemProps, DropdownLabelProps, DropdownPresentation, DropdownProps, DropdownSelectEvent, DropdownSeparatorProps, DropdownTriggerProps, } from './components/Dropdown/types';
3
3
  export type { ModalProps } from './components/Modal';
4
4
  export { Modal } from './components/Modal';
5
+ export type { PopoverAnchorProps, PopoverArrowProps, PopoverCloseProps, PopoverContentProps, PopoverDescriptionProps, PopoverProps, PopoverTitleProps, PopoverTriggerProps, } from './components/Popover';
6
+ export { Popover } from './components/Popover';
5
7
  export type { RadioGroupProps } from './components/RadioGroup';
6
8
  export { RadioGroup } from './components/RadioGroup';
7
9
  export type { SelectOption, SelectProps } from './components/Select';
package/dist/index.js CHANGED
@@ -3,6 +3,26 @@ import { Check, ChevronDown, Close, Search } from "@vellira-ui/icons";
3
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
+ //#region src/theme/fontWeight.ts
7
+ const nativeFontWeights = /* @__PURE__ */ new Set([
8
+ "normal",
9
+ "bold",
10
+ "100",
11
+ "200",
12
+ "300",
13
+ "400",
14
+ "500",
15
+ "600",
16
+ "700",
17
+ "800",
18
+ "900"
19
+ ]);
20
+ function toNativeFontWeight(weight) {
21
+ const normalizedWeight = String(weight);
22
+ if (!nativeFontWeights.has(normalizedWeight)) return "normal";
23
+ return normalizedWeight;
24
+ }
25
+ //#endregion
6
26
  //#region src/managers/FloatingManager/computeFloatingPosition.ts
7
27
  function clamp(value, min, max) {
8
28
  return Math.min(Math.max(value, min), Math.max(min, max));
@@ -1882,6 +1902,338 @@ const Modal = Object.assign(ModalRoot, {
1882
1902
  });
1883
1903
  Modal.displayName = "Modal";
1884
1904
  //#endregion
1905
+ //#region src/components/Popover/internal/PopoverContext.tsx
1906
+ const PopoverContext = createContext(null);
1907
+ function PopoverProvider({ children, value }) {
1908
+ return /* @__PURE__ */ jsx(PopoverContext.Provider, {
1909
+ value,
1910
+ children
1911
+ });
1912
+ }
1913
+ function usePopoverContext(componentName) {
1914
+ const context = useContext(PopoverContext);
1915
+ if (!context) throw new Error(`${componentName} must be used within Popover.`);
1916
+ return context;
1917
+ }
1918
+ //#endregion
1919
+ //#region src/components/Popover/Anchor/PopoverAnchor.tsx
1920
+ function PopoverAnchor({ children, asChild = false, ...anchorProps }) {
1921
+ const { anchorRef } = usePopoverContext("Popover.Anchor");
1922
+ if (asChild) return cloneElement(children, { ref: anchorRef });
1923
+ return /* @__PURE__ */ jsx(View, {
1924
+ ...anchorProps,
1925
+ ref: anchorRef,
1926
+ children
1927
+ });
1928
+ }
1929
+ PopoverAnchor.displayName = "Popover.Anchor";
1930
+ //#endregion
1931
+ //#region src/components/Popover/Arrow/PopoverArrow.styles.ts
1932
+ function createPopoverArrowStyles({ theme, side, arrowPosition }) {
1933
+ const tokens = theme.components.popover.arrow;
1934
+ const halfSize = tokens.size / 2;
1935
+ const position = side === "top" || side === "bottom" ? {
1936
+ left: arrowPosition.left ?? 0,
1937
+ transform: [{ translateX: -halfSize }, { rotate: "45deg" }]
1938
+ } : {
1939
+ top: arrowPosition.top ?? 0,
1940
+ transform: [{ translateY: -halfSize }, { rotate: "45deg" }]
1941
+ };
1942
+ const border = { borderColor: tokens.border };
1943
+ switch (side) {
1944
+ case "top":
1945
+ position.bottom = -halfSize;
1946
+ border.borderRightWidth = 1;
1947
+ border.borderBottomWidth = 1;
1948
+ break;
1949
+ case "bottom":
1950
+ position.top = -halfSize;
1951
+ border.borderLeftWidth = 1;
1952
+ border.borderTopWidth = 1;
1953
+ break;
1954
+ case "left":
1955
+ position.right = -halfSize;
1956
+ border.borderRightWidth = 1;
1957
+ border.borderTopWidth = 1;
1958
+ break;
1959
+ case "right":
1960
+ position.left = -halfSize;
1961
+ border.borderLeftWidth = 1;
1962
+ border.borderBottomWidth = 1;
1963
+ break;
1964
+ }
1965
+ return StyleSheet.create({ arrow: {
1966
+ position: "absolute",
1967
+ width: tokens.size,
1968
+ height: tokens.size,
1969
+ backgroundColor: tokens.bg,
1970
+ ...position,
1971
+ ...border
1972
+ } });
1973
+ }
1974
+ //#endregion
1975
+ //#region src/components/Popover/Arrow/PopoverArrow.tsx
1976
+ function PopoverArrow({ style }) {
1977
+ const { theme } = useTheme();
1978
+ const { placement, arrowPosition } = usePopoverContext("Popover.Arrow");
1979
+ const side = placement.split("-")[0];
1980
+ return /* @__PURE__ */ jsx(View, {
1981
+ accessible: false,
1982
+ pointerEvents: "none",
1983
+ style: [useMemo(() => createPopoverArrowStyles({
1984
+ theme,
1985
+ side,
1986
+ arrowPosition
1987
+ }), [
1988
+ theme,
1989
+ side,
1990
+ arrowPosition
1991
+ ]).arrow, style]
1992
+ });
1993
+ }
1994
+ PopoverArrow.displayName = "Popover.Arrow";
1995
+ //#endregion
1996
+ //#region src/components/Popover/Close/PopoverClose.tsx
1997
+ const PopoverClose = ({ children, asChild = false, onPress, ...closeProps }) => {
1998
+ const { setOpen } = usePopoverContext("Popover.Close");
1999
+ const handlePress = (event) => {
2000
+ children.props.onPress?.(event);
2001
+ onPress?.(event);
2002
+ if (event.defaultPrevented) return;
2003
+ setOpen(false, { reason: "close" });
2004
+ };
2005
+ if (asChild) return cloneElement(children, { onPress: handlePress });
2006
+ return /* @__PURE__ */ jsx(Pressable, {
2007
+ ...closeProps,
2008
+ onPress: handlePress,
2009
+ children
2010
+ });
2011
+ };
2012
+ PopoverClose.displayName = "PopoverClose";
2013
+ //#endregion
2014
+ //#region src/primitives/Portal/Portal.tsx
2015
+ const PortalContext = createContext(null);
2016
+ const styles$1 = StyleSheet.create({ host: { flex: 1 } });
2017
+ const PortalProvider = ({ children, container = null }) => /* @__PURE__ */ jsx(PortalContext.Provider, {
2018
+ value: container,
2019
+ children
2020
+ });
2021
+ const Portal = ({ children, visible = true, animationType = "none", hardwareAccelerated = true, navigationBarTranslucent = true, statusBarTranslucent = true, onDismiss, onRequestClose }) => {
2022
+ useContext(PortalContext);
2023
+ if (!visible) return null;
2024
+ return /* @__PURE__ */ jsx(Modal$1, {
2025
+ animationType,
2026
+ hardwareAccelerated,
2027
+ navigationBarTranslucent,
2028
+ onDismiss,
2029
+ onRequestClose,
2030
+ presentationStyle: "overFullScreen",
2031
+ statusBarTranslucent,
2032
+ transparent: true,
2033
+ visible: true,
2034
+ children: /* @__PURE__ */ jsx(View, {
2035
+ pointerEvents: "box-none",
2036
+ style: styles$1.host,
2037
+ children
2038
+ })
2039
+ });
2040
+ };
2041
+ Portal.__velliraPortal = true;
2042
+ Portal.displayName = "Portal";
2043
+ PortalProvider.displayName = "PortalProvider";
2044
+ //#endregion
2045
+ //#region src/components/Popover/Content/PopoverContent.styles.ts
2046
+ const styles = StyleSheet.create({
2047
+ layer: { flex: 1 },
2048
+ backdrop: StyleSheet.absoluteFill,
2049
+ content: { position: "absolute" }
2050
+ });
2051
+ function createPopoverContentStyles(theme) {
2052
+ const tokens = theme.components.popover.content;
2053
+ const shadow = tokens.shadow.native;
2054
+ return StyleSheet.create({ content: {
2055
+ minWidth: tokens.minWidth,
2056
+ maxWidth: tokens.maxWidth,
2057
+ padding: tokens.padding,
2058
+ gap: tokens.gap,
2059
+ backgroundColor: tokens.bg,
2060
+ borderColor: tokens.border,
2061
+ borderWidth: tokens.borderWidth,
2062
+ borderRadius: tokens.radius,
2063
+ shadowColor: shadow.color,
2064
+ shadowOpacity: shadow.opacity,
2065
+ shadowRadius: shadow.blur,
2066
+ shadowOffset: {
2067
+ width: shadow.x,
2068
+ height: shadow.y
2069
+ },
2070
+ elevation: shadow.elevation
2071
+ } });
2072
+ }
2073
+ //#endregion
2074
+ //#region src/components/Popover/Content/PopoverContent.tsx
2075
+ function PopoverContent({ children, style, ...contentProps }) {
2076
+ const { theme } = useTheme();
2077
+ const layerRef = useRef(null);
2078
+ const themedStyles = useMemo(() => createPopoverContentStyles(theme), [theme]);
2079
+ const { open, position, onFloatingLayout, updatePosition, setOpen, closeOnOutsidePress } = usePopoverContext("Popover.Content");
2080
+ useEffect(() => {
2081
+ if (!open) return;
2082
+ requestAnimationFrame(() => {
2083
+ updatePosition(layerRef);
2084
+ });
2085
+ }, [open, updatePosition]);
2086
+ return /* @__PURE__ */ jsx(Portal, {
2087
+ visible: open,
2088
+ onRequestClose: () => {
2089
+ setOpen(false, { reason: "escape-key" });
2090
+ },
2091
+ children: /* @__PURE__ */ jsxs(View, {
2092
+ ref: layerRef,
2093
+ pointerEvents: "box-none",
2094
+ style: styles.layer,
2095
+ children: [/* @__PURE__ */ jsx(Pressable, {
2096
+ testID: "popover-backdrop",
2097
+ accessibilityLabel: closeOnOutsidePress ? "Close popover" : void 0,
2098
+ accessibilityRole: closeOnOutsidePress ? "button" : void 0,
2099
+ onPress: closeOnOutsidePress ? () => {
2100
+ setOpen(false, { reason: "outside-press" });
2101
+ } : void 0,
2102
+ style: styles.backdrop
2103
+ }), /* @__PURE__ */ jsx(View, {
2104
+ ...contentProps,
2105
+ onLayout: onFloatingLayout,
2106
+ style: [
2107
+ styles.content,
2108
+ themedStyles.content,
2109
+ position,
2110
+ style
2111
+ ],
2112
+ children
2113
+ })]
2114
+ })
2115
+ });
2116
+ }
2117
+ //#endregion
2118
+ //#region src/components/Popover/Description/PopoverDescription.styles.ts
2119
+ function createPopoverDescriptionStyles(theme) {
2120
+ return StyleSheet.create({ description: {
2121
+ color: theme.components.popover.description.fg,
2122
+ fontSize: theme.tokens.typography.size.sm
2123
+ } });
2124
+ }
2125
+ //#endregion
2126
+ //#region src/components/Popover/Description/PopoverDescription.tsx
2127
+ const PopoverDescription = ({ children, style, ...descriptionProps }) => {
2128
+ const { theme } = useTheme();
2129
+ const styles = useMemo(() => createPopoverDescriptionStyles(theme), [theme]);
2130
+ return /* @__PURE__ */ jsx(Text, {
2131
+ ...descriptionProps,
2132
+ style: [styles.description, style],
2133
+ children
2134
+ });
2135
+ };
2136
+ PopoverDescription.displayName = "PopoverDescription";
2137
+ //#endregion
2138
+ //#region src/components/Popover/Root/PopoverRoot.tsx
2139
+ function getNativePlacement(side, align) {
2140
+ if (!side) return "bottom";
2141
+ if (!align || align === "center") return side;
2142
+ return `${side}-${align}`;
2143
+ }
2144
+ function PopoverRoot({ children, open: openProp, defaultOpen = false, onOpenChange, side = "bottom", align = "center", sideOffset = 8, closeOnOutsidePress = true }) {
2145
+ const triggerRef = useRef(null);
2146
+ const anchorRef = useRef(null);
2147
+ const getReferenceRef = useCallback(() => anchorRef.current ? anchorRef : triggerRef, []);
2148
+ const openChangeDetailsRef = useRef({ reason: "programmatic" });
2149
+ const [open, setOpenState] = useControllableState({
2150
+ value: openProp,
2151
+ defaultValue: defaultOpen,
2152
+ onChange: (nextOpen) => {
2153
+ onOpenChange?.(nextOpen, openChangeDetailsRef.current);
2154
+ }
2155
+ });
2156
+ const { position, arrowPosition, placement, updatePosition: updateFloatingPosition, onFloatingLayout } = useNativeFloatingPosition(getNativePlacement(side, align), sideOffset);
2157
+ const setOpen = useCallback((nextOpen, details) => {
2158
+ openChangeDetailsRef.current = details;
2159
+ setOpenState(nextOpen);
2160
+ }, [setOpenState]);
2161
+ return /* @__PURE__ */ jsx(PopoverProvider, {
2162
+ value: {
2163
+ open,
2164
+ closeOnOutsidePress,
2165
+ triggerRef,
2166
+ anchorRef,
2167
+ side,
2168
+ align,
2169
+ placement,
2170
+ position,
2171
+ arrowPosition,
2172
+ onFloatingLayout,
2173
+ updatePosition: useCallback((containerRef) => {
2174
+ updateFloatingPosition(getReferenceRef(), containerRef);
2175
+ }, [getReferenceRef, updateFloatingPosition]),
2176
+ setOpen
2177
+ },
2178
+ children
2179
+ });
2180
+ }
2181
+ PopoverRoot.displayName = "Popover.Root";
2182
+ //#endregion
2183
+ //#region src/components/Popover/Title/PopoverTitle.styles.ts
2184
+ function createPopoverTitleStyles(theme) {
2185
+ return StyleSheet.create({ title: {
2186
+ color: theme.components.popover.title.fg,
2187
+ fontSize: theme.tokens.typography.size.md,
2188
+ fontWeight: toNativeFontWeight(theme.tokens.typography.weight.semibold)
2189
+ } });
2190
+ }
2191
+ //#endregion
2192
+ //#region src/components/Popover/Title/PopoverTitle.tsx
2193
+ const PopoverTitle = ({ children, style, ...titleProps }) => {
2194
+ const { theme } = useTheme();
2195
+ const styles = useMemo(() => createPopoverTitleStyles(theme), [theme]);
2196
+ return /* @__PURE__ */ jsx(Text, {
2197
+ ...titleProps,
2198
+ style: [styles.title, style],
2199
+ children
2200
+ });
2201
+ };
2202
+ PopoverTitle.displayName = "PopoverTitle";
2203
+ //#endregion
2204
+ //#region src/components/Popover/Trigger/PopoverTrigger.tsx
2205
+ function PopoverTrigger({ children, asChild = false, onPress, ...triggerProps }) {
2206
+ const { open, setOpen, triggerRef } = usePopoverContext("Popover.Trigger");
2207
+ const handlePress = (event) => {
2208
+ children.props.onPress?.(event);
2209
+ onPress?.(event);
2210
+ if (event.defaultPrevented) return;
2211
+ setOpen(!open, { reason: "trigger" });
2212
+ };
2213
+ if (asChild) return cloneElement(children, {
2214
+ ref: triggerRef,
2215
+ onPress: handlePress
2216
+ });
2217
+ return /* @__PURE__ */ jsx(Pressable, {
2218
+ ...triggerProps,
2219
+ ref: triggerRef,
2220
+ onPress: handlePress,
2221
+ children
2222
+ });
2223
+ }
2224
+ //#endregion
2225
+ //#region src/components/Popover/Popover.tsx
2226
+ const Popover = Object.assign(PopoverRoot, {
2227
+ Anchor: PopoverAnchor,
2228
+ Trigger: PopoverTrigger,
2229
+ Content: PopoverContent,
2230
+ Arrow: PopoverArrow,
2231
+ Close: PopoverClose,
2232
+ Title: PopoverTitle,
2233
+ Description: PopoverDescription
2234
+ });
2235
+ Popover.displayName = "Popover";
2236
+ //#endregion
1885
2237
  //#region src/components/RadioGroup/internal/RadioGroupContext.tsx
1886
2238
  const RadioGroupContext = createContext(null);
1887
2239
  const RadioGroupProvider = RadioGroupContext.Provider;
@@ -5783,35 +6135,4 @@ const Input = forwardRef(({ label, description, value, defaultValue, onValueChan
5783
6135
  });
5784
6136
  Input.displayName = "Input";
5785
6137
  //#endregion
5786
- //#region src/primitives/Portal/Portal.tsx
5787
- const PortalContext = createContext(null);
5788
- const styles = StyleSheet.create({ host: { flex: 1 } });
5789
- const PortalProvider = ({ children, container = null }) => /* @__PURE__ */ jsx(PortalContext.Provider, {
5790
- value: container,
5791
- children
5792
- });
5793
- const Portal = ({ children, visible = true, animationType = "none", hardwareAccelerated = true, navigationBarTranslucent = true, statusBarTranslucent = true, onDismiss, onRequestClose }) => {
5794
- useContext(PortalContext);
5795
- if (!visible) return null;
5796
- return /* @__PURE__ */ jsx(Modal$1, {
5797
- animationType,
5798
- hardwareAccelerated,
5799
- navigationBarTranslucent,
5800
- onDismiss,
5801
- onRequestClose,
5802
- presentationStyle: "overFullScreen",
5803
- statusBarTranslucent,
5804
- transparent: true,
5805
- visible: true,
5806
- children: /* @__PURE__ */ jsx(View, {
5807
- pointerEvents: "box-none",
5808
- style: styles.host,
5809
- children
5810
- })
5811
- });
5812
- };
5813
- Portal.__velliraPortal = true;
5814
- Portal.displayName = "Portal";
5815
- PortalProvider.displayName = "PortalProvider";
5816
- //#endregion
5817
- export { Button, Checkbox, Dropdown, FormField, Input, Modal, Portal, PortalProvider, Radio, RadioGroup, Select, Tabs, ThemeProvider, Tooltip, nativeThemes, useTheme };
6138
+ export { Button, Checkbox, Dropdown, FormField, Input, Modal, Popover, Portal, PortalProvider, Radio, RadioGroup, Select, Tabs, ThemeProvider, Tooltip, nativeThemes, useTheme };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellira-ui/react-native",
3
- "version": "2.53.0",
3
+ "version": "2.54.0",
4
4
  "description": "React Native components for Vellira Design System",
5
5
  "author": "Roman Bakurov",
6
6
  "license": "MIT",