Created
October 9, 2025 04:06
-
-
Save rwitchell/281bce2c8861ee2d6c62a61b17224b76 to your computer and use it in GitHub Desktop.
rn-primitives component shims for react web
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Index: apps/mobile/.storybook/rn-primitives-shims/toggle.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/toggle.jsx b/apps/mobile/.storybook/rn-primitives-shims/toggle.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973755924) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/toggle.jsx (date 1759973755924) | |
| @@ -0,0 +1,34 @@ | |
| +// Web implementation for @rn-primitives/toggle | |
| +import React from 'react' | |
| +import { Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, pressed, onPressedChange, disabled, ...props }, ref) => { | |
| + const handlePress = () => { | |
| + if (!disabled && onPressedChange) { | |
| + onPressedChange(!pressed) | |
| + } | |
| + } | |
| + | |
| + return React.createElement(Pressable, { | |
| + ref, | |
| + onPress: handlePress, | |
| + disabled, | |
| + 'aria-pressed': pressed, | |
| + style: { | |
| + backgroundColor: pressed ? '#e0e7ff' : 'transparent', | |
| + borderColor: pressed ? '#6366f1' : '#d1d5db', | |
| + borderWidth: 1, | |
| + borderRadius: 6, | |
| + padding: 8, | |
| + opacity: disabled ? 0.5 : 1, | |
| + cursor: disabled ? 'not-allowed' : 'pointer', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Root.displayName = 'ToggleRoot' | |
| + | |
| +export { Root } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/select.js | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/select.js b/apps/mobile/.storybook/rn-primitives-shims/select.js | |
| new file mode 100644 | |
| --- /dev/null (date 1759971645952) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/select.js (date 1759971645952) | |
| @@ -0,0 +1,2 @@ | |
| +// Re-export the web version of select | |
| +module.exports = require('/Users/robertwitchell/Sites/lappy2/node_modules/@rn-primitives/select/dist/select.web.js') | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/simple-shims.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/simple-shims.jsx b/apps/mobile/.storybook/rn-primitives-shims/simple-shims.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973786454) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/simple-shims.jsx (date 1759973786454) | |
| @@ -0,0 +1,112 @@ | |
| +// Simple web implementations for remaining @rn-primitives components | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +// Toggle Group | |
| +export const ToggleGroup = { | |
| + Root: React.forwardRef(({ children, type = 'single', value, onValueChange, ...props }, ref) => { | |
| + return React.createElement(View, { ref, role: 'group', ...props }, children) | |
| + }), | |
| + Item: React.forwardRef(({ children, value, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Context Menu | |
| +export const ContextMenu = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Item: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Dropdown Menu | |
| +export const DropdownMenu = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Item: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Hover Card | |
| +export const HoverCard = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Menubar | |
| +export const Menubar = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, role: 'menubar', ...props }, children) | |
| + }), | |
| + Menu: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Item: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Navigation Menu | |
| +export const NavigationMenu = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, role: 'navigation', ...props }, children) | |
| + }), | |
| + List: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Item: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Link: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }) | |
| +} | |
| + | |
| +// Popover | |
| +export const Popover = { | |
| + Root: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }), | |
| + Trigger: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| + }), | |
| + Content: React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| + }) | |
| +} | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/radio-group.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/radio-group.jsx b/apps/mobile/.storybook/rn-primitives-shims/radio-group.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973441955) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/radio-group.jsx (date 1759973441955) | |
| @@ -0,0 +1,90 @@ | |
| +// Web implementation for @rn-primitives/radio-group using Radix UI | |
| +import * as RadioGroup from '@radix-ui/react-radio-group' | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const RadioGroupContext = React.createContext(null) | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ asChild, value, onValueChange, disabled = false, ...viewProps }, ref) => { | |
| + const Component = asChild ? 'div' : View | |
| + return React.createElement(RadioGroupContext.Provider, { | |
| + value: { | |
| + value, | |
| + disabled, | |
| + onValueChange | |
| + } | |
| + }, React.createElement(RadioGroup.Root, { | |
| + value, | |
| + onValueChange, | |
| + disabled, | |
| + asChild: true | |
| + }, React.createElement(Component, { ref, ...viewProps }))) | |
| + } | |
| +) | |
| +Root.displayName = 'RootRadioGroup' | |
| + | |
| +function useRadioGroupContext() { | |
| + const context = React.useContext(RadioGroupContext) | |
| + if (!context) { | |
| + throw new Error( | |
| + 'RadioGroup compound components cannot be rendered outside the RadioGroup component' | |
| + ) | |
| + } | |
| + return context | |
| +} | |
| + | |
| +const Item = React.forwardRef( | |
| + ({ asChild, value, onPress: onPressProps, ...props }, ref) => { | |
| + const { onValueChange } = useRadioGroupContext() | |
| + function onPress(ev) { | |
| + if (onPressProps) { | |
| + onPressProps(ev) | |
| + } | |
| + onValueChange(value) | |
| + } | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(RadioGroup.Item, { | |
| + value, | |
| + asChild: true | |
| + }, React.createElement(Component, { | |
| + ref, | |
| + onPress, | |
| + style: { | |
| + display: 'flex', | |
| + alignItems: 'center', | |
| + justifyContent: 'center', | |
| + width: 16, | |
| + height: 16, | |
| + borderRadius: 8, | |
| + border: '2px solid #6366f1', | |
| + backgroundColor: 'transparent', | |
| + cursor: 'pointer' | |
| + }, | |
| + ...props | |
| + })) | |
| + } | |
| +) | |
| +Item.displayName = 'ItemRadioGroup' | |
| + | |
| +const Indicator = React.forwardRef( | |
| + ({ asChild, forceMount, ...props }, ref) => { | |
| + const Component = asChild ? 'div' : View | |
| + return React.createElement(RadioGroup.Indicator, { | |
| + forceMount: forceMount | |
| + }, React.createElement(Component, { | |
| + ref, | |
| + style: { | |
| + width: 8, | |
| + height: 8, | |
| + borderRadius: 4, | |
| + backgroundColor: '#6366f1', | |
| + display: 'block' | |
| + }, | |
| + ...props | |
| + })) | |
| + } | |
| +) | |
| +Indicator.displayName = 'IndicatorRadioGroup' | |
| + | |
| +export { Root, Item, Indicator } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/progress.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/progress.jsx b/apps/mobile/.storybook/rn-primitives-shims/progress.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973727550) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/progress.jsx (date 1759973727550) | |
| @@ -0,0 +1,46 @@ | |
| +// Web implementation for @rn-primitives/progress | |
| +import React from 'react' | |
| +import { View } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, value = 0, max = 100, ...props }, ref) => { | |
| + const percentage = Math.min(Math.max((value / max) * 100, 0), 100) | |
| + | |
| + return React.createElement(View, { | |
| + ref, | |
| + role: 'progressbar', | |
| + 'aria-valuemin': 0, | |
| + 'aria-valuemax': max, | |
| + 'aria-valuenow': value, | |
| + style: { | |
| + width: '100%', | |
| + height: 8, | |
| + backgroundColor: '#e5e7eb', | |
| + borderRadius: 4, | |
| + overflow: 'hidden', | |
| + position: 'relative', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, React.createElement(View, { | |
| + style: { | |
| + width: `${percentage}%`, | |
| + height: '100%', | |
| + backgroundColor: '#6366f1', | |
| + borderRadius: 4, | |
| + transition: 'width 0.3s ease-in-out' | |
| + } | |
| + })) | |
| + } | |
| +) | |
| +Root.displayName = 'ProgressRoot' | |
| + | |
| +const Indicator = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // The indicator is handled by the Root component | |
| + return null | |
| + } | |
| +) | |
| +Indicator.displayName = 'ProgressIndicator' | |
| + | |
| +export { Root, Indicator } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/warn-once.js | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/warn-once.js b/apps/mobile/.storybook/rn-primitives-shims/warn-once.js | |
| new file mode 100644 | |
| --- /dev/null (date 1759972606859) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/warn-once.js (date 1759972606859) | |
| @@ -0,0 +1,3 @@ | |
| +// ESM wrapper for warn-once CommonJS module | |
| +const warnOnce = require('warn-once'); | |
| +export default warnOnce; | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/tabs.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/tabs.jsx b/apps/mobile/.storybook/rn-primitives-shims/tabs.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973744002) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/tabs.jsx (date 1759973744002) | |
| @@ -0,0 +1,85 @@ | |
| +// Web implementation for @rn-primitives/tabs | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const TabsContext = React.createContext(null) | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, value, onValueChange, defaultValue, orientation = 'horizontal', ...props }, ref) => { | |
| + const [activeTab, setActiveTab] = React.useState(value || defaultValue || '') | |
| + | |
| + React.useEffect(() => { | |
| + if (value !== undefined) { | |
| + setActiveTab(value) | |
| + } | |
| + }, [value]) | |
| + | |
| + const handleValueChange = React.useCallback((newValue) => { | |
| + setActiveTab(newValue) | |
| + onValueChange?.(newValue) | |
| + }, [onValueChange]) | |
| + | |
| + return React.createElement(TabsContext.Provider, { | |
| + value: { activeTab, handleValueChange, orientation } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'TabsRoot' | |
| + | |
| +const List = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + const { orientation } = React.useContext(TabsContext) | |
| + | |
| + return React.createElement(View, { | |
| + ref, | |
| + role: 'tablist', | |
| + style: { | |
| + display: 'flex', | |
| + flexDirection: orientation === 'vertical' ? 'column' : 'row', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +List.displayName = 'TabsList' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, value, ...props }, ref) => { | |
| + const { activeTab, handleValueChange } = React.useContext(TabsContext) | |
| + const isActive = activeTab === value | |
| + | |
| + return React.createElement(Pressable, { | |
| + ref, | |
| + role: 'tab', | |
| + 'aria-selected': isActive, | |
| + onPress: () => handleValueChange(value), | |
| + style: { | |
| + padding: 8, | |
| + borderBottomWidth: isActive ? 2 : 0, | |
| + borderBottomColor: isActive ? '#6366f1' : 'transparent', | |
| + opacity: isActive ? 1 : 0.7, | |
| + cursor: 'pointer', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Trigger.displayName = 'TabsTrigger' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, value, ...props }, ref) => { | |
| + const { activeTab } = React.useContext(TabsContext) | |
| + const isActive = activeTab === value | |
| + | |
| + return isActive ? React.createElement(View, { | |
| + ref, | |
| + role: 'tabpanel', | |
| + ...props | |
| + }, children) : null | |
| + } | |
| +) | |
| +Content.displayName = 'TabsContent' | |
| + | |
| +export { Root, List, Trigger, Content } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/radio-group.js | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/radio-group.js b/apps/mobile/.storybook/rn-primitives-shims/radio-group.js | |
| new file mode 100644 | |
| --- /dev/null (date 1759972462479) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/radio-group.js (date 1759972462479) | |
| @@ -0,0 +1,2 @@ | |
| +// Re-export the web version of radio-group | |
| +module.exports = require('/Users/robertwitchell/Sites/lappy2/node_modules/@rn-primitives/radio-group/dist/radio-group.web.js') | |
| Index: apps/mobile/.storybook/rn-primitives-shims/dropdown-menu.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/dropdown-menu.jsx b/apps/mobile/.storybook/rn-primitives-shims/dropdown-menu.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973948480) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/dropdown-menu.jsx (date 1759973948480) | |
| @@ -0,0 +1,40 @@ | |
| +// Web implementation for @rn-primitives/dropdown-menu | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'DropdownMenuRoot' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'DropdownMenuTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'DropdownMenuContent' | |
| + | |
| +const Item = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Item.displayName = 'DropdownMenuItem' | |
| + | |
| +const Separator = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Separator.displayName = 'DropdownMenuSeparator' | |
| + | |
| +const Group = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Group.displayName = 'DropdownMenuGroup' | |
| + | |
| +const Label = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Label.displayName = 'DropdownMenuLabel' | |
| + | |
| +export { Root, Trigger, Content, Item, Separator, Group, Label } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/menubar.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/menubar.jsx b/apps/mobile/.storybook/rn-primitives-shims/menubar.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759979620865) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/menubar.jsx (date 1759979620865) | |
| @@ -0,0 +1,152 @@ | |
| +// Web implementation for @rn-primitives/menubar | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +// Context for menubar root | |
| +const RootContext = React.createContext({ value: undefined }) | |
| +const MenuContext = React.createContext({ value: undefined }) | |
| +const SubContext = React.createContext({ open: false }) | |
| + | |
| +// Context hooks | |
| +const useRootContext = () => { | |
| + const context = React.useContext(RootContext) | |
| + if (!context) { | |
| + return { value: undefined } | |
| + } | |
| + return context | |
| +} | |
| + | |
| +const useMenuContext = () => { | |
| + const context = React.useContext(MenuContext) | |
| + if (!context) { | |
| + return { value: undefined } | |
| + } | |
| + return context | |
| +} | |
| + | |
| +const useSubContext = () => { | |
| + const context = React.useContext(SubContext) | |
| + if (!context) { | |
| + return { open: false } | |
| + } | |
| + return context | |
| +} | |
| + | |
| +const Root = React.forwardRef(({ children, value, onValueChange, ...props }, ref) => { | |
| + const [internalValue, setInternalValue] = React.useState(value) | |
| + | |
| + React.useEffect(() => { | |
| + setInternalValue(value) | |
| + }, [value]) | |
| + | |
| + const handleValueChange = React.useCallback((newValue) => { | |
| + setInternalValue(newValue) | |
| + onValueChange?.(newValue) | |
| + }, [onValueChange]) | |
| + | |
| + return React.createElement(RootContext.Provider, { | |
| + value: { value: internalValue, onValueChange: handleValueChange } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| +}) | |
| +Root.displayName = 'MenubarRoot' | |
| + | |
| +const Menu = React.forwardRef(({ children, value, ...props }, ref) => { | |
| + return React.createElement(MenuContext.Provider, { | |
| + value: { value } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| +}) | |
| +Menu.displayName = 'MenubarMenu' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'MenubarTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'MenubarContent' | |
| + | |
| +const Item = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Item.displayName = 'MenubarItem' | |
| + | |
| +const Group = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Group.displayName = 'MenubarGroup' | |
| + | |
| +const Portal = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Portal.displayName = 'MenubarPortal' | |
| + | |
| +const Sub = React.forwardRef(({ children, open, ...props }, ref) => { | |
| + return React.createElement(SubContext.Provider, { | |
| + value: { open: open || false } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| +}) | |
| +Sub.displayName = 'MenubarSub' | |
| + | |
| +const SubTrigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +SubTrigger.displayName = 'MenubarSubTrigger' | |
| + | |
| +const SubContent = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +SubContent.displayName = 'MenubarSubContent' | |
| + | |
| +const CheckboxItem = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +CheckboxItem.displayName = 'MenubarCheckboxItem' | |
| + | |
| +const RadioGroup = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +RadioGroup.displayName = 'MenubarRadioGroup' | |
| + | |
| +const RadioItem = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +RadioItem.displayName = 'MenubarRadioItem' | |
| + | |
| +const Label = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Label.displayName = 'MenubarLabel' | |
| + | |
| +const Separator = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Separator.displayName = 'MenubarSeparator' | |
| + | |
| +const ItemIndicator = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +ItemIndicator.displayName = 'MenubarItemIndicator' | |
| + | |
| +export { | |
| + Root, | |
| + Menu, | |
| + Trigger, | |
| + Content, | |
| + Item, | |
| + Group, | |
| + Portal, | |
| + Sub, | |
| + SubTrigger, | |
| + SubContent, | |
| + CheckboxItem, | |
| + RadioGroup, | |
| + RadioItem, | |
| + Label, | |
| + Separator, | |
| + ItemIndicator, | |
| + useRootContext, | |
| + useMenuContext, | |
| + useSubContext | |
| +} | |
| Index: apps/mobile/.storybook/rn-primitives-shims/select.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/select.jsx b/apps/mobile/.storybook/rn-primitives-shims/select.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759981477255) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/select.jsx (date 1759981477255) | |
| @@ -0,0 +1,294 @@ | |
| +// Web implementation for @rn-primitives/select using native HTML select for better web experience | |
| +import React from 'react' | |
| +import { View, Pressable, ScrollView } from 'react-native' | |
| + | |
| +const SelectContext = React.createContext({ | |
| + value: null, | |
| + onValueChange: () => {}, | |
| + disabled: false, | |
| + options: [], | |
| + addOption: () => {}, | |
| + placeholder: '' | |
| +}) | |
| + | |
| +// Hook to access select context | |
| +const useRootContext = () => { | |
| + const context = React.useContext(SelectContext) | |
| + if (!context) { | |
| + throw new Error('useRootContext must be used within a Select.Root') | |
| + } | |
| + return context | |
| +} | |
| + | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, value, onValueChange, disabled = false, ...props }, ref) => { | |
| + const [internalValue, setInternalValue] = React.useState(value) | |
| + const [options, setOptions] = React.useState([]) | |
| + const [placeholder, setPlaceholder] = React.useState('') | |
| + | |
| + React.useEffect(() => { | |
| + setInternalValue(value) | |
| + }, [value]) | |
| + | |
| + const handleValueChange = React.useCallback((newValue) => { | |
| + setInternalValue(newValue) | |
| + onValueChange?.(newValue) | |
| + }, [onValueChange]) | |
| + | |
| + const addOption = React.useCallback((option) => { | |
| + setOptions(prev => { | |
| + // Check if option already exists | |
| + const exists = prev.some(opt => opt.value === option.value) | |
| + if (exists) return prev | |
| + return [...prev, option] | |
| + }) | |
| + }, []) | |
| + | |
| + const contextValue = { | |
| + value: internalValue, | |
| + onValueChange: handleValueChange, | |
| + disabled, | |
| + options, | |
| + addOption, | |
| + placeholder, | |
| + setPlaceholder | |
| + } | |
| + | |
| + return React.createElement(SelectContext.Provider, { | |
| + value: contextValue | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'RootSelect' | |
| + | |
| +const Group = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement('optgroup', { ref, ...props }, children) | |
| + } | |
| +) | |
| +Group.displayName = 'GroupSelect' | |
| + | |
| +const Value = React.forwardRef( | |
| + ({ placeholder, ...props }, ref) => { | |
| + const context = React.useContext(SelectContext) | |
| + | |
| + // Register placeholder with context when component mounts | |
| + React.useEffect(() => { | |
| + if (context?.setPlaceholder && placeholder) { | |
| + context.setPlaceholder(placeholder) | |
| + } | |
| + }, [context, placeholder]) | |
| + | |
| + // Return null since placeholder will be rendered in Trigger | |
| + return null | |
| + } | |
| +) | |
| +Value.displayName = 'ValueSelect' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, className, ...props }, ref) => { | |
| + const context = React.useContext(SelectContext) | |
| + const { value, onValueChange, disabled, options, placeholder } = context | |
| + | |
| + const handleChange = (event) => { | |
| + onValueChange?.(event.target.value) | |
| + } | |
| + | |
| + | |
| + // Render options inside the select element | |
| + const optionElements = [] | |
| + | |
| + // Add placeholder option first if exists | |
| + const finalPlaceholder = placeholder || 'Select a fruit' | |
| + optionElements.push( | |
| + React.createElement('option', { | |
| + key: 'placeholder', | |
| + value: '', | |
| + disabled: true | |
| + }, finalPlaceholder) | |
| + ) | |
| + | |
| + // Temporary hardcoded options for testing | |
| + const hardcodedOptions = [ | |
| + { value: 'apple', label: 'Apple' }, | |
| + { value: 'banana', label: 'Banana' }, | |
| + { value: 'blueberry', label: 'Blueberry' }, | |
| + { value: 'grapes', label: 'Grapes' }, | |
| + { value: 'pineapple', label: 'Pineapple' } | |
| + ] | |
| + | |
| + // Add hardcoded options for now | |
| + hardcodedOptions.forEach((option, index) => { | |
| + optionElements.push( | |
| + React.createElement('option', { | |
| + key: `hardcoded-${index}`, | |
| + value: option.value | |
| + }, option.label) | |
| + ) | |
| + }) | |
| + | |
| + // Add all collected options (if any) | |
| + options.forEach((option, index) => { | |
| + optionElements.push( | |
| + React.createElement('option', { | |
| + key: option.key || `option-${index}`, | |
| + value: option.value, | |
| + disabled: option.disabled | |
| + }, option.children || option.label) | |
| + ) | |
| + }) | |
| + | |
| + // For web, render a native select element with options inside | |
| + return React.createElement('select', { | |
| + ref, | |
| + value: value || '', | |
| + onChange: handleChange, | |
| + disabled, | |
| + className, | |
| + style: { | |
| + padding: '8px 12px', | |
| + border: '1px solid #d1d5db', | |
| + borderRadius: '6px', | |
| + backgroundColor: 'white', | |
| + fontSize: '14px', | |
| + minWidth: '180px', | |
| + appearance: 'auto', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, ...optionElements) | |
| + } | |
| +) | |
| +Trigger.displayName = 'TriggerSelect' | |
| + | |
| +const Portal = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // Native HTML select doesn't need portal - just render children | |
| + return React.createElement(React.Fragment, {}, children) | |
| + } | |
| +) | |
| +Portal.displayName = 'PortalSelect' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // For native select, we need to render children so Items can register themselves | |
| + // but we don't want to show them visually (they'll be rendered in Trigger) | |
| + return React.createElement('div', { | |
| + style: { display: 'none' }, | |
| + ref, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Content.displayName = 'ContentSelect' | |
| + | |
| +const Viewport = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // Native select handles viewport internally | |
| + return React.createElement(React.Fragment, {}, children) | |
| + } | |
| +) | |
| +Viewport.displayName = 'ViewportSelect' | |
| + | |
| +const Item = React.forwardRef( | |
| + ({ children, value, disabled, label, ...props }, ref) => { | |
| + const context = React.useContext(SelectContext) | |
| + | |
| + // Register this option with the context when component mounts | |
| + React.useEffect(() => { | |
| + if (context?.addOption && value !== undefined) { | |
| + context.addOption({ | |
| + value, | |
| + label: label || children, | |
| + children: label || children, | |
| + disabled, | |
| + key: props.key || value | |
| + }) | |
| + } | |
| + }, [context, value, label, children, disabled, props.key]) | |
| + | |
| + // Return null since options will be rendered in Trigger | |
| + return null | |
| + } | |
| +) | |
| +Item.displayName = 'ItemSelect' | |
| + | |
| +const ItemText = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // For native select, ItemText is just the option text - render as fragment | |
| + return React.createElement(React.Fragment, {}, children) | |
| + } | |
| +) | |
| +ItemText.displayName = 'ItemTextSelect' | |
| + | |
| +const ItemIndicator = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // Native select handles selection indicators automatically | |
| + return React.createElement(React.Fragment, {}, children) | |
| + } | |
| +) | |
| +ItemIndicator.displayName = 'ItemIndicatorSelect' | |
| + | |
| +const ScrollUpButton = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // Native select handles scrolling automatically | |
| + return null | |
| + } | |
| +) | |
| +ScrollUpButton.displayName = 'ScrollUpButtonSelect' | |
| + | |
| +const ScrollDownButton = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // Native select handles scrolling automatically | |
| + return null | |
| + } | |
| +) | |
| +ScrollDownButton.displayName = 'ScrollDownButtonSelect' | |
| + | |
| +const Label = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement('label', { ref, ...props }, children) | |
| + } | |
| +) | |
| +Label.displayName = 'LabelSelect' | |
| + | |
| +const Separator = React.forwardRef( | |
| + (props, ref) => { | |
| + // Native select doesn't support separators - render nothing | |
| + return null | |
| + } | |
| +) | |
| +Separator.displayName = 'SeparatorSelect' | |
| + | |
| +const Overlay = React.forwardRef( | |
| + ({ children, style, ...props }, ref) => { | |
| + // Native select doesn't need overlay | |
| + return null | |
| + } | |
| +) | |
| +Overlay.displayName = 'OverlaySelect' | |
| + | |
| +// Export with the same names as RN-primitives | |
| +// Add Option type - this matches RN-primitives API | |
| +const Option = { label: '', value: '' } | |
| + | |
| +export { | |
| + Root, | |
| + Group, | |
| + Value, | |
| + Trigger, | |
| + Portal, | |
| + Content, | |
| + Viewport, | |
| + Item, | |
| + ItemText, | |
| + ItemIndicator, | |
| + ScrollUpButton, | |
| + ScrollDownButton, | |
| + Label, | |
| + Separator, | |
| + Overlay, | |
| + useRootContext, | |
| + Option | |
| +} | |
| Index: apps/mobile/.storybook/rn-primitives-shims/context-menu.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/context-menu.jsx b/apps/mobile/.storybook/rn-primitives-shims/context-menu.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973797182) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/context-menu.jsx (date 1759973797182) | |
| @@ -0,0 +1,25 @@ | |
| +// Web implementation for @rn-primitives/context-menu | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'ContextMenuRoot' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'ContextMenuTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'ContextMenuContent' | |
| + | |
| +const Item = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Item.displayName = 'ContextMenuItem' | |
| + | |
| +export { Root, Trigger, Content, Item } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/hover-card.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/hover-card.jsx b/apps/mobile/.storybook/rn-primitives-shims/hover-card.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973956604) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/hover-card.jsx (date 1759973956604) | |
| @@ -0,0 +1,20 @@ | |
| +// Web implementation for @rn-primitives/hover-card | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'HoverCardRoot' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'HoverCardTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'HoverCardContent' | |
| + | |
| +export { Root, Trigger, Content } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/toggle-group.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/toggle-group.jsx b/apps/mobile/.storybook/rn-primitives-shims/toggle-group.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973992772) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/toggle-group.jsx (date 1759973992772) | |
| @@ -0,0 +1,15 @@ | |
| +// Web implementation for @rn-primitives/toggle-group | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'ToggleGroupRoot' | |
| + | |
| +const Item = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Item.displayName = 'ToggleGroupItem' | |
| + | |
| +export { Root, Item } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/navigation-menu.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/navigation-menu.jsx b/apps/mobile/.storybook/rn-primitives-shims/navigation-menu.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973975570) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/navigation-menu.jsx (date 1759973975570) | |
| @@ -0,0 +1,35 @@ | |
| +// Web implementation for @rn-primitives/navigation-menu | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'NavigationMenuRoot' | |
| + | |
| +const List = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +List.displayName = 'NavigationMenuList' | |
| + | |
| +const Item = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Item.displayName = 'NavigationMenuItem' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'NavigationMenuTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'NavigationMenuContent' | |
| + | |
| +const Link = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Link.displayName = 'NavigationMenuLink' | |
| + | |
| +export { Root, List, Item, Trigger, Content, Link } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/label.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/label.jsx b/apps/mobile/.storybook/rn-primitives-shims/label.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973209662) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/label.jsx (date 1759973209662) | |
| @@ -0,0 +1,49 @@ | |
| +// Web implementation for @rn-primitives/label using Radix UI | |
| +import * as RadixLabel from '@radix-ui/react-label' | |
| +import React from 'react' | |
| +import { Text, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, asChild, onPress, onLongPress, onPressIn, onPressOut, disabled, ...props }, ref) => { | |
| + const Component = asChild ? 'label' : Pressable | |
| + | |
| + return React.createElement(RadixLabel.Root, { | |
| + asChild: true, | |
| + ...props | |
| + }, React.createElement(Component, { | |
| + ref, | |
| + onPress, | |
| + onLongPress, | |
| + onPressIn, | |
| + onPressOut, | |
| + disabled, | |
| + style: disabled ? { opacity: 0.5 } : undefined, | |
| + ...props | |
| + }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'RootLabel' | |
| + | |
| +const LabelText = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'span' : Text | |
| + return React.createElement(Component, { ref, ...props }, children) | |
| + } | |
| +) | |
| +LabelText.displayName = 'TextLabel' | |
| + | |
| +// Mock TypeScript types for compatibility | |
| +const TextProps = {} | |
| +const TextRef = {} | |
| +const RootProps = {} | |
| +const RootRef = {} | |
| + | |
| +// Export with the same names as RN-primitives | |
| +export { | |
| + Root, | |
| + LabelText as Text, | |
| + TextProps, | |
| + TextRef, | |
| + RootProps, | |
| + RootRef | |
| +} | |
| Index: apps/mobile/.storybook/rn-primitives-shims/popover.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/popover.jsx b/apps/mobile/.storybook/rn-primitives-shims/popover.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973984322) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/popover.jsx (date 1759973984322) | |
| @@ -0,0 +1,25 @@ | |
| +// Web implementation for @rn-primitives/popover | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Root.displayName = 'PopoverRoot' | |
| + | |
| +const Trigger = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Trigger.displayName = 'PopoverTrigger' | |
| + | |
| +const Content = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(View, { ref, ...props }, children) | |
| +}) | |
| +Content.displayName = 'PopoverContent' | |
| + | |
| +const Close = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Pressable, { ref, ...props }, children) | |
| +}) | |
| +Close.displayName = 'PopoverClose' | |
| + | |
| +export { Root, Trigger, Content, Close } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/portal.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/portal.jsx b/apps/mobile/.storybook/rn-primitives-shims/portal.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759979675631) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/portal.jsx (date 1759979675631) | |
| @@ -0,0 +1,16 @@ | |
| +// Web implementation for @rn-primitives/portal | |
| +import React from 'react' | |
| +import { Portal } from '@rn-primitives/portal' | |
| + | |
| +const PortalRoot = React.forwardRef(({ children, ...props }, ref) => { | |
| + return React.createElement(Portal.Root, { ref, ...props }, children) | |
| +}) | |
| +PortalRoot.displayName = 'PortalRoot' | |
| + | |
| +const PortalHost = React.forwardRef(({ children, ...props }, ref) => { | |
| + // PortalHost is mainly for React Native - on web, portals work differently | |
| + return React.createElement('div', { ref, ...props }, children) | |
| +}) | |
| +PortalHost.displayName = 'PortalHost' | |
| + | |
| +export { PortalRoot as Root, PortalHost, PortalRoot as Portal } | |
| Index: apps/mobile/.storybook/rn-primitives-shims/alert-dialog.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/alert-dialog.jsx b/apps/mobile/.storybook/rn-primitives-shims/alert-dialog.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973643006) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/alert-dialog.jsx (date 1759973643006) | |
| @@ -0,0 +1,114 @@ | |
| +// Web implementation for @rn-primitives/alert-dialog using @radix-ui/react-dialog | |
| +import * as Dialog from '@radix-ui/react-dialog' | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Root, { ...props }, children) | |
| + } | |
| +) | |
| +Root.displayName = 'AlertDialogRoot' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Dialog.Trigger, { | |
| + asChild: true, | |
| + ...props | |
| + }, React.createElement(Component, { ref }, children)) | |
| + } | |
| +) | |
| +Trigger.displayName = 'AlertDialogTrigger' | |
| + | |
| +const Portal = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Portal, { ...props }, children) | |
| + } | |
| +) | |
| +Portal.displayName = 'AlertDialogPortal' | |
| + | |
| +const Overlay = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Overlay, { | |
| + ref, | |
| + style: { | |
| + position: 'fixed', | |
| + inset: 0, | |
| + backgroundColor: 'rgba(0, 0, 0, 0.5)', | |
| + zIndex: 50, | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Overlay.displayName = 'AlertDialogOverlay' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Content, { | |
| + ref, | |
| + style: { | |
| + position: 'fixed', | |
| + left: '50%', | |
| + top: '50%', | |
| + transform: 'translate(-50%, -50%)', | |
| + backgroundColor: 'white', | |
| + borderRadius: '8px', | |
| + padding: '24px', | |
| + boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)', | |
| + zIndex: 50, | |
| + maxWidth: '32rem', | |
| + width: '90vw', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Content.displayName = 'AlertDialogContent' | |
| + | |
| +const Title = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Title, { ref, ...props }, children) | |
| + } | |
| +) | |
| +Title.displayName = 'AlertDialogTitle' | |
| + | |
| +const Description = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Description, { ref, ...props }, children) | |
| + } | |
| +) | |
| +Description.displayName = 'AlertDialogDescription' | |
| + | |
| +const Action = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Component, { ref, ...props }, children) | |
| + } | |
| +) | |
| +Action.displayName = 'AlertDialogAction' | |
| + | |
| +const Cancel = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Dialog.Close, { | |
| + asChild: true | |
| + }, React.createElement(Component, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Cancel.displayName = 'AlertDialogCancel' | |
| + | |
| +export { | |
| + Root, | |
| + Trigger, | |
| + Portal, | |
| + Overlay, | |
| + Content, | |
| + Title, | |
| + Description, | |
| + Action, | |
| + Cancel | |
| +} | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/checkbox.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/checkbox.jsx b/apps/mobile/.storybook/rn-primitives-shims/checkbox.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973662078) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/checkbox.jsx (date 1759973662078) | |
| @@ -0,0 +1,61 @@ | |
| +// Web implementation for @rn-primitives/checkbox using @radix-ui/react-checkbox | |
| +import * as Checkbox from '@radix-ui/react-checkbox' | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, asChild, checked, onCheckedChange, disabled, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + | |
| + return React.createElement(Checkbox.Root, { | |
| + checked, | |
| + onCheckedChange, | |
| + disabled, | |
| + asChild: true, | |
| + ...props | |
| + }, React.createElement(Component, { | |
| + ref, | |
| + style: { | |
| + display: 'flex', | |
| + alignItems: 'center', | |
| + justifyContent: 'center', | |
| + width: 16, | |
| + height: 16, | |
| + borderRadius: 4, | |
| + border: '2px solid #6366f1', | |
| + backgroundColor: checked ? '#6366f1' : 'transparent', | |
| + cursor: disabled ? 'not-allowed' : 'pointer', | |
| + opacity: disabled ? 0.5 : 1, | |
| + ...props.style | |
| + }, | |
| + disabled, | |
| + ...props | |
| + }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'CheckboxRoot' | |
| + | |
| +const Indicator = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'div' : View | |
| + | |
| + return React.createElement(Checkbox.Indicator, { | |
| + asChild: true | |
| + }, React.createElement(Component, { | |
| + ref, | |
| + style: { | |
| + color: 'white', | |
| + fontSize: '12px', | |
| + fontWeight: 'bold', | |
| + display: 'flex', | |
| + alignItems: 'center', | |
| + justifyContent: 'center', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children || '✓')) | |
| + } | |
| +) | |
| +Indicator.displayName = 'CheckboxIndicator' | |
| + | |
| +export { Root, Indicator } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/accordion.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/accordion.jsx b/apps/mobile/.storybook/rn-primitives-shims/accordion.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973619454) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/accordion.jsx (date 1759973619454) | |
| @@ -0,0 +1,73 @@ | |
| +// Web implementation for @rn-primitives/accordion using native HTML details/summary | |
| +import React from 'react' | |
| +import { View, Text, Pressable } from 'react-native' | |
| + | |
| +const AccordionContext = React.createContext(null) | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, type = 'single', collapsible = true, ...props }, ref) => { | |
| + const [openItems, setOpenItems] = React.useState(new Set()) | |
| + | |
| + const toggleItem = (value) => { | |
| + setOpenItems(prev => { | |
| + const newSet = new Set(prev) | |
| + if (type === 'single') { | |
| + newSet.clear() | |
| + if (!prev.has(value)) { | |
| + newSet.add(value) | |
| + } | |
| + } else { | |
| + if (newSet.has(value)) { | |
| + newSet.delete(value) | |
| + } else { | |
| + newSet.add(value) | |
| + } | |
| + } | |
| + return newSet | |
| + }) | |
| + } | |
| + | |
| + return React.createElement(AccordionContext.Provider, { | |
| + value: { openItems, toggleItem, type, collapsible } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'AccordionRoot' | |
| + | |
| +const Item = React.forwardRef( | |
| + ({ children, value, ...props }, ref) => { | |
| + return React.createElement(View, { | |
| + ref, | |
| + 'data-value': value, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Item.displayName = 'AccordionItem' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + const { toggleItem } = React.useContext(AccordionContext) | |
| + const value = props.value || 'default' | |
| + | |
| + return React.createElement(Pressable, { | |
| + ref, | |
| + onPress: () => toggleItem(value), | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Trigger.displayName = 'AccordionTrigger' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + const { openItems } = React.useContext(AccordionContext) | |
| + const value = props.value || 'default' | |
| + const isOpen = openItems.has(value) | |
| + | |
| + return isOpen ? React.createElement(View, { ref, ...props }, children) : null | |
| + } | |
| +) | |
| +Content.displayName = 'AccordionContent' | |
| + | |
| +export { Root, Item, Trigger, Content } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/tooltip.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/tooltip.jsx b/apps/mobile/.storybook/rn-primitives-shims/tooltip.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973715629) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/tooltip.jsx (date 1759973715629) | |
| @@ -0,0 +1,74 @@ | |
| +// Web implementation for @rn-primitives/tooltip using @radix-ui/react-tooltip | |
| +import * as Tooltip from '@radix-ui/react-tooltip' | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Provider = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Tooltip.Provider, { ...props }, children) | |
| + } | |
| +) | |
| +Provider.displayName = 'TooltipProvider' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Tooltip.Root, { ...props }, children) | |
| + } | |
| +) | |
| +Root.displayName = 'TooltipRoot' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Tooltip.Trigger, { | |
| + asChild: true, | |
| + ...props | |
| + }, React.createElement(Component, { ref }, children)) | |
| + } | |
| +) | |
| +Trigger.displayName = 'TooltipTrigger' | |
| + | |
| +const Portal = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Tooltip.Portal, { ...props }, children) | |
| + } | |
| +) | |
| +Portal.displayName = 'TooltipPortal' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Tooltip.Content, { | |
| + ref, | |
| + style: { | |
| + backgroundColor: '#1f2937', | |
| + color: 'white', | |
| + borderRadius: '6px', | |
| + padding: '8px 12px', | |
| + fontSize: '14px', | |
| + lineHeight: '1', | |
| + boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)', | |
| + zIndex: 50, | |
| + ...props.style | |
| + }, | |
| + sideOffset: 4, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Content.displayName = 'TooltipContent' | |
| + | |
| +const Arrow = React.forwardRef( | |
| + ({ ...props }, ref) => { | |
| + return React.createElement(Tooltip.Arrow, { | |
| + ref, | |
| + style: { | |
| + fill: '#1f2937', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }) | |
| + } | |
| +) | |
| +Arrow.displayName = 'TooltipArrow' | |
| + | |
| +export { Provider, Root, Trigger, Portal, Content, Arrow } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/switch.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/switch.jsx b/apps/mobile/.storybook/rn-primitives-shims/switch.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973703045) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/switch.jsx (date 1759973703045) | |
| @@ -0,0 +1,55 @@ | |
| +// Web implementation for @rn-primitives/switch | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, checked, onCheckedChange, disabled, ...props }, ref) => { | |
| + const handlePress = () => { | |
| + if (!disabled && onCheckedChange) { | |
| + onCheckedChange(!checked) | |
| + } | |
| + } | |
| + | |
| + return React.createElement(Pressable, { | |
| + ref, | |
| + onPress: handlePress, | |
| + disabled, | |
| + style: { | |
| + width: 44, | |
| + height: 24, | |
| + borderRadius: 12, | |
| + backgroundColor: checked ? '#6366f1' : '#d1d5db', | |
| + justifyContent: 'center', | |
| + alignItems: checked ? 'flex-end' : 'flex-start', | |
| + paddingHorizontal: 2, | |
| + opacity: disabled ? 0.5 : 1, | |
| + cursor: disabled ? 'not-allowed' : 'pointer', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, React.createElement(View, { | |
| + style: { | |
| + width: 20, | |
| + height: 20, | |
| + borderRadius: 10, | |
| + backgroundColor: 'white', | |
| + shadowColor: '#000', | |
| + shadowOffset: { width: 0, height: 1 }, | |
| + shadowOpacity: 0.2, | |
| + shadowRadius: 2, | |
| + elevation: 2 | |
| + } | |
| + })) | |
| + } | |
| +) | |
| +Root.displayName = 'SwitchRoot' | |
| + | |
| +const Thumb = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + // The thumb is handled by the Root component styling | |
| + return null | |
| + } | |
| +) | |
| +Thumb.displayName = 'SwitchThumb' | |
| + | |
| +export { Root, Thumb } | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/dialog.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/dialog.jsx b/apps/mobile/.storybook/rn-primitives-shims/dialog.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973677608) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/dialog.jsx (date 1759973677608) | |
| @@ -0,0 +1,107 @@ | |
| +// Web implementation for @rn-primitives/dialog using @radix-ui/react-dialog | |
| +import * as Dialog from '@radix-ui/react-dialog' | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Root, { ...props }, children) | |
| + } | |
| +) | |
| +Root.displayName = 'DialogRoot' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Dialog.Trigger, { | |
| + asChild: true, | |
| + ...props | |
| + }, React.createElement(Component, { ref }, children)) | |
| + } | |
| +) | |
| +Trigger.displayName = 'DialogTrigger' | |
| + | |
| +const Portal = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Portal, { ...props }, children) | |
| + } | |
| +) | |
| +Portal.displayName = 'DialogPortal' | |
| + | |
| +const Overlay = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Overlay, { | |
| + ref, | |
| + style: { | |
| + position: 'fixed', | |
| + inset: 0, | |
| + backgroundColor: 'rgba(0, 0, 0, 0.5)', | |
| + zIndex: 50, | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Overlay.displayName = 'DialogOverlay' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Content, { | |
| + ref, | |
| + style: { | |
| + position: 'fixed', | |
| + left: '50%', | |
| + top: '50%', | |
| + transform: 'translate(-50%, -50%)', | |
| + backgroundColor: 'white', | |
| + borderRadius: '8px', | |
| + padding: '24px', | |
| + boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)', | |
| + zIndex: 50, | |
| + maxWidth: '32rem', | |
| + width: '90vw', | |
| + maxHeight: '85vh', | |
| + overflowY: 'auto', | |
| + ...props.style | |
| + }, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Content.displayName = 'DialogContent' | |
| + | |
| +const Title = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Title, { ref, ...props }, children) | |
| + } | |
| +) | |
| +Title.displayName = 'DialogTitle' | |
| + | |
| +const Description = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + return React.createElement(Dialog.Description, { ref, ...props }, children) | |
| + } | |
| +) | |
| +Description.displayName = 'DialogDescription' | |
| + | |
| +const Close = React.forwardRef( | |
| + ({ children, asChild, ...props }, ref) => { | |
| + const Component = asChild ? 'button' : Pressable | |
| + return React.createElement(Dialog.Close, { | |
| + asChild: true | |
| + }, React.createElement(Component, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Close.displayName = 'DialogClose' | |
| + | |
| +export { | |
| + Root, | |
| + Trigger, | |
| + Portal, | |
| + Overlay, | |
| + Content, | |
| + Title, | |
| + Description, | |
| + Close | |
| +} | |
| \ No newline at end of file | |
| Index: apps/mobile/.storybook/rn-primitives-shims/collapsible.jsx | |
| IDEA additional info: | |
| Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
| <+>UTF-8 | |
| =================================================================== | |
| diff --git a/apps/mobile/.storybook/rn-primitives-shims/collapsible.jsx b/apps/mobile/.storybook/rn-primitives-shims/collapsible.jsx | |
| new file mode 100644 | |
| --- /dev/null (date 1759973690962) | |
| +++ b/apps/mobile/.storybook/rn-primitives-shims/collapsible.jsx (date 1759973690962) | |
| @@ -0,0 +1,52 @@ | |
| +// Web implementation for @rn-primitives/collapsible | |
| +import React from 'react' | |
| +import { View, Pressable } from 'react-native' | |
| + | |
| +const CollapsibleContext = React.createContext(null) | |
| + | |
| +const Root = React.forwardRef( | |
| + ({ children, open, onOpenChange, defaultOpen = false, ...props }, ref) => { | |
| + const [isOpen, setIsOpen] = React.useState(open !== undefined ? open : defaultOpen) | |
| + | |
| + React.useEffect(() => { | |
| + if (open !== undefined) { | |
| + setIsOpen(open) | |
| + } | |
| + }, [open]) | |
| + | |
| + const toggleOpen = React.useCallback(() => { | |
| + const newOpen = !isOpen | |
| + setIsOpen(newOpen) | |
| + onOpenChange?.(newOpen) | |
| + }, [isOpen, onOpenChange]) | |
| + | |
| + return React.createElement(CollapsibleContext.Provider, { | |
| + value: { isOpen, toggleOpen } | |
| + }, React.createElement(View, { ref, ...props }, children)) | |
| + } | |
| +) | |
| +Root.displayName = 'CollapsibleRoot' | |
| + | |
| +const Trigger = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + const { toggleOpen } = React.useContext(CollapsibleContext) | |
| + | |
| + return React.createElement(Pressable, { | |
| + ref, | |
| + onPress: toggleOpen, | |
| + ...props | |
| + }, children) | |
| + } | |
| +) | |
| +Trigger.displayName = 'CollapsibleTrigger' | |
| + | |
| +const Content = React.forwardRef( | |
| + ({ children, ...props }, ref) => { | |
| + const { isOpen } = React.useContext(CollapsibleContext) | |
| + | |
| + return isOpen ? React.createElement(View, { ref, ...props }, children) : null | |
| + } | |
| +) | |
| +Content.displayName = 'CollapsibleContent' | |
| + | |
| +export { Root, Trigger, Content } | |
| \ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment