{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-internal-hook-use-combined-animation-disabled-state", "type": "registry:hook", "title": "Use Combined Animation Disabled State", "description": "Use Combined Animation Disabled State from @pitsi-ui/native for native projects.", "dependencies": [ "@gorhom/bottom-sheet@^5.2.8", "react-native-reanimated@^4.1.1", "tailwind-variants@^3.2.2" ], "registryDependencies": [], "files": [ { "path": "registry/native-ui/src/helpers/internal/contexts/animation-settings-context.ts", "content": "import { createContext } from \"../utils\";\n\n/**\n * Context value for global animation settings\n */\nexport interface AnimationSettingsContextValue {\n /**\n * Whether all animations should be disabled (cascading from parent)\n */\n isAllAnimationsDisabled: boolean;\n}\n\nconst [AnimationSettingsProvider, useAnimationSettings] =\n createContext({\n name: \"AnimationSettingsContext\",\n strict: false,\n });\n\nexport { AnimationSettingsProvider, useAnimationSettings };\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/contexts/animation-settings-context.ts" }, { "path": "registry/native-ui/src/helpers/internal/hooks/use-combined-animation-disabled-state.ts", "content": "import { useGlobalAnimationSettings } from \"../../../providers/animation-settings\";\nimport { useAnimationSettings } from \"../contexts/animation-settings-context\";\nimport type { AnimationRoot } from \"../types/animation\";\nimport { getCombinedAnimationDisabledState, getRootAnimationState } from \"../utils/animation\";\n\n/**\n * Hook to combine global, parent, and own animation disabled states\n *\n * @description\n * This hook combines three sources of animation disabled state:\n * 1. Global state from GlobalAnimationSettingsProvider\n * 2. Parent state from AnimationSettingsContext (component tree cascading)\n * 3. Own state from the component's animation prop\n *\n * Priority: Global > Parent > Own (global wins if enabled)\n *\n * @param animation - Root animation configuration for the component\n * @returns Combined isAllAnimationsDisabled value\n *\n * @example\n * ```tsx\n * const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n * ```\n */\nexport function useCombinedAnimationDisabledState>(\n animation: AnimationRoot | undefined,\n): boolean {\n // Get global animation disabled state\n const { globalIsAllAnimationsDisabled } = useGlobalAnimationSettings();\n\n // Read parent animation disabled state from global context\n const parentAnimationSettingsContext = useAnimationSettings();\n const parentIsAllAnimationsDisabled = parentAnimationSettingsContext?.isAllAnimationsDisabled;\n\n // Get own animation disabled state\n const { isAllAnimationsDisabled: ownIsAllAnimationsDisabled } = getRootAnimationState(animation);\n\n // Combine global, parent, and own disable-all states (global > parent > own)\n return getCombinedAnimationDisabledState({\n globalIsAllAnimationsDisabled,\n parentIsAllAnimationsDisabled,\n ownIsAllAnimationsDisabled,\n });\n}\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/hooks/use-combined-animation-disabled-state.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/animation.ts", "content": "import type {\n BaseAnimationBuilder,\n EntryOrExitLayoutType,\n LayoutAnimationFunction,\n WithSpringConfig,\n WithTimingConfig,\n} from \"react-native-reanimated\";\n\n/**\n * Universal animation prop type\n * - `true` or `undefined`: Use default animations\n * - `false` or `\"disabled\"`: Disable all animations\n * - `object`: Custom animation configuration\n * - Can include `state?: 'disabled' | boolean | undefined` to disable animations while customizing properties\n */\nexport type Animation = Record> =\n | boolean\n | \"disabled\"\n | (TConfig & { state?: \"disabled\" | boolean });\n\nexport type AnimationDisabled = \"disabled\" | false;\n\n/**\n * Root-level animation prop type with cascading control\n * - `true` or `undefined`: Use default animations\n * - `false` or `\"disabled\"`: Disable only root animations (children can still animate)\n * - `\"disable-all\"`: Disable all animations including children (cascades down)\n * - `object`: Custom animation configuration\n * - Can include `state?: 'disabled' | 'disable-all' | boolean` to disable animations while customizing properties\n */\nexport type AnimationRoot = Record> =\n | boolean\n | \"disabled\"\n | \"disable-all\"\n | (TConfig & { state?: \"disabled\" | \"disable-all\" | boolean });\n\nexport type AnimationRootDisableAll = Extract;\n\n/**\n * Animation value that can be a custom config\n * Used for granular animation control within a component\n */\nexport type AnimationValue = Record> = TConfig;\n\nexport type LayoutTransition =\n | BaseAnimationBuilder\n | LayoutAnimationFunction\n | typeof BaseAnimationBuilder\n | undefined;\n\n/**\n * Spring animation configuration\n */\nexport interface SpringAnimationConfig {\n type: \"spring\";\n config?: WithSpringConfig;\n}\n\n/**\n * Timing animation configuration\n */\nexport interface TimingAnimationConfig {\n type: \"timing\";\n config?: WithTimingConfig;\n}\n\n/**\n * Animation configuration for popup overlay components (Dialog, Select, BottomSheet, Popover, etc.)\n * Supports both progress-based opacity animation and entering/exiting animations\n */\nexport type PopupOverlayAnimation = Animation<{\n /**\n * Opacity animation configuration (progress-based)\n * Takes effect for bottom-sheet/dialog presentation\n * @default [0, 1, 0] - opacity values for [idle, open, close] states\n */\n opacity?: AnimationValue<{\n /**\n * Opacity values [idle, open, close]\n * @default [0, 1, 0]\n */\n value?: [number, number, number];\n }>;\n /**\n * Takes effect for popover presentation\n * @default FadeIn with duration 200ms\n */\n entering?: EntryOrExitLayoutType;\n /**\n * Takes effect for popover presentation\n * @default FadeOut with duration 150ms\n */\n exiting?: EntryOrExitLayoutType;\n}>;\n\n/**\n * Animation configuration for popup dialog content components (Dialog, Select dialog presentation)\n * Supports opacity and scale animations\n */\nexport type PopupDialogContentAnimation = Animation<{\n /**\n * Custom Keyframe animation for entering transition\n * @default Keyframe with scale, and opacity (200ms)\n */\n entering?: EntryOrExitLayoutType;\n /**\n * Custom Keyframe animation for exiting transition\n * @default Keyframe mirroring entering animation (150ms)\n */\n exiting?: EntryOrExitLayoutType;\n}>;\n\n/**\n * Animation configuration for popup popover content components (Popover, Select popover presentation)\n * Supports custom Keyframe animations for entering and exiting transitions\n */\nexport type PopupPopoverContentAnimation = Animation<{\n /**\n * Custom Keyframe animation for entering transition\n * @default Keyframe with translateY/translateX, scale, and opacity (200ms)\n */\n entering?: EntryOrExitLayoutType;\n /**\n * Custom Keyframe animation for exiting transition\n * @default Keyframe mirroring entering animation (150ms)\n */\n exiting?: EntryOrExitLayoutType;\n}>;\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/animation.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/bottom-sheet.ts", "content": "import type { BottomSheetViewProps } from \"@gorhom/bottom-sheet/lib/typescript/components/bottomSheetView/types\";\nimport type { ReactNode } from \"react\";\nimport type { SharedValue } from \"react-native-reanimated\";\nimport type { AnimationDisabled } from \"./animation\";\n\n/**\n * State type for bottom sheet content container animation coordination\n */\nexport type BottomSheetContentContainerState = \"idle\" | \"open\" | \"close\";\n\n/**\n * Props for the reusable BottomSheetContentContainer component\n */\nexport interface BottomSheetContentContainerProps {\n /**\n * The content to be rendered inside the container\n */\n children?: ReactNode;\n /**\n * Additional CSS class for the content container\n */\n contentContainerClassName?: string;\n /**\n * Props for the content container\n */\n contentContainerProps?: Omit;\n /**\n * Whether the bottom sheet is open\n */\n isOpen: boolean;\n /**\n * Animation progress shared value (0=idle, 1=open, 2=close)\n */\n progress: SharedValue;\n /**\n * Whether the bottom sheet is dragging\n */\n isDragging: SharedValue;\n /**\n * Whether the bottom sheet is pan activated\n */\n isPanActivated: SharedValue;\n /**\n * Whether the bottom sheet is closing on swipe\n */\n isClosingOnSwipe: SharedValue;\n /**\n * Initial index of the bottom sheet\n */\n initialIndex: number;\n /**\n * Callback when the bottom sheet is opened\n */\n onOpenChange: (open: boolean) => void;\n /**\n * Whether the bottom sheet can be closed by panning down\n */\n enablePanDownToClose: boolean;\n}\n\n/**\n * Base props shared across BottomSheet Content components\n * Used by BottomSheet, Popover, and Select components when using bottom-sheet presentation\n */\nexport interface BaseBottomSheetContentProps {\n /**\n * The bottom sheet content\n */\n children?: ReactNode;\n /**\n * Additional CSS class for the bottom sheet\n */\n className?: string;\n /**\n * Additional CSS class for the container\n */\n containerClassName?: string;\n /**\n * Additional CSS class for the content container\n */\n contentContainerClassName?: string;\n /**\n * Additional CSS class for the background\n */\n backgroundClassName?: string;\n /**\n * Additional CSS class for the handle\n */\n handleClassName?: string;\n /**\n * Additional CSS class for the handle indicator\n */\n handleIndicatorClassName?: string;\n /**\n * Props for the content container\n */\n contentContainerProps?: Omit;\n /**\n * Animation configuration for bottom sheet content\n * - `false` or `\"disabled\"`: Disable all animations\n */\n animation?: AnimationDisabled;\n}\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/bottom-sheet.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/index.ts", "content": "export * from \"./animation\";\nexport * from \"./bottom-sheet\";\nexport * from \"./misc\";\nexport * from \"./primitives\";\nexport * from \"./theme\";\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/index.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/misc.ts", "content": "type ReactChild =\n | string\n | number\n | bigint\n | React.ReactElement>\n | Iterable\n | React.ReactPortal\n | Promise;\n\nexport type { ReactChild };\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/misc.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/primitives.ts", "content": "import type { Pressable, Text, View, ViewStyle } from \"react-native\";\n\n// Base utility types\n\n/**\n * Component props with optional asChild prop for polymorphic components\n * Allows components to render as different elements when asChild is true\n */\ntype ComponentPropsWithAsChild> =\n React.ComponentPropsWithoutRef & { asChild?: boolean };\n\n// Ref types\n\n/**\n * Reference type for React Native View component\n * Used for forwarding refs to View elements\n */\ntype ViewRef = React.ComponentRef;\n\n/**\n * Reference type for React Native Pressable component\n * Used for forwarding refs to Pressable elements\n */\ntype PressableRef = React.ComponentRef;\n\n/**\n * Reference type for React Native Text component\n * Used for forwarding refs to Text elements\n */\ntype TextRef = React.ComponentRef;\n\n// Slottable component props\n\n/**\n * View component props with asChild support for slot composition\n * Enables View components to be used with the Slot pattern\n */\ntype SlottableViewProps = ComponentPropsWithAsChild;\n\n/**\n * Pressable component props with asChild support for slot composition\n * Enables Pressable components to be used with the Slot pattern\n */\ntype SlottablePressableProps = ComponentPropsWithAsChild;\n\n/**\n * Text component props with asChild support for slot composition\n * Enables Text components to be used with the Slot pattern\n */\ntype SlottableTextProps = ComponentPropsWithAsChild;\n\n/**\n * Interface for components that can be force mounted even when normally hidden\n */\ninterface ForceMountable {\n /**\n * Whether to force mount the component in the DOM\n * Useful for animation purposes when component needs to be present but hidden\n */\n forceMount?: true | undefined;\n}\n\n/**\n * Interface for defining spacing/padding from screen edges\n */\ninterface Insets {\n /**\n * Distance from the top edge in pixels\n */\n top?: number;\n /**\n * Distance from the bottom edge in pixels\n */\n bottom?: number;\n /**\n * Distance from the left edge in pixels\n */\n left?: number;\n /**\n * Distance from the right edge in pixels\n */\n right?: number;\n}\n\n/**\n * Props for components that need to be positioned relative to a trigger element\n * Certain props are only available on the native version of the component.\n * @docs For the web version, see the Radix documentation https://www.radix-ui.com/primitives\n */\ninterface PositionedContentProps {\n /**\n * Whether to force mount the component in the DOM\n */\n forceMount?: true | undefined;\n /**\n * Custom styles to apply to the positioned content\n */\n style?: ViewStyle;\n /**\n * Offset along the alignment axis in pixels\n */\n alignOffset?: number;\n /**\n * Screen edge insets to respect when positioning\n */\n insets?: Insets;\n /**\n * Whether to automatically adjust position to avoid screen edges\n * @default true\n */\n avoidCollisions?: boolean;\n /**\n * Alignment relative to the trigger element\n * @default 'start'\n */\n align?: \"start\" | \"center\" | \"end\";\n /**\n * Preferred placement of the trigger element to position against\n * @default 'bottom'\n */\n placement?: \"top\" | \"bottom\" | \"left\" | \"right\";\n /**\n * Offset from the trigger element in pixels\n * @default 0\n */\n offset?: number;\n /**\n * Whether to disable the automatic positioning styles\n * Useful when you want to handle positioning manually\n * @default false\n */\n disablePositioningStyle?: boolean;\n}\n\nexport type {\n ComponentPropsWithAsChild,\n ForceMountable,\n Insets,\n PositionedContentProps,\n PressableRef,\n SlottablePressableProps,\n SlottableTextProps,\n SlottableViewProps,\n TextRef,\n ViewRef,\n};\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/primitives.ts" }, { "path": "registry/native-ui/src/helpers/internal/types/theme.ts", "content": "import type { ClassValue } from \"tailwind-variants\";\n\n/**\n * This Typescript utility transform a list of slots into a list of {slot: classes}\n */\ntype ElementSlots = {\n [key in S]?: Exclude;\n};\n\n/**\n * Type helper that preserves the exact type of combined style objects\n * This ensures that VariantProps inference works correctly for each style\n */\ntype CombinedStyles> = {\n [K in keyof T]: T[K];\n};\n\nexport type { CombinedStyles, ElementSlots };\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/theme.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/animation.ts", "content": "import type { Animation, AnimationRoot, AnimationValue } from \"../types/animation\";\n\n/**\n * Check if the entire animation is disabled\n * @param animation - Animation configuration\n * @returns true if animation is disabled\n */\nexport function isAnimationDisabled>(\n animation: Animation | AnimationRoot | undefined,\n): boolean {\n // Check top-level disabled values\n if (animation === false || animation === \"disabled\") {\n return true;\n }\n\n // Check state property in config objects\n if (typeof animation === \"object\" && animation !== null && \"state\" in animation) {\n const state = animation.state;\n return state === false || state === \"disabled\";\n }\n\n return false;\n}\n\n/**\n * Check if root animation should cascade disable to all children\n * @param animation - Root animation configuration\n * @returns true if all animations should be disabled (including children)\n */\nexport function shouldDisableAll>(\n animation: AnimationRoot | undefined,\n): boolean {\n // Check top-level disable-all value\n if (animation === \"disable-all\") {\n return true;\n }\n\n // Check state property in config objects\n if (typeof animation === \"object\" && animation !== null && \"state\" in animation) {\n const state = animation.state;\n return state === \"disable-all\";\n }\n\n return false;\n}\n\n/**\n * Get animation state including config and disabled status\n * @param animation - Animation configuration\n * @returns Object with animationConfig and isAnimationDisabled\n */\nexport function getAnimationState>(\n animation: Animation | undefined,\n): {\n animationConfig: TConfig | undefined;\n isAnimationDisabled: boolean;\n} {\n const isDisabled = isAnimationDisabled(animation);\n // Always extract config when it's an object, regardless of disabled state\n // This allows users to customize colors/properties even when animations are disabled\n const config =\n typeof animation === \"object\" && animation !== null ? (animation as TConfig) : undefined;\n\n return {\n animationConfig: config,\n isAnimationDisabled: isDisabled,\n };\n}\n\n/**\n * Get root animation state including config, disabled status, and cascade flag\n * @param animation - Root animation configuration\n * @returns Object with animationConfig, isAnimationDisabled, and isAllAnimationsDisabled\n */\nexport function getRootAnimationState>(\n animation: AnimationRoot | undefined,\n): {\n animationConfig: TConfig | undefined;\n isAnimationDisabled: boolean;\n isAllAnimationsDisabled: boolean;\n} {\n const shouldCascade = shouldDisableAll(animation);\n const isDisabled = isAnimationDisabled(animation) || shouldCascade;\n // Always extract config when it's an object, regardless of disabled state\n // This allows users to customize colors/properties even when animations are disabled\n const config =\n typeof animation === \"object\" && animation !== null ? (animation as TConfig) : undefined;\n\n return {\n animationConfig: config,\n isAnimationDisabled: isDisabled,\n isAllAnimationsDisabled: shouldCascade,\n };\n}\n\n/**\n * Get animation value property or return default\n * Extracts a property from the animation value config object\n *\n * @param options - Object containing animationValue, property, and defaultValue\n * @param options.animationValue - The animation value configuration\n * @param options.property - Property name to extract\n * @param options.defaultValue - Default value if property is not found\n * @returns The property value or default (never undefined)\n *\n * @example\n * const scaleValue = getAnimationValueProperty({\n * animationValue: animation?.scale,\n * property: 'value',\n * defaultValue: 0.95\n * });\n */\nexport function getAnimationValueProperty<\n TConfig extends Record,\n K extends keyof TConfig,\n D extends NonNullable,\n>(options: {\n animationValue: AnimationValue | undefined;\n property: K;\n defaultValue: D;\n}): NonNullable {\n // If animation value is undefined, return default\n if (options.animationValue === undefined) {\n return options.defaultValue;\n }\n\n // Return the property value if it exists, otherwise return default\n return (options.animationValue[options.property] ?? options.defaultValue) as NonNullable<\n TConfig[K]\n >;\n}\n\n/**\n * Get animation value merged config or return default\n * Merges the animation value config with defaults, useful when you need multiple properties\n *\n * @param options - Object containing animationValue, property, and defaultValue\n * @param options.animationValue - The animation value configuration\n * @param options.property - Property name to extract from the config\n * @param options.defaultValue - Default configuration object\n * @returns The merged config object or default\n *\n * @example\n * const scaleConfig = getAnimationValueMergedConfig({\n * animationValue: animation?.scale,\n * property: 'timingConfig',\n * defaultValue: { duration: 150 }\n * });\n */\nexport function getAnimationValueMergedConfig<\n TConfig extends Record,\n K extends keyof TConfig,\n>(options: {\n animationValue: AnimationValue | undefined;\n property: K;\n defaultValue: TConfig[K];\n}): TConfig[K] {\n // If animation value is undefined, return default\n if (options.animationValue === undefined) {\n return options.defaultValue;\n }\n\n const value = options.animationValue[options.property];\n\n // If the specific property value is undefined or not an object, return default\n if (value === undefined || typeof value !== \"object\") {\n return options.defaultValue;\n }\n\n // Merge with defaults to ensure all properties exist\n return { ...options.defaultValue, ...value };\n}\n\n/**\n * Determine if animations should be disabled based on disabled flags\n * Priority: isAllAnimationsDisabled > isAnimationDisabled\n *\n * @param options - Object containing isAnimationDisabled and isAllAnimationsDisabled\n * @param options.isAnimationDisabled - Whether animation is explicitly disabled\n * @param options.isAllAnimationsDisabled - Whether all animations should be disabled (cascading from root/global)\n * @returns true if animations should be disabled, false otherwise\n *\n * @example\n * const isDisabled = getIsAnimationDisabledValue({\n * isAnimationDisabled: false,\n * isAllAnimationsDisabled: true\n * });\n * // Returns: true (all animations disabled takes priority)\n */\nexport function getIsAnimationDisabledValue(options: {\n isAnimationDisabled: boolean;\n isAllAnimationsDisabled: boolean | undefined;\n}): boolean {\n const { isAnimationDisabled: isDisabled, isAllAnimationsDisabled } = options;\n\n // First priority: if all animations are disabled, return true\n if (isAllAnimationsDisabled === true) {\n return true;\n }\n\n // Second priority: if this animation is disabled, return true\n if (isDisabled) {\n return true;\n }\n\n // Default: animations are enabled\n return false;\n}\n\n/**\n * Combine global, parent, and own animation disabled states\n * Priority: Global > Parent > Own (global wins if enabled)\n *\n * @param options - Object containing globalIsAllAnimationsDisabled, parentIsAllAnimationsDisabled, and ownIsAllAnimationsDisabled\n * @param options.globalIsAllAnimationsDisabled - Whether global provider has disable-all (from GlobalAnimationSettingsProvider)\n * @param options.parentIsAllAnimationsDisabled - Whether parent context has disable-all (from AnimationSettingsContext)\n * @param options.ownIsAllAnimationsDisabled - Whether own animation prop has disable-all\n * @returns Combined isAllAnimationsDisabled value (global || parent || own)\n *\n * @example\n * const combined = getCombinedAnimationDisabledState({\n * globalIsAllAnimationsDisabled: true,\n * parentIsAllAnimationsDisabled: false,\n * ownIsAllAnimationsDisabled: false\n * });\n * // Returns: true (global wins)\n */\nexport function getCombinedAnimationDisabledState(options: {\n globalIsAllAnimationsDisabled?: boolean;\n parentIsAllAnimationsDisabled: boolean | undefined;\n ownIsAllAnimationsDisabled: boolean;\n}): boolean {\n const {\n globalIsAllAnimationsDisabled,\n parentIsAllAnimationsDisabled,\n ownIsAllAnimationsDisabled,\n } = options;\n\n // Global always wins if it has disable-all\n if (globalIsAllAnimationsDisabled === true) {\n return true;\n }\n\n // Parent wins if it has disable-all\n if (parentIsAllAnimationsDisabled === true) {\n return true;\n }\n\n // Otherwise use own value\n return ownIsAllAnimationsDisabled;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/animation.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/children-to-string.ts", "content": "import { Children, isValidElement, type ReactNode } from \"react\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\n/**\n * Recursively checks if children contain any React elements.\n * Used to determine if children can be stringified.\n *\n * @param children - React children to check\n * @returns True if children contain React elements, false otherwise\n */\nfunction hasReactElements(children: ReactNode): boolean {\n if (children == null || typeof children === \"boolean\") {\n return false;\n }\n\n if (isValidElement(children)) {\n return true;\n }\n\n if (Array.isArray(children)) {\n return children.some((child) => hasReactElements(child));\n }\n\n return false;\n}\n\n/**\n * Converts React children to a string representation.\n * Handles cases where children might be an array of mixed types (strings, numbers, variables).\n *\n * @param children - React children that might be string, number, array, or React elements\n * @returns A string representation of the children or null if not convertible\n */\nexport function childrenToString(children: ReactNode | SharedValue): string | null {\n // Handle null/undefined\n if (children == null) {\n return null;\n }\n\n // Handle string directly\n if (typeof children === \"string\") {\n return children;\n }\n\n // Handle number\n if (typeof children === \"number\") {\n return String(children);\n }\n\n // Handle boolean (usually we don't want to render true/false as text)\n if (typeof children === \"boolean\") {\n return null;\n }\n\n // Check if children is a React element - if so, cannot be stringified\n if (isValidElement(children)) {\n return null;\n }\n\n // Handle array of children (e.g., {someVar} text)\n if (Array.isArray(children)) {\n // Check if array contains any React elements - if so, cannot be stringified\n // This handles cases where conditional children create arrays with React elements\n if (hasReactElements(children)) {\n return null;\n }\n\n const stringified = children\n .map((child) => {\n // Recursively handle each child\n if (typeof child === \"string\" || typeof child === \"number\") {\n return String(child);\n }\n // Skip booleans, null, undefined\n if (child == null || typeof child === \"boolean\") {\n return \"\";\n }\n // Recursively process nested arrays (only if they don't contain React elements)\n if (Array.isArray(child)) {\n const nested = childrenToString(child);\n return nested ?? \"\";\n }\n return String(child);\n })\n .join(\"\");\n\n return stringified || null;\n }\n\n // Handle React fragments and other iterable children\n try {\n const childArray = Children.toArray(children as ReactNode);\n if (childArray.length > 0) {\n // Check if any children are React elements\n if (hasReactElements(childArray)) {\n return null;\n }\n return childrenToString(childArray);\n }\n } catch {\n // Not iterable or other error, return null\n }\n\n return null;\n}\n\n/**\n * Checks if React children can be converted to a string.\n *\n * @param children - React children to check\n * @returns True if children can be converted to string, false otherwise\n */\nexport function isStringifiableChildren(children: ReactNode): boolean {\n return childrenToString(children) !== null;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/children-to-string.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/combine-styles.ts", "content": "import type { CombinedStyles } from \"../types\";\n\n/**\n * Helper function to combine style objects with proper type inference\n * This preserves the exact types of each style object, including VariantProps\n * @example\n * const styles = combineStyles({\n * root,\n * item,\n * content\n * });\n */\nexport function combineStyles>(styles: T): CombinedStyles {\n return styles as CombinedStyles;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/combine-styles.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/create-context.ts", "content": "import * as React from \"react\";\n\nexport interface CreateContextOptions {\n /**\n * If `true`, React will throw if context is `null` or `undefined`\n * In some cases, you might want to support nested context, so you can set it to `false`\n */\n strict?: boolean;\n /**\n * Error message to throw if the context is `undefined`\n */\n errorMessage?: string;\n /**\n * The display name of the context\n */\n name?: string;\n}\n\nexport type CreateContextReturn = [React.Provider, () => T, React.Context];\n\n/**\n * Creates a named context, provider, and hook.\n *\n * @param options create context options\n */\nexport function createContext(options: CreateContextOptions = {}) {\n const {\n strict = true,\n errorMessage = \"useContext: `context` is undefined. Seems you forgot to wrap component within the Provider\",\n name,\n } = options;\n\n const Context = React.createContext(undefined);\n\n Context.displayName = name;\n\n function useContext() {\n const context = React.useContext(Context);\n\n if (!context && strict) {\n const error = new Error(errorMessage);\n\n error.name = \"ContextError\";\n (\n Error as ErrorConstructor & {\n captureStackTrace?: (\n targetObject: object,\n constructorOpt?: (...args: unknown[]) => unknown,\n ) => void;\n }\n ).captureStackTrace?.(error, useContext);\n throw error;\n }\n\n return context;\n }\n\n return [Context.Provider, useContext, Context] as CreateContextReturn;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/create-context.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/ease-gradient/create-interpolation.ts", "content": "/**\n * Easing gradient utilities for React Native\n *\n * Original source: https://github.com/phamfoo/react-native-easing-gradient\n * Author: @phamfoo\n * License: MIT\n *\n * This code has been adapted for use in PitsiUI Native with modifications\n * for TypeScript compatibility and integration with the animation system.\n */\n\nimport { Animated } from \"react-native\";\n\n// @ts-expect-error\nconst AnimatedInterpolation = Animated.Interpolation;\n\ntype ColorInterpolateFunction = (input: number) => string;\n\nfunction createInterpolation(config: Animated.InterpolationConfigType): ColorInterpolateFunction {\n if (AnimatedInterpolation.__createInterpolation) {\n return AnimatedInterpolation.__createInterpolation(config);\n }\n\n return (input) => {\n const interpolation = new AnimatedInterpolation({ __getValue: () => input }, config);\n\n return interpolation.__getValue();\n };\n}\n\nexport { createInterpolation };\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/ease-gradient/create-interpolation.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/ease-gradient/index.ts", "content": "/**\n * Easing gradient utilities for React Native\n *\n * Original source: https://github.com/phamfoo/react-native-easing-gradient\n * Author: @phamfoo\n * License: MIT\n *\n * This code has been adapted for use in PitsiUI Native with modifications\n * for TypeScript compatibility and integration with the animation system.\n */\n\nimport { Easing, type EasingFunction } from \"react-native\";\nimport { createInterpolation } from \"./create-interpolation\";\n\ninterface ColorStops {\n [location: number]: {\n color: string;\n easing?: EasingFunction;\n };\n}\n\ninterface GradientParams {\n colorStops: ColorStops;\n extraColorStopsPerTransition?: number;\n easing?: EasingFunction;\n}\n\nconst easeInOut = Easing.bezier(0.42, 0, 0.58, 1);\n\nfunction easeGradient({\n colorStops,\n easing = easeInOut,\n extraColorStopsPerTransition = 12,\n}: GradientParams): {\n colors: [string, string, ...string[]];\n locations: [number, number, ...number[]];\n} {\n const colors: string[] = [];\n const locations: number[] = [];\n\n const initialLocations = Object.keys(colorStops)\n .map((key) => Number(key))\n .sort();\n\n const totalColorStops = initialLocations.length;\n\n for (let currentStopIndex = 0; currentStopIndex < totalColorStops - 1; currentStopIndex++) {\n const startLocation = initialLocations[currentStopIndex];\n const endLocation = initialLocations[currentStopIndex + 1];\n\n if (startLocation === undefined || endLocation === undefined) {\n continue;\n }\n\n const startStop = colorStops[startLocation];\n const endStop = colorStops[endLocation];\n\n if (!startStop || !endStop) {\n continue;\n }\n\n const startColor = startStop.color;\n const endColor = endStop.color;\n const currentEasing = startStop.easing ?? easing;\n\n const colorScale = createInterpolation({\n inputRange: [0, 1],\n outputRange: [startColor, endColor],\n easing: currentEasing,\n });\n\n const currentTransitionLength = endLocation - startLocation;\n const stepSize = 1 / (extraColorStopsPerTransition + 1);\n\n for (let stepIndex = 0; stepIndex <= extraColorStopsPerTransition + 1; stepIndex++) {\n const progress = stepIndex * stepSize;\n const color = colorScale(progress);\n colors.push(color);\n locations.push(startLocation + currentTransitionLength * progress);\n }\n }\n\n return {\n colors: colors as [string, string, ...string[]],\n locations: locations as [number, number, ...number[]],\n };\n}\n\nexport { easeGradient };\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/ease-gradient/index.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/get-element-by-display-name.ts", "content": "import React from \"react\";\nimport type { ReactChild } from \"../types\";\n\nexport const getElementByDisplayName = (\n children: React.ReactNode,\n displayName: string,\n): ReactChild | undefined => {\n const element = React.Children.toArray(children).find(\n (child) => React.isValidElement(child) && (child.type as any)?.displayName === displayName,\n );\n\n return element;\n};\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/get-element-by-display-name.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/get-element-with-default.ts", "content": "import type React from \"react\";\nimport type { ReactChild } from \"../types\";\nimport { getElementByDisplayName } from \"./get-element-by-display-name\";\n\nexport const getElementWithDefault = (\n children: React.ReactNode,\n displayName: string,\n defaultElement: React.ReactElement,\n): ReactChild => {\n const element = getElementByDisplayName(children, displayName);\n\n if (!element) {\n return defaultElement;\n }\n\n return element;\n};\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/get-element-with-default.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/has-prop.ts", "content": "import type { ReactElement } from \"react\";\n\n/**\n * Checks if a React element has a specific prop defined\n * @param element - The React element to check\n * @param propName - The name of the prop to check for\n * @returns true if the element has the prop, false otherwise\n */\nexport function hasProp(element: ReactElement | null | undefined, propName: string): boolean {\n if (!element?.props || typeof element.props !== \"object\") {\n return false;\n }\n\n return propName in element.props;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/has-prop.ts" }, { "path": "registry/native-ui/src/helpers/internal/utils/index.ts", "content": "export * from \".//animation\";\nexport * from \"./children-to-string\";\nexport * from \"./combine-styles\";\nexport * from \"./create-context\";\nexport * from \"./ease-gradient\";\nexport * from \"./get-element-by-display-name\";\nexport * from \"./get-element-with-default\";\nexport * from \"./has-prop\";\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/utils/index.ts" }, { "path": "registry/native-ui/src/providers/animation-settings/index.ts", "content": "export {\n default as GlobalAnimationSettingsProvider,\n useGlobalAnimationSettings,\n} from \"./provider\";\nexport type {\n GlobalAnimationSettingsContextValue,\n GlobalAnimationSettingsProviderProps,\n} from \"./types\";\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/providers/animation-settings/index.ts" }, { "path": "registry/native-ui/src/providers/animation-settings/provider.tsx", "content": "import type React from \"react\";\nimport { useReducedMotion } from \"react-native-reanimated\";\nimport { createContext } from \"../../helpers/internal/utils\";\nimport type {\n GlobalAnimationSettingsContextValue,\n GlobalAnimationSettingsProviderProps,\n} from \"./types\";\n\nconst [GlobalAnimationSettingsProvider, useGlobalAnimationSettings] =\n createContext({\n name: \"GlobalAnimationSettingsContext\",\n strict: false,\n });\n\nexport { useGlobalAnimationSettings };\n\n/**\n * GlobalAnimationSettingsProvider Component\n *\n * @description\n * Provider component that controls global animation settings across the application.\n * When animation is set to 'disable-all', all animations will be disabled globally.\n * Additionally, if the user has enabled reduce motion in accessibility settings,\n * all animations will be disabled automatically.\n *\n * This provider wraps AnimationSettingsProvider to cascade the global setting\n * down through the component tree.\n *\n * @param {GlobalAnimationSettingsProviderProps} props - Provider props\n * @param {AnimationRootDisableAll} [props.animation] - Global animation setting\n * @param {ReactNode} props.children - Child components to wrap\n */\nexport const GlobalAnimationSettingsProviderComponent: React.FC<\n GlobalAnimationSettingsProviderProps\n> = ({ animation, children }) => {\n const reducedMotion = useReducedMotion();\n const globalIsAllAnimationsDisabled = animation === \"disable-all\" || reducedMotion;\n\n return (\n \n {children}\n \n );\n};\n\nexport default GlobalAnimationSettingsProviderComponent;\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/providers/animation-settings/provider.tsx" }, { "path": "registry/native-ui/src/providers/animation-settings/types.ts", "content": "import type { ReactNode } from \"react\";\nimport type { AnimationRootDisableAll } from \"../../helpers/internal/types/animation\";\n\n/**\n * Props for GlobalAnimationSettingsProvider component\n */\nexport interface GlobalAnimationSettingsProviderProps {\n /**\n * Global animation setting\n * When set to 'disable-all', all animations across the app will be disabled\n */\n animation?: AnimationRootDisableAll;\n /**\n * Child components to render within the provider\n */\n children: ReactNode;\n}\n\n/**\n * Context value for global animation settings\n */\nexport interface GlobalAnimationSettingsContextValue {\n /**\n * Whether all animations should be disabled globally\n */\n globalIsAllAnimationsDisabled: boolean;\n}\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/providers/animation-settings/types.ts" } ], "categories": [ "native", "react-native", "internal-hooks" ], "meta": { "package": "@pitsi-ui/native", "packageSlug": "native-ui", "platform": "native" } }