{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-internal-utils-animation", "type": "registry:lib", "title": "Animation", "description": "Animation from @pitsi-ui/native for native projects.", "dependencies": [ "react-native-reanimated@^4.1.1" ], "registryDependencies": [], "files": [ { "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:lib", "target": "@components/pitsi-ui/native-ui/src/helpers/internal/types/animation.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" } ], "categories": [ "native", "react-native", "internal-lib" ], "meta": { "package": "@pitsi-ui/native", "packageSlug": "native-ui", "platform": "native" } }