{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-ui", "type": "registry:item", "title": "Pitsi UI Native", "description": "React Native components, primitives, providers, helpers, and native UI utilities from @pitsi-ui/native.", "dependencies": [ "@expo/ui", "@gorhom/bottom-sheet@^5.2.8", "react-native-gesture-handler@^2.28.0", "react-native-reanimated@^4.1.1", "react-native-safe-area-context@^5.6.0", "react-native-screens", "react-native-svg@^15.12.1", "react-native-worklets", "tailwind-variants@^3.2.2", "uniwind" ], "registryDependencies": [], "files": [ { "path": "registry/native-ui/src/_hooks/index.ts", "content": "import * as React from \"react\";\nimport { useColorScheme } from \"react-native\";\n\ntype Key = number | string;\ntype Selection = \"all\" | Set;\n\nexport interface ListOptions {\n filter?: (item: T, filterText: string) => boolean;\n getKey?: (item: T) => Key;\n initialFilterText?: string;\n initialItems?: T[];\n initialSelectedKeys?: \"all\" | Iterable;\n}\n\nexport interface ListData {\n addKeysToSelection(keys: Selection): void;\n append(...values: T[]): void;\n filterText: string;\n getItem(key: Key): T | undefined;\n insert(index: number, ...values: T[]): void;\n insertAfter(key: Key, ...values: T[]): void;\n insertBefore(key: Key, ...values: T[]): void;\n items: T[];\n move(key: Key, toIndex: number): void;\n prepend(...values: T[]): void;\n remove(...keys: Key[]): void;\n removeKeysFromSelection(keys: Selection): void;\n removeSelectedItems(): void;\n selectedKeys: Selection;\n setFilterText(filterText: string): void;\n setSelectedKeys(keys: Selection): void;\n}\n\nexport interface ListState {\n filterText: string;\n items: T[];\n selectedKeys: Selection;\n}\n\nexport interface UseOverlayStateProps {\n defaultOpen?: boolean;\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n}\n\nexport interface UseOverlayStateReturn {\n close(): void;\n readonly isOpen: boolean;\n open(): void;\n setOpen(isOpen: boolean): void;\n toggle(): void;\n}\n\nexport type Theme = string;\n\nfunction iterableToSelection(value?: \"all\" | Iterable): Selection {\n if (value === \"all\") {\n return \"all\";\n }\n\n return new Set(value ?? []);\n}\n\nfunction selectionToSet(value: Selection): Set {\n return value === \"all\" ? new Set() : new Set(value);\n}\n\nfunction resolveKey(item: T, index: number, getKey?: (item: T) => Key): Key {\n if (getKey) {\n return getKey(item);\n }\n\n if (typeof item === \"object\" && item !== null && \"id\" in item) {\n const id = (item as { id?: unknown }).id;\n\n if (typeof id === \"string\" || typeof id === \"number\") {\n return id;\n }\n }\n\n return index;\n}\n\nexport function createListActions(_options?: { getKey?: (item: T) => Key }, _setState?: C) {\n return {};\n}\n\nexport function useCSSVariable(\n _variableName: string,\n override?: string,\n _cache = true,\n): string | undefined {\n return override;\n}\n\nexport function useIsHydrated() {\n return true;\n}\n\nexport const useIsomorphicLayoutEffect = React.useLayoutEffect;\nexport const useSafeLayoutEffect = React.useLayoutEffect;\n\nexport function useMeasuredHeight(_ref: React.RefObject) {\n return { height: undefined as number | undefined };\n}\n\nexport function useMediaQuery(\n _query: string,\n options: { defaultValue?: boolean; initializeWithValue?: boolean } = {},\n): boolean {\n return options.defaultValue ?? false;\n}\n\nexport function useIsMounted(): () => boolean {\n const isMounted = React.useRef(false);\n\n React.useEffect(() => {\n isMounted.current = true;\n\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return React.useCallback(() => isMounted.current, []);\n}\n\nexport function useOverlayState(props: UseOverlayStateProps = {}): UseOverlayStateReturn {\n const { defaultOpen = false, isOpen: controlledIsOpen, onOpenChange } = props;\n const [uncontrolledIsOpen, setUncontrolledIsOpen] = React.useState(defaultOpen);\n const isControlled = controlledIsOpen !== undefined;\n const isOpen = controlledIsOpen ?? uncontrolledIsOpen;\n\n const setOpen = React.useCallback(\n (nextOpen: boolean) => {\n onOpenChange?.(nextOpen);\n\n if (!isControlled) {\n setUncontrolledIsOpen(nextOpen);\n }\n },\n [isControlled, onOpenChange],\n );\n\n const open = React.useCallback(() => setOpen(true), [setOpen]);\n const close = React.useCallback(() => setOpen(false), [setOpen]);\n const toggle = React.useCallback(() => setOpen(!isOpen), [isOpen, setOpen]);\n\n return { close, isOpen, open, setOpen, toggle };\n}\n\nexport function useTheme(defaultTheme: Theme = \"system\") {\n const colorScheme = useColorScheme();\n const [theme, setTheme] = React.useState(() =>\n defaultTheme === \"system\" ? (colorScheme ?? \"light\") : defaultTheme,\n );\n\n React.useEffect(() => {\n if (defaultTheme === \"system\") {\n setTheme(colorScheme ?? \"light\");\n }\n }, [colorScheme, defaultTheme]);\n\n return { setTheme, theme };\n}\n\nexport function useListData(options: ListOptions = {}): ListData {\n const { filter, getKey, initialFilterText = \"\", initialItems = [] } = options;\n const [rawItems, setRawItems] = React.useState(initialItems);\n const [selectedKeys, setSelectedKeys] = React.useState(() =>\n iterableToSelection(options.initialSelectedKeys),\n );\n const [filterText, setFilterText] = React.useState(initialFilterText);\n\n const items = React.useMemo(\n () => (filter ? rawItems.filter((item) => filter(item, filterText)) : rawItems),\n [filter, filterText, rawItems],\n );\n\n const getItem = React.useCallback(\n (key: Key) => rawItems.find((item, index) => resolveKey(item, index, getKey) === key),\n [getKey, rawItems],\n );\n\n const insert = React.useCallback((index: number, ...values: T[]) => {\n setRawItems((current) => [\n ...current.slice(0, Math.max(0, index)),\n ...values,\n ...current.slice(Math.max(0, index)),\n ]);\n }, []);\n\n const remove = React.useCallback(\n (...keys: Key[]) => {\n const removals = new Set(keys);\n setRawItems((current) =>\n current.filter((item, index) => !removals.has(resolveKey(item, index, getKey))),\n );\n },\n [getKey],\n );\n\n const addKeysToSelection = React.useCallback((keys: Selection) => {\n setSelectedKeys((current) => {\n if (current === \"all\" || keys === \"all\") {\n return \"all\";\n }\n\n return new Set([...current, ...keys]);\n });\n }, []);\n\n const removeKeysFromSelection = React.useCallback((keys: Selection) => {\n setSelectedKeys((current) => {\n if (current === \"all\") {\n return keys === \"all\" ? new Set() : current;\n }\n\n if (keys === \"all\") {\n return new Set();\n }\n\n const next = selectionToSet(current);\n\n for (const key of keys) {\n next.delete(key);\n }\n\n return next;\n });\n }, []);\n\n return {\n addKeysToSelection,\n append: (...values) => setRawItems((current) => [...current, ...values]),\n filterText,\n getItem,\n insert,\n insertAfter: (key, ...values) => {\n const index = rawItems.findIndex(\n (item, itemIndex) => resolveKey(item, itemIndex, getKey) === key,\n );\n insert(index < 0 ? rawItems.length : index + 1, ...values);\n },\n insertBefore: (key, ...values) => {\n const index = rawItems.findIndex(\n (item, itemIndex) => resolveKey(item, itemIndex, getKey) === key,\n );\n insert(index < 0 ? 0 : index, ...values);\n },\n items,\n move: (key, toIndex) => {\n setRawItems((current) => {\n const fromIndex = current.findIndex(\n (item, itemIndex) => resolveKey(item, itemIndex, getKey) === key,\n );\n\n if (fromIndex < 0) {\n return current;\n }\n\n const next = [...current];\n const [item] = next.splice(fromIndex, 1);\n\n if (item === undefined) {\n return current;\n }\n\n next.splice(Math.max(0, toIndex), 0, item);\n\n return next;\n });\n },\n prepend: (...values) => setRawItems((current) => [...values, ...current]),\n remove,\n removeKeysFromSelection,\n removeSelectedItems: () => {\n if (selectedKeys === \"all\") {\n setRawItems([]);\n } else {\n remove(...selectedKeys);\n }\n },\n selectedKeys,\n setFilterText,\n setSelectedKeys,\n };\n}\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/_hooks/index.ts" }, { "path": "registry/native-ui/src/_utils/index.ts", "content": "import { type TV, tv as tvBase, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../helpers/external/utils\";\nimport { createWebParityComponent } from \"../helpers/web-parity\";\n\nexport { cn, type VariantProps };\n\nexport type Dict = Record;\nexport type Booleanish = boolean | \"false\" | \"true\";\nexport type DOMRenderFunction = (props: Record, renderProps: unknown) => unknown;\n\nexport interface DOMRenderProps {\n render?: DOMRenderFunction;\n}\n\nexport function isArray(value: unknown): value is Array {\n return Array.isArray(value);\n}\n\nexport function isEmptyArray(value: unknown) {\n return isArray(value) && value.length === 0;\n}\n\nexport function isObject(value: unknown): value is Dict {\n const type = typeof value;\n\n return value !== null && (type === \"object\" || type === \"function\") && !isArray(value);\n}\n\nexport function isEmptyObject(value: unknown) {\n return isObject(value) && Object.keys(value).length === 0;\n}\n\nexport function isEmpty(value: unknown): boolean {\n if (isArray(value)) {\n return isEmptyArray(value);\n }\n\n if (isObject(value)) {\n return isEmptyObject(value);\n }\n\n return value == null || value === \"\";\n}\n\nexport const dataAttr = (condition: boolean | undefined) =>\n (condition ? \"true\" : undefined) as Booleanish | undefined;\n\nexport const isNumeric = (value?: number | string) =>\n value != null && Number.parseInt(value.toString(), 10) > 0;\n\nexport function getGregorianYearOffset(identifier: string): number {\n switch (identifier) {\n case \"buddhist\":\n return 543;\n case \"coptic\":\n return -284;\n case \"ethiopic\":\n case \"ethioaa\":\n return -8;\n case \"hebrew\":\n return 3760;\n case \"indian\":\n return -78;\n case \"islamic-civil\":\n case \"islamic-tbla\":\n case \"islamic-umalqura\":\n return -579;\n case \"persian\":\n return -600;\n default:\n return 0;\n }\n}\n\nexport function getYearRange(start?: T | null, end?: T | null): T[] {\n if (!start || !end) {\n return [];\n }\n\n return [start, end].filter((value, index, values) => index === 0 || value !== values[0]);\n}\n\nexport const disabledClasses = \"\";\nexport const focusRingClasses = \"\";\nexport const ariaDisabledClasses = \"\";\n\nexport function composeTwRenderProps(\n className: string | ((value: T) => string) | undefined,\n tailwind?: string | ((value: T) => string | undefined),\n): string | ((value: T) => string) {\n if (typeof className === \"function\" || typeof tailwind === \"function\") {\n return (value: T) =>\n cn(\n typeof tailwind === \"function\" ? tailwind(value) : tailwind,\n typeof className === \"function\" ? className(value) : className,\n ) ?? \"\";\n }\n\n return cn(tailwind, className) ?? \"\";\n}\n\nexport const composeSlotClassName = (\n slotFn: ((args?: { className?: string; [key: string]: unknown }) => string) | undefined,\n className?: string,\n variants?: Record,\n): string | undefined =>\n typeof slotFn === \"function\" ? slotFn({ ...(variants ?? {}), className }) : className;\n\nexport const tv: TV = (options, config) =>\n tvBase(options, {\n ...config,\n twMerge: config?.twMerge ?? false,\n });\n\nexport const mapPropsVariants = , K extends keyof T>(\n props: T,\n variantKeys?: K[],\n removeVariantProps = true,\n): readonly [Omit | T, Pick | Record] => {\n if (!variantKeys) {\n return [props, {}];\n }\n\n const picked = variantKeys.reduce>>((acc, key) => {\n if (key in props) {\n acc[key] = props[key];\n }\n\n return acc;\n }, {});\n\n if (!removeVariantProps) {\n return [props, picked as Pick];\n }\n\n const omitted = Object.keys(props)\n .filter((key) => !variantKeys.includes(key as K))\n .reduce>((acc, key) => {\n const typedKey = key as keyof T;\n acc[typedKey] = props[typedKey];\n\n return acc;\n }, {});\n\n return [omitted as Omit, picked as Pick];\n};\n\nexport function createVariantBuilder>(baseClass: string) {\n return (\n config: { modifiers?: Record; variants?: Partial } = {},\n ) => {\n const classes = [baseClass];\n\n if (config.variants) {\n for (const value of Object.values(config.variants)) {\n if (value) {\n classes.push(`${baseClass}--${value}`);\n }\n }\n }\n\n if (config.modifiers) {\n for (const [modifier, enabled] of Object.entries(config.modifiers)) {\n if (enabled) {\n classes.push(`${baseClass}--${modifier}`);\n }\n }\n }\n\n return classes.join(\" \");\n };\n}\n\nexport interface VariantDefinition> {\n base: string;\n defaults?: Partial<{ [K in keyof V]: V[K][number] }>;\n variants: V;\n}\n\nexport type VariantConfig> = {\n base: string;\n modifiers?: Record;\n variants?: T;\n};\n\nexport function createVariants>(\n definition: VariantDefinition,\n) {\n type VariantProps = {\n [K in keyof V]?: V[K][number];\n } & {\n modifiers?: Record;\n };\n\n return (props: VariantProps = {}) => {\n const classes = [definition.base];\n const mergedProps: Record = {};\n\n if (definition.defaults) {\n for (const [key, value] of Object.entries(definition.defaults)) {\n mergedProps[key] = value;\n }\n }\n\n for (const [key, value] of Object.entries(props)) {\n if (value !== undefined) {\n mergedProps[key] = value;\n }\n }\n\n for (const [key, value] of Object.entries(mergedProps)) {\n if (key !== \"modifiers\" && value) {\n classes.push(`${definition.base}--${String(value)}`);\n }\n }\n\n if (props.modifiers) {\n for (const [modifier, enabled] of Object.entries(props.modifiers)) {\n if (enabled) {\n classes.push(`${definition.base}--${modifier}`);\n }\n }\n }\n\n return classes.join(\" \");\n };\n}\n\nexport type VariantPropsOf> = T extends (\n props: infer P,\n) => string\n ? P\n : never;\n\nexport const dom = new Proxy(\n {},\n {\n get(_target, elementType) {\n if (typeof elementType !== \"string\") {\n return undefined;\n }\n\n return createWebParityComponent(`PitsiUINative.dom.${elementType}`);\n },\n },\n) as Record>;\n\nexport interface LoggerOptions {\n enabled?: boolean;\n prefix?: string;\n}\n\nexport class Logger {\n private enabled: boolean;\n private prefix: string;\n\n constructor(options: LoggerOptions = {}) {\n this.enabled = options.enabled ?? true;\n this.prefix = options.prefix ?? \"PitsiUI\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log(\"debug\", message, ...args);\n }\n\n divider(char = \"=\", length = 80): void {\n if (this.enabled) {\n console.log(char.repeat(length));\n }\n }\n\n error(message: string, ...args: unknown[]): void {\n this.log(\"error\", message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log(\"info\", message, ...args);\n }\n\n newline(): void {\n if (this.enabled) {\n console.log();\n }\n }\n\n success(message: string, ...args: unknown[]): void {\n this.log(\"success\", message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log(\"warn\", message, ...args);\n }\n\n private log(\n level: \"debug\" | \"error\" | \"info\" | \"success\" | \"warn\",\n message: string,\n ...args: unknown[]\n ) {\n if (!this.enabled) {\n return;\n }\n\n const formatted = `[${this.prefix}] ${level}: ${message}`;\n\n if (level === \"error\") {\n console.error(formatted, ...args);\n return;\n }\n\n if (level === \"warn\") {\n console.warn(formatted, ...args);\n return;\n }\n\n console.log(formatted, ...args);\n }\n}\n\nexport const logger = new Logger();\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/_utils/index.ts" }, { "path": "registry/native-ui/src/_utils/preview-meta.ts", "content": "export type PreviewBg = \"dotted\" | \"grid\" | \"solid\" | \"transparent\";\nexport type PreviewPadding = \"default\" | \"loose\" | \"tight\";\nexport type PreviewAlign = \"center\" | \"end\" | \"start\";\nexport type PreviewSize = \"fullscreen\" | \"large\" | \"medium\" | \"small\";\n\nexport interface PreviewMeta {\n align?: PreviewAlign;\n autoOpen?: boolean;\n bg?: PreviewBg;\n firstOnly?: boolean;\n minHeight?: number | string;\n padding?: PreviewPadding;\n screenshotWidth?: number | string;\n size?: PreviewSize;\n zoom?: number;\n}\n\nexport const DEFAULT_META: PreviewMeta = {\n align: \"center\",\n bg: \"transparent\",\n padding: \"default\",\n size: \"small\",\n};\n\nexport const SCREENSHOT_BASE_ZOOM_BY_SIZE: Record = {\n fullscreen: 0.45,\n large: 0.85,\n medium: 1.4,\n small: 2.3,\n};\n\nexport const componentMeta: Record = {};\nexport const demoMeta: Record = {};\n\nfunction compact(obj: T): Partial {\n const out = {} as Partial;\n\n for (const key of Object.keys(obj) as (keyof T)[]) {\n if (obj[key] !== undefined) {\n out[key] = obj[key];\n }\n }\n\n return out;\n}\n\nexport function resolvePreviewMeta(\n demoName: string,\n componentName: string | undefined,\n callSite: PreviewMeta = {},\n): Required> & PreviewMeta {\n const merged: PreviewMeta = {\n ...DEFAULT_META,\n ...(componentName ? compact(componentMeta[componentName] ?? {}) : {}),\n ...compact(demoMeta[demoName] ?? {}),\n ...compact(callSite),\n };\n\n return merged as Required> & PreviewMeta;\n}\n\nexport function resolveScreenshotZoom(componentName: string, zoomOverride: null | number): number {\n if (zoomOverride !== null && Number.isFinite(zoomOverride)) {\n return zoomOverride;\n }\n\n const meta = componentMeta[componentName];\n const size = meta?.size ?? \"small\";\n const base = SCREENSHOT_BASE_ZOOM_BY_SIZE[size];\n\n return base * (meta?.zoom ?? 1);\n}\n\nexport function componentNameFromFile(file: string | undefined): string | undefined {\n if (!file) return undefined;\n const segment = file.split(\"/\")[0];\n\n return segment && segment.length > 0 ? segment : undefined;\n}\n", "type": "registry:lib", "target": "@components/pitsi-ui/native-ui/src/_utils/preview-meta.ts" }, { "path": "registry/native-ui/src/components/accordion/accordion.animation.ts", "content": "import { useEffect } from \"react\";\nimport { interpolate, useAnimatedStyle, useSharedValue, withSpring } from \"react-native-reanimated\";\nimport { useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport {\n createContext,\n getAnimationState,\n getAnimationValueMergedConfig,\n getAnimationValueProperty,\n getIsAnimationDisabledValue,\n getRootAnimationState,\n} from \"../../helpers/internal/utils\";\nimport {\n ACCORDION_LAYOUT_TRANSITION,\n type AccordionAnimationContextValue,\n type AccordionContentAnimation,\n type AccordionIndicatorAnimation,\n type AccordionRootAnimation,\n DEFAULT_CONTENT_ENTERING,\n DEFAULT_CONTENT_EXITING,\n INDICATOR_SPRING_CONFIG,\n} from \"./accordion\";\n\nconst [AccordionAnimationProvider, useAccordionAnimation] =\n createContext({\n name: \"AccordionAnimationContext\",\n });\n\nexport { AccordionAnimationProvider, useAccordionAnimation };\n\n// --------------------------------------------------\n\n/**\n * Animation hook for Accordion root component\n * Handles layout transition configuration and provides context for child components\n */\nexport function useAccordionRootAnimation(options: {\n animation: AccordionRootAnimation | undefined;\n}) {\n const { animation } = options;\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n const { animationConfig, isAnimationDisabled } = getRootAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Layout transition animation\n const layoutTransitionValue = getAnimationValueProperty({\n animationValue: animationConfig?.layout,\n property: \"value\",\n defaultValue: ACCORDION_LAYOUT_TRANSITION,\n });\n\n return {\n layoutTransition: isAnimationDisabledValue ? undefined : layoutTransitionValue,\n isAllAnimationsDisabled,\n };\n}\n\n// --------------------------------------------------\n\n/**\n * Animation hook for Accordion Indicator component\n * Handles rotation animation for the chevron icon\n */\nexport function useAccordionIndicatorAnimation(options: {\n animation: AccordionIndicatorAnimation | undefined;\n isExpanded: boolean;\n}) {\n const { animation, isExpanded } = options;\n\n // Read from global animation context (always available in compound parts)\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { animationConfig, isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Rotation animation values\n const rotationValue = getAnimationValueProperty({\n animationValue: animationConfig?.rotation,\n property: \"value\",\n defaultValue: [0, -180] as [number, number],\n });\n\n const rotationSpringConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.rotation,\n property: \"springConfig\",\n defaultValue: INDICATOR_SPRING_CONFIG,\n });\n\n const rotation = useSharedValue(0);\n\n useEffect(() => {\n if (isAnimationDisabledValue) {\n rotation.set(isExpanded ? 1 : 0);\n } else {\n rotation.set(withSpring(isExpanded ? 1 : 0, rotationSpringConfig));\n }\n }, [isExpanded, isAnimationDisabledValue, rotation, rotationSpringConfig]);\n\n const rContainerStyle = useAnimatedStyle(() => {\n return {\n transform: [\n {\n rotate: `${interpolate(rotation.get(), [0, 1], [rotationValue[0], rotationValue[1]])}deg`,\n },\n ],\n };\n });\n\n return {\n rContainerStyle,\n };\n}\n\n// --------------------------------------------------\n\n/**\n * Animation hook for Accordion Content component\n * Handles entering and exiting animations\n */\nexport function useAccordionContentAnimation(options: {\n animation: AccordionContentAnimation | undefined;\n}) {\n const { animation } = options;\n\n // Read from global animation context (always available in compound parts)\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { animationConfig, isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Entering animation\n const enteringValue = getAnimationValueProperty({\n animationValue: animationConfig?.entering,\n property: \"value\",\n defaultValue: DEFAULT_CONTENT_ENTERING,\n });\n\n // Exiting animation\n const exitingValue = getAnimationValueProperty({\n animationValue: animationConfig?.exiting,\n property: \"value\",\n defaultValue: DEFAULT_CONTENT_EXITING,\n });\n\n return {\n entering: isAnimationDisabledValue ? undefined : enteringValue,\n exiting: isAnimationDisabledValue ? undefined : exitingValue,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/accordion/accordion.animation.ts" }, { "path": "registry/native-ui/src/components/accordion/accordion.tsx", "content": "import { Children, forwardRef, useMemo } from \"react\";\nimport { StyleSheet, type View, type ViewStyle } from \"react-native\";\nimport Animated, {\n type AnimatedProps,\n Easing,\n type EntryOrExitLayoutType,\n FadeIn,\n FadeOut,\n LinearTransition,\n type WithSpringConfig,\n} from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { useThemeColor } from \"../../helpers/external/hooks\";\nimport { ChevronDownIcon } from \"../../helpers/internal/components\";\nimport { AnimationSettingsProvider } from \"../../helpers/internal/contexts\";\nimport type {\n Animation,\n AnimationRoot,\n AnimationValue,\n ElementSlots,\n LayoutTransition,\n ViewRef,\n} from \"../../helpers/internal/types\";\nimport { combineStyles, createContext } from \"../../helpers/internal/utils\";\nimport type {\n ContentProps as PrimitiveContentProps,\n IndicatorProps as PrimitiveIndicatorProps,\n ItemProps as PrimitiveItemProps,\n RootProps as PrimitiveRootProps,\n TriggerProps as PrimitiveTriggerProps,\n} from \"../../primitives/accordion\";\nimport * as AccordionPrimitive from \"../../primitives/accordion\";\nimport {\n AccordionAnimationProvider,\n useAccordionAnimation,\n useAccordionContentAnimation,\n useAccordionIndicatorAnimation,\n useAccordionRootAnimation,\n} from \"./accordion.animation\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for Accordion components\n */\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.Accordion.Root\",\n ITEM: \"PitsiUINative.Accordion.Item\",\n TRIGGER: \"PitsiUINative.Accordion.Trigger\",\n INDICATOR: \"PitsiUINative.Accordion.Indicator\",\n CONTENT: \"PitsiUINative.Accordion.Content\",\n CHEVRON_DOWN_ICON: \"PitsiUINative.Accordion.ChevronDownIcon\",\n} as const;\n\n/**\n * Default layout transition for accordion animations\n */\nexport const ACCORDION_LAYOUT_TRANSITION = LinearTransition.springify()\n .damping(140)\n .stiffness(1600)\n .mass(4);\n\n/**\n * Default icon size for the indicator\n */\nexport const DEFAULT_ICON_SIZE = 16;\n\n/**\n * Rotation values for indicator animation\n */\nexport const INDICATOR_ROTATION = {\n COLLAPSED: \"0deg\",\n EXPANDED: \"180deg\",\n};\n\n/**\n * Spring configuration for indicator animation\n */\nexport const INDICATOR_SPRING_CONFIG = {\n damping: 140,\n stiffness: 1000,\n mass: 4,\n};\n\n/**\n * Default entering animation for accordion content\n */\nexport const DEFAULT_CONTENT_ENTERING = FadeIn.duration(200).easing(Easing.out(Easing.ease));\n\n/**\n * Default exiting animation for accordion content\n */\nexport const DEFAULT_CONTENT_EXITING = FadeOut.duration(200).easing(Easing.in(Easing.ease));\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n slots: {\n container: \"flex-col overflow-hidden\",\n separator: \"h-hairline bg-separator\",\n },\n variants: {\n variant: {\n default: {\n container: \"\",\n separator: \"\",\n },\n surface: {\n container: \"bg-surface rounded-3xl border border-surface shadow-surface\",\n separator: \"mx-3\",\n },\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n});\n\nconst item = tv({\n base: \"flex-col overflow-hidden\",\n});\n\nconst trigger = tv({\n base: \"flex-row items-center justify-between py-4 px-3 gap-4 bg-transparent z-10\",\n variants: {\n variant: {\n default: \"\",\n surface: \"px-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n});\n\nconst indicator = tv({\n base: \"items-center justify-center\",\n});\n\nconst content = tv({\n base: \"px-3 pb-4 bg-transparent\",\n variants: {\n variant: {\n default: \"\",\n surface: \"px-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n});\n\nexport const accordionClassNames = combineStyles({\n root,\n item,\n trigger,\n indicator,\n content,\n});\n\nexport const accordionStyleSheet = StyleSheet.create({\n root: {\n borderCurve: \"continuous\",\n },\n});\n\nexport type RootSlots = keyof ReturnType;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Variant types for the Accordion component\n */\nexport type AccordionVariant = \"default\" | \"surface\";\n\n/**\n * Icon props for the Accordion.Indicator component\n */\nexport interface AccordionIndicatorIconProps {\n /** @default 16 */\n size?: number;\n /** @default foreground */\n color?: string;\n}\n\n/**\n * Animation configuration for accordion root component\n */\nexport type AccordionRootAnimation = AnimationRoot<{\n layout?: AnimationValue<{\n value?: LayoutTransition;\n }>;\n}>;\n\n/**\n * Props for the Accordion root component\n */\nexport type AccordionRootProps = Omit, \"layout\"> & {\n children?: React.ReactNode;\n /** @default 'default' */\n variant?: AccordionVariant;\n /** @default false */\n hideSeparator?: boolean;\n className?: string;\n classNames?: ElementSlots;\n styles?: Partial>;\n animation?: AccordionRootAnimation;\n};\n\n/**\n * Render function props for accordion item children\n */\nexport type AccordionItemRenderProps = {\n isExpanded: boolean;\n value: string;\n};\n\n/**\n * Props for the Accordion.Item component\n */\nexport interface AccordionItemProps extends Omit, \"children\"> {\n children?: React.ReactNode | ((props: AccordionItemRenderProps) => React.ReactNode);\n className?: string;\n}\n\n/**\n * Props for the Accordion.Trigger component\n */\nexport interface AccordionTriggerProps extends PrimitiveTriggerProps {\n children?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Animation configuration for accordion indicator component\n */\nexport type AccordionIndicatorAnimation = Animation<{\n rotation?: AnimationValue<{\n value?: [number, number];\n springConfig?: WithSpringConfig;\n }>;\n}>;\n\n/**\n * Props for the Accordion.Indicator component\n */\nexport interface AccordionIndicatorProps extends AnimatedProps {\n children?: React.ReactNode;\n className?: string;\n iconProps?: AccordionIndicatorIconProps;\n animation?: AccordionIndicatorAnimation;\n isAnimatedStyleActive?: boolean;\n}\n\n/**\n * Animation configuration for accordion content component\n */\nexport type AccordionContentAnimation = Animation<{\n entering?: AnimationValue<{\n value?: EntryOrExitLayoutType;\n }>;\n exiting?: AnimationValue<{\n value?: EntryOrExitLayoutType;\n }>;\n}>;\n\n/**\n * Props for the Accordion.Content component\n */\nexport interface AccordionContentProps extends PrimitiveContentProps {\n children?: React.ReactNode;\n className?: string;\n animation?: AccordionContentAnimation;\n}\n\n/**\n * Context values shared between Accordion components\n */\nexport interface AccordionContextValue {\n variant: AccordionVariant;\n}\n\n/**\n * Context value for accordion animation state\n */\nexport interface AccordionAnimationContextValue {\n layoutTransition?: LayoutTransition;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Animated views\n * -----------------------------------------------------------------------------------------------*/\nconst AnimatedRootView = Animated.createAnimatedComponent(AccordionPrimitive.Root);\n\nconst AnimatedItemView = Animated.createAnimatedComponent(AccordionPrimitive.Item);\n\nconst AnimatedIndicator = Animated.createAnimatedComponent(AccordionPrimitive.Indicator);\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\nconst [AccordionInnerProvider, useAccordionInnerContext] = createContext({\n name: \"AccordionInnerContext\",\n});\n\nconst useAccordion = AccordionPrimitive.useRootContext;\nconst useAccordionItem = AccordionPrimitive.useItemContext;\n\n/* -------------------------------------------------------------------------------------------------\n * Accordion.Root\n * -----------------------------------------------------------------------------------------------*/\nconst Root = forwardRef((props, ref) => {\n const {\n children,\n variant = \"default\",\n hideSeparator = false,\n className,\n classNames,\n styles,\n style,\n animation,\n ...restProps\n } = props;\n\n const { container, separator } = accordionClassNames.root({ variant });\n\n const containerClassName = container({\n className: [className, classNames?.container],\n });\n\n const separatorClassName = separator({ className: classNames?.separator });\n\n const { layoutTransition, isAllAnimationsDisabled } = useAccordionRootAnimation({\n animation,\n });\n\n const contextValue: AccordionContextValue = useMemo(\n () => ({\n variant,\n }),\n [variant],\n );\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n const animationContextValue = useMemo(\n () => ({\n layoutTransition,\n }),\n [layoutTransition],\n );\n\n return (\n \n \n \n \n {Children.map(children, (child, index) => (\n <>\n {child}\n {!hideSeparator && index < Children.count(children) - 1 && (\n \n )}\n \n ))}\n \n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Accordion.Item\n * -----------------------------------------------------------------------------------------------*/\nconst Item = forwardRef((props, ref) => {\n const {\n children,\n value,\n layout: layoutProp,\n className,\n isDisabled: isDisabledProp,\n ...restProps\n } = props;\n\n const itemClassName = accordionClassNames.item({ className });\n\n const { layoutTransition } = useAccordionAnimation();\n const { value: rootValue } = useAccordion();\n\n const itemValue = value as string;\n\n const isExpanded = Array.isArray(rootValue)\n ? rootValue.includes(itemValue)\n : rootValue === itemValue;\n\n const renderProps: AccordionItemRenderProps = useMemo(\n () => ({\n isExpanded,\n value: itemValue,\n }),\n [isExpanded, itemValue],\n );\n\n const content = typeof children === \"function\" ? children(renderProps) : children;\n\n return (\n \n {content}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Accordion.Trigger\n * -----------------------------------------------------------------------------------------------*/\nconst Trigger = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const { variant } = useAccordionInnerContext();\n\n const triggerClassName = accordionClassNames.trigger({\n variant,\n className,\n });\n\n return (\n \n \n {children}\n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Accordion.Indicator\n * -----------------------------------------------------------------------------------------------*/\nconst Indicator = forwardRef((props, ref) => {\n const {\n children,\n className,\n iconProps,\n animation,\n isAnimatedStyleActive = true,\n style,\n ...restProps\n } = props;\n\n const { isExpanded } = useAccordionItem();\n\n const themeColorForeground = useThemeColor(\"foreground\");\n\n const indicatorClassName = accordionClassNames.indicator({ className });\n\n const { rContainerStyle } = useAccordionIndicatorAnimation({\n animation,\n isExpanded,\n });\n\n const indicatorStyle = isAnimatedStyleActive ? [rContainerStyle, style] : style;\n\n if (children) {\n return (\n \n {children}\n \n );\n }\n\n return (\n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Accordion.Content\n * -----------------------------------------------------------------------------------------------*/\nconst Content = forwardRef((props, ref) => {\n const { children, className, animation, ...restProps } = props;\n\n const { variant } = useAccordionInnerContext();\n\n const { isExpanded } = useAccordionItem();\n\n const contentClassName = accordionClassNames.content({ variant, className });\n\n const { entering: animatedEntering, exiting: animatedExiting } = useAccordionContentAnimation({\n animation,\n });\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n \n \n {children}\n \n \n );\n});\n\nRoot.displayName = DISPLAY_NAME.ROOT;\nItem.displayName = DISPLAY_NAME.ITEM;\nTrigger.displayName = DISPLAY_NAME.TRIGGER;\nIndicator.displayName = DISPLAY_NAME.INDICATOR;\nContent.displayName = DISPLAY_NAME.CONTENT;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Accordion - Main container managing accordion state and behavior.\n * @component Accordion.Item - Container for individual accordion items.\n * @component Accordion.Trigger - Interactive element that toggles item expansion.\n * @component Accordion.Indicator - Optional visual indicator (defaults to chevron).\n * @component Accordion.Content - Container for expandable content with animations.\n *\n * @see https://pitsiui.com/docs/native/components/accordion\n * -----------------------------------------------------------------------------------------------*/\nconst Accordion = Object.assign(Root, {\n /** @required Container for individual accordion items */\n Item,\n /** @required Interactive trigger element */\n Trigger,\n /** @optional Visual indicator showing expansion state (defaults to chevron) */\n Indicator,\n /** @required Container for expandable content with animations */\n Content,\n});\n\nexport default Accordion;\nexport { Accordion, useAccordion, useAccordionItem };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/accordion/accordion.tsx" }, { "path": "registry/native-ui/src/components/accordion/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Accordion, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n Profile\n \n \n \n Name, avatar, and account preferences.\n \n \n \n \n Security\n \n \n \n Password, sessions, and two-factor settings.\n \n \n \n );\n}\n\nexport function Surface() {\n return (\n \n \n \n Sync\n \n \n \n Keep data available across devices.\n \n \n \n \n Exports\n \n \n \n Download backups as JSON or CSV files.\n \n \n \n );\n}\n\nexport function Multiple() {\n return (\n \n \n \n Nutrition\n \n \n \n Meals, macros, water, and targets.\n \n \n \n \n Training\n \n \n \n Workouts, templates, and performance history.\n \n \n \n );\n}\n\nexport function DisabledItem() {\n return (\n \n \n \n \n Available\n \n \n \n This panel can be toggled.\n \n \n \n \n Locked\n \n \n \n This panel is disabled.\n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/accordion/demos/index.tsx" }, { "path": "registry/native-ui/src/components/accordion/index.ts", "content": "export type {\n AccordionContentProps,\n AccordionContextValue,\n AccordionIndicatorProps,\n AccordionItemProps,\n AccordionRootProps,\n AccordionTriggerProps,\n AccordionVariant,\n} from \"./accordion\";\nexport {\n ACCORDION_LAYOUT_TRANSITION as AccordionLayoutTransition,\n Accordion,\n accordionClassNames,\n default,\n useAccordion,\n useAccordionItem,\n} from \"./accordion\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/accordion/index.ts" }, { "path": "registry/native-ui/src/components/alert-dialog/alert-dialog.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { DangerIcon, InfoIcon, SuccessIcon, WarningIcon } from \"../icons\";\nimport {\n ModalBackdrop,\n type ModalBackdropProps,\n ModalBody,\n type ModalBodyProps,\n ModalCloseTrigger,\n type ModalCloseTriggerProps,\n ModalContainer,\n type ModalContainerProps,\n ModalDialog,\n type ModalDialogProps,\n ModalFooter,\n type ModalFooterProps,\n ModalHeader,\n type ModalHeaderProps,\n ModalHeading,\n type ModalHeadingProps,\n ModalRoot,\n type ModalRootProps,\n ModalTrigger,\n type ModalTriggerProps,\n} from \"../modal\";\n\ntype AlertDialogStatus = \"accent\" | \"danger\" | \"default\" | \"success\" | \"warning\";\n\nexport const alertDialogVariants = tv({\n slots: {\n icon: \"size-10 items-center justify-center rounded-full bg-danger-soft\",\n },\n variants: {\n status: {\n accent: {\n icon: \"bg-accent-soft\",\n },\n danger: {\n icon: \"bg-danger-soft\",\n },\n default: {\n icon: \"bg-default\",\n },\n success: {\n icon: \"bg-success-soft\",\n },\n warning: {\n icon: \"bg-warning-soft\",\n },\n },\n },\n defaultVariants: {\n status: \"danger\",\n },\n});\n\nexport type AlertDialogVariants = VariantProps;\n\nexport type AlertDialogRootProps = ModalRootProps;\nexport type AlertDialogTriggerProps = ModalTriggerProps;\nexport type AlertDialogContainerProps = ModalContainerProps;\nexport type AlertDialogDialogProps = ModalDialogProps;\nexport type AlertDialogHeaderProps = ModalHeaderProps;\nexport type AlertDialogHeadingProps = ModalHeadingProps;\nexport type AlertDialogBodyProps = ModalBodyProps;\nexport type AlertDialogFooterProps = ModalFooterProps;\nexport type AlertDialogCloseTriggerProps = ModalCloseTriggerProps;\n\nexport interface AlertDialogBackdropProps extends ModalBackdropProps {\n isKeyboardDismissDisabled?: boolean;\n}\n\nexport interface AlertDialogIconProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n status?: AlertDialogStatus;\n}\n\nconst AlertDialogRoot = ModalRoot;\nconst AlertDialogTrigger = ModalTrigger;\nconst AlertDialogContainer = ModalContainer;\nconst AlertDialogDialog = ModalDialog;\nconst AlertDialogHeader = ModalHeader;\nconst AlertDialogHeading = ModalHeading;\nconst AlertDialogBody = ModalBody;\nconst AlertDialogFooter = ModalFooter;\nconst AlertDialogCloseTrigger = ModalCloseTrigger;\n\nfunction AlertDialogBackdrop({\n isDismissable = false,\n isKeyboardDismissDisabled: _isKeyboardDismissDisabled,\n ...props\n}: AlertDialogBackdropProps) {\n return ;\n}\n\nAlertDialogBackdrop.displayName = \"PitsiUINative.AlertDialogBackdrop\";\n\nfunction getDefaultIcon(status: AlertDialogStatus) {\n switch (status) {\n case \"success\":\n return ;\n case \"warning\":\n return ;\n case \"accent\":\n case \"default\":\n return ;\n default:\n return ;\n }\n}\n\nconst AlertDialogIcon = forwardRef(\n ({ children, className, status = \"danger\", ...props }, ref) => {\n const slots = alertDialogVariants({ status });\n\n return (\n \n {children ?? getDefaultIcon(status)}\n \n );\n },\n);\n\nAlertDialogIcon.displayName = \"PitsiUINative.AlertDialogIcon\";\n\nexport {\n AlertDialogBackdrop,\n AlertDialogBody,\n AlertDialogCloseTrigger,\n AlertDialogContainer,\n AlertDialogDialog,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogHeading,\n AlertDialogIcon,\n AlertDialogRoot,\n AlertDialogTrigger,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert-dialog/alert-dialog.tsx" }, { "path": "registry/native-ui/src/components/alert-dialog/demos/index.tsx", "content": "import { AlertDialog, Button } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n \n \n \n \n Delete item?\n \n This action cannot be undone.\n \n \n \n \n \n \n \n );\n}\n\nexport { Basic as Statuses };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert-dialog/demos/index.tsx" }, { "path": "registry/native-ui/src/components/alert-dialog/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n AlertDialogBackdrop,\n AlertDialogBody,\n AlertDialogCloseTrigger,\n AlertDialogContainer,\n AlertDialogDialog,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogHeading,\n AlertDialogIcon,\n AlertDialogRoot,\n AlertDialogTrigger,\n} from \"./alert-dialog\";\n\nexport const AlertDialog = Object.assign(AlertDialogRoot, {\n Backdrop: AlertDialogBackdrop,\n Body: AlertDialogBody,\n CloseTrigger: AlertDialogCloseTrigger,\n Container: AlertDialogContainer,\n Dialog: AlertDialogDialog,\n Footer: AlertDialogFooter,\n Header: AlertDialogHeader,\n Heading: AlertDialogHeading,\n Icon: AlertDialogIcon,\n Root: AlertDialogRoot,\n Trigger: AlertDialogTrigger,\n});\n\nexport type AlertDialog = {\n BackdropProps: ComponentProps;\n BodyProps: ComponentProps;\n CloseTriggerProps: ComponentProps;\n ContainerProps: ComponentProps;\n DialogProps: ComponentProps;\n FooterProps: ComponentProps;\n HeaderProps: ComponentProps;\n HeadingProps: ComponentProps;\n IconProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n AlertDialogBackdropProps,\n AlertDialogBodyProps,\n AlertDialogCloseTriggerProps,\n AlertDialogContainerProps,\n AlertDialogDialogProps,\n AlertDialogFooterProps,\n AlertDialogHeaderProps,\n AlertDialogHeadingProps,\n AlertDialogIconProps,\n AlertDialogRootProps,\n AlertDialogRootProps as AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogVariants,\n} from \"./alert-dialog\";\nexport {\n AlertDialogBackdrop,\n AlertDialogBody,\n AlertDialogCloseTrigger,\n AlertDialogContainer,\n AlertDialogDialog,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogHeading,\n AlertDialogIcon,\n AlertDialogRoot,\n AlertDialogTrigger,\n alertDialogVariants,\n} from \"./alert-dialog\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert-dialog/index.ts" }, { "path": "registry/native-ui/src/components/alert/alert.hooks.ts", "content": "import { useThemeColor } from \"../../helpers/external/hooks\";\nimport type { AlertStatus } from \"../../primitives/alert/alert.types\";\n\n/**\n * Resolves the default icon color based on the current alert status.\n */\nexport function useStatusColor(status: AlertStatus): string {\n const [foreground, accent, success, warning, danger] = useThemeColor([\n \"foreground\",\n \"accent\",\n \"success\",\n \"warning\",\n \"danger\",\n ]);\n\n switch (status) {\n case \"accent\":\n return accent;\n case \"success\":\n return success;\n case \"warning\":\n return warning;\n case \"danger\":\n return danger;\n default:\n return foreground;\n }\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/alert.hooks.ts" }, { "path": "registry/native-ui/src/components/alert/alert.tsx", "content": "import { forwardRef } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport { tv } from \"tailwind-variants\";\nimport { HeroText } from \"../../helpers/internal/components\";\nimport { combineStyles } from \"../../helpers/internal/utils\";\nimport * as AlertPrimitives from \"../../primitives/alert\";\nimport type * as AlertPrimitiveTypes from \"../../primitives/alert/alert.types\";\nimport { useStatusColor } from \"./alert.hooks\";\nimport { DefaultIcon } from \"./default-icon\";\nimport { SuccessIcon } from \"./success-icon\";\nimport { WarningIcon } from \"./warning-icon\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for Alert components\n */\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.Alert\",\n INDICATOR: \"PitsiUINative.Alert.Indicator\",\n CONTENT: \"PitsiUINative.Alert.Content\",\n TITLE: \"PitsiUINative.Alert.Title\",\n DESCRIPTION: \"PitsiUINative.Alert.Description\",\n};\n\n/** Default icon size in pixels */\nexport const DEFAULT_ICON_SIZE = 18;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Props for the icon rendered inside the alert indicator.\n */\nexport interface AlertIconProps {\n /**\n * Icon size in pixels\n *\n * @default 20\n */\n size?: number;\n /**\n * Icon color as a CSS color string\n */\n color?: string;\n}\n\n/**\n * Props for the Alert root component.\n * Renders a styled alert container with status-based visual treatment.\n */\nexport interface AlertRootProps extends AlertPrimitiveTypes.RootProps {\n /**\n * Children elements to render inside the alert\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Alert.Indicator component.\n * Renders a status icon by default when no children are provided.\n */\nexport interface AlertIndicatorProps extends AlertPrimitiveTypes.IndicatorProps {\n /**\n * Custom children to render instead of the default status icon\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Props passed to the default status icon (size and color overrides)\n */\n iconProps?: AlertIconProps;\n}\n\n/**\n * Props for the Alert.Content component.\n * Container for the title and description.\n */\nexport interface AlertContentProps extends AlertPrimitiveTypes.ContentProps {\n /**\n * Children elements (typically Alert.Title and Alert.Description)\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Alert.Title component.\n * Renders the alert heading with status-based text color.\n */\nexport interface AlertTitleProps extends Omit {\n /**\n * Title text content\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Alert.Description component.\n * Renders the alert body text with muted styling.\n */\nexport interface AlertDescriptionProps\n extends Omit {\n /**\n * Description text content\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Root style definition for the Alert container\n */\nconst root = tv({\n base: \"p-3 flex-row gap-3 rounded-3xl bg-surface shadow-surface\",\n});\n\n/**\n * Indicator style definition for the status icon container\n */\nconst indicator = tv({\n base: \"pt-[3.5px]\",\n});\n\n/**\n * Content style definition for the title/description wrapper\n */\nconst content = tv({\n base: \"flex-1\",\n});\n\n/**\n * Title style definition with status-based color variants\n */\nconst title = tv({\n base: \"text-base font-medium\",\n variants: {\n status: {\n default: \"text-foreground\",\n accent: \"text-accent\",\n success: \"text-success\",\n warning: \"text-warning\",\n danger: \"text-danger\",\n },\n },\n defaultVariants: {\n status: \"default\",\n },\n});\n\n/**\n * Description style definition\n */\nconst description = tv({\n base: \"text-sm text-muted\",\n});\n\nexport const alertClassNames = combineStyles({\n root,\n indicator,\n content,\n title,\n description,\n});\n\n/** StyleSheet for native-only properties */\nexport const alertStyleSheet = StyleSheet.create({\n root: {\n borderCurve: \"continuous\",\n },\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Utils\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Resolves the default icon component based on the current alert status.\n */\nexport function getStatusIcon(\n status: AlertPrimitiveTypes.AlertStatus,\n iconProps: AlertIconProps,\n): React.ReactElement {\n const { size = DEFAULT_ICON_SIZE, color } = iconProps;\n\n switch (status) {\n case \"success\":\n return ;\n case \"warning\":\n return ;\n default:\n return ;\n }\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Alert.Root\n * -----------------------------------------------------------------------------------------------*/\nconst useAlert = AlertPrimitives.useRootContext;\n\nconst AlertRoot = forwardRef((props, ref) => {\n const { children, status = \"default\", className, style, ...restProps } = props;\n\n const rootClassName = alertClassNames.root({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Alert.Indicator\n * -----------------------------------------------------------------------------------------------*/\nconst AlertIndicator = forwardRef(\n (props, ref) => {\n const { children, className, iconProps, ...restProps } = props;\n\n const { status } = useAlert();\n const statusColor = useStatusColor(status);\n\n const indicatorClassName = alertClassNames.indicator({ className });\n\n /** Merge default color with user-provided iconProps */\n const resolvedIconProps: AlertIconProps = {\n size: iconProps?.size ?? DEFAULT_ICON_SIZE,\n color: iconProps?.color ?? statusColor,\n };\n\n return (\n \n {children ?? getStatusIcon(status, resolvedIconProps)}\n \n );\n },\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Alert.Content\n * -----------------------------------------------------------------------------------------------*/\nconst AlertContent = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const contentClassName = alertClassNames.content({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Alert.Title\n * -----------------------------------------------------------------------------------------------*/\nconst AlertTitle = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const { status } = useAlert();\n\n const titleClassName = alertClassNames.title({ status, className });\n\n return (\n \n \n {children}\n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Alert.Description\n * -----------------------------------------------------------------------------------------------*/\nconst AlertDescription = forwardRef(\n (props, ref) => {\n const { children, className, ...restProps } = props;\n\n const descriptionClassName = alertClassNames.description({ className });\n\n return (\n \n \n {children}\n \n \n );\n },\n);\n\nAlertRoot.displayName = DISPLAY_NAME.ROOT;\nAlertIndicator.displayName = DISPLAY_NAME.INDICATOR;\nAlertContent.displayName = DISPLAY_NAME.CONTENT;\nAlertTitle.displayName = DISPLAY_NAME.TITLE;\nAlertDescription.displayName = DISPLAY_NAME.DESCRIPTION;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Alert - Main container that renders a styled alert with role=\"alert\"\n * and configurable status (default, accent, success, warning, danger).\n * @component Alert.Indicator - Renders a status-appropriate icon by default.\n * @component Alert.Content - Flex-1 wrapper for Alert.Title and Alert.Description.\n * @component Alert.Title - Heading text with status-based color.\n * @component Alert.Description - Body text rendered with muted color.\n *\n * @see https://pitsiui.com/docs/native/components/alert\n * -----------------------------------------------------------------------------------------------*/\nconst Alert = Object.assign(AlertRoot, {\n /** @optional Status icon rendered as the leading visual element */\n Indicator: AlertIndicator,\n /** @optional Wrapper for title and description content */\n Content: AlertContent,\n /** @optional Primary heading with status-aware text color */\n Title: AlertTitle,\n /** @optional Secondary description with muted text color */\n Description: AlertDescription,\n});\n\nexport { Alert, useAlert };\nexport default Alert;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/alert.tsx" }, { "path": "registry/native-ui/src/components/alert/default-icon.tsx", "content": "import type React from \"react\";\nimport Svg, { Path } from \"react-native-svg\";\nimport type { AlertIconProps } from \"./alert\";\n\n/**\n * Default info circle icon for the Alert indicator.\n * Used for \"default\", \"accent\", and \"danger\" status values.\n */\nexport const DefaultIcon: React.FC = ({ size = 20, color }) => {\n return (\n \n \n \n );\n};\n\nDefaultIcon.displayName = \"PitsiUINative.Alert.DefaultIcon\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/default-icon.tsx" }, { "path": "registry/native-ui/src/components/alert/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Alert, Button, CloseButton, Spinner, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n New features available\n \n Check out our latest updates including dark mode support and improved accessibility\n features.\n \n \n \n\n \n \n \n Update available\n \n A new version of the application is available. Please refresh to get the latest features\n and bug fixes.\n \n \n \n \n\n \n \n \n Unable to connect to server\n \n We're experiencing connection issues. Please try the following:\n \n \n - Check your internet connection\n - Refresh the page\n - Clear your browser cache\n \n \n \n \n\n \n \n \n Profile updated successfully\n \n \n \n\n \n \n \n \n \n Processing your request\n \n Please wait while we sync your data. This may take a few moments.\n \n \n \n\n \n \n \n Scheduled maintenance\n \n Our services will be unavailable on Sunday, March 15th from 2:00 AM to 6:00 AM UTC for\n scheduled maintenance.\n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/demos/index.tsx" }, { "path": "registry/native-ui/src/components/alert/index.ts", "content": "// Component exports\n\n// Type exports (named exports for better tree-shaking)\nexport type {\n AlertContentProps,\n AlertDescriptionProps,\n AlertIconProps,\n AlertIndicatorProps,\n AlertRootProps,\n AlertTitleProps,\n} from \"./alert\";\nexport { Alert, alertClassNames, default, useAlert } from \"./alert\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/index.ts" }, { "path": "registry/native-ui/src/components/alert/success-icon.tsx", "content": "import type React from \"react\";\nimport Svg, { Path } from \"react-native-svg\";\nimport type { AlertIconProps } from \"./alert\";\n\n/**\n * Success check circle icon for the Alert indicator.\n * Used for the \"success\" status value.\n */\nexport const SuccessIcon: React.FC = ({ size = 20, color }) => {\n return (\n \n \n \n );\n};\n\nSuccessIcon.displayName = \"PitsiUINative.Alert.SuccessIcon\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/success-icon.tsx" }, { "path": "registry/native-ui/src/components/alert/warning-icon.tsx", "content": "import type React from \"react\";\nimport Svg, { Path } from \"react-native-svg\";\nimport type { AlertIconProps } from \"./alert\";\n\n/**\n * Warning triangle icon for the Alert indicator.\n * Used for the \"warning\" status value.\n */\nexport const WarningIcon: React.FC = ({ size = 20, color }) => {\n return (\n \n \n \n );\n};\n\nWarningIcon.displayName = \"PitsiUINative.Alert.WarningIcon\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/alert/warning-icon.tsx" }, { "path": "registry/native-ui/src/components/aspect-ratio/aspect-ratio.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps, type ViewStyle } from \"react-native\";\n\nexport interface AspectRatioRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n ratio?: number | string;\n}\n\nfunction resolveAspectRatio(ratio: number | string | undefined) {\n if (typeof ratio === \"number\" && Number.isFinite(ratio) && ratio > 0) {\n return ratio;\n }\n\n if (typeof ratio === \"string\") {\n const parts = ratio.split(\"/\");\n const width = Number(parts[0]?.trim());\n const height = Number(parts[1]?.trim());\n\n if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {\n return width / height;\n }\n\n const parsed = Number(ratio);\n\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed;\n }\n }\n\n return 1;\n}\n\nconst AspectRatioRoot = forwardRef(\n ({ children, className, ratio, style, ...props }, ref) => {\n const aspectRatio = resolveAspectRatio(ratio);\n const ratioStyle: ViewStyle = { aspectRatio };\n\n return (\n \n {children}\n \n );\n },\n);\n\nAspectRatioRoot.displayName = \"PitsiUINative.AspectRatio\";\n\nexport { AspectRatioRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/aspect-ratio/aspect-ratio.tsx" }, { "path": "registry/native-ui/src/components/aspect-ratio/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { AspectRatio, Surface, Text } from \"../..\";\n\nexport function Default() {\n return (\n \n \n \n 16:9\n \n \n \n \n 4:3\n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/aspect-ratio/demos/index.tsx" }, { "path": "registry/native-ui/src/components/aspect-ratio/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { AspectRatioRoot } from \"./aspect-ratio\";\n\nexport const AspectRatio = Object.assign(AspectRatioRoot, {\n Root: AspectRatioRoot,\n});\n\nexport type AspectRatio = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n AspectRatioRootProps,\n AspectRatioRootProps as AspectRatioProps,\n} from \"./aspect-ratio\";\nexport { AspectRatioRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/aspect-ratio/index.ts" }, { "path": "registry/native-ui/src/components/autocomplete/autocomplete.tsx", "content": "import { Children, forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { CloseIcon, IconChevronDown } from \"../icons\";\nimport { Text } from \"../text\";\n\nexport const autocompleteVariants = tv({\n slots: {\n base: \"relative gap-1.5\",\n clearButton: \"size-8 items-center justify-center rounded-full bg-default\",\n filter: \"gap-1\",\n indicator: \"ml-auto size-5 items-center justify-center\",\n popover: \"max-h-72 gap-1 rounded-2xl border border-border bg-background p-2\",\n trigger: \"min-h-11 flex-row items-center gap-2 rounded-xl border border-border px-3 py-2\",\n value: \"min-w-0 flex-1\",\n valueText: \"text-sm text-foreground\",\n },\n variants: {\n fullWidth: {\n false: {},\n true: {\n base: \"w-full\",\n trigger: \"w-full\",\n },\n },\n variant: {\n primary: {},\n secondary: {\n trigger: \"bg-default\",\n },\n },\n },\n defaultVariants: {\n fullWidth: false,\n variant: \"primary\",\n },\n});\n\nexport type AutocompleteVariants = VariantProps;\n\nfunction renderTextChildren(children: ReactNode, className: string) {\n return Children.map(children, (child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return {child};\n }\n return child;\n });\n}\n\nexport interface AutocompleteRootProps<\n TValue = object,\n Mode extends \"multiple\" | \"single\" = \"single\",\n> extends Omit,\n AutocompleteVariants {\n children?: ReactNode | ((props: { items?: Iterable; selectionMode?: Mode }) => ReactNode);\n className?: string;\n isDisabled?: boolean;\n items?: Iterable;\n onClear?: () => void;\n selectedKey?: string | number | null;\n selectedKeys?: Set;\n selectionMode?: Mode;\n}\n\nfunction AutocompleteRootInner(\n {\n children,\n className,\n fullWidth,\n isDisabled,\n items,\n onClear: _onClear,\n selectionMode,\n variant,\n ...props\n }: AutocompleteRootProps,\n ref: React.ForwardedRef,\n) {\n const slots = autocompleteVariants({ fullWidth, variant });\n\n return (\n \n {typeof children === \"function\" ? children({ items, selectionMode }) : children}\n \n );\n}\n\nconst AutocompleteRoot = forwardRef(AutocompleteRootInner) as <\n TValue = object,\n Mode extends \"multiple\" | \"single\" = \"single\",\n>(\n props: AutocompleteRootProps & { ref?: React.ForwardedRef },\n) => React.ReactElement | null;\n\nexport interface AutocompleteTriggerProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst AutocompleteTrigger = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = autocompleteVariants();\n return (\n \n {children}\n \n );\n },\n);\n\nexport interface AutocompleteValueProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n placeholder?: ReactNode;\n}\n\nconst AutocompleteValue = forwardRef(\n ({ children, className, placeholder, ...props }, ref) => {\n const slots = autocompleteVariants();\n return (\n \n {renderTextChildren(children ?? placeholder, slots.valueText())}\n \n );\n },\n);\n\nexport interface AutocompleteIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst AutocompleteIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = autocompleteVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport interface AutocompletePopoverProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n placement?: \"bottom\" | \"left\" | \"right\" | \"top\";\n}\n\nconst AutocompletePopover = forwardRef(\n ({ className, placement: _placement, ...props }, ref) => {\n const slots = autocompleteVariants();\n return ;\n },\n);\n\nexport interface AutocompleteFilterProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst AutocompleteFilter = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = autocompleteVariants();\n return ;\n },\n);\n\nexport interface AutocompleteClearButtonProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst AutocompleteClearButton = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = autocompleteVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport {\n AutocompleteClearButton,\n AutocompleteFilter,\n AutocompleteIndicator,\n AutocompletePopover,\n AutocompleteRoot,\n AutocompleteTrigger,\n AutocompleteValue,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/autocomplete/autocomplete.tsx" }, { "path": "registry/native-ui/src/components/autocomplete/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n AutocompleteClearButton,\n AutocompleteFilter,\n AutocompleteIndicator,\n AutocompletePopover,\n AutocompleteRoot,\n AutocompleteTrigger,\n AutocompleteValue,\n} from \"./autocomplete\";\n\nexport const Autocomplete = Object.assign(AutocompleteRoot, {\n ClearButton: AutocompleteClearButton,\n Filter: AutocompleteFilter,\n Indicator: AutocompleteIndicator,\n Popover: AutocompletePopover,\n Root: AutocompleteRoot,\n Trigger: AutocompleteTrigger,\n Value: AutocompleteValue,\n});\n\nexport type Autocomplete = {\n ClearButtonProps: ComponentProps;\n FilterProps: ComponentProps;\n IndicatorProps: ComponentProps;\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n ValueProps: ComponentProps;\n};\n\nexport type {\n AutocompleteClearButtonProps,\n AutocompleteFilterProps,\n AutocompleteIndicatorProps,\n AutocompletePopoverProps,\n AutocompleteRootProps,\n AutocompleteRootProps as AutocompleteProps,\n AutocompleteTriggerProps,\n AutocompleteValueProps,\n AutocompleteVariants,\n} from \"./autocomplete\";\n\nexport {\n AutocompleteClearButton,\n AutocompleteFilter,\n AutocompleteIndicator,\n AutocompletePopover,\n AutocompleteRoot,\n AutocompleteTrigger,\n AutocompleteValue,\n autocompleteVariants,\n} from \"./autocomplete\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/autocomplete/index.ts" }, { "path": "registry/native-ui/src/components/avatar/avatar.animation.ts", "content": "import { Easing, FadeIn, useAnimatedStyle, withTiming } from \"react-native-reanimated\";\nimport { useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport type { AnimationRootDisableAll } from \"../../helpers/internal/types\";\nimport {\n getAnimationState,\n getAnimationValueMergedConfig,\n getAnimationValueProperty,\n getIsAnimationDisabledValue,\n} from \"../../helpers/internal/utils\";\nimport * as AvatarPrimitives from \"../../primitives/avatar\";\nimport type { AvatarFallbackAnimation, AvatarImageAnimation } from \"./avatar\";\n\n/**\n * Animation hook for Avatar root component\n * Handles root-level animation configuration and provides context for child components\n */\nexport function useAvatarRootAnimation(options: {\n animation: AnimationRootDisableAll | undefined;\n}) {\n const { animation } = options;\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n return {\n isAllAnimationsDisabled,\n };\n}\n\n/**\n * Animation hook for Avatar Image component\n * Handles opacity animation for the avatar image based on loading status\n */\nexport function useAvatarImageAnimation(options: { animation: AvatarImageAnimation | undefined }) {\n const { animation } = options;\n\n // Read from global animation context (always available in compound parts)\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { status } = AvatarPrimitives.useRootContext();\n\n const { animationConfig, isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Opacity animation\n const opacityValue = getAnimationValueProperty({\n animationValue: animationConfig?.opacity,\n property: \"value\",\n defaultValue: [0, 1] as [number, number],\n });\n const opacityTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.opacity,\n property: \"timingConfig\",\n defaultValue: { duration: 200, easing: Easing.in(Easing.ease) },\n });\n\n const rImageStyle = useAnimatedStyle(() => {\n const isLoaded = status === \"loaded\";\n const targetOpacity = isLoaded ? opacityValue[1] : opacityValue[0];\n\n if (isAnimationDisabledValue) {\n return {\n opacity: targetOpacity,\n };\n }\n\n return {\n opacity: withTiming(targetOpacity, opacityTimingConfig),\n };\n });\n\n return {\n rImageStyle,\n };\n}\n\n/**\n * Animation hook for Avatar Fallback component\n * Handles entering animation for the avatar fallback\n */\nexport function useAvatarFallbackAnimation(options: {\n animation: AvatarFallbackAnimation | undefined;\n delayMs?: number;\n}) {\n const { animation, delayMs } = options;\n\n // Read from global animation context (always available in compound parts)\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { animationConfig, isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Entering animation\n const enteringValue = getAnimationValueProperty({\n animationValue: animationConfig?.entering,\n property: \"value\",\n defaultValue: FadeIn.duration(200)\n .easing(Easing.in(Easing.ease))\n .delay(delayMs ?? 0),\n });\n\n return {\n entering: isAnimationDisabledValue ? undefined : enteringValue,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/avatar.animation.ts" }, { "path": "registry/native-ui/src/components/avatar/avatar.context.ts", "content": "import { createContext } from \"../../helpers/internal/utils\";\nimport type { AvatarContextValue } from \"./avatar\";\n\n/**\n * Avatar context provider and hook\n * Provides size, color, and animation state to child components\n */\nexport const [AvatarProvider, useInnerAvatarContext] = createContext({\n name: \"AvatarContext\",\n});\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/avatar.context.ts" }, { "path": "registry/native-ui/src/components/avatar/avatar.tsx", "content": "import { forwardRef, useMemo } from \"react\";\nimport {\n type ImageSourcePropType,\n type ImageProps as RNImageProps,\n StyleSheet,\n type TextProps,\n type TextStyle,\n type ViewStyle,\n} from \"react-native\";\nimport Animated, {\n type AnimatedProps,\n type EntryOrExitLayoutType,\n type WithTimingConfig,\n} from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { useThemeColor } from \"../../helpers/external/hooks\";\nimport { HeroText } from \"../../helpers/internal/components\";\nimport { AnimationSettingsProvider } from \"../../helpers/internal/contexts\";\nimport type {\n Animation,\n AnimationRootDisableAll,\n AnimationValue,\n ElementSlots,\n} from \"../../helpers/internal/types\";\nimport { childrenToString, combineStyles } from \"../../helpers/internal/utils\";\nimport type {\n FallbackProps as PrimitiveFallbackProps,\n FallbackRef as PrimitiveFallbackRef,\n ImageProps as PrimitiveImageProps,\n ImageRef as PrimitiveImageRef,\n RootProps as PrimitiveRootProps,\n RootRef as PrimitiveRootRef,\n} from \"../../primitives/avatar\";\nimport * as AvatarPrimitives from \"../../primitives/avatar\";\nimport type { ImageProps } from \"../../primitives/avatar/avatar.types\";\nimport {\n useAvatarFallbackAnimation,\n useAvatarImageAnimation,\n useAvatarRootAnimation,\n} from \"./avatar.animation\";\nimport { AvatarProvider, useInnerAvatarContext } from \"./avatar.context\";\nimport type { PersonIconProps } from \"./person-icon\";\nimport { PersonIcon } from \"./person-icon\";\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Available sizes for the Avatar component\n */\nexport type AvatarSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Available variants for the Avatar component\n */\nexport type AvatarVariant = \"default\" | \"soft\";\n\n/**\n * Available color variants for the Avatar component\n */\nexport type AvatarColor = \"accent\" | \"default\" | \"success\" | \"warning\" | \"danger\";\n\n/**\n * Props for the Avatar root component\n */\nexport interface AvatarRootProps extends PrimitiveRootProps {\n /** @default 'md' */\n size?: AvatarSize;\n /** @default 'default' */\n variant?: AvatarVariant;\n /** @default 'accent' */\n color?: AvatarColor;\n className?: string;\n animation?: AnimationRootDisableAll;\n}\n\n/**\n * Animation configuration for avatar image component\n */\nexport type AvatarImageAnimation = Animation<{\n opacity?: AnimationValue<{\n value?: [number, number];\n timingConfig?: WithTimingConfig;\n }>;\n}>;\n\n/**\n * Props for the Avatar image component\n */\nexport type AvatarImageProps =\n | (AnimatedProps & {\n className?: string;\n asChild?: false;\n animation?: AvatarImageAnimation;\n isAnimatedStyleActive?: boolean;\n })\n | (PrimitiveImageProps & {\n className?: string;\n asChild: true;\n });\n\n/**\n * Animation configuration for avatar fallback component\n */\nexport type AvatarFallbackAnimation = Animation<{\n entering?: AnimationValue<{\n value?: EntryOrExitLayoutType;\n }>;\n}>;\n\n/**\n * Props for the Avatar fallback component\n */\nexport interface AvatarFallbackProps\n extends Omit, \"entering\"> {\n /** @default 0 */\n delayMs?: number;\n color?: AvatarColor;\n className?: string;\n classNames?: ElementSlots;\n styles?: {\n container?: ViewStyle;\n text?: TextStyle;\n };\n textProps?: TextProps;\n iconProps?: PersonIconProps;\n animation?: AvatarFallbackAnimation;\n}\n\n/**\n * Context value shared between Avatar components\n */\nexport interface AvatarContextValue {\n size: AvatarSize;\n color: AvatarColor;\n}\n\n/** Reference type for the Avatar root component */\nexport type AvatarRootRef = PrimitiveRootRef;\n\n/** Reference type for the Avatar image component */\nexport type AvatarImageRef = PrimitiveImageRef;\n\n/** Reference type for the Avatar fallback component */\nexport type AvatarFallbackRef = PrimitiveFallbackRef;\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for Avatar components\n */\nexport const AVATAR_DISPLAY_NAME = {\n ROOT: \"PitsiUINative.Avatar\",\n IMAGE: \"PitsiUINative.Avatar.Image\",\n FALLBACK: \"PitsiUINative.Avatar.Fallback\",\n};\n\n/**\n * Default icon sizes for different avatar sizes\n */\nexport const AVATAR_DEFAULT_ICON_SIZE: Record = {\n sm: 14,\n md: 16,\n lg: 20,\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"items-center justify-center overflow-hidden rounded-full\",\n variants: {\n variant: {\n default: \"bg-default\",\n soft: \"\",\n },\n size: {\n sm: \"size-10\",\n md: \"size-12\",\n lg: \"size-16\",\n },\n color: {\n accent: \"\",\n default: \"\",\n success: \"\",\n warning: \"\",\n danger: \"\",\n },\n },\n compoundVariants: [\n {\n variant: \"soft\",\n color: \"accent\",\n className: \"bg-accent/15\",\n },\n {\n variant: \"soft\",\n color: \"default\",\n className: \"bg-default\",\n },\n {\n variant: \"soft\",\n color: \"success\",\n className: \"bg-success/15\",\n },\n {\n variant: \"soft\",\n color: \"warning\",\n className: \"bg-warning/15\",\n },\n {\n variant: \"soft\",\n color: \"danger\",\n className: \"bg-danger/15\",\n },\n ],\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n color: \"accent\",\n },\n});\n\nconst image = tv({\n base: \"h-full w-full\",\n});\n\nconst fallback = tv({\n slots: {\n container: \"h-full w-full items-center justify-center rounded-full\",\n text: \"font-medium\",\n },\n variants: {\n size: {\n sm: {\n text: \"text-xs\",\n },\n md: {\n text: \"text-sm\",\n },\n lg: {\n text: \"text-base\",\n },\n },\n color: {\n default: {\n text: \"text-default-foreground\",\n },\n accent: {\n text: \"text-accent\",\n },\n success: {\n text: \"text-success\",\n },\n warning: {\n text: \"text-warning\",\n },\n danger: {\n text: \"text-danger\",\n },\n },\n },\n defaultVariants: {\n size: \"md\",\n color: \"default\",\n },\n});\n\nexport const avatarClassNames = combineStyles({\n root,\n image,\n fallback,\n});\n\nexport const avatarStyleSheet = StyleSheet.create({\n borderCurve: {\n borderCurve: \"continuous\",\n },\n});\n\n/**\n * Export slot types for type-safe classNames props\n */\nexport type AvatarFallbackSlots = keyof ReturnType;\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar.Root\n * -----------------------------------------------------------------------------------------------*/\nconst AnimatedFallback = Animated.createAnimatedComponent(AvatarPrimitives.Fallback);\n\n/**\n * Hook to access Avatar primitive root context\n */\nconst useAvatar = AvatarPrimitives.useRootContext;\n\nconst AvatarRoot = forwardRef((props, ref) => {\n const {\n children,\n size = \"md\",\n variant = \"default\",\n color = \"accent\",\n className,\n style,\n animation,\n ...restProps\n } = props;\n\n const rootClassName = avatarClassNames.root({\n variant,\n size,\n color,\n className,\n });\n\n const { isAllAnimationsDisabled } = useAvatarRootAnimation({\n animation,\n });\n\n const contextValue = useMemo(\n () => ({\n size,\n color,\n }),\n [size, color],\n );\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n return (\n \n \n \n {children}\n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar.Image\n * -----------------------------------------------------------------------------------------------*/\nconst AvatarImage = forwardRef((props, ref) => {\n const { className, style: styleProp, source, asChild, ...restProps } = props;\n\n const animation = asChild ? undefined : \"animation\" in props ? props.animation : undefined;\n\n const isAnimatedStyleActive = asChild\n ? true\n : \"isAnimatedStyleActive\" in props\n ? (props.isAnimatedStyleActive ?? true)\n : true;\n\n const { rImageStyle } = useAvatarImageAnimation({\n animation,\n });\n\n const imageClassName = avatarClassNames.image({\n className,\n });\n\n const imageStyle = isAnimatedStyleActive ? [rImageStyle, styleProp] : styleProp;\n\n if (asChild) {\n return (\n )}\n />\n );\n }\n\n return (\n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar.Fallback\n * -----------------------------------------------------------------------------------------------*/\nconst DefaultFallbackIcon: React.FC<{\n sizeVariant: AvatarSize;\n colorVariant: AvatarColor;\n iconProps?: PersonIconProps;\n}> = ({ sizeVariant, colorVariant, iconProps }) => {\n const [\n themeColorDefaultForeground,\n themeColorAccent,\n themeColorSuccess,\n themeColorWarning,\n themeColorDanger,\n ] = useThemeColor([\"default-foreground\", \"accent\", \"success\", \"warning\", \"danger\"]);\n\n const iconSize = iconProps?.size ?? AVATAR_DEFAULT_ICON_SIZE[sizeVariant];\n\n const defaultIconColorMap: Record = {\n default: themeColorDefaultForeground,\n accent: themeColorAccent,\n success: themeColorSuccess,\n warning: themeColorWarning,\n danger: themeColorDanger,\n };\n\n const iconColor = iconProps?.color ?? defaultIconColorMap[colorVariant];\n\n return ;\n};\n\nconst AvatarFallback = forwardRef((props, ref) => {\n const { size, color: contextColor } = useInnerAvatarContext();\n\n const {\n children,\n color: colorProp,\n className,\n classNames,\n style,\n styles,\n textProps,\n iconProps,\n delayMs,\n animation,\n ...restProps\n } = props;\n\n const stringifiedChildren = childrenToString(children);\n\n const color = colorProp ?? contextColor;\n\n const { container, text } = avatarClassNames.fallback({\n size,\n color,\n });\n\n const fallbackContainerClassName = container({\n className: [className, classNames?.container],\n });\n\n const fallbackTextClassName = text({\n className: [classNames?.text, textProps?.className],\n });\n\n const { entering } = useAvatarFallbackAnimation({\n animation,\n delayMs,\n });\n\n return (\n \n {children ? (\n stringifiedChildren ? (\n \n {stringifiedChildren}\n \n ) : (\n children\n )\n ) : (\n \n )}\n \n );\n});\n\nAvatarRoot.displayName = AVATAR_DISPLAY_NAME.ROOT;\nAvatarImage.displayName = AVATAR_DISPLAY_NAME.IMAGE;\nAvatarFallback.displayName = AVATAR_DISPLAY_NAME.FALLBACK;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Avatar - Main container that manages avatar display state.\n * @component Avatar.Image - Optional image component that displays the avatar image.\n * @component Avatar.Fallback - Optional fallback component shown when image fails to load.\n *\n * @see https://pitsiui.com/docs/native/components/avatar\n * -----------------------------------------------------------------------------------------------*/\nconst Avatar = Object.assign(AvatarRoot, {\n /** @optional Displays the avatar image with loading state management */\n Image: AvatarImage,\n /** @optional Shows fallback content when image is unavailable */\n Fallback: AvatarFallback,\n});\n\nexport default Avatar;\nexport { Avatar, useAvatar };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/avatar.tsx" }, { "path": "registry/native-ui/src/components/avatar/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Avatar, Separator, Text } from \"../..\";\n\nconst users = [\n {\n id: 1,\n image: \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg\",\n name: \"John Doe\",\n },\n {\n id: 2,\n image: \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg\",\n name: \"Kate Wilson\",\n },\n {\n id: 3,\n image: \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg\",\n name: \"Emily Chen\",\n },\n {\n id: 4,\n image: \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg\",\n name: \"Michael Brown\",\n },\n {\n id: 5,\n image: \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg\",\n name: \"Olivia Davis\",\n },\n];\n\nconst colors = [\"default\", \"accent\", \"success\", \"warning\", \"danger\"] as const;\n\nfunction initials(name: string) {\n return name\n .split(\" \")\n .map((part) => part[0])\n .join(\"\");\n}\n\nexport function Basic() {\n return (\n \n \n \n JD\n \n \n \n B\n \n \n JR\n \n \n );\n}\n\nexport function Colors() {\n return (\n \n {colors.map((color) => (\n \n {color.slice(0, 2).toUpperCase()}\n \n ))}\n \n );\n}\n\nexport function CustomStyles() {\n return (\n \n \n \n XL\n \n\n \n \n SQ\n \n\n \n \n GB\n \n\n \n \n \n ON\n \n \n \n \n );\n}\n\nexport function Fallback() {\n return (\n \n \n JD\n \n\n \n \n P\n \n \n\n \n \n NA\n \n\n \n \n GB\n \n \n \n );\n}\n\nexport function Group() {\n return (\n \n \n {users.slice(0, 4).map((user, index) => (\n \n \n {initials(user.name)}\n \n ))}\n \n\n \n {users.slice(0, 3).map((user, index) => (\n \n \n {initials(user.name)}\n \n ))}\n \n \n +{users.length - 3}\n \n \n \n \n );\n}\n\nexport function Sizes() {\n return (\n \n \n \n SM\n \n \n \n MD\n \n \n \n LG\n \n \n );\n}\n\nexport function Variants() {\n const rows = [\n { label: \"letter\", soft: false },\n { label: \"letter soft\", soft: true },\n { label: \"icon\", soft: false },\n { label: \"icon soft\", soft: true },\n ];\n\n return (\n \n \n \n {colors.map((color) => (\n \n {color}\n \n ))}\n \n\n \n\n {rows.map((row) => (\n \n {row.label}\n {colors.map((color) => (\n \n \n {row.label.includes(\"icon\") ? \"P\" : \"AG\"}\n \n \n ))}\n \n ))}\n\n \n img\n {users.slice(0, colors.length).map((user, index) => (\n \n \n \n {initials(user.name).slice(0, 1)}\n \n \n ))}\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/demos/index.tsx" }, { "path": "registry/native-ui/src/components/avatar/index.ts", "content": "export type {\n AvatarColor,\n AvatarContextValue,\n AvatarFallbackProps,\n AvatarFallbackRef,\n AvatarImageProps,\n AvatarImageRef,\n AvatarRootProps,\n AvatarRootRef,\n AvatarSize,\n} from \"./avatar\";\nexport { Avatar, avatarClassNames, default, useAvatar } from \"./avatar\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/index.ts" }, { "path": "registry/native-ui/src/components/avatar/person-icon.tsx", "content": "import type React from \"react\";\nimport Svg, { Path } from \"react-native-svg\";\n\nexport interface PersonIconProps {\n size?: number;\n color?: string;\n}\n\nexport const PersonIcon: React.FC = ({ size = 16, color = \"currentColor\" }) => {\n return (\n \n \n \n );\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/avatar/person-icon.tsx" }, { "path": "registry/native-ui/src/components/badge/badge.tsx", "content": "import { createContext, forwardRef, type ReactNode, useContext, useMemo } from \"react\";\nimport { type StyleProp, type TextProps, View, type ViewProps, type ViewStyle } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nconst badgeVariants = tv({\n defaultVariants: {\n color: \"default\",\n placement: \"top-right\",\n size: \"md\",\n variant: \"primary\",\n },\n slots: {\n anchor: \"relative self-start\",\n base: \"absolute items-center justify-center border border-background\",\n label: \"font-medium tabular-nums\",\n },\n variants: {\n color: {\n accent: {},\n danger: {},\n default: {},\n success: {},\n warning: {},\n },\n placement: {\n \"bottom-left\": {},\n \"bottom-right\": {},\n \"top-left\": {},\n \"top-right\": {},\n },\n size: {\n lg: {\n base: \"min-h-8 min-w-8 rounded-2xl px-2\",\n label: \"text-sm\",\n },\n md: {\n base: \"min-h-7 min-w-7 rounded-3xl px-1.5\",\n label: \"text-xs\",\n },\n sm: {\n base: \"min-h-4 min-w-4 rounded-xl px-1\",\n label: \"text-[10px]\",\n },\n },\n variant: {\n primary: {},\n secondary: {\n base: \"bg-default\",\n label: \"text-default-foreground\",\n },\n soft: {},\n },\n },\n compoundVariants: [\n {\n color: \"accent\",\n variant: \"primary\",\n className: { base: \"bg-accent\", label: \"text-accent-foreground\" },\n },\n {\n color: \"danger\",\n variant: \"primary\",\n className: { base: \"bg-danger\", label: \"text-danger-foreground\" },\n },\n {\n color: \"default\",\n variant: \"primary\",\n className: { base: \"bg-default\", label: \"text-default-foreground\" },\n },\n {\n color: \"success\",\n variant: \"primary\",\n className: { base: \"bg-success\", label: \"text-success-foreground\" },\n },\n {\n color: \"warning\",\n variant: \"primary\",\n className: { base: \"bg-warning\", label: \"text-warning-foreground\" },\n },\n { color: \"accent\", variant: \"soft\", className: { base: \"bg-accent/15\", label: \"text-accent\" } },\n { color: \"danger\", variant: \"soft\", className: { base: \"bg-danger/15\", label: \"text-danger\" } },\n {\n color: \"default\",\n variant: \"soft\",\n className: { base: \"bg-default\", label: \"text-default-foreground\" },\n },\n {\n color: \"success\",\n variant: \"soft\",\n className: { base: \"bg-success/15\", label: \"text-success\" },\n },\n {\n color: \"warning\",\n variant: \"soft\",\n className: { base: \"bg-warning/15\", label: \"text-warning\" },\n },\n ],\n});\n\nexport type BadgeVariants = VariantProps;\n\ninterface BadgeContextValue {\n slots: ReturnType;\n}\n\nconst BadgeContext = createContext(null);\n\nexport interface BadgeAnchorProps extends ViewProps {\n children: ReactNode;\n className?: string;\n}\n\nconst BadgeAnchor = forwardRef(({ children, className, ...props }, ref) => {\n const slots = badgeVariants();\n\n return (\n \n {children}\n \n );\n});\n\nBadgeAnchor.displayName = \"PitsiUINative.Badge.Anchor\";\n\nexport interface BadgeRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n color?: BadgeVariants[\"color\"];\n placement?: BadgeVariants[\"placement\"];\n size?: BadgeVariants[\"size\"];\n variant?: BadgeVariants[\"variant\"];\n}\n\nfunction placementStyle(placement: BadgeVariants[\"placement\"]): StyleProp {\n switch (placement) {\n case \"bottom-left\":\n return { bottom: 0, left: 0, transform: [{ translateX: -4 }, { translateY: 4 }] };\n case \"bottom-right\":\n return { bottom: 0, right: 0, transform: [{ translateX: 4 }, { translateY: 4 }] };\n case \"top-left\":\n return { left: 0, top: 0, transform: [{ translateX: -4 }, { translateY: -4 }] };\n default:\n return { right: 0, top: 0, transform: [{ translateX: 4 }, { translateY: -4 }] };\n }\n}\n\nconst BadgeRoot = forwardRef(\n (\n {\n children,\n className,\n color = \"default\",\n placement = \"top-right\",\n size = \"md\",\n style,\n variant = \"primary\",\n ...props\n },\n ref,\n ) => {\n const slots = useMemo(\n () => badgeVariants({ color, placement, size, variant }),\n [color, placement, size, variant],\n );\n const content =\n typeof children === \"string\" || typeof children === \"number\" ? (\n {children}\n ) : (\n children\n );\n\n return (\n \n \n {content}\n \n \n );\n },\n);\n\nBadgeRoot.displayName = \"PitsiUINative.Badge\";\n\nexport interface BadgeLabelProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst BadgeLabel = forwardRef, BadgeLabelProps>(\n ({ children, className, ...props }, ref) => {\n const context = useContext(BadgeContext);\n\n return (\n \n {children}\n \n );\n },\n);\n\nBadgeLabel.displayName = \"PitsiUINative.Badge.Label\";\n\nexport { BadgeAnchor, BadgeLabel, BadgeRoot, badgeVariants };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/badge/badge.tsx" }, { "path": "registry/native-ui/src/components/badge/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Avatar, Badge, Separator, Text } from \"../..\";\n\nconst AVATAR_URL = \"https://pitsiui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg\";\nconst colors = [\"default\", \"accent\", \"success\", \"warning\", \"danger\"] as const;\n\nfunction AvatarBadge({\n children,\n color = \"danger\",\n label = \"John Doe\",\n placement = \"top-right\",\n size = \"sm\",\n variant = \"primary\",\n}: {\n children?: React.ReactNode;\n color?: \"accent\" | \"danger\" | \"default\" | \"success\" | \"warning\";\n label?: string;\n placement?: \"bottom-left\" | \"bottom-right\" | \"top-left\" | \"top-right\";\n size?: \"sm\" | \"md\" | \"lg\";\n variant?: \"primary\" | \"secondary\" | \"soft\";\n}) {\n return (\n \n \n \n JD\n \n \n {children}\n \n \n );\n}\n\nexport function Basic() {\n return (\n \n 5\n New\n \n \n );\n}\n\nexport function Colors() {\n return (\n \n {colors.map((color) => (\n \n ))}\n \n );\n}\n\nexport function Dot() {\n return (\n \n {colors\n .filter((color) => color !== \"default\")\n .map((color) => (\n \n ))}\n \n );\n}\n\nexport function Placements() {\n const placements = [\"top-right\", \"top-left\", \"bottom-right\", \"bottom-left\"] as const;\n\n return (\n \n {placements.map((placement) => (\n \n \n {placement}\n \n ))}\n \n );\n}\n\nexport function Sizes() {\n return (\n \n {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n \n 5\n \n ))}\n \n );\n}\n\nexport function Variants() {\n const variants = [\"primary\", \"secondary\", \"soft\"] as const;\n\n return (\n \n {variants.map((variant, index) => (\n \n {variant}\n \n {colors.map((color) => (\n \n 5\n \n ))}\n \n {index < variants.length - 1 ? : null}\n \n ))}\n \n );\n}\n\nexport function WithContent() {\n return (\n \n 5\n New\n 99+\n \n !\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/badge/demos/index.tsx" }, { "path": "registry/native-ui/src/components/badge/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { BadgeAnchor, BadgeLabel, BadgeRoot } from \"./badge\";\n\nexport const Badge = Object.assign(BadgeRoot, {\n Anchor: BadgeAnchor,\n Label: BadgeLabel,\n Root: BadgeRoot,\n});\n\nexport type Badge = {\n AnchorProps: ComponentProps;\n LabelProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n BadgeAnchorProps,\n BadgeLabelProps,\n BadgeRootProps,\n BadgeRootProps as BadgeProps,\n BadgeVariants,\n} from \"./badge\";\nexport { BadgeAnchor, BadgeLabel, BadgeRoot, badgeVariants } from \"./badge\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/badge/index.ts" }, { "path": "registry/native-ui/src/components/bottom-sheet/bottom-sheet.shared.ts", "content": "import { StyleSheet } from \"react-native\";\nimport { tv } from \"tailwind-variants\";\nimport { useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport type { AnimationDisabled } from \"../../helpers/internal/types\";\nimport {\n combineStyles,\n getAnimationState,\n getIsAnimationDisabledValue,\n} from \"../../helpers/internal/utils\";\n\nconst overlay = tv({\n base: \"absolute inset-0 bg-backdrop\",\n});\n\nconst contentContainer = tv({\n base: \"flex-1 p-5 pb-safe-offset-3 bg-transparent\",\n});\n\nconst contentBackground = tv({\n base: \"bg-overlay rounded-t-4xl shadow-overlay\",\n});\n\nconst contentHandleIndicator = tv({\n base: \"bg-separator\",\n});\n\nconst close = tv({\n base: \"\",\n});\n\nconst label = tv({\n base: \"text-lg font-medium text-foreground\",\n});\n\nconst description = tv({\n base: \"text-base text-muted\",\n});\n\nexport const bottomSheetClassNames = combineStyles({\n overlay,\n contentContainer,\n contentBackground,\n contentHandleIndicator,\n close,\n label,\n description,\n});\n\nexport const bottomSheetStyleSheet = StyleSheet.create({\n contentContainer: {\n borderCurve: \"continuous\",\n },\n});\n\n/**\n * Animation hook for BottomSheet Content component.\n * Kept outside the compound component module so reusable internal content can\n * consume it without importing the public BottomSheet component back into\n * itself.\n */\nexport function useBottomSheetContentAnimation(options: {\n /** Animation configuration for bottom sheet content */\n animation: AnimationDisabled | undefined;\n}) {\n const { animation } = options;\n\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n return {\n isAnimationDisabledValue,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/bottom-sheet/bottom-sheet.shared.ts" }, { "path": "registry/native-ui/src/components/bottom-sheet/bottom-sheet.tsx", "content": "import type GorhomBottomSheet from \"@gorhom/bottom-sheet\";\nimport type { BottomSheetProps } from \"@gorhom/bottom-sheet\";\nimport { forwardRef, type ReactNode, useMemo } from \"react\";\nimport {\n type GestureResponderEvent,\n type Text as RNText,\n StyleSheet,\n type TextProps,\n} from \"react-native\";\nimport Animated, { type SharedValue, useSharedValue } from \"react-native-reanimated\";\nimport { BottomSheetContent as InternalBottomSheetContent } from \"../../helpers/internal/components/bottom-sheet-content\";\nimport { FullWindowOverlay } from \"../../helpers/internal/components/full-window-overlay\";\nimport { HeroText } from \"../../helpers/internal/components/hero-text\";\nimport { AnimationSettingsProvider, useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport { usePopupOverlayAnimation, usePopupRootAnimation } from \"../../helpers/internal/hooks\";\nimport type {\n AnimationRootDisableAll,\n BaseBottomSheetContentProps,\n PopupOverlayAnimation,\n PressableRef,\n} from \"../../helpers/internal/types\";\nimport { createContext } from \"../../helpers/internal/utils\";\nimport * as BottomSheetPrimitives from \"../../primitives/bottom-sheet\";\nimport type * as BottomSheetPrimitivesTypes from \"../../primitives/bottom-sheet/bottom-sheet.types\";\nimport { CloseButton, type CloseButtonProps } from \"../close-button\";\nimport { bottomSheetClassNames, bottomSheetStyleSheet } from \"./bottom-sheet.shared\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for BottomSheet components\n */\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.BottomSheet.Root\",\n TRIGGER: \"PitsiUINative.BottomSheet.Trigger\",\n PORTAL: \"PitsiUINative.BottomSheet.Portal\",\n OVERLAY: \"PitsiUINative.BottomSheet.Overlay\",\n CONTENT: \"PitsiUINative.BottomSheet.Content\",\n CLOSE: \"PitsiUINative.BottomSheet.Close\",\n TITLE: \"PitsiUINative.BottomSheet.Title\",\n DESCRIPTION: \"PitsiUINative.BottomSheet.Description\",\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Context value for bottom sheet animation state\n */\nexport interface BottomSheetAnimationContextValue {\n /** Animation progress shared value (0=idle, 1=open, 2=close) */\n progress: SharedValue;\n /** Dragging state shared value */\n isDragging: SharedValue;\n}\n\n/**\n * BottomSheet Root component props\n */\nexport interface BottomSheetRootProps extends BottomSheetPrimitivesTypes.RootProps {\n /**\n * The content of the bottom sheet\n */\n children?: ReactNode;\n /**\n * Animation configuration for bottom sheet root\n * - `\"disable-all\"`: Disable all animations including children\n * - `undefined`: Use default animations\n */\n animation?: AnimationRootDisableAll;\n}\n\n/**\n * BottomSheet Trigger component props\n */\nexport interface BottomSheetTriggerProps extends BottomSheetPrimitivesTypes.TriggerProps {\n /**\n * The trigger element content\n */\n children?: ReactNode;\n}\n\n/**\n * BottomSheet Portal component props\n */\nexport interface BottomSheetPortalProps extends BottomSheetPrimitivesTypes.PortalProps {\n /**\n * When true, uses a regular View instead of FullWindowOverlay on iOS.\n * Enables React Native element inspector but overlay won't appear above native modals.\n * @default false\n */\n disableFullWindowOverlay?: boolean;\n /**\n * Controls whether VoiceOver treats the overlay window as a modal container.\n * When `false`, VoiceOver can still access elements behind the overlay.\n * When `true`, VoiceOver is restricted to elements inside the overlay.\n * @default false\n * @platform ios\n * @unstable This prop maps directly to the native `accessibilityViewIsModal`\n * on the container view and may change in a future react-native-screens release.\n */\n unstable_accessibilityContainerViewIsModal?: boolean;\n /**\n * The portal content\n */\n children: ReactNode;\n}\n\n/**\n * BottomSheet Overlay component props\n */\nexport interface BottomSheetOverlayProps extends BottomSheetPrimitivesTypes.OverlayProps {\n /**\n * Additional CSS class for the overlay\n *\n * @note The following style properties are occupied by animations and cannot be set via className:\n * - `opacity` - Animated for overlay show/hide transitions (idle: 0, open: 1, close: 0)\n *\n * To customize this property, use the `animation` prop:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.\n */\n className?: string;\n /**\n * Animation configuration for overlay\n * - `false` or `\"disabled\"`: Disable all animations\n * - `true` or `undefined`: Use default animations\n * - `object`: Custom animation configuration\n */\n animation?: Omit;\n /**\n * Whether animated styles (react-native-reanimated) are active\n * When `false`, the animated style is removed and you can implement custom logic\n * This prop should only be used when you want to write custom styling logic instead of the default animated styles\n * @default true\n */\n isAnimatedStyleActive?: boolean;\n}\n\n/**\n * BottomSheet Content component props\n */\nexport interface BottomSheetContentProps\n extends Partial,\n BaseBottomSheetContentProps {}\n\n/**\n * BottomSheet Close component props\n *\n * Extends CloseButtonProps, allowing full override of all close button props.\n * Automatically handles bottom sheet close functionality when pressed.\n */\nexport type BottomSheetCloseProps = CloseButtonProps;\n\n/**\n * BottomSheet Title component props\n */\nexport interface BottomSheetTitleProps extends TextProps {\n /**\n * Additional CSS class for the title\n */\n className?: string;\n}\n\n/**\n * BottomSheet Description component props\n */\nexport interface BottomSheetDescriptionProps extends TextProps {\n /**\n * Additional CSS class for the description\n */\n className?: string;\n}\n\n/**\n * Return type for the useBottomSheetAnimation hook\n */\nexport interface UseBottomSheetAnimationReturn {\n /**\n * Animation progress shared value (0=idle, 1=open, 2=close)\n */\n progress: SharedValue;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Overlay style definition\n *\n * @note ANIMATED PROPERTIES (cannot be set via className):\n * The following property is animated and cannot be overridden using Tailwind classes:\n * - `opacity` - Animated for overlay show/hide transitions (idle: 0, open: 1, close: 0)\n *\n * To customize this property, use the `animation` prop on `BottomSheet.Overlay`:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and apply your own via className or style prop,\n * set `isAnimatedStyleActive={false}` on `BottomSheet.Overlay`.\n */\n/* -------------------------------------------------------------------------------------------------\n * Context / Animation\n * -----------------------------------------------------------------------------------------------*/\nconst [BottomSheetAnimationProvider, useBottomSheetAnimation] =\n createContext({\n name: \"BottomSheetAnimationContext\",\n });\n\nexport { BottomSheetAnimationProvider, useBottomSheetAnimation };\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\nconst AnimatedOverlay = Animated.createAnimatedComponent(BottomSheetPrimitives.Overlay);\n\nconst useBottomSheet = BottomSheetPrimitives.useRootContext;\n\n// --------------------------------------------------\n\nconst BottomSheetRoot = forwardRef(\n ({ children, isOpen, isDefaultOpen, onOpenChange, animation, ...props }, ref) => {\n const { progress, isDragging, isAllAnimationsDisabled } = usePopupRootAnimation({\n animation,\n });\n\n const animationContextValue = useMemo(\n () => ({\n progress,\n isDragging,\n }),\n [progress, isDragging],\n );\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n return (\n \n \n \n {children}\n \n \n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst BottomSheetTrigger = forwardRef<\n BottomSheetPrimitivesTypes.TriggerRef,\n BottomSheetTriggerProps\n>((props, ref) => {\n return ;\n});\n\n// --------------------------------------------------\n\nconst BottomSheetPortal = ({\n children,\n disableFullWindowOverlay = false,\n unstable_accessibilityContainerViewIsModal,\n ...props\n}: BottomSheetPortalProps) => {\n const animationSettingsContext = useAnimationSettings();\n const animationContext = useBottomSheetAnimation();\n\n return (\n \n \n \n \n \n {children}\n \n \n \n \n \n );\n};\n\n// --------------------------------------------------\n\nconst BottomSheetOverlay = forwardRef<\n BottomSheetPrimitivesTypes.OverlayRef,\n BottomSheetOverlayProps\n>(({ className, style, animation, isAnimatedStyleActive = true, ...props }, ref) => {\n const { isOpen } = useBottomSheet();\n const { progress } = useBottomSheetAnimation();\n const isDragging = useSharedValue(false);\n\n const overlayClassName = bottomSheetClassNames.overlay({ className });\n\n const { rContainerStyle } = usePopupOverlayAnimation({\n progress,\n isDragging,\n animation,\n });\n\n if (!isOpen) {\n return null;\n }\n\n const overlayStyle = isAnimatedStyleActive ? [rContainerStyle, style] : style;\n\n return (\n \n );\n});\n\n// --------------------------------------------------\n\nconst BottomSheetContent = forwardRef(\n (\n {\n children,\n index: initialIndex,\n backgroundClassName,\n handleIndicatorClassName,\n contentContainerClassName: contentContainerClassNameProp,\n contentContainerProps,\n animationConfigs,\n animation,\n ...restProps\n },\n ref,\n ) => {\n const { isOpen, onOpenChange } = useBottomSheet();\n\n const { progress, isDragging } = useBottomSheetAnimation();\n\n return (\n \n {children}\n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst BottomSheetClose = forwardRef((props, ref) => {\n const { onPress: onPressProp, ...restProps } = props;\n const { onOpenChange } = useBottomSheet();\n\n const onPress = (ev: GestureResponderEvent) => {\n onOpenChange(false);\n if (typeof onPressProp === \"function\") {\n onPressProp(ev);\n }\n };\n\n return ;\n});\n\n// --------------------------------------------------\n\nconst BottomSheetTitle = forwardRef(\n ({ className, children, ...props }, ref) => {\n const { nativeID } = useBottomSheet();\n const titleClassName = bottomSheetClassNames.label({ className });\n\n return (\n \n {children}\n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst BottomSheetDescription = forwardRef(\n ({ className, children, ...props }, ref) => {\n const { nativeID } = useBottomSheet();\n\n const descriptionClassName = bottomSheetClassNames.description({\n className,\n });\n\n return (\n \n {children}\n \n );\n },\n);\n\n// --------------------------------------------------\n\nBottomSheetRoot.displayName = DISPLAY_NAME.ROOT;\nBottomSheetTrigger.displayName = DISPLAY_NAME.TRIGGER;\nBottomSheetPortal.displayName = DISPLAY_NAME.PORTAL;\nBottomSheetOverlay.displayName = DISPLAY_NAME.OVERLAY;\nBottomSheetContent.displayName = DISPLAY_NAME.CONTENT;\nBottomSheetClose.displayName = DISPLAY_NAME.CLOSE;\nBottomSheetTitle.displayName = DISPLAY_NAME.TITLE;\nBottomSheetDescription.displayName = DISPLAY_NAME.DESCRIPTION;\n\n/**\n * Compound BottomSheet component with sub-components\n */\nconst BottomSheet = Object.assign(BottomSheetRoot, {\n /** @optional Trigger element to open the bottom sheet */\n Trigger: BottomSheetTrigger,\n /** @optional Portal container for overlay and content */\n Portal: BottomSheetPortal,\n /** @optional Background overlay */\n Overlay: BottomSheetOverlay,\n /** @optional Main bottom sheet content container */\n Content: BottomSheetContent,\n /** @optional Close button for the bottom sheet */\n Close: BottomSheetClose,\n /** @optional Bottom sheet title text */\n Title: BottomSheetTitle,\n /** @optional Bottom sheet description text */\n Description: BottomSheetDescription,\n});\n\nexport { useBottomSheet };\nexport default BottomSheet;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/bottom-sheet/bottom-sheet.tsx" }, { "path": "registry/native-ui/src/components/bottom-sheet/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { BottomSheet, Button, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n \n \n \n \n \n Profile\n Update visible account details.\n \n \n \n \n \n \n \n \n );\n}\n\nexport function Closed() {\n return (\n \n \n \n \n \n \n \n \n Actions\n \n This sheet starts closed and opens from trigger.\n \n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/bottom-sheet/demos/index.tsx" }, { "path": "registry/native-ui/src/components/bottom-sheet/index.ts", "content": "export type {\n BottomSheetAnimationContextValue,\n BottomSheetCloseProps,\n BottomSheetContentProps,\n BottomSheetDescriptionProps,\n BottomSheetOverlayProps,\n BottomSheetPortalProps,\n BottomSheetRootProps,\n BottomSheetTitleProps,\n BottomSheetTriggerProps,\n UseBottomSheetAnimationReturn,\n} from \"./bottom-sheet\";\nexport {\n BottomSheetAnimationProvider,\n default as BottomSheet,\n useBottomSheet,\n useBottomSheetAnimation,\n} from \"./bottom-sheet\";\nexport {\n bottomSheetClassNames,\n bottomSheetStyleSheet,\n useBottomSheetContentAnimation,\n} from \"./bottom-sheet.shared\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/bottom-sheet/index.ts" }, { "path": "registry/native-ui/src/components/breadcrumbs/breadcrumbs.tsx", "content": "import {\n Children,\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useContext,\n} from \"react\";\nimport { Linking, Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nconst breadcrumbsVariants = tv({\n slots: {\n base: \"flex-row flex-wrap items-center\",\n item: \"flex-row items-center gap-1 px-0.5\",\n link: \"text-sm font-medium text-muted underline-offset-4\",\n linkCurrent: \"text-link\",\n separator: \"text-xs text-muted\",\n },\n});\n\nexport type BreadcrumbsVariants = VariantProps;\n\ninterface BreadcrumbsContextValue {\n separator?: ReactNode;\n slots: ReturnType;\n}\n\nconst BreadcrumbsContext = createContext(null);\n\nexport interface BreadcrumbsRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n separator?: ReactNode;\n}\n\nconst BreadcrumbsRoot = forwardRef(\n ({ children, className, separator, ...props }, ref) => {\n const slots = breadcrumbsVariants();\n const childArray = Children.toArray(children);\n\n return (\n \n \n {childArray.map((child, index) => {\n if (!isValidElement(child)) return child;\n\n return cloneElement(child as ReactElement, {\n isLast: index === childArray.length - 1,\n });\n })}\n \n \n );\n },\n);\n\nBreadcrumbsRoot.displayName = \"PitsiUINative.Breadcrumbs\";\n\nexport interface BreadcrumbsItemProps extends Omit {\n children?: ReactNode;\n className?: string;\n href?: string;\n isCurrent?: boolean;\n isDisabled?: boolean;\n isLast?: boolean;\n}\n\nfunction openHref(href: string | undefined) {\n if (!href || href.startsWith(\"#\") || href.startsWith(\"/\")) return;\n void Linking.openURL(href);\n}\n\nfunction renderSeparator(separator: ReactNode) {\n if (separator == null) return >;\n if (typeof separator === \"string\" || typeof separator === \"number\") {\n return {separator};\n }\n return separator;\n}\n\nconst BreadcrumbsItem = forwardRef(\n (\n {\n children,\n className,\n href,\n isCurrent = false,\n isDisabled = false,\n isLast = false,\n onPress,\n ...props\n },\n ref,\n ) => {\n const context = useContext(BreadcrumbsContext);\n const slots = context?.slots ?? breadcrumbsVariants();\n const current = isCurrent || isLast;\n const disabled = isDisabled || current;\n\n return (\n \n {\n onPress?.(event);\n if (!event.defaultPrevented) openHref(href);\n }}\n ref={ref}\n {...props}\n >\n \n {children}\n \n \n {!current ? renderSeparator(context?.separator) : null}\n \n );\n },\n);\n\nBreadcrumbsItem.displayName = \"PitsiUINative.Breadcrumbs.Item\";\n\nexport { BreadcrumbsItem, BreadcrumbsRoot, breadcrumbsVariants };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/breadcrumbs/breadcrumbs.tsx" }, { "path": "registry/native-ui/src/components/breadcrumbs/demos/index.tsx", "content": "import { Breadcrumbs, Text } from \"../..\";\n\nexport function BreadcrumbsBasic() {\n return (\n \n Products\n Laptop\n \n );\n}\n\nexport function CustomRenderFunction() {\n return (\n \n Home\n Products\n Electronics\n Laptop\n \n );\n}\n\nexport function BreadcrumbsCustomSeparator() {\n return (\n /}>\n Home\n Products\n Electronics\n Laptop\n \n );\n}\n\nexport function BreadcrumbsDisabled() {\n return (\n \n Home\n Products\n Electronics\n Laptop\n \n );\n}\n\nexport function BreadcrumbsLevel2() {\n return (\n \n Home\n Current Page\n \n );\n}\n\nexport function BreadcrumbsLevel3() {\n return (\n \n Home\n Category\n Current Page\n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/breadcrumbs/demos/index.tsx" }, { "path": "registry/native-ui/src/components/breadcrumbs/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { BreadcrumbsItem, BreadcrumbsRoot } from \"./breadcrumbs\";\n\nexport const Breadcrumbs = Object.assign(BreadcrumbsRoot, {\n Item: BreadcrumbsItem,\n Root: BreadcrumbsRoot,\n});\n\nexport type Breadcrumbs = {\n ItemProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n BreadcrumbsItemProps,\n BreadcrumbsRootProps,\n BreadcrumbsRootProps as BreadcrumbsProps,\n BreadcrumbsVariants,\n} from \"./breadcrumbs\";\nexport { BreadcrumbsItem, BreadcrumbsRoot, breadcrumbsVariants } from \"./breadcrumbs\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/breadcrumbs/index.ts" }, { "path": "registry/native-ui/src/components/button-group/button-group.tsx", "content": "import {\n Children,\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useContext,\n useMemo,\n} from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport type { ButtonRootProps } from \"../button\";\n\nconst buttonGroupVariants = tv({\n defaultVariants: {\n fullWidth: false,\n orientation: \"horizontal\",\n },\n slots: {\n base: \"items-center justify-center gap-0 overflow-hidden rounded-3xl\",\n separator: \"bg-current opacity-15\",\n },\n variants: {\n fullWidth: {\n false: {},\n true: {\n base: \"w-full\",\n },\n },\n orientation: {\n horizontal: {\n base: \"flex-row\",\n separator: \"h-1/2 w-hairline\",\n },\n vertical: {\n base: \"flex-col\",\n separator: \"h-hairline w-1/2\",\n },\n },\n },\n});\n\nexport type ButtonGroupVariants = VariantProps;\n\ntype ButtonGroupContextValue = {\n fullWidth?: boolean;\n isDisabled?: boolean;\n orientation: \"horizontal\" | \"vertical\";\n size?: ButtonRootProps[\"size\"];\n slots: ReturnType;\n variant?: ButtonRootProps[\"variant\"];\n};\n\nexport const ButtonGroupContext = createContext(null);\nexport const BUTTON_GROUP_CHILD = \"__button_group_child\";\n\nexport interface ButtonGroupRootProps\n extends Omit,\n Pick,\n ButtonGroupVariants {\n children?: ReactNode;\n className?: string;\n isDisabled?: boolean;\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nconst ButtonGroupRoot = forwardRef(\n (\n {\n children,\n className,\n fullWidth,\n isDisabled,\n orientation = \"horizontal\",\n size,\n variant,\n ...props\n },\n ref,\n ) => {\n const slots = useMemo(\n () => buttonGroupVariants({ fullWidth, orientation }),\n [fullWidth, orientation],\n );\n const context = useMemo(\n () => ({ fullWidth, isDisabled, orientation, size, slots, variant }),\n [fullWidth, isDisabled, orientation, size, slots, variant],\n );\n const wrappedChildren = Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n\n return cloneElement(child as ReactElement>, {\n [BUTTON_GROUP_CHILD]: true,\n });\n });\n\n return (\n \n \n {wrappedChildren}\n \n \n );\n },\n);\n\nButtonGroupRoot.displayName = \"PitsiUINative.ButtonGroup\";\n\nexport interface ButtonGroupSeparatorProps extends ViewProps {\n [BUTTON_GROUP_CHILD]?: boolean;\n className?: string;\n}\n\nconst ButtonGroupSeparator = forwardRef(\n ({ className, ...props }, ref) => {\n const context = useContext(ButtonGroupContext);\n const slots = context?.slots ?? buttonGroupVariants();\n\n return (\n \n );\n },\n);\n\nButtonGroupSeparator.displayName = \"PitsiUINative.ButtonGroup.Separator\";\n\nexport { ButtonGroupRoot, ButtonGroupSeparator, buttonGroupVariants };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/button-group/button-group.tsx" }, { "path": "registry/native-ui/src/components/button-group/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Button, ButtonGroup } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n \n \n );\n}\n\nexport function Orientation() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/button-group/demos/index.tsx" }, { "path": "registry/native-ui/src/components/button-group/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ButtonGroupRoot, ButtonGroupSeparator } from \"./button-group\";\n\nexport const ButtonGroup = Object.assign(ButtonGroupRoot, {\n Root: ButtonGroupRoot,\n Separator: ButtonGroupSeparator,\n});\n\nexport type ButtonGroup = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n SeparatorProps: ComponentProps;\n};\n\nexport type {\n ButtonGroupRootProps,\n ButtonGroupRootProps as ButtonGroupProps,\n ButtonGroupSeparatorProps,\n ButtonGroupVariants,\n} from \"./button-group\";\nexport { BUTTON_GROUP_CHILD, ButtonGroupContext, buttonGroupVariants } from \"./button-group\";\nexport { ButtonGroupRoot, ButtonGroupSeparator };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/button-group/index.ts" }, { "path": "registry/native-ui/src/components/button/button.tsx", "content": "import { forwardRef, useMemo } from \"react\";\nimport { StyleSheet, type TextProps } from \"react-native\";\nimport { tv } from \"tailwind-variants\";\nimport { useThemeColor } from \"../../helpers/external/hooks\";\nimport { colorKit } from \"../../helpers/external/utils\";\nimport { HeroText } from \"../../helpers/internal/components/hero-text\";\nimport type {\n AnimationRoot,\n AnimationRootDisableAll,\n PressableRef,\n TextRef,\n} from \"../../helpers/internal/types\";\nimport { childrenToString, combineStyles, createContext } from \"../../helpers/internal/utils\";\nimport {\n PressableFeedback,\n type PressableFeedbackHighlightAnimation,\n type PressableFeedbackProps,\n type PressableFeedbackRippleAnimation,\n type PressableFeedbackScaleAnimation,\n} from \"../pressable-feedback\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\nexport const DISPLAY_NAME = {\n BUTTON_ROOT: \"PitsiUINative.Button.Root\",\n BUTTON_LABEL: \"PitsiUINative.Button.Label\",\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"outline\"\n | \"ghost\"\n | \"danger\"\n | \"danger-soft\";\n\nexport type ButtonFeedbackVariant = \"scale-highlight\" | \"scale-ripple\" | \"scale\" | \"none\";\n\ntype ButtonRootPropsBase = Omit & {\n /** @default 'primary' */\n variant?: ButtonVariant;\n /** @default 'md' */\n size?: ButtonSize;\n /** @default false */\n isIconOnly?: boolean;\n};\n\nexport type ButtonRootPropsScaleHighlight = ButtonRootPropsBase & {\n /** @default 'scale-highlight' */\n feedbackVariant?: \"scale-highlight\";\n animation?: AnimationRoot<{\n scale?: PressableFeedbackScaleAnimation;\n highlight?: PressableFeedbackHighlightAnimation;\n }>;\n};\n\ntype ButtonRootPropsScaleRipple = ButtonRootPropsBase & {\n feedbackVariant: \"scale-ripple\";\n animation?: AnimationRoot<{\n scale?: PressableFeedbackScaleAnimation;\n ripple?: PressableFeedbackRippleAnimation;\n }>;\n};\n\ntype ButtonRootPropsScale = ButtonRootPropsBase & {\n feedbackVariant: \"scale\";\n animation?: AnimationRoot<{\n scale?: PressableFeedbackScaleAnimation;\n }>;\n};\n\ntype ButtonRootPropsNone = ButtonRootPropsBase & {\n feedbackVariant: \"none\";\n animation?: AnimationRootDisableAll;\n};\n\nexport type ButtonRootProps =\n | ButtonRootPropsScaleHighlight\n | ButtonRootPropsScaleRipple\n | ButtonRootPropsScale\n | ButtonRootPropsNone;\n\nexport interface ButtonLabelProps extends TextProps {\n children?: React.ReactNode;\n className?: string;\n}\n\nexport interface ButtonContextValue {\n size: ButtonSize;\n variant: ButtonVariant;\n isDisabled: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n *\n * @note ANIMATED PROPERTIES (cannot be set via className):\n * `transform` (specifically `scale`) — animated for press feedback. Use the\n * `animation` prop to customize: `;\n}\n\nexport function CustomRenderFunction() {\n return (\n \n );\n}\n\nexport function CustomVariants() {\n return (\n \n );\n}\n\nexport function Disabled() {\n return (\n \n \n \n \n \n \n \n \n );\n}\n\nexport function FullWidth() {\n return (\n \n \n \n \n );\n}\n\nexport function IconOnly() {\n return (\n \n \n \n \n \n );\n}\n\nexport function Loading() {\n return (\n \n );\n}\n\nexport function LoadingState() {\n const [isLoading, setLoading] = useState(false);\n\n const handlePress = () => {\n setLoading(true);\n setTimeout(() => setLoading(false), 2000);\n };\n\n return (\n \n );\n}\n\nexport function OutlineVariant() {\n return (\n \n \n Button\n \n \n \n \n \n ButtonGroup\n \n \n \n \n \n \n \n );\n}\n\nexport function RippleEffect() {\n return (\n \n );\n}\n\nexport function Sizes() {\n return (\n \n \n \n \n \n );\n}\n\nexport function Social() {\n return (\n \n \n \n \n \n );\n}\n\nexport function Variants() {\n return (\n \n \n \n \n \n \n \n \n \n );\n}\n\nexport function WithIcons() {\n return (\n \n \n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/button/demos/index.tsx" }, { "path": "registry/native-ui/src/components/button/index.ts", "content": "export type {\n ButtonContextValue,\n ButtonFeedbackVariant,\n ButtonLabelProps,\n ButtonRootProps,\n ButtonRootPropsScaleHighlight,\n ButtonSize,\n ButtonVariant,\n} from \"./button\";\nexport {\n Button,\n buttonClassNames,\n default,\n resolveAnimationObject,\n useButton,\n} from \"./button\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/button/index.ts" }, { "path": "registry/native-ui/src/components/calendar-year-picker/calendar-year-picker.tsx", "content": "import {\n createContext,\n forwardRef,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n} from \"react\";\nimport {\n Linking,\n Pressable,\n type PressableProps,\n ScrollView,\n type ScrollViewProps,\n View,\n type ViewProps,\n} from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { cn } from \"../../_utils\";\nimport type { TextRef } from \"../../helpers/internal/types\";\nimport { Text, type TextProps } from \"../text\";\n\nexport type YearPickerContextValue = Record;\nexport type YearPickerStateContextValue = Record;\n\nexport const YearPickerContext = createContext({});\nexport const YearPickerStateContext = createContext({});\n\nexport function useYearPicker() {\n return useContext(YearPickerContext);\n}\n\nexport function useYearPickerState() {\n return useContext(YearPickerStateContext);\n}\n\nexport type CalendarYearPickerCellRenderProps = {\n isDisabled: boolean;\n isFocused: boolean;\n isFocusVisible: boolean;\n isHovered: boolean;\n isPressed: boolean;\n isSelected: boolean;\n year?: number;\n};\n\nexport type CalendarYearPickerTriggerRenderProps = Omit;\n\ntype InteractiveChildren = ReactNode | ((state: CalendarYearPickerCellRenderProps) => ReactNode);\ntype TriggerChildren = ReactNode | ((state: CalendarYearPickerTriggerRenderProps) => ReactNode);\n\ntype SharedProps = {\n className?: string;\n disabled?: boolean;\n href?: string;\n isDisabled?: boolean;\n isSelected?: boolean;\n label?: ReactNode;\n onAction?: () => void;\n onClick?: () => void;\n selected?: boolean;\n slot?: string;\n textValue?: string;\n title?: ReactNode;\n value?: ReactNode;\n year?: number;\n};\n\nexport const calendarYearPickerVariants = tv({\n slots: {\n cell: \"min-h-10 min-w-20 items-center justify-center rounded-xl px-3 py-2\",\n grid: \"max-h-72\",\n gridBody: \"flex-row flex-wrap gap-2\",\n root: \"gap-2\",\n trigger: \"min-h-10 flex-row items-center gap-2 rounded-xl px-3 py-2\",\n triggerHeading: \"text-base font-semibold text-foreground\",\n triggerIndicator: \"size-5 items-center justify-center\",\n },\n});\n\nexport type CalendarYearPickerVariants = VariantProps;\n\nexport type CalendarYearPickerRootProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarYearPickerGridProps = Omit &\n SharedProps & {\n children?: ReactNode;\n orientation?: \"both\" | \"horizontal\" | \"vertical\" | string;\n };\nexport type CalendarYearPickerGridBodyProps = Omit &\n SharedProps & {\n children?: ReactNode | ((values: CalendarYearPickerCellRenderProps) => ReactNode);\n };\nexport type CalendarYearPickerCellProps = Omit &\n SharedProps & {\n children?: InteractiveChildren;\n };\nexport type CalendarYearPickerTriggerProps = Omit &\n SharedProps & {\n children?: TriggerChildren;\n };\nexport type CalendarYearPickerTriggerHeadingProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarYearPickerTriggerIndicatorProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\n\nfunction stripSharedProps(props: TProps) {\n const {\n className: _className,\n disabled: _disabled,\n href: _href,\n isDisabled: _isDisabled,\n isSelected: _isSelected,\n label: _label,\n onAction: _onAction,\n onClick: _onClick,\n selected: _selected,\n slot: _slot,\n textValue: _textValue,\n title: _title,\n value: _value,\n year: _year,\n ...nativeProps\n } = props;\n\n return nativeProps;\n}\n\nfunction renderNode(value: ReactNode) {\n if (value == null || typeof value === \"boolean\") return null;\n if (typeof value === \"string\" || typeof value === \"number\") {\n return {value};\n }\n\n return value;\n}\n\nfunction sharedContent(children: ReactNode | undefined, props: SharedProps) {\n return children ?? props.label ?? props.title ?? props.value ?? props.textValue ?? null;\n}\n\nfunction createTriggerState(props: SharedProps): CalendarYearPickerTriggerRenderProps {\n return {\n isDisabled: Boolean(props.disabled || props.isDisabled),\n isFocused: false,\n isFocusVisible: false,\n isHovered: false,\n isPressed: false,\n isSelected: Boolean(props.selected || props.isSelected),\n };\n}\n\nfunction createCellState(props: SharedProps, isPressed = false): CalendarYearPickerCellRenderProps {\n return {\n ...createTriggerState(props),\n isPressed,\n year: props.year,\n };\n}\n\nconst CalendarYearPickerRoot = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarYearPickerVariants();\n const nativeProps = stripSharedProps(props);\n\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarYearPickerGrid = forwardRef(\n ({ children, className, horizontal, orientation, ...props }, ref) => {\n const slots = calendarYearPickerVariants();\n const nativeProps = stripSharedProps(props);\n const resolvedHorizontal = horizontal ?? orientation === \"horizontal\";\n\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarYearPickerGridBody = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarYearPickerVariants();\n const nativeProps = stripSharedProps(props);\n const years = Array.from({ length: 12 }, (_, index) => 2021 + index);\n\n return (\n \n {typeof children === \"function\"\n ? years.map((year) => (\n \n {children(createCellState({ year }))}\n \n ))\n : renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarYearPickerCell = forwardRef(\n (\n {\n children,\n className,\n disabled,\n href,\n isDisabled,\n isSelected,\n onAction,\n onClick,\n onPress,\n selected,\n year,\n ...props\n },\n ref,\n ) => {\n const slots = calendarYearPickerVariants();\n const disabledValue = Boolean(disabled || isDisabled);\n const selectedValue = Boolean(selected || isSelected);\n const nativeProps = stripSharedProps({ ...props, href, year });\n\n return (\n onAction()\n : onClick\n ? () => onClick()\n : href\n ? () => void Linking.openURL(href)\n : undefined)\n }\n {...nativeProps}\n >\n {({ pressed }) =>\n renderNode(\n typeof children === \"function\"\n ? children(\n createCellState({ disabled, isDisabled, isSelected, selected, year }, pressed),\n )\n : (sharedContent(children, { ...props, year }) ?? year),\n )\n }\n \n );\n },\n);\n\nconst CalendarYearPickerTrigger = forwardRef(\n (\n {\n children,\n className,\n disabled,\n href,\n isDisabled,\n isSelected,\n onAction,\n onClick,\n onPress,\n selected,\n ...props\n },\n ref,\n ) => {\n const slots = calendarYearPickerVariants();\n const disabledValue = Boolean(disabled || isDisabled);\n const selectedValue = Boolean(selected || isSelected);\n const nativeProps = stripSharedProps({ ...props, href });\n\n return (\n onAction()\n : onClick\n ? () => onClick()\n : href\n ? () => void Linking.openURL(href)\n : undefined)\n }\n {...nativeProps}\n >\n {({ pressed }) =>\n renderNode(\n typeof children === \"function\"\n ? children({\n ...createTriggerState({ disabled, isDisabled, isSelected, selected }),\n isPressed: pressed,\n })\n : sharedContent(children, props),\n )\n }\n \n );\n },\n);\n\nconst CalendarYearPickerTriggerHeading = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarYearPickerVariants();\n\n return (\n \n {sharedContent(children, props) ?? \"2026\"}\n \n );\n },\n);\n\nconst CalendarYearPickerTriggerIndicator = forwardRef<\n View,\n CalendarYearPickerTriggerIndicatorProps\n>(({ children, className, ...props }, ref) => {\n const slots = calendarYearPickerVariants();\n\n return (\n \n {children ?? }\n \n );\n});\n\nCalendarYearPickerRoot.displayName = \"PitsiUINative.CalendarYearPickerRoot\";\nCalendarYearPickerGrid.displayName = \"PitsiUINative.CalendarYearPickerGrid\";\nCalendarYearPickerGridBody.displayName = \"PitsiUINative.CalendarYearPickerGridBody\";\nCalendarYearPickerCell.displayName = \"PitsiUINative.CalendarYearPickerCell\";\nCalendarYearPickerTrigger.displayName = \"PitsiUINative.CalendarYearPickerTrigger\";\nCalendarYearPickerTriggerHeading.displayName = \"PitsiUINative.CalendarYearPickerTriggerHeading\";\nCalendarYearPickerTriggerIndicator.displayName = \"PitsiUINative.CalendarYearPickerTriggerIndicator\";\n\nfunction CalendarYearPickerProvider({\n children,\n value,\n}: PropsWithChildren<{ value?: YearPickerContextValue }>) {\n return {children};\n}\n\nexport {\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerProvider,\n CalendarYearPickerRoot,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar-year-picker/calendar-year-picker.tsx" }, { "path": "registry/native-ui/src/components/calendar-year-picker/demos/index.tsx", "content": "import { CalendarYearPicker } from \"../index\";\n\nconst years = Array.from({ length: 12 }, (_, index) => 2021 + index);\n\nexport function Basic() {\n return (\n \n \n 2026\n \n \n \n \n {years.map((year) => (\n \n {year}\n \n ))}\n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar-year-picker/demos/index.tsx" }, { "path": "registry/native-ui/src/components/calendar-year-picker/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerProvider,\n CalendarYearPickerRoot,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n calendarYearPickerVariants,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n YearPickerStateContext,\n} from \"./calendar-year-picker\";\n\nexport const CalendarYearPicker = Object.assign(CalendarYearPickerRoot, {\n Cell: CalendarYearPickerCell,\n Grid: CalendarYearPickerGrid,\n GridBody: CalendarYearPickerGridBody,\n Provider: CalendarYearPickerProvider,\n Root: CalendarYearPickerRoot,\n Trigger: CalendarYearPickerTrigger,\n TriggerHeading: CalendarYearPickerTriggerHeading,\n TriggerIndicator: CalendarYearPickerTriggerIndicator,\n});\n\nexport type CalendarYearPicker = {\n CellProps: ComponentProps;\n GridBodyProps: ComponentProps;\n GridProps: ComponentProps;\n Props: ComponentProps;\n ProviderProps: ComponentProps;\n RootProps: ComponentProps;\n TriggerHeadingProps: ComponentProps;\n TriggerIndicatorProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n CalendarYearPickerCellProps,\n CalendarYearPickerCellRenderProps,\n CalendarYearPickerGridBodyProps,\n CalendarYearPickerGridProps,\n CalendarYearPickerRootProps,\n CalendarYearPickerTriggerHeadingProps,\n CalendarYearPickerTriggerIndicatorProps,\n CalendarYearPickerTriggerProps,\n CalendarYearPickerTriggerRenderProps,\n CalendarYearPickerVariants,\n YearPickerContextValue,\n YearPickerStateContextValue,\n} from \"./calendar-year-picker\";\n\nexport {\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerProvider,\n CalendarYearPickerRoot,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n calendarYearPickerVariants,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n YearPickerStateContext,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar-year-picker/index.ts" }, { "path": "registry/native-ui/src/components/calendar/calendar.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport {\n Linking,\n Pressable,\n type PressableProps,\n ScrollView,\n type ScrollViewProps,\n View,\n type ViewProps,\n} from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { cn } from \"../../_utils\";\nimport type { TextRef } from \"../../helpers/internal/types\";\nimport {\n CalendarYearPickerCell,\n type CalendarYearPickerCellProps,\n type CalendarYearPickerCellRenderProps,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n type CalendarYearPickerGridBodyProps,\n type CalendarYearPickerGridProps,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n type CalendarYearPickerTriggerHeadingProps,\n CalendarYearPickerTriggerIndicator,\n type CalendarYearPickerTriggerIndicatorProps,\n type CalendarYearPickerTriggerProps,\n type CalendarYearPickerTriggerRenderProps,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n type YearPickerContextValue,\n YearPickerStateContext,\n type YearPickerStateContextValue,\n} from \"../calendar-year-picker\";\nimport { Text, type TextProps } from \"../text\";\n\nexport type CalendarDayValue = {\n day: number;\n month: number;\n year: number;\n toString: () => string;\n};\n\nexport type CalendarCellRenderProps = {\n date?: CalendarDayValue | unknown;\n isDisabled: boolean;\n isFocused: boolean;\n isFocusVisible: boolean;\n isHovered: boolean;\n isPressed: boolean;\n isSelected: boolean;\n};\n\ntype InteractiveChildren = ReactNode | ((state: CalendarCellRenderProps) => ReactNode);\n\ntype SharedProps = {\n className?: string;\n date?: CalendarDayValue | unknown;\n disabled?: boolean;\n href?: string;\n isDisabled?: boolean;\n isSelected?: boolean;\n label?: ReactNode;\n offset?: unknown;\n onAction?: () => void;\n onClick?: () => void;\n selected?: boolean;\n slot?: \"next\" | \"previous\" | string;\n textValue?: string;\n title?: ReactNode;\n value?: ReactNode;\n};\n\nexport const calendarVariants = tv({\n slots: {\n cell: \"size-10 items-center justify-center rounded-full\",\n cellIndicator: \"absolute bottom-1 size-1 rounded-full bg-link\",\n grid: \"w-full\",\n gridBody: \"flex-row flex-wrap\",\n gridHeader: \"flex-row\",\n header: \"flex-row items-center justify-between\",\n headerCell: \"w-10 py-1 text-center text-xs text-muted\",\n heading: \"text-base font-semibold text-foreground\",\n navButton: \"size-9 items-center justify-center rounded-full bg-default\",\n root: \"gap-3 rounded-2xl bg-background p-3\",\n },\n});\n\nexport type CalendarVariants = VariantProps;\n\nexport type CalendarRootProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarHeaderProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarHeadingProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarNavButtonProps = Omit &\n SharedProps & {\n children?: InteractiveChildren;\n };\nexport type CalendarGridProps = Omit &\n SharedProps & {\n children?: ReactNode;\n orientation?: \"both\" | \"horizontal\" | \"vertical\" | string;\n };\nexport type CalendarGridHeaderProps = Omit &\n SharedProps & {\n children?: ReactNode | ((day: string) => ReactNode);\n };\nexport type CalendarGridBodyProps = Omit &\n SharedProps & {\n children?: ReactNode | ((date: CalendarDayValue) => ReactNode);\n };\nexport type CalendarHeaderCellProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\nexport type CalendarCellProps = Omit &\n SharedProps & {\n children?: InteractiveChildren;\n };\nexport type CalendarCellIndicatorProps = Omit &\n SharedProps & {\n children?: ReactNode;\n };\n\nconst weekdays = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst days = Array.from({ length: 35 }, (_, index): CalendarDayValue => {\n const day = index + 1;\n return {\n day,\n month: 5,\n toString: () => `2026-05-${String(day).padStart(2, \"0\")}`,\n year: 2026,\n };\n});\n\nfunction stripSharedProps(props: TProps) {\n const {\n className: _className,\n date: _date,\n disabled: _disabled,\n href: _href,\n isDisabled: _isDisabled,\n isSelected: _isSelected,\n label: _label,\n offset: _offset,\n onAction: _onAction,\n onClick: _onClick,\n selected: _selected,\n slot: _slot,\n textValue: _textValue,\n title: _title,\n value: _value,\n ...nativeProps\n } = props;\n\n return nativeProps;\n}\n\nfunction renderNode(value: ReactNode) {\n if (value == null || typeof value === \"boolean\") return null;\n if (typeof value === \"string\" || typeof value === \"number\") {\n return {value};\n }\n\n return value;\n}\n\nfunction sharedContent(children: ReactNode | undefined, props: SharedProps) {\n return children ?? props.label ?? props.title ?? props.value ?? props.textValue ?? null;\n}\n\nfunction createCellState(props: SharedProps, isPressed = false): CalendarCellRenderProps {\n return {\n date: props.date,\n isDisabled: Boolean(props.disabled || props.isDisabled),\n isFocused: false,\n isFocusVisible: false,\n isHovered: false,\n isPressed,\n isSelected: Boolean(props.selected || props.isSelected),\n };\n}\n\nfunction getDayLabel(date: unknown) {\n if (date && typeof date === \"object\" && \"day\" in date) {\n const day = (date as { day?: unknown }).day;\n return typeof day === \"number\" || typeof day === \"string\" ? day : null;\n }\n\n return null;\n}\n\nconst CalendarRoot = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n const nativeProps = stripSharedProps(props);\n\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarHeader = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarHeading = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n return (\n \n {sharedContent(children, props) ?? \"May 2026\"}\n \n );\n },\n);\n\nconst CalendarNavButton = forwardRef(\n (\n {\n children,\n className,\n disabled,\n href,\n isDisabled,\n isSelected,\n onAction,\n onClick,\n onPress,\n selected,\n slot,\n ...props\n },\n ref,\n ) => {\n const slots = calendarVariants();\n const disabledValue = Boolean(disabled || isDisabled);\n const selectedValue = Boolean(selected || isSelected);\n const nativeProps = stripSharedProps({ ...props, href, slot });\n\n return (\n onAction()\n : onClick\n ? () => onClick()\n : href\n ? () => void Linking.openURL(href)\n : undefined)\n }\n {...nativeProps}\n >\n {({ pressed }) =>\n renderNode(\n typeof children === \"function\"\n ? children(createCellState({ disabled, isDisabled, isSelected, selected }, pressed))\n : (sharedContent(children, props) ?? (slot === \"previous\" ? \"<\" : \">\")),\n )\n }\n \n );\n },\n);\n\nconst CalendarGrid = forwardRef(\n ({ children, className, horizontal, orientation, ...props }, ref) => {\n const slots = calendarVariants();\n const resolvedHorizontal = horizontal ?? orientation === \"horizontal\";\n\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarGridHeader = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n\n return (\n \n {typeof children === \"function\"\n ? weekdays.map((day) => (\n {children(day)}\n ))\n : renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarGridBody = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n\n return (\n \n {typeof children === \"function\"\n ? days.map((date) => (\n \n {children(date)}\n \n ))\n : renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nconst CalendarHeaderCell = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n return (\n \n {sharedContent(children, props)}\n \n );\n },\n);\n\nconst CalendarCell = forwardRef(\n (\n {\n children,\n className,\n date,\n disabled,\n href,\n isDisabled,\n isSelected,\n onAction,\n onClick,\n onPress,\n selected,\n ...props\n },\n ref,\n ) => {\n const slots = calendarVariants();\n const disabledValue = Boolean(disabled || isDisabled);\n const selectedValue = Boolean(selected || isSelected);\n const nativeProps = stripSharedProps({ ...props, date, href });\n\n return (\n onAction()\n : onClick\n ? () => onClick()\n : href\n ? () => void Linking.openURL(href)\n : undefined)\n }\n {...nativeProps}\n >\n {({ pressed }) =>\n renderNode(\n typeof children === \"function\"\n ? children(\n createCellState({ date, disabled, isDisabled, isSelected, selected }, pressed),\n )\n : (sharedContent(children, props) ?? getDayLabel(date)),\n )\n }\n \n );\n },\n);\n\nconst CalendarCellIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = calendarVariants();\n return (\n \n {renderNode(sharedContent(children, props))}\n \n );\n },\n);\n\nCalendarRoot.displayName = \"PitsiUINative.CalendarRoot\";\nCalendarHeader.displayName = \"PitsiUINative.CalendarHeader\";\nCalendarHeading.displayName = \"PitsiUINative.CalendarHeading\";\nCalendarNavButton.displayName = \"PitsiUINative.CalendarNavButton\";\nCalendarGrid.displayName = \"PitsiUINative.CalendarGrid\";\nCalendarGridHeader.displayName = \"PitsiUINative.CalendarGridHeader\";\nCalendarGridBody.displayName = \"PitsiUINative.CalendarGridBody\";\nCalendarHeaderCell.displayName = \"PitsiUINative.CalendarHeaderCell\";\nCalendarCell.displayName = \"PitsiUINative.CalendarCell\";\nCalendarCellIndicator.displayName = \"PitsiUINative.CalendarCellIndicator\";\n\nexport type {\n CalendarYearPickerCellProps,\n CalendarYearPickerCellRenderProps,\n CalendarYearPickerGridBodyProps,\n CalendarYearPickerGridProps,\n CalendarYearPickerTriggerHeadingProps,\n CalendarYearPickerTriggerIndicatorProps,\n CalendarYearPickerTriggerProps,\n CalendarYearPickerTriggerRenderProps,\n YearPickerContextValue,\n YearPickerStateContextValue,\n};\nexport {\n CalendarCell,\n CalendarCellIndicator,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n CalendarHeaderCell,\n CalendarHeading,\n CalendarNavButton,\n CalendarRoot,\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n YearPickerStateContext,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar/calendar.tsx" }, { "path": "registry/native-ui/src/components/calendar/demos/index.tsx", "content": "import { Calendar } from \"../index\";\n\nconst weekdays = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst days = Array.from({ length: 35 }, (_, index) => index + 1);\n\nexport function Basic() {\n return (\n \n \n \n May 2026\n \n \n \n \n {weekdays.map((day) => (\n {day}\n ))}\n \n \n {days.map((day) => (\n `2026-05-${day}`, year: 2026 }}\n key={day}\n selected={day === 27}\n />\n ))}\n \n \n \n );\n}\n\nexport function WithIndicators() {\n return (\n \n \n May 2026\n \n \n \n {weekdays.map((day) => (\n {day}\n ))}\n \n \n {days.map((day) => (\n `2026-05-${day}`, year: 2026 }}\n key={day}\n selected={day === 12 || day === 27}\n >\n {day}\n {(day === 12 || day === 27) && }\n \n ))}\n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar/demos/index.tsx" }, { "path": "registry/native-ui/src/components/calendar/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n CalendarCell,\n CalendarCellIndicator,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n CalendarHeaderCell,\n CalendarHeading,\n CalendarNavButton,\n CalendarRoot,\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n calendarVariants,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n YearPickerStateContext,\n} from \"./calendar\";\n\nexport const Calendar = Object.assign(CalendarRoot, {\n Cell: CalendarCell,\n CellIndicator: CalendarCellIndicator,\n Grid: CalendarGrid,\n GridBody: CalendarGridBody,\n GridHeader: CalendarGridHeader,\n Header: CalendarHeader,\n HeaderCell: CalendarHeaderCell,\n Heading: CalendarHeading,\n NavButton: CalendarNavButton,\n Root: CalendarRoot,\n YearPickerCell: CalendarYearPickerCell,\n YearPickerGrid: CalendarYearPickerGrid,\n YearPickerGridBody: CalendarYearPickerGridBody,\n YearPickerTrigger: CalendarYearPickerTrigger,\n YearPickerTriggerHeading: CalendarYearPickerTriggerHeading,\n YearPickerTriggerIndicator: CalendarYearPickerTriggerIndicator,\n});\n\nexport type Calendar = {\n CellIndicatorProps: ComponentProps;\n CellProps: ComponentProps;\n GridBodyProps: ComponentProps;\n GridHeaderProps: ComponentProps;\n GridProps: ComponentProps;\n HeaderCellProps: ComponentProps;\n HeaderProps: ComponentProps;\n HeadingProps: ComponentProps;\n NavButtonProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n CalendarCellIndicatorProps,\n CalendarCellProps,\n CalendarGridBodyProps,\n CalendarGridHeaderProps,\n CalendarGridProps,\n CalendarHeaderCellProps,\n CalendarHeaderProps,\n CalendarHeadingProps,\n CalendarNavButtonProps,\n CalendarRootProps,\n CalendarRootProps as CalendarProps,\n CalendarVariants,\n CalendarYearPickerCellProps,\n CalendarYearPickerCellRenderProps,\n CalendarYearPickerGridBodyProps,\n CalendarYearPickerGridProps,\n CalendarYearPickerTriggerHeadingProps,\n CalendarYearPickerTriggerIndicatorProps,\n CalendarYearPickerTriggerProps,\n CalendarYearPickerTriggerRenderProps,\n YearPickerContextValue,\n YearPickerStateContextValue,\n} from \"./calendar\";\n\nexport {\n CalendarCell,\n CalendarCellIndicator,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n CalendarHeaderCell,\n CalendarHeading,\n CalendarNavButton,\n CalendarRoot,\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n calendarVariants,\n useYearPicker,\n useYearPickerState,\n YearPickerContext,\n YearPickerStateContext,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/calendar/index.ts" }, { "path": "registry/native-ui/src/components/card/card.tsx", "content": "import { forwardRef } from \"react\";\nimport { type TextProps, View, type ViewProps } from \"react-native\";\nimport { tv } from \"tailwind-variants\";\nimport { HeroText } from \"../../helpers/internal/components/hero-text\";\nimport type { TextRef, ViewRef } from \"../../helpers/internal/types\";\nimport { combineStyles } from \"../../helpers/internal/utils\";\nimport { Surface, type SurfaceRootProps } from \"../surface\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for Card components\n */\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.Card.Root\",\n HEADER: \"PitsiUINative.Card.Header\",\n BODY: \"PitsiUINative.Card.Body\",\n FOOTER: \"PitsiUINative.Card.Footer\",\n TITLE: \"PitsiUINative.Card.Title\",\n DESCRIPTION: \"PitsiUINative.Card.Description\",\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Props for the Card.Root component\n */\nexport interface CardRootProps extends SurfaceRootProps {}\n\n/**\n * Props for the Card.Header component\n */\nexport interface CardHeaderProps extends ViewProps {\n /**\n * Children elements to be rendered inside the header\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Card.Body component\n */\nexport interface CardBodyProps extends ViewProps {\n /**\n * Children elements to be rendered inside the body\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Card.Footer component\n */\nexport interface CardFooterProps extends ViewProps {\n /**\n * Children elements to be rendered inside the footer\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Card.Title component\n */\nexport interface CardTitleProps extends TextProps {\n /**\n * Children elements to be rendered as the title text\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Props for the Card.Description component\n */\nexport interface CardDescriptionProps extends TextProps {\n /**\n * Children elements to be rendered as the description text\n */\n children?: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"min-h-32\",\n});\n\nconst header = tv({\n base: \"\",\n});\n\nconst body = tv({\n base: \"\",\n});\n\nconst footer = tv({\n base: \"\",\n});\n\nconst label = tv({\n base: \"text-lg text-foreground font-medium\",\n});\n\nconst description = tv({\n base: \"text-base text-muted\",\n});\n\nexport const cardClassNames = combineStyles({\n root,\n header,\n body,\n footer,\n label,\n description,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Root\n * -----------------------------------------------------------------------------------------------*/\nconst CardRoot = forwardRef((props, ref) => {\n const { children, variant = \"default\", className, ...restProps } = props;\n\n const rootClassName = cardClassNames.root({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Header\n * -----------------------------------------------------------------------------------------------*/\nconst CardHeader = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const headerClassName = cardClassNames.header({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Body\n * -----------------------------------------------------------------------------------------------*/\nconst CardBody = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const bodyClassName = cardClassNames.body({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Footer\n * -----------------------------------------------------------------------------------------------*/\nconst CardFooter = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const footerClassName = cardClassNames.footer({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Title\n * -----------------------------------------------------------------------------------------------*/\nconst CardTitle = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const titleClassName = cardClassNames.label({ className });\n\n return (\n \n {children}\n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Card.Description\n * -----------------------------------------------------------------------------------------------*/\nconst CardDescription = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const descriptionClassName = cardClassNames.description({\n className,\n });\n\n return (\n \n {children}\n \n );\n});\n\nCardRoot.displayName = DISPLAY_NAME.ROOT;\nCardHeader.displayName = DISPLAY_NAME.HEADER;\nCardBody.displayName = DISPLAY_NAME.BODY;\nCardFooter.displayName = DISPLAY_NAME.FOOTER;\nCardTitle.displayName = DISPLAY_NAME.TITLE;\nCardDescription.displayName = DISPLAY_NAME.DESCRIPTION;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Card - Main container that extends Surface component. Provides base card structure\n * with configurable surface variants and handles overall layout.\n * @component Card.Header - Header section for top-aligned content like icons or badges.\n * @component Card.Body - Main content area with flex-1 that expands to fill all available space\n * between Card.Header and Card.Footer.\n * @component Card.Title - Title text with foreground color and medium font weight.\n * @component Card.Description - Description text with muted color and smaller font size.\n * @component Card.Footer - Footer section for bottom-aligned actions like buttons.\n *\n * @see https://pitsiui.com/docs/native/components/card\n * -----------------------------------------------------------------------------------------------*/\nconst Card = Object.assign(CardRoot, {\n /** @optional Top-aligned header section */\n Header: CardHeader,\n /** @optional Main content area that expands between header and footer */\n Body: CardBody,\n /** @optional Bottom-aligned footer for actions */\n Footer: CardFooter,\n /** @optional Title text with styled typography */\n Title: CardTitle,\n /** @optional Description text with muted styling */\n Description: CardDescription,\n});\n\nexport { Card };\nexport default Card;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/card/card.tsx" }, { "path": "registry/native-ui/src/components/card/demos/index.tsx", "content": "import { Alert, View } from \"react-native\";\n\nimport { Avatar, Button, Card, CloseButton, Input, Label, Link, Text, TextField } from \"../..\";\n\nconst COLORS = {\n ai: \"#4facfe\",\n avocado: \"#a8edea\",\n cherries: \"#ff7e5f\",\n indie: \"#667eea\",\n neoBg: \"#ffd1ff\",\n neoProduct: \"#fcb69f\",\n robot: \"#5ee7df\",\n sound: \"#ff9a9e\",\n};\n\nfunction ColorTile({\n accessibilityLabel,\n className,\n color,\n}: {\n accessibilityLabel: string;\n className?: string;\n color: string;\n}) {\n return (\n \n );\n}\n\nexport function Default() {\n return (\n \n $\n \n Become an Acme Creator!\n \n Visit the Acme Creator Hub to sign up today and start earning credits from your fans and\n followers.\n \n \n \n \n Creator Hub\n \n \n \n \n );\n}\n\nexport function Horizontal() {\n return (\n \n \n \n \n \n Become an ACME Creator!\n \n \n \n Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet\n faucibus etiam.\n \n \n \n \n Only 10 spots\n Submission ends Oct 10.\n \n \n \n \n \n );\n}\n\nexport function Variants() {\n return (\n \n \n \n Transparent\n Minimal prominence with transparent background\n \n \n Use for less important content or nested cards\n \n \n\n \n \n Default\n Standard card appearance\n \n \n The default card variant for most use cases\n \n \n\n \n \n Secondary\n Medium prominence\n \n \n Use to draw moderate attention\n \n \n\n \n \n Tertiary\n Higher prominence\n \n \n Use for primary or featured content\n \n \n \n );\n}\n\nexport function WithAvatar() {\n return (\n \n \n \n \n Indie Hackers\n 148 members\n \n \n \n IH\n \n By Martha\n \n \n\n \n \n \n AI Builders\n 362 members\n \n \n \n B\n \n By John\n \n \n \n );\n}\n\nexport function WithForm() {\n return (\n \n \n Login\n Enter your credentials to access your account\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Forgot password?\n \n \n \n );\n}\n\nexport function WithImages() {\n return (\n \n \n \n \n \n Become an ACME Creator!\n \n \n \n Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet\n faucibus etiam.\n \n \n \n \n Only 10 spots\n Submission ends Oct 10.\n \n \n \n \n\n \n \n \n $\n \n \n \n Payment\n You can now withdraw on crypto\n Add your wallet in settings to withdraw\n \n \n \n Go to settings\n \n \n \n \n\n \n \n \n JK\n \n \n Indie Hackers\n 148 members\n \n \n \n JK\n \n By John\n \n \n\n \n \n AB\n \n \n AI Builders\n 362 members\n \n \n \n M\n \n By Martha\n \n \n \n\n \n \n NEO\n \n Home Robot\n \n \n \n \n Available soon\n Get notified\n \n \n \n \n \n\n \n \n \n NEO\n $499/m\n \n \n \n \n\n \n \n \n \n Bridging the Future\n Today, 6:30 PM\n \n \n \n \n \n Avocado Hackathon\n Wed, 4:30 PM\n \n \n \n \n \n Sound Electro | Beyond art\n Fri, 8:00 PM\n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/card/demos/index.tsx" }, { "path": "registry/native-ui/src/components/card/index.ts", "content": "export type {\n CardBodyProps,\n CardDescriptionProps,\n CardFooterProps,\n CardHeaderProps,\n CardRootProps,\n CardTitleProps,\n} from \"./card\";\nexport { Card, cardClassNames, default } from \"./card\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/card/index.ts" }, { "path": "registry/native-ui/src/components/chart/chart.tsx", "content": "import { type ComponentType, forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nexport const chartVariants = tv({\n slots: {\n container: \"min-h-48 w-full gap-3 rounded-2xl border border-border bg-background p-4\",\n legend: \"text-xs text-muted\",\n legendContent: \"flex-row flex-wrap gap-2\",\n root: \"w-full\",\n tooltip: \"rounded-xl border border-border bg-background p-3\",\n tooltipContent: \"gap-1\",\n },\n});\n\nexport type ChartVariants = VariantProps;\n\nexport type ChartConfig = Record<\n string,\n {\n color?: string;\n icon?: ComponentType;\n label?: ReactNode;\n theme?: Record;\n }\n>;\n\nexport interface ChartContainerProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n config?: ChartConfig;\n initialDimension?: { height: number; width: number };\n}\n\nconst ChartContainer = forwardRef(\n (\n { children, className, config: _config, initialDimension: _initialDimension, ...props },\n ref,\n ) => {\n const slots = chartVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nChartContainer.displayName = \"PitsiUINative.ChartContainer\";\n\nexport interface ChartLegendContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n hideIcon?: boolean;\n nameKey?: string;\n payload?: Array<{ color?: string; dataKey?: string; value?: ReactNode }>;\n verticalAlign?: \"bottom\" | \"top\";\n}\n\nconst ChartLegendContent = forwardRef(\n ({ children, className, hideIcon = false, payload, ...props }, ref) => {\n const slots = chartVariants();\n\n return (\n \n {children ??\n payload?.map((item, index) => (\n \n {!hideIcon ? (\n \n ) : null}\n {item.value ?? item.dataKey}\n \n ))}\n \n );\n },\n);\n\nChartLegendContent.displayName = \"PitsiUINative.ChartLegendContent\";\n\nexport interface ChartTooltipContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n hideIndicator?: boolean;\n hideLabel?: boolean;\n indicator?: \"dashed\" | \"dot\" | \"line\";\n label?: ReactNode;\n payload?: Array<{ color?: string; name?: ReactNode; value?: ReactNode }>;\n}\n\nconst ChartTooltipContent = forwardRef(\n (\n {\n children,\n className,\n hideIndicator = false,\n hideLabel = false,\n indicator: _indicator = \"dot\",\n label,\n payload,\n ...props\n },\n ref,\n ) => {\n const slots = chartVariants();\n\n return (\n \n {children ?? (\n <>\n {!hideLabel && label ? (\n {label}\n ) : null}\n {payload?.map((item, index) => (\n \n \n {!hideIndicator ? (\n \n ) : null}\n {item.name}\n \n {item.value}\n \n ))}\n \n )}\n \n );\n },\n);\n\nChartTooltipContent.displayName = \"PitsiUINative.ChartTooltipContent\";\n\nfunction ChartLegend({ className, ...props }: ViewProps & { className?: string }) {\n const slots = chartVariants();\n return ;\n}\n\nfunction ChartStyle(_props: ViewProps & { config?: ChartConfig; id?: string }) {\n return null;\n}\n\nfunction ChartTooltip({ className, ...props }: ViewProps & { className?: string }) {\n const slots = chartVariants();\n return ;\n}\n\nconst Chart = Object.assign(\n forwardRef(({ className, ...props }, ref) => {\n const slots = chartVariants();\n return ;\n }),\n {\n Container: ChartContainer,\n Legend: ChartLegend,\n LegendContent: ChartLegendContent,\n Style: ChartStyle,\n Tooltip: ChartTooltip,\n TooltipContent: ChartTooltipContent,\n },\n);\n\nexport {\n Chart,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n ChartTooltip,\n ChartTooltipContent,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chart/chart.tsx" }, { "path": "registry/native-ui/src/components/chart/demos/index.tsx", "content": "import { Card, Chart, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n Chart preview\n \n \n \n \n \n \n );\n}\n\nexport { Basic as AreaChart, Basic as BarChart, Basic as LineChart };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chart/demos/index.tsx" }, { "path": "registry/native-ui/src/components/chart/index.ts", "content": "export type {\n ChartConfig,\n ChartContainerProps,\n ChartLegendContentProps,\n ChartTooltipContentProps,\n ChartVariants,\n} from \"./chart\";\nexport {\n Chart,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n ChartTooltip,\n ChartTooltipContent,\n chartVariants,\n} from \"./chart\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chart/index.ts" }, { "path": "registry/native-ui/src/components/checkbox-group/checkbox-group.tsx", "content": "import {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useState,\n} from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Checkbox, type CheckboxProps } from \"../checkbox\";\nimport { TextField } from \"../text-field\";\n\nexport const checkboxGroupVariants = tv({\n base: \"gap-3\",\n variants: {\n variant: {\n primary: \"\",\n secondary: \"\",\n },\n },\n defaultVariants: {\n variant: \"primary\",\n },\n});\n\nexport type CheckboxGroupVariants = VariantProps;\n\nexport interface CheckboxGroupProps\n extends Omit,\n CheckboxGroupVariants {\n children?: ReactNode;\n defaultValue?: string[];\n isDisabled?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n name?: string;\n onChange?: (value: string[]) => void;\n value?: string[];\n}\n\ntype CheckboxElementProps = CheckboxProps & {\n value?: string;\n};\n\nfunction wireCheckboxChildren(\n children: ReactNode,\n selectedValues: string[],\n setSelectedValues: (value: string[]) => void,\n options: {\n isDisabled?: boolean;\n isInvalid?: boolean;\n variant?: CheckboxProps[\"variant\"];\n },\n): ReactNode {\n return Children.map(children, (child) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n if (child.type !== Checkbox) {\n const nestedChildren = (child.props as { children?: ReactNode }).children;\n\n if (!nestedChildren) {\n return child;\n }\n\n return cloneElement(child, {\n children: wireCheckboxChildren(nestedChildren, selectedValues, setSelectedValues, options),\n } as Partial);\n }\n\n const checkbox = child as ReactElement;\n const value = checkbox.props.value;\n\n if (!value) {\n return child;\n }\n\n const isSelected = selectedValues.includes(value);\n\n return cloneElement(checkbox, {\n isDisabled: checkbox.props.isDisabled ?? options.isDisabled,\n isInvalid: checkbox.props.isInvalid ?? options.isInvalid,\n isSelected,\n onSelectedChange: (nextSelected: boolean) => {\n const nextValues = nextSelected\n ? Array.from(new Set([...selectedValues, value]))\n : selectedValues.filter((item) => item !== value);\n setSelectedValues(nextValues);\n checkbox.props.onSelectedChange?.(nextSelected);\n },\n variant: checkbox.props.variant ?? options.variant,\n });\n });\n}\n\nconst CheckboxGroup = forwardRef(\n (\n {\n children,\n className,\n defaultValue = [],\n isDisabled = false,\n isInvalid = false,\n isRequired = false,\n name: _name,\n onChange,\n value,\n variant,\n ...props\n },\n ref,\n ) => {\n const [internalValue, setInternalValue] = useState(defaultValue);\n const selectedValues = value ?? internalValue;\n const rootClassName = checkboxGroupVariants({ className, variant });\n\n const setSelectedValues = (nextValue: string[]) => {\n if (value === undefined) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n };\n\n const content = wireCheckboxChildren(children, selectedValues, setSelectedValues, {\n isDisabled,\n isInvalid,\n variant,\n });\n\n return (\n \n \n {content}\n \n \n );\n },\n);\n\nCheckboxGroup.displayName = \"PitsiUINative.CheckboxGroup\";\n\nexport { CheckboxGroup };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox-group/checkbox-group.tsx" }, { "path": "registry/native-ui/src/components/checkbox-group/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { View } from \"react-native\";\n\nimport { Checkbox, CheckboxGroup, Description, Label, Text } from \"../..\";\n\nfunction CheckboxRow({ label, value }: { label: string; value: string }) {\n return (\n \n \n \n \n \n \n );\n}\n\nexport function Basic() {\n return (\n \n \n Choose all that apply\n \n \n \n \n );\n}\n\nexport function Controlled() {\n const [selected, setSelected] = useState([\"coding\", \"design\"]);\n\n return (\n \n \n \n \n \n \n Selected: {selected.join(\", \") || \"None\"}\n \n );\n}\n\nexport {\n Basic as CustomRenderFunction,\n Basic as Disabled,\n Basic as FeaturesAndAddOns,\n Basic as Indeterminate,\n Basic as OnSurface,\n Basic as Validation,\n Basic as WithCustomIndicator,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox-group/demos/index.tsx" }, { "path": "registry/native-ui/src/components/checkbox-group/index.ts", "content": "export type { CheckboxGroupProps, CheckboxGroupVariants } from \"./checkbox-group\";\nexport { CheckboxGroup, checkboxGroupVariants } from \"./checkbox-group\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox-group/index.ts" }, { "path": "registry/native-ui/src/components/checkbox/checkbox.animation.ts", "content": "import { useAnimatedStyle, useSharedValue, withTiming } from \"react-native-reanimated\";\nimport { useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport {\n createContext,\n getAnimationState,\n getAnimationValueMergedConfig,\n getAnimationValueProperty,\n getIsAnimationDisabledValue,\n getRootAnimationState,\n} from \"../../helpers/internal/utils\";\nimport { useControlField } from \"../control-field/control-field.context\";\nimport type {\n CheckboxAnimationContextValue,\n CheckboxIndicatorAnimation,\n CheckboxRootAnimation,\n} from \"./checkbox\";\n\nconst [CheckboxAnimationProvider, useCheckboxAnimation] =\n createContext({\n name: \"CheckboxAnimationContext\",\n });\n\nexport { CheckboxAnimationProvider, useCheckboxAnimation };\n\n// --------------------------------------------------\n\nexport function useCheckboxRootAnimation(options: {\n animation: CheckboxRootAnimation | undefined;\n}) {\n const { animation } = options;\n\n const isCheckboxPressed = useSharedValue(false);\n const controlFieldContext = useControlField();\n\n const { animationConfig, isAnimationDisabled } = getRootAnimationState(animation);\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n const scaleValue = getAnimationValueProperty({\n animationValue: animationConfig?.scale,\n property: \"value\",\n defaultValue: [1, 0.96] as [number, number],\n });\n\n const scaleTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.scale,\n property: \"timingConfig\",\n defaultValue: { duration: 150 },\n });\n\n const rContainerStyle = useAnimatedStyle(() => {\n if (isAnimationDisabledValue) {\n return {};\n }\n\n const pressed = isCheckboxPressed.get() || (controlFieldContext?.isPressed.get() ?? false);\n\n return {\n transform: [\n {\n scale: withTiming(pressed ? scaleValue[1] : scaleValue[0], scaleTimingConfig),\n },\n ],\n };\n });\n\n return {\n rContainerStyle,\n isCheckboxPressed,\n isAllAnimationsDisabled,\n };\n}\n\n// --------------------------------------------------\n\nexport function useCheckboxIndicatorAnimation(options: {\n animation: CheckboxIndicatorAnimation | undefined;\n isSelected: boolean | undefined;\n}) {\n const { animation, isSelected } = options;\n\n // Read from global animation context (always available in compound parts)\n const { isAllAnimationsDisabled } = useAnimationSettings();\n\n const { animationConfig, isAnimationDisabled } = getAnimationState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n // Opacity animation\n const opacityValue = getAnimationValueProperty({\n animationValue: animationConfig?.opacity,\n property: \"value\",\n defaultValue: [0, 1] as [number, number],\n });\n const opacityTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.opacity,\n property: \"timingConfig\",\n defaultValue: { duration: 100 },\n });\n\n // BorderRadius animation\n const borderRadiusValue = getAnimationValueProperty({\n animationValue: animationConfig?.borderRadius,\n property: \"value\",\n defaultValue: [8, 0] as [number, number],\n });\n const borderRadiusTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.borderRadius,\n property: \"timingConfig\",\n defaultValue: { duration: 50 },\n });\n\n // TranslateX animation\n const translateXValue = getAnimationValueProperty({\n animationValue: animationConfig?.translateX,\n property: \"value\",\n defaultValue: [-4, 0] as [number, number],\n });\n const translateXTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.translateX,\n property: \"timingConfig\",\n defaultValue: { duration: 100 },\n });\n\n // Scale animation\n const scaleValue = getAnimationValueProperty({\n animationValue: animationConfig?.scale,\n property: \"value\",\n defaultValue: [0.8, 1] as [number, number],\n });\n const scaleTimingConfig = getAnimationValueMergedConfig({\n animationValue: animationConfig?.scale,\n property: \"timingConfig\",\n defaultValue: { duration: 100 },\n });\n\n const rContainerStyle = useAnimatedStyle(() => {\n if (isAnimationDisabledValue) {\n return {\n opacity: isSelected ? opacityValue[1] : opacityValue[0],\n borderRadius: isSelected ? borderRadiusValue[1] : borderRadiusValue[0],\n transform: [\n {\n translateX: isSelected ? translateXValue[1] : translateXValue[0],\n },\n {\n scale: isSelected ? scaleValue[1] : scaleValue[0],\n },\n ],\n };\n }\n\n return {\n opacity: withTiming(isSelected ? opacityValue[1] : opacityValue[0], opacityTimingConfig),\n borderRadius: withTiming(\n isSelected ? borderRadiusValue[1] : borderRadiusValue[0],\n borderRadiusTimingConfig,\n ),\n transform: [\n {\n translateX: withTiming(\n isSelected ? translateXValue[1] : translateXValue[0],\n translateXTimingConfig,\n ),\n },\n {\n scale: withTiming(isSelected ? scaleValue[1] : scaleValue[0], scaleTimingConfig),\n },\n ],\n };\n });\n\n return {\n rContainerStyle,\n isAnimationDisabled: isAnimationDisabled || isAllAnimationsDisabled,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox/checkbox.animation.ts" }, { "path": "registry/native-ui/src/components/checkbox/checkbox.tsx", "content": "import { forwardRef, useCallback, useMemo } from \"react\";\nimport { type GestureResponderEvent, StyleSheet, View } from \"react-native\";\nimport Animated, {\n type AnimatedProps,\n type SharedValue,\n type WithTimingConfig,\n} from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { useIsOnSurface, useThemeColor } from \"../../helpers/external/hooks\";\nimport { AnimatedCheckIcon, CheckIcon } from \"../../helpers/internal/components\";\nimport { AnimationSettingsProvider } from \"../../helpers/internal/contexts\";\nimport type { Animation, AnimationRoot, AnimationValue } from \"../../helpers/internal/types\";\nimport { combineStyles } from \"../../helpers/internal/utils\";\nimport * as CheckboxPrimitives from \"../../primitives/checkbox\";\nimport type * as CheckboxPrimitivesTypes from \"../../primitives/checkbox/checkbox.types\";\nimport {\n CheckboxAnimationProvider,\n useCheckboxIndicatorAnimation,\n useCheckboxRootAnimation,\n} from \"./checkbox.animation\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\nexport const DISPLAY_NAME = {\n CHECKBOX_ROOT: \"PitsiUINative.Checkbox.Root\",\n CHECKBOX_INDICATOR: \"PitsiUINative.Checkbox.Indicator\",\n} as const;\n\nexport const DEFAULT_HIT_SLOP = 6;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Context value for checkbox animation state\n */\nexport interface CheckboxAnimationContextValue {\n /** Shared value tracking if the checkbox is pressed */\n isCheckboxPressed: SharedValue;\n}\n\n/**\n * Checkbox Indicator Icon Props\n */\nexport interface CheckboxIndicatorIconProps {\n /** Indicator size */\n size?: number;\n /** Indicator stroke width */\n strokeWidth?: number;\n /** Indicator color */\n color?: string;\n /** Enter duration */\n enterDuration?: number;\n /** Exit duration */\n exitDuration?: number;\n}\n\n/**\n * Render function props for checkbox children\n */\nexport interface CheckboxRenderProps {\n /** Whether the checkbox is selected */\n isSelected?: boolean;\n /** Whether the checkbox is invalid */\n isInvalid: boolean;\n /** Whether the checkbox is disabled */\n isDisabled: boolean;\n}\n\n/**\n * Animation configuration for checkbox root component\n */\nexport type CheckboxRootAnimation = AnimationRoot<{\n scale?: AnimationValue<{\n /**\n * Scale values [unpressed, pressed]\n * @default [1, 0.95]\n */\n value?: [number, number];\n /**\n * Animation timing configuration\n */\n timingConfig?: WithTimingConfig;\n }>;\n}>;\n\n/**\n * Props for the main Checkbox component\n */\nexport interface CheckboxProps extends Omit {\n /** Child elements to render inside the checkbox, or a render function */\n children?: React.ReactNode | ((props: CheckboxRenderProps) => React.ReactNode);\n\n /** Variant style for the checkbox\n * @default 'primary'\n */\n variant?: \"primary\" | \"secondary\";\n\n /** Custom class name for the checkbox */\n className?: string;\n /** Form/group value associated with this checkbox. */\n value?: string;\n\n /** Animation configuration for checkbox scale animation */\n animation?: CheckboxRootAnimation;\n /**\n * Whether animated styles (react-native-reanimated) are active\n * When `false`, the animated style is removed and you can implement custom logic\n * This prop should only be used when you want to write custom styling logic instead of the default animated styles\n * @default true\n */\n isAnimatedStyleActive?: boolean;\n}\n\n/**\n * Animation configuration for checkbox indicator component\n */\nexport type CheckboxIndicatorAnimation = Animation<{\n opacity?: AnimationValue<{\n /**\n * Opacity values [unselected, selected]\n * @default [0, 1]\n */\n value?: [number, number];\n /**\n * Animation timing configuration\n * @default { duration: 100 }\n */\n timingConfig?: WithTimingConfig;\n }>;\n borderRadius?: AnimationValue<{\n /**\n * Border radius values [unselected, selected]\n * @default [99, 0]\n */\n value?: [number, number];\n /**\n * Animation timing configuration\n * @default { duration: 50 }\n */\n timingConfig?: WithTimingConfig;\n }>;\n translateX?: AnimationValue<{\n /**\n * TranslateX values [unselected, selected]\n * @default [-4, 0]\n */\n value?: [number, number];\n /**\n * Animation timing configuration\n * @default { duration: 100 }\n */\n timingConfig?: WithTimingConfig;\n }>;\n scale?: AnimationValue<{\n /**\n * Scale values [unselected, selected]\n * @default [0.8, 1]\n */\n value?: [number, number];\n /**\n * Animation timing configuration\n * @default { duration: 100 }\n */\n timingConfig?: WithTimingConfig;\n }>;\n}>;\n\n/**\n * Props for the CheckboxIndicator component\n */\nexport interface CheckboxIndicatorProps\n extends AnimatedProps> {\n /** Child elements to render inside the indicator, or a render function */\n children?: React.ReactNode | ((props: CheckboxRenderProps) => React.ReactNode);\n\n /** Custom class name for the indicator */\n className?: string;\n\n /** Custom icon props for the indicator */\n iconProps?: CheckboxIndicatorIconProps;\n\n /**\n * Animation configuration\n * - `false` or `\"disabled\"`: Disable all animations\n * - `true` or `undefined`: Use default animations\n * - `object`: Custom animation configuration\n */\n animation?: CheckboxIndicatorAnimation;\n /**\n * Whether animated styles (react-native-reanimated) are active\n * @default true\n */\n isAnimatedStyleActive?: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"size-6 rounded-lg overflow-hidden\",\n variants: {\n variant: {\n primary: \"bg-field shadow-field\",\n secondary: \"bg-default\",\n },\n isSelected: {\n true: \"\",\n false: \"\",\n },\n isDisabled: {\n true: \"disabled:opacity-disabled disabled:pointer-events-none\",\n false: \"\",\n },\n isInvalid: {\n true: \"border border-danger\",\n false: \"border-0\",\n },\n },\n compoundVariants: [\n {\n isSelected: false,\n isInvalid: true,\n className: \"bg-transparent\",\n },\n ],\n defaultVariants: {\n variant: \"primary\",\n isSelected: false,\n isDisabled: false,\n isInvalid: false,\n },\n});\n\nconst indicator = tv({\n base: \"absolute inset-0 items-center justify-center\",\n variants: {\n isInvalid: {\n true: \"bg-danger\",\n false: \"bg-accent\",\n },\n },\n defaultVariants: {\n isInvalid: false,\n },\n});\n\nexport const checkboxClassNames = combineStyles({\n root,\n indicator,\n});\n\nexport const checkboxStyleSheet = StyleSheet.create({\n root: {\n borderCurve: \"continuous\",\n },\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Animated views\n * -----------------------------------------------------------------------------------------------*/\nconst AnimatedRootView = Animated.createAnimatedComponent(CheckboxPrimitives.Root);\n\nconst AnimatedIndicatorView = Animated.createAnimatedComponent(CheckboxPrimitives.Indicator);\n\nconst useCheckbox = CheckboxPrimitives.useCheckboxContext;\n\n/* -------------------------------------------------------------------------------------------------\n * Checkbox.Root\n * -----------------------------------------------------------------------------------------------*/\nconst CheckboxRoot = forwardRef((props, ref) => {\n const {\n children,\n isSelected,\n onSelectedChange,\n isDisabled = false,\n isInvalid = false,\n variant,\n value: _value,\n hitSlop = DEFAULT_HIT_SLOP,\n className,\n style,\n onPressIn,\n onPressOut,\n animation,\n isAnimatedStyleActive = true,\n ...restProps\n } = props;\n\n const isOnSurfaceAutoDetected = useIsOnSurface();\n const finalVariant =\n variant !== undefined ? variant : isOnSurfaceAutoDetected ? \"secondary\" : \"primary\";\n\n const rootClassName = checkboxClassNames.root({\n variant: finalVariant,\n isSelected,\n isDisabled,\n isInvalid,\n className,\n });\n\n const { rContainerStyle, isCheckboxPressed, isAllAnimationsDisabled } = useCheckboxRootAnimation({\n animation,\n });\n\n const rootStyle = isAnimatedStyleActive\n ? [rContainerStyle, checkboxStyleSheet.root, style]\n : [checkboxStyleSheet.root, style];\n\n const animationContextValue = useMemo(\n () => ({\n isCheckboxPressed,\n }),\n [isCheckboxPressed],\n );\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n const handlePressIn = useCallback(\n (event: GestureResponderEvent) => {\n isCheckboxPressed.set(true);\n onPressIn?.(event);\n },\n [isCheckboxPressed, onPressIn],\n );\n\n const handlePressOut = useCallback(\n (event: GestureResponderEvent) => {\n isCheckboxPressed.set(false);\n onPressOut?.(event);\n },\n [isCheckboxPressed, onPressOut],\n );\n\n const renderProps: CheckboxRenderProps = {\n isSelected,\n isInvalid,\n isDisabled,\n };\n\n const content =\n typeof children === \"function\" ? children(renderProps) : (children ?? );\n\n return (\n \n \n \n {content}\n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Checkbox.Indicator\n * -----------------------------------------------------------------------------------------------*/\nconst CheckboxIndicator = forwardRef(\n (props, ref) => {\n const {\n children,\n iconProps,\n className,\n style,\n animation,\n isAnimatedStyleActive = true,\n ...restProps\n } = props;\n\n const { isSelected, isDisabled, isInvalid } = useCheckbox();\n\n const themeColorAccentForeground = useThemeColor(\"accent-foreground\");\n\n const iconSize = iconProps?.size;\n const iconStrokeWidth = iconProps?.strokeWidth;\n const iconColor = iconProps?.color ?? themeColorAccentForeground;\n const iconEnterDuration = iconProps?.enterDuration;\n const iconExitDuration = iconProps?.exitDuration;\n\n const indicatorClassName = checkboxClassNames.indicator({\n isInvalid,\n className,\n });\n\n const { rContainerStyle, isAnimationDisabled } = useCheckboxIndicatorAnimation({\n animation,\n isSelected,\n });\n\n const indicatorStyle = isAnimatedStyleActive ? [rContainerStyle, style] : style;\n\n const renderProps: CheckboxRenderProps = {\n isSelected,\n isInvalid: isInvalid ?? false,\n isDisabled: isDisabled ?? false,\n };\n\n const content =\n typeof children === \"function\"\n ? children(renderProps)\n : (children ??\n (isAnimationDisabled ? (\n \n \n \n ) : (\n \n )));\n\n return (\n \n {content}\n \n );\n },\n);\n\nCheckboxRoot.displayName = DISPLAY_NAME.CHECKBOX_ROOT;\nCheckboxIndicator.displayName = DISPLAY_NAME.CHECKBOX_INDICATOR;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Checkbox - Main container that handles selection state and user interaction.\n * Renders default indicator with checkmark if no children provided.\n * @component Checkbox.Indicator - Optional checkmark container that scales in when selected.\n *\n * @see https://pitsiui.com/docs/native/components/checkbox\n * -----------------------------------------------------------------------------------------------*/\nconst Checkbox = Object.assign(CheckboxRoot, {\n /** @optional Custom indicator with scale animations */\n Indicator: CheckboxIndicator,\n});\n\nexport { Checkbox, useCheckbox };\nexport default Checkbox;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox/checkbox.tsx" }, { "path": "registry/native-ui/src/components/checkbox/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { Alert, View } from \"react-native\";\n\nimport { Button, Checkbox, Text } from \"../..\";\n\nfunction FieldRow({\n children,\n description,\n label,\n}: {\n children: React.ReactNode;\n description?: string;\n label: string;\n}) {\n return (\n \n {children}\n \n {label}\n {description ? {description} : null}\n \n \n );\n}\n\nexport function Basic() {\n return ;\n}\n\nexport function Controlled() {\n const [isSelected, setSelected] = useState(true);\n\n return (\n \n \n \n \n Selected: {isSelected ? \"true\" : \"false\"}\n \n );\n}\n\nexport function CustomIndicator() {\n return (\n \n \n OK\n \n \n );\n}\n\nexport function CustomRenderFunction() {\n return (\n \n {({ isSelected }) => (\n \n {isSelected ? \"ON\" : \"OFF\"}\n \n )}\n \n );\n}\n\nexport function CustomStyles() {\n return (\n \n \n \n );\n}\n\nexport function DefaultSelected() {\n return ;\n}\n\nexport function Disabled() {\n return (\n \n \n \n \n );\n}\n\nexport function Form() {\n const [accepts, setAccepts] = useState(false);\n\n return (\n \n \n \n \n \n \n );\n}\n\nexport function FullRounded() {\n return (\n \n \n \n );\n}\n\nexport function Indeterminate() {\n return (\n \n \n \n \n \n );\n}\n\nexport function Invalid() {\n return ;\n}\n\nexport function RenderProps() {\n return (\n \n {({ isSelected, isInvalid }) => (\n \n {isSelected ? \"OK\" : \"\"}\n \n )}\n \n );\n}\n\nexport function Variants() {\n return (\n \n \n \n \n );\n}\n\nexport function WithDescription() {\n return (\n \n \n \n );\n}\n\nexport function WithLabel() {\n return (\n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox/demos/index.tsx" }, { "path": "registry/native-ui/src/components/checkbox/index.ts", "content": "export type {\n CheckboxAnimationContextValue,\n CheckboxIndicatorAnimation,\n CheckboxIndicatorIconProps,\n CheckboxIndicatorProps,\n CheckboxProps,\n CheckboxRenderProps,\n CheckboxRootAnimation,\n} from \"./checkbox\";\nexport { Checkbox, checkboxClassNames, default, useCheckbox } from \"./checkbox\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/checkbox/index.ts" }, { "path": "registry/native-ui/src/components/chip/chip.animation.ts", "content": "import { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport type { AnimationRootDisableAll } from \"../../helpers/internal/types\";\n\n/**\n * Animation hook for Chip root component\n * Handles root-level animation configuration and provides context for child components\n */\nexport function useChipRootAnimation(options: { animation: AnimationRootDisableAll | undefined }) {\n const { animation } = options;\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n return {\n isAllAnimationsDisabled,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chip/chip.animation.ts" }, { "path": "registry/native-ui/src/components/chip/chip.tsx", "content": "import { forwardRef, useMemo } from \"react\";\nimport {\n Pressable,\n type PressableProps,\n type StyleProp,\n StyleSheet,\n type TextProps,\n type ViewStyle,\n} from \"react-native\";\nimport { tv } from \"tailwind-variants\";\nimport { HeroText } from \"../../helpers/internal/components/hero-text\";\nimport { AnimationSettingsProvider } from \"../../helpers/internal/contexts\";\nimport type { AnimationRootDisableAll, PressableRef, TextRef } from \"../../helpers/internal/types\";\nimport { childrenToString, combineStyles, createContext } from \"../../helpers/internal/utils\";\nimport { useChipRootAnimation } from \"./chip.animation\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for chip components\n */\nexport const DISPLAY_NAME = {\n CHIP_ROOT: \"PitsiUINative.Chip.Root\",\n CHIP_LABEL_CONTENT: \"PitsiUINative.Chip.Label\",\n} as const;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chip size variants\n */\nexport type ChipSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Chip variant types\n */\nexport type ChipVariant = \"primary\" | \"secondary\" | \"tertiary\" | \"soft\";\n\n/**\n * Chip color variants\n */\nexport type ChipColor = \"accent\" | \"default\" | \"success\" | \"warning\" | \"danger\";\n\n/**\n * Props for the main Chip component\n */\nexport interface ChipProps extends PressableProps {\n /** Child elements to render inside the chip */\n children?: React.ReactNode;\n\n /** Visual variant of the chip @default 'primary' */\n variant?: ChipVariant;\n\n /** Size of the chip @default 'md' */\n size?: ChipSize;\n\n /** Color theme of the chip @default 'accent' */\n color?: ChipColor;\n\n /** Custom class name for the chip */\n className?: string;\n\n /**\n * Animation configuration for chip\n * - `\"disable-all\"`: Disable all animations including children\n * - `undefined`: Use default animations\n */\n animation?: AnimationRootDisableAll;\n}\n\n/**\n * Props for the ChipLabel component\n */\nexport interface ChipLabelProps extends TextProps {\n /** Child elements to render as the label. If string, will be wrapped in Text component */\n children?: React.ReactNode;\n\n /** Custom class name for the label */\n className?: string;\n}\n\n/**\n * Context value for chip components\n */\nexport interface ChipContextValue {\n /** Size of the chip */\n size: ChipSize;\n\n /** Variant of the chip */\n variant: ChipVariant;\n\n /** Color theme of the chip */\n color: ChipColor;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"self-start flex-row items-center justify-center gap-1 overflow-hidden\",\n variants: {\n variant: {\n primary: \"\",\n secondary: \"bg-default\",\n tertiary: \"bg-transparent\",\n soft: \"\",\n },\n size: {\n sm: \"px-2 py-0.5 rounded-xl\",\n md: \"px-3 py-[3px] rounded-2xl\",\n lg: \"px-4 py-1 rounded-3xl\",\n },\n color: {\n accent: \"\",\n default: \"\",\n success: \"\",\n warning: \"\",\n danger: \"\",\n },\n },\n compoundVariants: [\n // Primary variant colors\n {\n variant: \"primary\",\n color: \"accent\",\n className: \"bg-accent\",\n },\n {\n variant: \"primary\",\n color: \"default\",\n className: \"bg-default\",\n },\n {\n variant: \"primary\",\n color: \"success\",\n className: \"bg-success\",\n },\n {\n variant: \"primary\",\n color: \"warning\",\n className: \"bg-warning\",\n },\n {\n variant: \"primary\",\n color: \"danger\",\n className: \"bg-danger\",\n },\n // Soft variant colors\n {\n variant: \"soft\",\n color: \"accent\",\n className: \"bg-accent/15\",\n },\n {\n variant: \"soft\",\n color: \"default\",\n className: \"bg-default\",\n },\n {\n variant: \"soft\",\n color: \"success\",\n className: \"bg-success/15\",\n },\n {\n variant: \"soft\",\n color: \"warning\",\n className: \"bg-warning/15\",\n },\n {\n variant: \"soft\",\n color: \"danger\",\n className: \"bg-danger/15\",\n },\n ],\n defaultVariants: {\n size: \"md\",\n variant: \"primary\",\n color: \"accent\",\n },\n});\n\nconst label = tv({\n base: \"font-medium\",\n variants: {\n variant: {\n primary: \"\",\n secondary: \"\",\n tertiary: \"\",\n soft: \"\",\n },\n size: {\n sm: \"text-xs\",\n md: \"text-sm\",\n lg: \"text-base\",\n },\n color: {\n accent: \"\",\n default: \"\",\n success: \"\",\n warning: \"\",\n danger: \"\",\n },\n },\n compoundVariants: [\n // Primary variant text colors\n {\n variant: \"primary\",\n color: \"accent\",\n className: \"text-accent-foreground\",\n },\n {\n variant: \"primary\",\n color: \"default\",\n className: \"text-default-foreground\",\n },\n {\n variant: \"primary\",\n color: \"success\",\n className: \"text-success-foreground\",\n },\n {\n variant: \"primary\",\n color: \"warning\",\n className: \"text-warning-foreground\",\n },\n {\n variant: \"primary\",\n color: \"danger\",\n className: \"text-danger-foreground\",\n },\n // Secondary variant text colors\n {\n variant: \"secondary\",\n color: \"accent\",\n className: \"text-accent\",\n },\n {\n variant: \"secondary\",\n color: \"default\",\n className: \"text-default-foreground\",\n },\n {\n variant: \"secondary\",\n color: \"success\",\n className: \"text-success\",\n },\n {\n variant: \"secondary\",\n color: \"warning\",\n className: \"text-warning\",\n },\n {\n variant: \"secondary\",\n color: \"danger\",\n className: \"text-danger\",\n },\n // Tertiary variant text colors\n {\n variant: \"tertiary\",\n color: \"accent\",\n className: \"text-foreground\",\n },\n {\n variant: \"tertiary\",\n color: \"default\",\n className: \"text-default-foreground\",\n },\n {\n variant: \"tertiary\",\n color: \"success\",\n className: \"text-success\",\n },\n {\n variant: \"tertiary\",\n color: \"warning\",\n className: \"text-warning\",\n },\n {\n variant: \"tertiary\",\n color: \"danger\",\n className: \"text-danger\",\n },\n // Soft variant text colors\n {\n variant: \"soft\",\n color: \"accent\",\n className: \"text-accent\",\n },\n {\n variant: \"soft\",\n color: \"default\",\n className: \"text-default-foreground\",\n },\n {\n variant: \"soft\",\n color: \"success\",\n className: \"text-success\",\n },\n {\n variant: \"soft\",\n color: \"warning\",\n className: \"text-warning\",\n },\n {\n variant: \"soft\",\n color: \"danger\",\n className: \"text-danger\",\n },\n ],\n defaultVariants: {\n size: \"md\",\n variant: \"primary\",\n color: \"accent\",\n },\n});\n\nexport const chipClassNames = combineStyles({\n root,\n label,\n});\n\nexport const chipStyleSheet = StyleSheet.create({\n root: {\n borderCurve: \"continuous\",\n },\n});\n\nexport type LabelContentSlots = keyof ReturnType;\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\nconst [ChipProvider, useChip] = createContext({\n name: \"ChipContext\",\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Chip.Root\n * -----------------------------------------------------------------------------------------------*/\nconst ChipRoot = forwardRef((props, ref) => {\n const {\n children,\n variant = \"primary\",\n size = \"md\",\n color = \"accent\",\n className,\n style,\n animation,\n ...restProps\n } = props;\n\n const stringifiedChildren = childrenToString(children);\n\n const rootClassName = chipClassNames.root({\n size,\n variant,\n color,\n className,\n });\n\n const { isAllAnimationsDisabled } = useChipRootAnimation({\n animation,\n });\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n const contextValue = useMemo(\n () => ({\n size,\n variant,\n color,\n }),\n [size, variant, color],\n );\n\n return (\n \n \n }\n {...restProps}\n >\n {stringifiedChildren ? {stringifiedChildren} : children}\n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Chip.Label\n * -----------------------------------------------------------------------------------------------*/\nconst ChipLabel = forwardRef((props, ref) => {\n const { children, className, ...restProps } = props;\n\n const { size, variant, color } = useChip();\n\n const labelClassName = chipClassNames.label({\n size,\n variant,\n color,\n className,\n });\n\n return (\n \n {children}\n \n );\n});\n\nChipRoot.displayName = DISPLAY_NAME.CHIP_ROOT;\nChipLabel.displayName = DISPLAY_NAME.CHIP_LABEL_CONTENT;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Chip - Main container that displays a compact element. Renders with\n * string children as label or accepts compound components for custom layouts.\n * @component Chip.Label - Text content of the chip. When string is provided,\n * it renders as Text. Otherwise renders children as-is.\n *\n * Props flow from Chip to sub-components via context (size, variant, color).\n *\n * @see https://pitsiui.com/docs/native/components/chip\n * -----------------------------------------------------------------------------------------------*/\nconst Chip = Object.assign(ChipRoot, {\n /** Chip label - renders text or custom content */\n Label: ChipLabel,\n});\n\nexport { Chip, useChip };\nexport default Chip;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chip/chip.tsx" }, { "path": "registry/native-ui/src/components/chip/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Chip, Separator, Text } from \"../..\";\n\nconst colors = [\"accent\", \"default\", \"success\", \"warning\", \"danger\"] as const;\nconst sizes = [\"lg\", \"md\", \"sm\"] as const;\nconst variants = [\"primary\", \"secondary\", \"tertiary\", \"soft\"] as const;\n\nfunction IconText({ children }: { children: string }) {\n return {children};\n}\n\nexport function Basic() {\n return (\n \n Default\n Accent\n Success\n Warning\n Danger\n \n );\n}\n\nexport function Statuses() {\n return (\n \n \n \n .\n Default\n \n \n .\n Active\n \n \n .\n Pending\n \n \n .\n Inactive\n \n \n\n \n \n i\n New Feature\n \n \n OK\n Available\n \n \n !\n Beta\n \n \n x\n Deprecated\n \n \n \n );\n}\n\nexport function Variants() {\n return (\n \n {sizes.map((size, index) => (\n \n {size}\n \n \n {colors.map((color) => (\n \n {color}\n \n ))}\n \n \n {variants.map((variant) => (\n \n {variant}\n {colors.map((color) => (\n \n \n o\n Label\n o\n \n \n ))}\n \n ))}\n \n {index < sizes.length - 1 ? : null}\n \n ))}\n \n );\n}\n\nexport function WithIcon() {\n return (\n \n \n i\n Information\n \n \n OK\n Completed\n \n \n ...\n Pending\n \n \n x\n Failed\n \n \n Label\n v\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chip/demos/index.tsx" }, { "path": "registry/native-ui/src/components/chip/index.ts", "content": "export type {\n ChipColor,\n ChipContextValue,\n ChipLabelProps,\n ChipProps,\n ChipSize,\n ChipVariant,\n} from \"./chip\";\nexport { Chip, chipClassNames, default, useChip } from \"./chip\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/chip/index.ts" }, { "path": "registry/native-ui/src/components/close-button/close-button.tsx", "content": "import { forwardRef } from \"react\";\nimport { tv } from \"tailwind-variants\";\nimport { useThemeColor } from \"../../helpers/external/hooks\";\nimport { CloseIcon } from \"../../helpers/internal/components\";\nimport type { PressableRef } from \"../../helpers/internal/types\";\nimport { combineStyles } from \"../../helpers/internal/utils\";\nimport { Button, type ButtonRootProps } from \"../button\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for CloseButton components\n */\nexport const DISPLAY_NAME = {\n CLOSE_BUTTON_ROOT: \"PitsiUINative.CloseButton.Root\",\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Props for customizing the close icon\n */\nexport interface CloseButtonIconProps {\n /**\n * Size of the icon\n * @default 16\n */\n size?: number;\n /**\n * Color of the icon\n * @default Uses theme foreground color\n */\n color?: string;\n}\n\n/**\n * Props for the CloseButton component\n *\n * Extends ButtonRootProps, allowing full override of all button props.\n * Defaults to variant='tertiary', size='sm', and isIconOnly=true.\n */\nexport type CloseButtonProps = ButtonRootProps & {\n /**\n * Props for customizing the close icon\n */\n iconProps?: CloseButtonIconProps;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"h-8\",\n});\n\nexport const closeButtonClassNames = combineStyles({\n root,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * CloseButton\n * -----------------------------------------------------------------------------------------------*/\nconst CloseButtonRoot = forwardRef((props, ref) => {\n const { iconProps, className, children, ...restProps } = props;\n\n const themeColorMuted = useThemeColor(\"muted\");\n\n /** Resolved root className from close-button styles */\n const rootClassName = closeButtonClassNames.root({ className });\n\n return (\n \n {children ?? (\n \n )}\n \n );\n});\n\nCloseButtonRoot.displayName = DISPLAY_NAME.CLOSE_BUTTON_ROOT;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component CloseButton - A specialized button component that renders a close icon by default.\n * It is a Button with default variant='tertiary', size='sm', and isIconOnly=true.\n * The close icon can be customized via the iconProps prop, or you can provide custom children.\n *\n * @see Full documentation: https://pitsiui.com/docs/native/components/close-button\n * -----------------------------------------------------------------------------------------------*/\nconst CloseButton = CloseButtonRoot;\n\nexport { CloseButton };\nexport default CloseButton;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/close-button/close-button.tsx" }, { "path": "registry/native-ui/src/components/close-button/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { View } from \"react-native\";\n\nimport { CloseButton, Text } from \"../..\";\n\nexport function Default() {\n return ;\n}\n\nexport function Interactive() {\n const [count, setCount] = useState(0);\n\n return (\n \n setCount(count + 1)}\n />\n Clicked: {count} times\n \n );\n}\n\nexport function WithCustomIcon() {\n return (\n \n \n \n (x)\n \n Custom Icon\n \n \n \n x\n \n Alternative Icon\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/close-button/demos/index.tsx" }, { "path": "registry/native-ui/src/components/close-button/index.ts", "content": "export type { CloseButtonIconProps, CloseButtonProps } from \"./close-button\";\nexport { CloseButton, closeButtonClassNames, default } from \"./close-button\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/close-button/index.ts" }, { "path": "registry/native-ui/src/components/color-area/color-area.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { type ColorValue, colorString } from \"../color-utils\";\n\nexport const colorAreaVariants = tv({\n slots: {\n root: \"h-40 w-full overflow-hidden rounded-2xl border border-border bg-default\",\n thumb: \"size-6 rounded-full border-2 border-background bg-white\",\n },\n});\n\nexport type ColorAreaVariants = VariantProps;\n\nexport interface ColorAreaRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n color?: ColorValue;\n value?: ColorValue;\n}\n\nconst ColorAreaRoot = forwardRef(\n ({ className, color, style, value, ...props }, ref) => {\n const slots = colorAreaVariants();\n return (\n \n );\n },\n);\n\nexport interface ColorAreaThumbProps extends ViewProps {\n className?: string;\n}\n\nconst ColorAreaThumb = forwardRef(({ className, ...props }, ref) => {\n const slots = colorAreaVariants();\n return ;\n});\n\nexport { ColorAreaRoot, ColorAreaThumb };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-area/color-area.tsx" }, { "path": "registry/native-ui/src/components/color-area/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ColorAreaRoot, ColorAreaThumb } from \"./color-area\";\n\nexport const ColorArea = Object.assign(ColorAreaRoot, {\n Root: ColorAreaRoot,\n Thumb: ColorAreaThumb,\n});\n\nexport type ColorArea = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n ThumbProps: ComponentProps;\n};\n\nexport type {\n ColorAreaRootProps,\n ColorAreaRootProps as ColorAreaProps,\n ColorAreaThumbProps,\n ColorAreaVariants,\n} from \"./color-area\";\n\nexport { ColorAreaRoot, ColorAreaThumb, colorAreaVariants } from \"./color-area\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-area/index.ts" }, { "path": "registry/native-ui/src/components/color-field/color-field.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport type { ColorValue } from \"../color-utils\";\n\nexport const colorFieldVariants = tv({\n base: \"gap-1.5\",\n});\n\nexport type ColorFieldVariants = VariantProps;\n\nexport interface ColorFieldRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n defaultValue?: ColorValue;\n onChange?: (value: ColorValue) => void;\n value?: ColorValue;\n}\n\nconst ColorFieldRoot = forwardRef(\n (\n { className, defaultValue: _defaultValue, onChange: _onChange, value: _value, ...props },\n ref,\n ) => ,\n);\n\nColorFieldRoot.displayName = \"PitsiUINative.ColorFieldRoot\";\n\nexport { ColorFieldRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-field/color-field.tsx" }, { "path": "registry/native-ui/src/components/color-field/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n ColorInputGroupInput,\n ColorInputGroupPrefix,\n ColorInputGroupRoot,\n ColorInputGroupSuffix,\n} from \"../color-input-group\";\nimport type { ColorValue } from \"../color-utils\";\nimport { ColorFieldRoot } from \"./color-field\";\n\nexport const ColorField = Object.assign(ColorFieldRoot, {\n Group: ColorInputGroupRoot,\n Input: ColorInputGroupInput,\n Prefix: ColorInputGroupPrefix,\n Root: ColorFieldRoot,\n Suffix: ColorInputGroupSuffix,\n});\n\nexport type ColorField = {\n GroupProps: ComponentProps;\n InputProps: ComponentProps;\n PrefixProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SuffixProps: ComponentProps;\n};\n\nexport type {\n ColorFieldRootProps,\n ColorFieldRootProps as ColorFieldProps,\n ColorFieldVariants,\n} from \"./color-field\";\nexport { ColorFieldRoot, colorFieldVariants } from \"./color-field\";\nexport type { ColorValue };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-field/index.ts" }, { "path": "registry/native-ui/src/components/color-input-group/color-input-group.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { TextInput, type TextInputProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const colorInputGroupVariants = tv({\n slots: {\n input: \"min-h-11 min-w-0 flex-1 px-3 text-base text-foreground\",\n prefix: \"px-3\",\n root: \"min-h-11 flex-row items-center overflow-hidden rounded-xl border border-border bg-background\",\n suffix: \"px-3\",\n },\n});\n\nexport type ColorInputGroupVariants = VariantProps;\n\nexport interface ColorInputGroupRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorInputGroupRoot = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorInputGroupVariants();\n return ;\n },\n);\n\nexport interface ColorInputGroupInputProps extends TextInputProps {\n className?: string;\n}\n\nconst ColorInputGroupInput = forwardRef(\n ({ className, placeholderTextColor = \"#8a8a8a\", ...props }, ref) => {\n const slots = colorInputGroupVariants();\n return (\n \n );\n },\n);\n\nexport interface ColorInputGroupPrefixProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorInputGroupPrefix = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorInputGroupVariants();\n return ;\n },\n);\n\nexport interface ColorInputGroupSuffixProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorInputGroupSuffix = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorInputGroupVariants();\n return ;\n },\n);\n\nexport { ColorInputGroupInput, ColorInputGroupPrefix, ColorInputGroupRoot, ColorInputGroupSuffix };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-input-group/color-input-group.tsx" }, { "path": "registry/native-ui/src/components/color-input-group/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n ColorInputGroupInput,\n ColorInputGroupPrefix,\n ColorInputGroupRoot,\n ColorInputGroupSuffix,\n} from \"./color-input-group\";\n\nexport const ColorInputGroup = Object.assign(ColorInputGroupRoot, {\n Input: ColorInputGroupInput,\n Prefix: ColorInputGroupPrefix,\n Root: ColorInputGroupRoot,\n Suffix: ColorInputGroupSuffix,\n});\n\nexport type ColorInputGroup = {\n InputProps: ComponentProps;\n PrefixProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SuffixProps: ComponentProps;\n};\n\nexport type {\n ColorInputGroupInputProps,\n ColorInputGroupPrefixProps,\n ColorInputGroupRootProps,\n ColorInputGroupRootProps as ColorInputGroupProps,\n ColorInputGroupSuffixProps,\n ColorInputGroupVariants,\n} from \"./color-input-group\";\n\nexport {\n ColorInputGroupInput,\n ColorInputGroupPrefix,\n ColorInputGroupRoot,\n ColorInputGroupSuffix,\n colorInputGroupVariants,\n} from \"./color-input-group\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-input-group/index.ts" }, { "path": "registry/native-ui/src/components/color-picker/color-picker.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const colorPickerVariants = tv({\n slots: {\n popover: \"gap-3 rounded-2xl border border-border bg-background p-3\",\n root: \"relative gap-2\",\n trigger: \"min-h-10 flex-row items-center gap-2 rounded-xl border border-border px-3 py-2\",\n },\n});\n\nexport type ColorPickerVariants = VariantProps;\n\nexport interface ColorPickerRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorPickerRoot = forwardRef(({ className, ...props }, ref) => {\n const slots = colorPickerVariants();\n return ;\n});\n\nexport interface ColorPickerTriggerProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorPickerTrigger = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorPickerVariants();\n return ;\n },\n);\n\nexport interface ColorPickerPopoverProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorPickerPopover = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorPickerVariants();\n return ;\n },\n);\n\nexport { ColorPickerPopover, ColorPickerRoot, ColorPickerTrigger };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-picker/color-picker.tsx" }, { "path": "registry/native-ui/src/components/color-picker/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ColorPickerPopover, ColorPickerRoot, ColorPickerTrigger } from \"./color-picker\";\n\nexport const ColorPicker = Object.assign(ColorPickerRoot, {\n Popover: ColorPickerPopover,\n Root: ColorPickerRoot,\n Trigger: ColorPickerTrigger,\n});\n\nexport type ColorPicker = {\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n ColorPickerPopoverProps,\n ColorPickerRootProps,\n ColorPickerRootProps as ColorPickerProps,\n ColorPickerTriggerProps,\n ColorPickerVariants,\n} from \"./color-picker\";\n\nexport {\n ColorPickerPopover,\n ColorPickerRoot,\n ColorPickerTrigger,\n colorPickerVariants,\n} from \"./color-picker\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-picker/index.ts" }, { "path": "registry/native-ui/src/components/color-slider/color-slider.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { type TextProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { type ColorValue, colorString } from \"../color-utils\";\nimport { Text } from \"../text\";\n\nexport type AlphaChannel = \"alpha\";\nexport type RGBChannel = \"blue\" | \"green\" | \"red\";\nexport type HSLHSBSharedChannel = \"hue\" | \"saturation\";\nexport type HSLChannel = HSLHSBSharedChannel | \"lightness\";\nexport type HSBChannel = HSLHSBSharedChannel | \"brightness\";\n\nexport const colorSliderVariants = tv({\n slots: {\n output: \"text-xs text-muted\",\n root: \"gap-2\",\n thumb: \"size-6 rounded-full border-2 border-background bg-white\",\n track: \"h-3 overflow-hidden rounded-full bg-default\",\n },\n});\n\nexport type ColorSliderVariants = VariantProps;\n\nexport interface ColorSliderRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorSliderRoot = forwardRef(({ className, ...props }, ref) => {\n const slots = colorSliderVariants();\n return ;\n});\n\nexport interface ColorSliderTrackProps extends ViewProps {\n className?: string;\n color?: ColorValue;\n value?: ColorValue;\n}\n\nconst ColorSliderTrack = forwardRef(\n ({ className, color, style, value, ...props }, ref) => {\n const slots = colorSliderVariants();\n return (\n \n );\n },\n);\n\nexport interface ColorSliderThumbProps extends ViewProps {\n className?: string;\n}\n\nconst ColorSliderThumb = forwardRef(({ className, ...props }, ref) => {\n const slots = colorSliderVariants();\n return ;\n});\n\nexport interface ColorSliderOutputProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorSliderOutput = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorSliderVariants();\n return ;\n },\n);\n\nexport interface ColorSliderChannelProps extends ViewProps {\n className?: string;\n}\n\nexport { ColorSliderOutput, ColorSliderRoot, ColorSliderThumb, ColorSliderTrack };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-slider/color-slider.tsx" }, { "path": "registry/native-ui/src/components/color-slider/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n ColorSliderOutput,\n ColorSliderRoot,\n ColorSliderThumb,\n ColorSliderTrack,\n} from \"./color-slider\";\n\nexport const ColorSlider = Object.assign(ColorSliderRoot, {\n Output: ColorSliderOutput,\n Root: ColorSliderRoot,\n Thumb: ColorSliderThumb,\n Track: ColorSliderTrack,\n});\n\nexport type ColorSlider = {\n OutputProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n ThumbProps: ComponentProps;\n TrackProps: ComponentProps;\n};\n\nexport type {\n AlphaChannel,\n ColorSliderChannelProps,\n ColorSliderOutputProps,\n ColorSliderRootProps,\n ColorSliderRootProps as ColorSliderProps,\n ColorSliderThumbProps,\n ColorSliderTrackProps,\n ColorSliderVariants,\n HSBChannel,\n HSLChannel,\n HSLHSBSharedChannel,\n RGBChannel,\n} from \"./color-slider\";\n\nexport {\n ColorSliderOutput,\n ColorSliderRoot,\n ColorSliderThumb,\n ColorSliderTrack,\n colorSliderVariants,\n} from \"./color-slider\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-slider/index.ts" }, { "path": "registry/native-ui/src/components/color-swatch-picker/color-swatch-picker.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { ColorSwatchRoot, type ColorSwatchRootProps } from \"../color-swatch\";\nimport { type ColorValue, colorString } from \"../color-utils\";\nimport { Text } from \"../text\";\n\nexport const colorSwatchPickerVariants = tv({\n slots: {\n indicator: \"absolute inset-0 items-center justify-center rounded-full\",\n item: \"size-10 items-center justify-center rounded-full\",\n root: \"flex-row flex-wrap gap-2\",\n },\n});\n\nexport type ColorSwatchPickerVariants = VariantProps;\n\nexport interface ColorSwatchPickerRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorSwatchPickerRoot = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = colorSwatchPickerVariants();\n return ;\n },\n);\n\nexport interface ColorSwatchPickerItemProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n color?: ColorValue;\n value?: ColorValue;\n}\n\nconst ColorSwatchPickerItem = forwardRef(\n ({ children, className, color, value, ...props }, ref) => {\n const slots = colorSwatchPickerVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport interface ColorSwatchPickerIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ColorSwatchPickerIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = colorSwatchPickerVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport interface ColorSwatchPickerSwatchProps extends ColorSwatchRootProps {}\n\nconst ColorSwatchPickerSwatch = ColorSwatchRoot;\n\nexport {\n ColorSwatchPickerIndicator,\n ColorSwatchPickerItem,\n ColorSwatchPickerRoot,\n ColorSwatchPickerSwatch,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-swatch-picker/color-swatch-picker.tsx" }, { "path": "registry/native-ui/src/components/color-swatch-picker/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n ColorSwatchPickerIndicator,\n ColorSwatchPickerItem,\n ColorSwatchPickerRoot,\n ColorSwatchPickerSwatch,\n} from \"./color-swatch-picker\";\n\nexport const ColorSwatchPicker = Object.assign(ColorSwatchPickerRoot, {\n Indicator: ColorSwatchPickerIndicator,\n Item: ColorSwatchPickerItem,\n Root: ColorSwatchPickerRoot,\n Swatch: ColorSwatchPickerSwatch,\n});\n\nexport type ColorSwatchPicker = {\n IndicatorProps: ComponentProps;\n ItemProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SwatchProps: ComponentProps;\n};\n\nexport type {\n ColorSwatchPickerIndicatorProps,\n ColorSwatchPickerItemProps,\n ColorSwatchPickerRootProps,\n ColorSwatchPickerRootProps as ColorSwatchPickerProps,\n ColorSwatchPickerSwatchProps,\n ColorSwatchPickerVariants,\n} from \"./color-swatch-picker\";\n\nexport {\n ColorSwatchPickerIndicator,\n ColorSwatchPickerItem,\n ColorSwatchPickerRoot,\n ColorSwatchPickerSwatch,\n colorSwatchPickerVariants,\n} from \"./color-swatch-picker\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-swatch-picker/index.ts" }, { "path": "registry/native-ui/src/components/color-swatch/color-swatch.tsx", "content": "import { forwardRef } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { type ColorValue, colorString } from \"../color-utils\";\n\nexport const colorSwatchVariants = tv({\n base: \"size-8 rounded-full border border-border\",\n});\n\nexport type ColorSwatchVariants = VariantProps;\n\nexport interface ColorSwatchRootProps extends ViewProps {\n className?: string;\n color?: ColorValue;\n value?: ColorValue;\n}\n\nconst ColorSwatchRoot = forwardRef(\n ({ className, color, style, value, ...props }, ref) => (\n \n ),\n);\n\nColorSwatchRoot.displayName = \"PitsiUINative.ColorSwatchRoot\";\n\nexport { ColorSwatchRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-swatch/color-swatch.tsx" }, { "path": "registry/native-ui/src/components/color-swatch/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ColorSwatchRoot } from \"./color-swatch\";\n\nexport const ColorSwatch = Object.assign(ColorSwatchRoot, {\n Root: ColorSwatchRoot,\n});\n\nexport type ColorSwatch = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n ColorSwatchRootProps,\n ColorSwatchRootProps as ColorSwatchProps,\n ColorSwatchVariants,\n} from \"./color-swatch\";\n\nexport { ColorSwatchRoot, colorSwatchVariants } from \"./color-swatch\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-swatch/index.ts" }, { "path": "registry/native-ui/src/components/color-utils.ts", "content": "export type ColorValue =\n | string\n | {\n hex?: string;\n toHex?: () => string;\n toString?: () => string;\n };\n\nexport function colorString(value?: ColorValue) {\n if (!value) return \"transparent\";\n if (typeof value === \"string\") return value;\n if (typeof value.toHex === \"function\") return value.toHex();\n if (typeof value.hex === \"string\") return value.hex;\n if (typeof value.toString === \"function\") return value.toString();\n return \"transparent\";\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/color-utils.ts" }, { "path": "registry/native-ui/src/components/combo-box/combo-box.tsx", "content": "import { Children, createContext, forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { IconChevronDown } from \"../icons\";\nimport { Text } from \"../text\";\n\nexport const comboBoxVariants = tv({\n slots: {\n base: \"relative gap-1.5\",\n inputGroup:\n \"min-h-11 flex-row items-center overflow-hidden rounded-xl border border-border bg-background\",\n popover: \"max-h-72 rounded-2xl border border-border bg-background p-2\",\n trigger: \"min-h-11 flex-row items-center gap-2 rounded-xl px-3 py-2\",\n triggerText: \"text-sm text-foreground\",\n },\n variants: {\n fullWidth: {\n false: {},\n true: {\n base: \"w-full\",\n inputGroup: \"w-full\",\n },\n },\n },\n defaultVariants: {\n fullWidth: false,\n },\n});\n\nexport type ComboBoxVariants = VariantProps;\nexport const ComboBoxContext = createContext>({});\n\nfunction renderTextChildren(children: ReactNode, className: string) {\n return Children.map(children, (child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return {child};\n }\n return child;\n });\n}\n\nexport interface ComboBoxRootProps\n extends Omit,\n ComboBoxVariants {\n children?: ReactNode | ((props: { isOpen: boolean; items?: Iterable }) => ReactNode);\n className?: string;\n defaultInputValue?: string;\n inputValue?: string;\n isDisabled?: boolean;\n items?: Iterable;\n menuTrigger?: \"focus\" | \"input\" | \"manual\";\n onInputChange?: (value: string) => void;\n selectedKey?: string | number | null;\n variant?: \"primary\" | \"secondary\";\n}\n\nfunction ComboBoxRootInner(\n {\n children,\n className,\n fullWidth,\n isDisabled,\n items,\n menuTrigger: _menuTrigger,\n variant: _variant,\n ...props\n }: ComboBoxRootProps,\n ref: React.ForwardedRef,\n) {\n const slots = comboBoxVariants({ fullWidth });\n\n return (\n \n \n {typeof children === \"function\" ? children({ isOpen: true, items }) : children}\n \n \n );\n}\n\nconst ComboBoxRoot = forwardRef(ComboBoxRootInner) as (\n props: ComboBoxRootProps & { ref?: React.ForwardedRef },\n) => React.ReactElement | null;\n\nexport interface ComboBoxInputGroupProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ComboBoxInputGroup = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = comboBoxVariants();\n return ;\n },\n);\n\nexport interface ComboBoxTriggerProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ComboBoxTrigger = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = comboBoxVariants();\n return (\n \n {children ? renderTextChildren(children, slots.triggerText()) : }\n \n );\n },\n);\n\nexport interface ComboBoxPopoverProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n placement?: \"bottom\" | \"left\" | \"right\" | \"top\";\n}\n\nconst ComboBoxPopover = forwardRef(\n ({ className, placement: _placement, ...props }, ref) => {\n const slots = comboBoxVariants();\n return ;\n },\n);\n\nexport { ComboBoxInputGroup, ComboBoxPopover, ComboBoxRoot, ComboBoxTrigger };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/combo-box/combo-box.tsx" }, { "path": "registry/native-ui/src/components/combo-box/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ComboBoxInputGroup, ComboBoxPopover, ComboBoxRoot, ComboBoxTrigger } from \"./combo-box\";\n\nexport const ComboBox = Object.assign(ComboBoxRoot, {\n InputGroup: ComboBoxInputGroup,\n Popover: ComboBoxPopover,\n Root: ComboBoxRoot,\n Trigger: ComboBoxTrigger,\n});\n\nexport type ComboBox = {\n InputGroupProps: ComponentProps;\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n ComboBoxInputGroupProps,\n ComboBoxPopoverProps,\n ComboBoxRootProps,\n ComboBoxRootProps as ComboBoxProps,\n ComboBoxTriggerProps,\n ComboBoxVariants,\n} from \"./combo-box\";\n\nexport {\n ComboBoxContext,\n ComboBoxInputGroup,\n ComboBoxPopover,\n ComboBoxRoot,\n ComboBoxTrigger,\n comboBoxVariants,\n} from \"./combo-box\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/combo-box/index.ts" }, { "path": "registry/native-ui/src/components/command/command.tsx", "content": "import {\n Children,\n createContext,\n forwardRef,\n isValidElement,\n type ReactNode,\n useContext,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Pressable,\n type PressableProps,\n ScrollView,\n type ScrollViewProps,\n TextInput,\n type TextInputProps,\n View,\n type ViewProps,\n} from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { IconSearch } from \"../icons\";\nimport { Text } from \"../text\";\n\nexport const commandVariants = tv({\n slots: {\n base: \"w-full overflow-hidden rounded-2xl bg-surface shadow-sm\",\n dialog: \"w-full max-w-lg self-center rounded-2xl border border-border bg-surface p-0 shadow-sm\",\n empty: \"items-center justify-center px-4 py-6\",\n emptyText: \"text-center text-sm text-muted\",\n group: \"gap-1 p-1\",\n groupHeading: \"px-2 py-1.5 text-xs font-medium text-muted\",\n input: \"min-h-12 flex-1 bg-transparent px-0 py-3 text-sm text-foreground\",\n inputWrapper: \"flex-row items-center gap-2 border-border border-b px-4\",\n item: \"min-h-10 flex-row items-center gap-2 rounded-xl px-3 py-2\",\n itemText: \"text-sm text-foreground\",\n list: \"max-h-80 p-1\",\n searchIcon: \"text-muted\",\n separator: \"my-1 h-px w-full bg-border\",\n shortcut: \"ml-auto text-xs text-muted\",\n },\n});\n\nexport type CommandVariants = VariantProps;\n\ntype CommandContextValue = {\n onValueChange?: (value: string) => void;\n query: string;\n setQuery: (value: string) => void;\n shouldFilter: boolean;\n slots: ReturnType;\n value?: string;\n};\n\nconst CommandContext = createContext(undefined);\n\nfunction useCommandContext() {\n return useContext(CommandContext);\n}\n\nfunction renderTextChildren(children: ReactNode, className: string) {\n return Children.map(children, (child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return {child};\n }\n\n return child;\n });\n}\n\nfunction childrenToText(children: ReactNode): string {\n if (children == null || typeof children === \"boolean\") return \"\";\n if (typeof children === \"string\" || typeof children === \"number\") return String(children);\n if (Array.isArray(children)) return children.map(childrenToText).join(\" \");\n\n if (isValidElement<{ children?: ReactNode }>(children)) {\n return childrenToText(children.props.children);\n }\n\n return \"\";\n}\n\nexport interface CommandRootProps extends Omit {\n children?: ReactNode;\n className?: string;\n defaultValue?: string;\n filter?: (value: string, search: string, keywords?: string[]) => number;\n label?: string;\n loop?: boolean;\n onValueChange?: (value: string) => void;\n shouldFilter?: boolean;\n value?: string;\n}\n\nconst CommandRoot = forwardRef(\n (\n {\n children,\n className,\n defaultValue,\n filter: _filter,\n label,\n loop: _loop,\n onValueChange,\n shouldFilter = true,\n value,\n ...props\n },\n ref,\n ) => {\n const slots = useMemo(() => commandVariants(), []);\n const [internalQuery, setInternalQuery] = useState(defaultValue ?? value ?? \"\");\n const query = value ?? internalQuery;\n\n const contextValue = useMemo(\n () => ({\n onValueChange,\n query,\n setQuery: (nextValue) => {\n if (value === undefined) {\n setInternalQuery(nextValue);\n }\n onValueChange?.(nextValue);\n },\n shouldFilter,\n slots,\n value,\n }),\n [onValueChange, query, shouldFilter, slots, value],\n );\n\n return (\n \n \n {children}\n \n \n );\n },\n);\n\nCommandRoot.displayName = \"PitsiUINative.CommandRoot\";\n\nexport interface CommandInputProps extends Omit {\n className?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst CommandInput = forwardRef(\n (\n {\n className,\n onChangeText,\n onValueChange,\n placeholder = \"Search...\",\n returnKeyType = \"search\",\n value,\n ...props\n },\n ref,\n ) => {\n const context = useCommandContext();\n const slots = context?.slots ?? commandVariants();\n const inputValue = value ?? context?.query ?? \"\";\n\n return (\n \n \n {\n context?.setQuery(nextValue);\n onValueChange?.(nextValue);\n onChangeText?.(nextValue);\n }}\n placeholder={placeholder}\n returnKeyType={returnKeyType}\n value={inputValue}\n {...props}\n />\n \n );\n },\n);\n\nCommandInput.displayName = \"PitsiUINative.CommandInput\";\n\nexport interface CommandListProps extends ScrollViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst CommandList = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = useCommandContext()?.slots ?? commandVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nCommandList.displayName = \"PitsiUINative.CommandList\";\n\nexport interface CommandEmptyProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst CommandEmpty = forwardRef(\n ({ children, className, ...props }, ref) => {\n const context = useCommandContext();\n const slots = context?.slots ?? commandVariants();\n\n if (!context?.query) {\n return null;\n }\n\n return (\n \n {renderTextChildren(children ?? \"No results found.\", slots.emptyText())}\n \n );\n },\n);\n\nCommandEmpty.displayName = \"PitsiUINative.CommandEmpty\";\n\nexport interface CommandGroupProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n heading?: ReactNode;\n}\n\nconst CommandGroup = forwardRef(\n ({ children, className, heading, ...props }, ref) => {\n const slots = useCommandContext()?.slots ?? commandVariants();\n\n return (\n \n {heading ? renderTextChildren(heading, slots.groupHeading()) : null}\n {children}\n \n );\n },\n);\n\nCommandGroup.displayName = \"PitsiUINative.CommandGroup\";\n\nexport interface CommandItemProps extends Omit {\n children?: ReactNode;\n className?: string;\n disabled?: boolean;\n isDisabled?: boolean;\n keywords?: string[];\n onSelect?: (value: string) => void;\n textValue?: string;\n value?: string;\n}\n\nconst CommandItem = forwardRef(\n (\n {\n children,\n className,\n disabled = false,\n isDisabled = false,\n keywords,\n onPress,\n onSelect,\n textValue,\n value,\n ...props\n },\n ref,\n ) => {\n const context = useCommandContext();\n const slots = context?.slots ?? commandVariants();\n const itemValue = value ?? textValue ?? childrenToText(children);\n const haystack = [itemValue, ...(keywords ?? [])].join(\" \").toLocaleLowerCase();\n const query = context?.query.toLocaleLowerCase() ?? \"\";\n\n if (context?.shouldFilter && query && !haystack.includes(query)) {\n return null;\n }\n\n const resolvedDisabled = disabled || isDisabled;\n\n return (\n {\n onPress?.(event);\n onSelect?.(itemValue);\n }}\n {...props}\n >\n {renderTextChildren(children, slots.itemText())}\n \n );\n },\n);\n\nCommandItem.displayName = \"PitsiUINative.CommandItem\";\n\nexport interface CommandSeparatorProps extends ViewProps {\n className?: string;\n}\n\nconst CommandSeparator = forwardRef(({ className, ...props }, ref) => {\n const slots = useCommandContext()?.slots ?? commandVariants();\n\n return ;\n});\n\nCommandSeparator.displayName = \"PitsiUINative.CommandSeparator\";\n\nexport interface CommandShortcutProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst CommandShortcut = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = useCommandContext()?.slots ?? commandVariants();\n\n return (\n \n {renderTextChildren(children, slots.shortcut({ className }))}\n \n );\n },\n);\n\nCommandShortcut.displayName = \"PitsiUINative.CommandShortcut\";\n\nexport interface CommandDialogProps extends CommandRootProps {\n onOpenChange?: (open: boolean) => void;\n open?: boolean;\n}\n\nconst CommandDialog = forwardRef(\n ({ children, className, onOpenChange: _onOpenChange, open = true, ...props }, ref) => {\n const slots = commandVariants();\n\n if (!open) {\n return null;\n }\n\n return (\n \n {children}\n \n );\n },\n);\n\nCommandDialog.displayName = \"PitsiUINative.CommandDialog\";\n\nexport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandRoot,\n CommandSeparator,\n CommandShortcut,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/command/command.tsx" }, { "path": "registry/native-ui/src/components/command/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { View } from \"react-native\";\n\nimport { Command, Text } from \"../..\";\n\nexport function Default() {\n const [selected, setSelected] = useState(\"No command selected\");\n\n return (\n \n \n \n \n No command found.\n \n \n New file\n N\n \n \n Open search\n S\n \n \n \n \n \n Settings\n \n \n \n \n Selected: {selected}\n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/command/demos/index.tsx" }, { "path": "registry/native-ui/src/components/command/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandRoot,\n CommandSeparator,\n CommandShortcut,\n} from \"./command\";\n\nexport const Command = Object.assign(CommandRoot, {\n Dialog: CommandDialog,\n Empty: CommandEmpty,\n Group: CommandGroup,\n Input: CommandInput,\n Item: CommandItem,\n List: CommandList,\n Root: CommandRoot,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n});\n\nexport type Command = {\n DialogProps: ComponentProps;\n EmptyProps: ComponentProps;\n GroupProps: ComponentProps;\n InputProps: ComponentProps;\n ItemProps: ComponentProps;\n ListProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SeparatorProps: ComponentProps;\n ShortcutProps: ComponentProps;\n};\n\nexport type {\n CommandDialogProps,\n CommandEmptyProps,\n CommandGroupProps,\n CommandInputProps,\n CommandItemProps,\n CommandListProps,\n CommandRootProps,\n CommandRootProps as CommandProps,\n CommandSeparatorProps,\n CommandShortcutProps,\n CommandVariants,\n} from \"./command\";\n\nexport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandRoot,\n CommandSeparator,\n CommandShortcut,\n commandVariants,\n} from \"./command\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/command/index.ts" }, { "path": "registry/native-ui/src/components/context-menu/context-menu.tsx", "content": "import { Children, forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nexport const contextMenuVariants = tv({\n slots: {\n content: \"min-w-48 gap-1 rounded-2xl border border-border bg-background p-1\",\n indicator: \"size-5 items-center justify-center\",\n item: \"min-h-10 flex-row items-center gap-3 rounded-xl px-3 py-2\",\n itemText: \"text-sm text-foreground\",\n root: \"relative\",\n separator: \"my-1 h-px w-full bg-border\",\n sub: \"gap-1\",\n submenuIndicator: \"ml-auto size-5 items-center justify-center\",\n trigger: \"self-start\",\n },\n});\n\nexport type ContextMenuVariants = VariantProps;\n\nfunction renderTextChildren(children: ReactNode, className: string) {\n return Children.map(children, (child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return {child};\n }\n return child;\n });\n}\n\nexport interface ContextMenuRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ContextMenuRoot = forwardRef(({ className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return ;\n});\n\nexport interface ContextMenuTriggerProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ContextMenuTrigger = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return ;\n },\n);\n\nexport interface ContextMenuContentProps extends Omit {\n children?: ReactNode | ((item: TValue) => ReactNode);\n className?: string;\n items?: Iterable;\n}\n\nfunction ContextMenuContentInner(\n { children, className, items: _items, ...props }: ContextMenuContentProps,\n ref: React.ForwardedRef,\n) {\n const slots = contextMenuVariants();\n return (\n \n {typeof children === \"function\" ? null : children}\n \n );\n}\n\nconst ContextMenuContent = forwardRef(ContextMenuContentInner) as (\n props: ContextMenuContentProps & { ref?: React.ForwardedRef },\n) => React.ReactElement | null;\n\nexport interface ContextMenuItemProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n isDisabled?: boolean;\n onAction?: () => void;\n onClick?: () => void;\n}\n\nconst ContextMenuItem = forwardRef(\n ({ children, className, isDisabled = false, onAction, onClick, onPress, ...props }, ref) => {\n const slots = contextMenuVariants();\n return (\n {\n onPress?.(event);\n onAction?.();\n onClick?.();\n }}\n {...props}\n >\n {renderTextChildren(children, slots.itemText())}\n \n );\n },\n);\n\nexport interface ContextMenuItemIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ContextMenuItemIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport interface ContextMenuSeparatorProps extends ViewProps {\n className?: string;\n}\n\nconst ContextMenuSeparator = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return ;\n },\n);\n\nexport interface ContextMenuSubProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ContextMenuSub = forwardRef(({ className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return ;\n});\n\nexport interface ContextMenuSubContentProps\n extends ContextMenuContentProps {}\n\nconst ContextMenuSubContent = ContextMenuContent;\n\nexport interface ContextMenuSubTriggerProps extends ContextMenuItemProps {}\n\nconst ContextMenuSubTrigger = ContextMenuItem;\n\nexport interface ContextMenuSubmenuIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst ContextMenuSubmenuIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = contextMenuVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nexport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuItemIndicator,\n ContextMenuRoot,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubmenuIndicator,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/context-menu/context-menu.tsx" }, { "path": "registry/native-ui/src/components/context-menu/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuItemIndicator,\n ContextMenuRoot,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubmenuIndicator,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from \"./context-menu\";\n\nexport const ContextMenu = Object.assign(ContextMenuRoot, {\n Content: ContextMenuContent,\n Item: ContextMenuItem,\n ItemIndicator: ContextMenuItemIndicator,\n Root: ContextMenuRoot,\n Separator: ContextMenuSeparator,\n Sub: ContextMenuSub,\n SubContent: ContextMenuSubContent,\n SubTrigger: ContextMenuSubTrigger,\n SubmenuIndicator: ContextMenuSubmenuIndicator,\n Trigger: ContextMenuTrigger,\n});\n\nexport type ContextMenu = {\n ContentProps: ComponentProps;\n ItemIndicatorProps: ComponentProps;\n ItemProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SeparatorProps: ComponentProps;\n SubContentProps: ComponentProps;\n SubProps: ComponentProps;\n SubTriggerProps: ComponentProps;\n SubmenuIndicatorProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n ContextMenuContentProps,\n ContextMenuItemIndicatorProps,\n ContextMenuItemProps,\n ContextMenuRootProps,\n ContextMenuRootProps as ContextMenuProps,\n ContextMenuSeparatorProps,\n ContextMenuSubContentProps,\n ContextMenuSubmenuIndicatorProps,\n ContextMenuSubProps,\n ContextMenuSubTriggerProps,\n ContextMenuTriggerProps,\n ContextMenuVariants,\n} from \"./context-menu\";\n\nexport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuItemIndicator,\n ContextMenuRoot,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubmenuIndicator,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n contextMenuVariants,\n} from \"./context-menu\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/context-menu/index.ts" }, { "path": "registry/native-ui/src/components/control-field/control-field.context.ts", "content": "import { createContext } from \"../../helpers/internal/utils\";\nimport type { ControlFieldContextValue } from \"./control-field\";\n\n/**\n * ControlField context provider and hook\n * Extracted to separate file to avoid circular dependencies with Checkbox/Switch animation files\n */\nconst [ControlFieldProvider, useControlField] = createContext({\n name: \"ControlFieldContext\",\n strict: false,\n});\n\nexport { ControlFieldProvider, useControlField };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/control-field/control-field.context.ts" }, { "path": "registry/native-ui/src/components/control-field/control-field.tsx", "content": "import type React from \"react\";\nimport { cloneElement, forwardRef, useCallback, useMemo } from \"react\";\nimport {\n type GestureResponderEvent,\n Pressable,\n type PressableProps,\n View,\n type ViewProps,\n} from \"react-native\";\nimport { type SharedValue, useSharedValue } from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { AnimationSettingsProvider, FormFieldProvider } from \"../../helpers/internal/contexts\";\nimport { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport type { AnimationRootDisableAll, PressableRef } from \"../../helpers/internal/types\";\nimport { combineStyles, hasProp } from \"../../helpers/internal/utils\";\nimport { Checkbox } from \"../checkbox\";\nimport { Radio } from \"../radio\";\nimport { Switch } from \"../switch\";\nimport { ControlFieldProvider, useControlField } from \"./control-field.context\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for ControlField components\n */\nexport const DISPLAY_NAME = {\n CONTROL_FIELD: \"PitsiUINative.ControlField\",\n CONTROL_FIELD_INDICATOR: \"PitsiUINative.ControlField.Indicator\",\n} as const;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Render function props for control field children\n */\nexport type ControlFieldRenderProps = Pick<\n ControlFieldProps,\n \"isSelected\" | \"isDisabled\" | \"isInvalid\"\n>;\n\n/**\n * ControlField component props\n */\nexport interface ControlFieldProps extends Omit {\n /** Content to render inside the form control, or a render function */\n children?: React.ReactNode | ((props: ControlFieldRenderProps) => React.ReactNode);\n\n /** Custom class name for the root element */\n className?: string;\n\n /** Whether the control is selected/checked @default undefined */\n isSelected?: boolean;\n\n /** Whether the form control is disabled @default false */\n isDisabled?: boolean;\n\n /** Whether the form control is invalid @default false */\n isInvalid?: boolean;\n\n /** Whether the form control is required @default false */\n isRequired?: boolean;\n\n /** Callback when selection state changes */\n onSelectedChange?: (isSelected: boolean) => void;\n\n /** Animation configuration. Use `\"disable-all\"` to disable all animations including children */\n animation?: AnimationRootDisableAll;\n}\n\n/**\n * Props for the ControlFieldIndicator component\n */\nexport interface ControlFieldIndicatorProps extends ViewProps {\n /** Control component to render (Switch, Checkbox) */\n children?: React.ReactNode;\n\n /** Custom class name for the indicator element */\n className?: string;\n\n /** Variant of the control to render when no children provided @default 'switch' */\n variant?: \"checkbox\" | \"radio\" | \"switch\";\n}\n\n/**\n * Context value for form control components\n */\nexport interface ControlFieldContextValue\n extends Pick {\n isPressed: SharedValue;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"flex-row items-center gap-3\",\n});\n\nconst indicator = tv({\n base: \"\",\n});\n\nexport const controlFieldClassNames = combineStyles({\n root,\n indicator,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Utils (animation)\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Animation hook for ControlField root component\n * Handles root-level animation configuration and provides context for child components\n */\nexport function useControlFieldRootAnimation(options: {\n animation: AnimationRootDisableAll | undefined;\n}) {\n const { animation } = options;\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n return {\n isAllAnimationsDisabled,\n };\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ControlField.Root\n * -----------------------------------------------------------------------------------------------*/\nconst ControlField = forwardRef((props, ref) => {\n const {\n children,\n className,\n isSelected,\n onSelectedChange,\n isDisabled = false,\n isInvalid = false,\n isRequired = false,\n onPressIn,\n onPressOut,\n animation,\n ...restProps\n } = props;\n\n const renderProps: ControlFieldRenderProps = useMemo(\n () => ({\n isSelected,\n isDisabled: isDisabled ?? false,\n isInvalid: isInvalid ?? false,\n }),\n [isSelected, isDisabled, isInvalid],\n );\n\n const content = typeof children === \"function\" ? children(renderProps) : children;\n\n const rootClassName = controlFieldClassNames.root({\n className,\n });\n\n const { isAllAnimationsDisabled } = useControlFieldRootAnimation({\n animation,\n });\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n const isPressed = useSharedValue(false);\n\n const handlePress = (e: GestureResponderEvent) => {\n if (!isDisabled && onSelectedChange && isSelected !== undefined) {\n onSelectedChange(!isSelected);\n\n if (props.onPress && typeof props.onPress === \"function\") {\n props.onPress(e);\n }\n }\n };\n\n const handlePressIn = useCallback(\n (e: GestureResponderEvent) => {\n isPressed.set(true);\n if (onPressIn && typeof onPressIn === \"function\") {\n onPressIn(e);\n }\n },\n [isPressed, onPressIn],\n );\n\n const handlePressOut = useCallback(\n (e: GestureResponderEvent) => {\n isPressed.set(false);\n if (onPressOut && typeof onPressOut === \"function\") {\n onPressOut(e);\n }\n },\n [isPressed, onPressOut],\n );\n\n const contextValue: ControlFieldContextValue = useMemo(\n () => ({\n isSelected,\n onSelectedChange,\n isDisabled,\n isInvalid,\n isPressed,\n }),\n [isSelected, onSelectedChange, isDisabled, isInvalid, isPressed],\n );\n\n const formFieldContextValue = useMemo(\n () => ({\n isDisabled: isDisabled ?? false,\n isInvalid: isInvalid ?? false,\n isRequired: isRequired ?? false,\n hasFieldPadding: false,\n }),\n [isDisabled, isInvalid, isRequired],\n );\n\n return (\n \n \n \n \n {content}\n \n \n \n \n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * ControlField.Indicator\n * -----------------------------------------------------------------------------------------------*/\nconst ControlFieldIndicator = forwardRef((props, ref) => {\n const { children, className, variant = \"switch\", ...restProps } = props;\n const { isSelected, onSelectedChange, isDisabled, isInvalid } = useControlField();\n\n const indicatorClassName = controlFieldClassNames.indicator({\n className,\n });\n\n const enhancedChildren = useMemo(() => {\n if (children) {\n if (typeof children !== \"object\") return children;\n\n const child = children as React.ReactElement;\n\n return cloneElement(child, {\n // Only pass props from context if child doesn't already have them\n ...(isSelected !== undefined && !hasProp(child, \"isSelected\") && { isSelected }),\n ...(onSelectedChange && !hasProp(child, \"onSelectedChange\") && { onSelectedChange }),\n ...(isDisabled !== undefined && !hasProp(child, \"isDisabled\") && { isDisabled }),\n ...(isInvalid !== undefined && !hasProp(child, \"isInvalid\") && { isInvalid }),\n });\n }\n\n // Render default component based on variant when no children provided\n if (variant === \"checkbox\") {\n return (\n \n );\n }\n\n if (variant === \"radio\") {\n return (\n \n );\n }\n\n return (\n \n );\n }, [children, variant, isSelected, onSelectedChange, isDisabled, isInvalid]);\n\n return (\n \n {enhancedChildren}\n \n );\n});\n\nControlField.displayName = DISPLAY_NAME.CONTROL_FIELD;\nControlFieldIndicator.displayName = DISPLAY_NAME.CONTROL_FIELD_INDICATOR;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component ControlField - Wrapper that provides consistent layout and interaction for form controls.\n * Handles press events to toggle selection state and manages disabled states.\n *\n * @component ControlField.Indicator - Container for the control component (Switch, Checkbox, Radio).\n * Automatically passes down isSelected, onSelectedChange, isDisabled, and isInvalid props.\n *\n * Props flow from ControlField to sub-components via context.\n * -----------------------------------------------------------------------------------------------*/\nconst CompoundControlField = Object.assign(ControlField, {\n /** @optional Container for control component */\n Indicator: ControlFieldIndicator,\n});\n\nexport { useControlField } from \"./control-field.context\";\nexport { CompoundControlField as ControlField };\nexport default CompoundControlField;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/control-field/control-field.tsx" }, { "path": "registry/native-ui/src/components/control-field/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { View } from \"react-native\";\n\nimport { ControlField, Text } from \"../..\";\n\nexport function Basic() {\n const [selected, setSelected] = useState(true);\n\n return (\n \n \n Enable sync\n \n );\n}\n\nexport function Variants() {\n const [newsletter, setNewsletter] = useState(true);\n const [plan, setPlan] = useState(false);\n const [offline, setOffline] = useState(true);\n\n return (\n \n \n \n Weekly newsletter\n \n \n \n Starter plan\n \n \n \n Offline mode\n \n \n );\n}\n\nexport function States() {\n return (\n \n \n \n Disabled selected\n \n \n \n Invalid choice\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/control-field/demos/index.tsx" }, { "path": "registry/native-ui/src/components/control-field/index.ts", "content": "export type {\n ControlFieldContextValue,\n ControlFieldIndicatorProps,\n ControlFieldProps,\n ControlFieldRenderProps,\n} from \"./control-field\";\nexport {\n ControlField,\n controlFieldClassNames,\n default,\n useControlField,\n useControlFieldRootAnimation,\n} from \"./control-field\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/control-field/index.ts" }, { "path": "registry/native-ui/src/components/date-field/date-field.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const dateFieldVariants = tv({\n base: \"gap-2\",\n});\n\nexport type DateFieldVariants = VariantProps;\n\nexport interface DateFieldRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DateFieldRoot = forwardRef(({ className, ...props }, ref) => (\n \n));\n\nDateFieldRoot.displayName = \"PitsiUINative.DateFieldRoot\";\n\nexport { DateFieldRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-field/date-field.tsx" }, { "path": "registry/native-ui/src/components/date-field/demos/index.tsx", "content": "import { Text } from \"../../../index\";\nimport { DateField } from \"../index\";\n\nexport function Basic() {\n return (\n \n Start date\n \n \n \n \n \n Use ISO dates for native parity demos.\n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-field/demos/index.tsx" }, { "path": "registry/native-ui/src/components/date-field/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DateInputGroupInput,\n DateInputGroupInputContainer,\n DateInputGroupPrefix,\n DateInputGroupRoot,\n DateInputGroupSegment,\n DateInputGroupSuffix,\n} from \"../date-input-group\";\nimport { DateFieldRoot, dateFieldVariants } from \"./date-field\";\n\nexport const DateField = Object.assign(DateFieldRoot, {\n Group: DateInputGroupRoot,\n Input: DateInputGroupInput,\n InputContainer: DateInputGroupInputContainer,\n Prefix: DateInputGroupPrefix,\n Root: DateFieldRoot,\n Segment: DateInputGroupSegment,\n Suffix: DateInputGroupSuffix,\n});\n\nexport type DateField = {\n GroupProps: ComponentProps;\n InputContainerProps: ComponentProps;\n InputProps: ComponentProps;\n PrefixProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SegmentProps: ComponentProps;\n SuffixProps: ComponentProps;\n};\n\nexport type {\n DateFieldRootProps,\n DateFieldRootProps as DateFieldProps,\n DateFieldVariants,\n} from \"./date-field\";\n\nexport { DateFieldRoot, dateFieldVariants };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-field/index.ts" }, { "path": "registry/native-ui/src/components/date-input-group/date-input-group.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { TextInput, type TextInputProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text, type TextProps } from \"../text\";\n\nexport const dateInputGroupVariants = tv({\n slots: {\n input: \"min-h-11 min-w-0 flex-1 px-2 text-base text-foreground\",\n inputContainer: \"min-w-0 flex-1 flex-row items-center\",\n prefix: \"px-3\",\n root: \"min-h-11 flex-row items-center overflow-hidden rounded-xl border border-border bg-background\",\n segment: \"text-base text-foreground\",\n suffix: \"px-3\",\n },\n});\n\nexport type DateInputGroupVariants = VariantProps;\n\nexport interface DateInputGroupRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DateInputGroupInputProps extends TextInputProps {\n className?: string;\n}\n\nexport interface DateInputGroupInputContainerProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DateInputGroupPrefixProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DateInputGroupSegmentProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DateInputGroupSuffixProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DateInputGroupRoot = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = dateInputGroupVariants();\n return ;\n },\n);\n\nconst DateInputGroupInput = forwardRef(\n ({ className, keyboardType, placeholderTextColor = \"#8a8a8a\", ...props }, ref) => {\n const slots = dateInputGroupVariants();\n return (\n \n );\n },\n);\n\nconst DateInputGroupInputContainer = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = dateInputGroupVariants();\n return ;\n },\n);\n\nconst DateInputGroupPrefix = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = dateInputGroupVariants();\n return ;\n },\n);\n\nfunction DateInputGroupSegment({ className, ...props }: DateInputGroupSegmentProps) {\n const slots = dateInputGroupVariants();\n return ;\n}\n\nconst DateInputGroupSuffix = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = dateInputGroupVariants();\n return ;\n },\n);\n\nDateInputGroupRoot.displayName = \"PitsiUINative.DateInputGroupRoot\";\nDateInputGroupInput.displayName = \"PitsiUINative.DateInputGroupInput\";\nDateInputGroupInputContainer.displayName = \"PitsiUINative.DateInputGroupInputContainer\";\nDateInputGroupPrefix.displayName = \"PitsiUINative.DateInputGroupPrefix\";\nDateInputGroupSuffix.displayName = \"PitsiUINative.DateInputGroupSuffix\";\n\nexport {\n DateInputGroupInput,\n DateInputGroupInputContainer,\n DateInputGroupPrefix,\n DateInputGroupRoot,\n DateInputGroupSegment,\n DateInputGroupSuffix,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-input-group/date-input-group.tsx" }, { "path": "registry/native-ui/src/components/date-input-group/demos/index.tsx", "content": "import { Text } from \"../../../index\";\nimport { DateInputGroup } from \"../index\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n );\n}\n\nexport function WithSlots() {\n return (\n \n \n Date\n \n \n 2026\n -\n 05\n -\n 27\n \n \n UTC\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-input-group/demos/index.tsx" }, { "path": "registry/native-ui/src/components/date-input-group/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DateInputGroupInput,\n DateInputGroupInputContainer,\n DateInputGroupPrefix,\n DateInputGroupRoot,\n DateInputGroupSegment,\n DateInputGroupSuffix,\n dateInputGroupVariants,\n} from \"./date-input-group\";\n\nexport const DateInputGroup = Object.assign(DateInputGroupRoot, {\n Input: DateInputGroupInput,\n InputContainer: DateInputGroupInputContainer,\n Prefix: DateInputGroupPrefix,\n Root: DateInputGroupRoot,\n Segment: DateInputGroupSegment,\n Suffix: DateInputGroupSuffix,\n});\n\nexport type DateInputGroup = {\n InputContainerProps: ComponentProps;\n InputProps: ComponentProps;\n PrefixProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SegmentProps: ComponentProps;\n SuffixProps: ComponentProps;\n};\n\nexport type {\n DateInputGroupInputContainerProps,\n DateInputGroupInputProps,\n DateInputGroupPrefixProps,\n DateInputGroupRootProps,\n DateInputGroupRootProps as DateInputGroupProps,\n DateInputGroupSegmentProps,\n DateInputGroupSuffixProps,\n DateInputGroupVariants,\n} from \"./date-input-group\";\n\nexport {\n DateInputGroupInput,\n DateInputGroupInputContainer,\n DateInputGroupPrefix,\n DateInputGroupRoot,\n DateInputGroupSegment,\n DateInputGroupSuffix,\n dateInputGroupVariants,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-input-group/index.ts" }, { "path": "registry/native-ui/src/components/date-picker/date-picker.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nexport const datePickerVariants = tv({\n slots: {\n indicator: \"ml-auto size-5 items-center justify-center\",\n popover: \"rounded-2xl border border-border bg-background p-3\",\n root: \"relative gap-2\",\n trigger: \"min-h-11 flex-row items-center gap-2 rounded-xl border border-border px-3 py-2\",\n },\n});\n\nexport type DatePickerVariants = VariantProps;\n\nexport interface DatePickerRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DatePickerPopoverProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface DatePickerTriggerProps extends Omit {\n children?: ReactNode;\n className?: string;\n disabled?: boolean;\n isDisabled?: boolean;\n label?: ReactNode;\n onAction?: () => void;\n onClick?: () => void;\n textValue?: string;\n title?: ReactNode;\n value?: ReactNode;\n}\n\nexport interface DatePickerTriggerIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nfunction renderTriggerContent(children: ReactNode, fallback: ReactNode) {\n const content = children ?? fallback;\n if (typeof content === \"string\" || typeof content === \"number\") {\n return {content};\n }\n\n return content;\n}\n\nconst DatePickerRoot = forwardRef(({ className, ...props }, ref) => {\n const slots = datePickerVariants();\n return ;\n});\n\nconst DatePickerPopover = forwardRef(\n ({ className, ...props }, ref) => {\n const slots = datePickerVariants();\n return ;\n },\n);\n\nconst DatePickerTrigger = forwardRef(\n (\n {\n children,\n className,\n disabled,\n isDisabled,\n label,\n onAction,\n onClick,\n onPress,\n textValue,\n title,\n value,\n ...props\n },\n ref,\n ) => {\n const slots = datePickerVariants();\n const resolvedDisabled = Boolean(disabled || isDisabled);\n return (\n onAction() : onClick ? () => onClick() : undefined)}\n {...props}\n >\n {renderTriggerContent(children, label ?? title ?? value ?? textValue)}\n \n );\n },\n);\n\nconst DatePickerTriggerIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = datePickerVariants();\n return (\n \n {children ?? }\n \n );\n },\n);\n\nDatePickerRoot.displayName = \"PitsiUINative.DatePickerRoot\";\nDatePickerPopover.displayName = \"PitsiUINative.DatePickerPopover\";\nDatePickerTrigger.displayName = \"PitsiUINative.DatePickerTrigger\";\nDatePickerTriggerIndicator.displayName = \"PitsiUINative.DatePickerTriggerIndicator\";\n\nexport { DatePickerPopover, DatePickerRoot, DatePickerTrigger, DatePickerTriggerIndicator };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-picker/date-picker.tsx" }, { "path": "registry/native-ui/src/components/date-picker/demos/index.tsx", "content": "import { Text } from \"../../../index\";\nimport { DatePicker } from \"../index\";\nimport { useState } from \"react\";\nimport { View } from \"react-native\";\n\nconst dates = [\"2026-05-27\", \"2026-05-28\", \"2026-05-29\"];\n\nexport function Basic() {\n return (\n \n \n 2026-05-27\n \n \n \n );\n}\n\nexport function WithPopover() {\n return (\n \n \n May 27, 2026\n \n \n \n \n Selected date\n Calendar composition is supplied by the app.\n \n \n \n );\n}\n\nexport function ControlledTrigger() {\n const [index, setIndex] = useState(0);\n const value = dates[index] ?? dates[0];\n\n return (\n \n setIndex((index + 1) % dates.length)}>\n {value}\n \n \n Tap the trigger to cycle demo state.\n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-picker/demos/index.tsx" }, { "path": "registry/native-ui/src/components/date-picker/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DatePickerPopover,\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerTriggerIndicator,\n datePickerVariants,\n} from \"./date-picker\";\n\nexport const DatePicker = Object.assign(DatePickerRoot, {\n Popover: DatePickerPopover,\n Root: DatePickerRoot,\n Trigger: DatePickerTrigger,\n TriggerIndicator: DatePickerTriggerIndicator,\n});\n\nexport type DatePicker = {\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerIndicatorProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n DatePickerPopoverProps,\n DatePickerRootProps,\n DatePickerRootProps as DatePickerProps,\n DatePickerTriggerIndicatorProps,\n DatePickerTriggerProps,\n DatePickerVariants,\n} from \"./date-picker\";\n\nexport {\n DatePickerPopover,\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerTriggerIndicator,\n datePickerVariants,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-picker/index.ts" }, { "path": "registry/native-ui/src/components/date-range-picker/date-range-picker.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport type { View } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport {\n DatePickerPopover,\n type DatePickerPopoverProps,\n DatePickerRoot,\n type DatePickerRootProps,\n DatePickerTrigger,\n DatePickerTriggerIndicator,\n type DatePickerTriggerIndicatorProps,\n type DatePickerTriggerProps,\n} from \"../date-picker\";\nimport { Text, type TextProps } from \"../text\";\n\nexport const dateRangePickerVariants = tv({\n slots: {\n rangeSeparator: \"px-1 text-sm text-muted\",\n },\n});\n\nexport type DateRangePickerVariants = VariantProps;\n\nexport type DateRangePickerRootProps = DatePickerRootProps;\nexport type DateRangePickerPopoverProps = DatePickerPopoverProps;\nexport type DateRangePickerTriggerProps = DatePickerTriggerProps;\nexport type DateRangePickerTriggerIndicatorProps = DatePickerTriggerIndicatorProps;\n\nexport interface DateRangePickerRangeSeparatorProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DateRangePickerRoot = forwardRef((props, ref) => (\n \n));\n\nconst DateRangePickerPopover = forwardRef((props, ref) => (\n \n));\n\nconst DateRangePickerTrigger = forwardRef((props, ref) => (\n \n));\n\nconst DateRangePickerTriggerIndicator = forwardRef(\n (props, ref) => ,\n);\n\nfunction DateRangePickerRangeSeparator({\n children,\n className,\n ...props\n}: DateRangePickerRangeSeparatorProps) {\n const slots = dateRangePickerVariants();\n return (\n \n {children ?? \"-\"}\n \n );\n}\n\nDateRangePickerRoot.displayName = \"PitsiUINative.DateRangePickerRoot\";\nDateRangePickerPopover.displayName = \"PitsiUINative.DateRangePickerPopover\";\nDateRangePickerTrigger.displayName = \"PitsiUINative.DateRangePickerTrigger\";\nDateRangePickerTriggerIndicator.displayName = \"PitsiUINative.DateRangePickerTriggerIndicator\";\n\nexport {\n DateRangePickerPopover,\n DateRangePickerRangeSeparator,\n DateRangePickerRoot,\n DateRangePickerTrigger,\n DateRangePickerTriggerIndicator,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-range-picker/date-range-picker.tsx" }, { "path": "registry/native-ui/src/components/date-range-picker/demos/index.tsx", "content": "import { Text } from \"../../../index\";\nimport { DateRangePicker } from \"../index\";\nimport { useState } from \"react\";\n\nconst ranges: [string, string][] = [\n [\"2026-05-27\", \"2026-06-02\"],\n [\"2026-06-03\", \"2026-06-09\"],\n [\"2026-06-10\", \"2026-06-16\"],\n];\nconst fallbackRange: [string, string] = [\"2026-05-27\", \"2026-06-02\"];\n\nexport function Basic() {\n return (\n \n \n 2026-05-27\n \n 2026-06-02\n \n \n \n );\n}\n\nexport function ControlledTrigger() {\n const [index, setIndex] = useState(0);\n const [start, end] = ranges[index] ?? fallbackRange;\n\n return (\n \n setIndex((index + 1) % ranges.length)}>\n {start}\n \n {end}\n \n \n Tap the trigger to cycle demo state.\n \n );\n}\n\nexport function WithPopover() {\n return (\n \n \n This week\n \n \n \n Render native range calendar content here.\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-range-picker/demos/index.tsx" }, { "path": "registry/native-ui/src/components/date-range-picker/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DateRangePickerPopover,\n DateRangePickerRangeSeparator,\n DateRangePickerRoot,\n DateRangePickerTrigger,\n DateRangePickerTriggerIndicator,\n dateRangePickerVariants,\n} from \"./date-range-picker\";\n\nexport const DateRangePicker = Object.assign(DateRangePickerRoot, {\n Popover: DateRangePickerPopover,\n RangeSeparator: DateRangePickerRangeSeparator,\n Root: DateRangePickerRoot,\n Trigger: DateRangePickerTrigger,\n TriggerIndicator: DateRangePickerTriggerIndicator,\n});\n\nexport type DateRangePicker = {\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RangeSeparatorProps: ComponentProps;\n RootProps: ComponentProps;\n TriggerIndicatorProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n DateRangePickerPopoverProps,\n DateRangePickerRangeSeparatorProps,\n DateRangePickerRootProps,\n DateRangePickerRootProps as DateRangePickerProps,\n DateRangePickerTriggerIndicatorProps,\n DateRangePickerTriggerProps,\n DateRangePickerVariants,\n} from \"./date-range-picker\";\n\nexport {\n DateRangePickerPopover,\n DateRangePickerRangeSeparator,\n DateRangePickerRoot,\n DateRangePickerTrigger,\n DateRangePickerTriggerIndicator,\n dateRangePickerVariants,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/date-range-picker/index.ts" }, { "path": "registry/native-ui/src/components/description/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Description, Input, Label } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n We'll never share your email with anyone else.\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/description/demos/index.tsx" }, { "path": "registry/native-ui/src/components/description/description.animation.ts", "content": "import { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport {\n getAnimationValueProperty,\n getIsAnimationDisabledValue,\n getRootAnimationState,\n} from \"../../helpers/internal/utils\";\nimport {\n type DescriptionAnimation,\n ENTERING_ANIMATION_CONFIG,\n EXITING_ANIMATION_CONFIG,\n} from \"./description\";\n\n// --------------------------------------------------\n\n/**\n * Animation hook for Description component\n * Handles entering and exiting animations for the description text\n */\nexport function useDescriptionAnimation(options: {\n animation: DescriptionAnimation | undefined;\n hideOnInvalid: boolean;\n}) {\n const { animation, hideOnInvalid } = options;\n\n const { animationConfig, isAnimationDisabled } = getRootAnimationState(animation);\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n const enteringValue = getAnimationValueProperty({\n animationValue: animationConfig?.entering,\n property: \"value\",\n defaultValue: ENTERING_ANIMATION_CONFIG,\n });\n\n const exitingValue = getAnimationValueProperty({\n animationValue: animationConfig?.exiting,\n property: \"value\",\n defaultValue: EXITING_ANIMATION_CONFIG,\n });\n\n return {\n entering: isAnimationDisabledValue || !hideOnInvalid ? undefined : enteringValue,\n exiting: isAnimationDisabledValue || !hideOnInvalid ? undefined : exitingValue,\n };\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/description/description.animation.ts" }, { "path": "registry/native-ui/src/components/description/description.tsx", "content": "import { forwardRef } from \"react\";\nimport type { TextProps } from \"react-native\";\nimport Animated, {\n type AnimatedProps,\n Easing,\n type EntryOrExitLayoutType,\n FadeIn,\n FadeOut,\n} from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { HeroText } from \"../../helpers/internal/components\";\nimport { useFormField } from \"../../helpers/internal/contexts\";\nimport type { AnimationRoot, AnimationValue, TextRef } from \"../../helpers/internal/types\";\nimport { combineStyles } from \"../../helpers/internal/utils\";\nimport { useDescriptionAnimation } from \"./description.animation\";\n\nconst AnimatedText = Animated.createAnimatedComponent(HeroText);\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for Description components\n */\nexport const DISPLAY_NAME = {\n DESCRIPTION: \"PitsiUINative.Description\",\n} as const;\n\n/**\n * Animation duration for description transitions\n */\nexport const ANIMATION_DURATION = 150;\n\n/**\n * Animation easing function for description transitions\n */\nexport const ANIMATION_EASING = Easing.out(Easing.ease);\n\n/**\n * Animation configuration for entering transitions\n */\nexport const ENTERING_ANIMATION_CONFIG =\n FadeIn.duration(ANIMATION_DURATION).easing(ANIMATION_EASING);\n\n/**\n * Animation configuration for exiting transitions\n */\nexport const EXITING_ANIMATION_CONFIG =\n FadeOut.duration(ANIMATION_DURATION).easing(ANIMATION_EASING);\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Animation configuration for Description component\n * Used by the Description component for animation support\n */\nexport type DescriptionAnimation = AnimationRoot<{\n entering?: AnimationValue<{\n /**\n * Custom entering animation for description\n */\n value?: EntryOrExitLayoutType;\n }>;\n exiting?: AnimationValue<{\n /**\n * Custom exiting animation for description\n */\n value?: EntryOrExitLayoutType;\n }>;\n}>;\n\n/**\n * Props for the Description component\n */\nexport interface DescriptionProps extends Omit, \"entering\" | \"exiting\"> {\n /**\n * Description text content\n */\n children?: React.ReactNode;\n /**\n * Whether the description is in an invalid state (overrides context)\n * @default undefined\n */\n isInvalid?: boolean;\n /**\n * Whether the description is disabled (overrides context)\n * @default undefined\n */\n isDisabled?: boolean;\n /**\n * Whether to hide the description when invalid\n * @default false\n */\n hideOnInvalid?: boolean;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Native ID for accessibility. Used to link description to form fields via aria-describedby.\n * When provided, form fields can reference this description using aria-describedby={nativeID}.\n */\n nativeID?: string;\n /**\n * Animation configuration for description\n * - `true` or `undefined`: Use default animations\n * - `false` or `\"disabled\"`: Disable only description animations (children can still animate)\n * - `\"disable-all\"`: Disable all animations including children (cascades down)\n * - `object`: Custom animation configuration\n */\n animation?: DescriptionAnimation;\n}\n\n/**\n * Reference type for the Description component\n */\nexport type DescriptionRef = TextRef;\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n base: \"text-sm text-muted\",\n variants: {\n isInsideField: {\n true: \"px-1.5\",\n },\n isInvalid: {\n true: \"text-danger\",\n },\n isDisabled: {\n true: \"opacity-disabled\",\n false: \"\",\n },\n },\n defaultVariants: {\n isDisabled: false,\n },\n});\n\nexport const descriptionClassNames = combineStyles({\n root,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Description\n * -----------------------------------------------------------------------------------------------*/\nconst Description = forwardRef((props, ref) => {\n const {\n children,\n className,\n nativeID,\n isInvalid: localIsInvalid,\n isDisabled: localIsDisabled,\n hideOnInvalid = false,\n animation,\n ...restProps\n } = props;\n\n const formField = useFormField();\n\n const isInvalid = localIsInvalid !== undefined ? localIsInvalid : (formField?.isInvalid ?? false);\n\n const isDisabled =\n localIsDisabled !== undefined ? localIsDisabled : (formField?.isDisabled ?? false);\n\n const isInsideField = formField?.hasFieldPadding ?? false;\n\n const rootClassName = descriptionClassNames.root({\n isInvalid,\n isDisabled,\n isInsideField,\n className,\n });\n\n const { entering, exiting } = useDescriptionAnimation({\n animation,\n hideOnInvalid,\n });\n\n if (isInvalid && hideOnInvalid) return null;\n\n return (\n \n {children}\n \n );\n});\n\nDescription.displayName = DISPLAY_NAME.DESCRIPTION;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * @component Description - Provides accessible description text with proper styling.\n * Can be linked to form fields via the nativeID prop for accessibility support.\n *\n * @see https://pitsiui.com/docs/native/components/description\n * -----------------------------------------------------------------------------------------------*/\nexport { Description };\nexport default Description;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/description/description.tsx" }, { "path": "registry/native-ui/src/components/description/index.ts", "content": "export type { DescriptionProps, DescriptionRef } from \"./description\";\nexport { Description, default, descriptionClassNames } from \"./description\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/description/index.ts" }, { "path": "registry/native-ui/src/components/dialog/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Button, Dialog } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n \n \n \n \n \n Delete workout?\n \n This removes the workout from your history. This action cannot be undone.\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}\n\nexport function NotSwipeable() {\n return (\n \n \n \n \n \n \n \n \n Settings saved\n Your preferences have been updated.\n \n \n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/dialog/demos/index.tsx" }, { "path": "registry/native-ui/src/components/dialog/dialog.tsx", "content": "/**\n * Display names for Dialog components\n */\nimport { forwardRef, type ReactNode, useLayoutEffect, useMemo, useRef } from \"react\";\nimport {\n type GestureResponderEvent,\n type Text as RNText,\n type StyleProp,\n StyleSheet,\n type TextProps,\n type View,\n type ViewStyle,\n} from \"react-native\";\nimport { GestureDetector } from \"react-native-gesture-handler\";\nimport Animated, { type SharedValue } from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { FullWindowOverlay, HeroText } from \"../../helpers/internal/components\";\nimport { AnimationSettingsProvider, useAnimationSettings } from \"../../helpers/internal/contexts\";\nimport {\n usePopupDialogContentAnimation,\n usePopupOverlayAnimation,\n usePopupRootAnimation,\n} from \"../../helpers/internal/hooks\";\nimport type {\n AnimationRootDisableAll,\n PopupDialogContentAnimation,\n PopupOverlayAnimation,\n PressableRef,\n} from \"../../helpers/internal/types\";\nimport { combineStyles, createContext } from \"../../helpers/internal/utils\";\nimport * as DialogPrimitives from \"../../primitives/dialog\";\nimport type * as DialogPrimitivesTypes from \"../../primitives/dialog/dialog.types\";\nimport { CloseButton, type CloseButtonProps } from \"../close-button\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.Dialog.Root\",\n TRIGGER: \"PitsiUINative.Dialog.Trigger\",\n PORTAL: \"PitsiUINative.Dialog.Portal\",\n OVERLAY: \"PitsiUINative.Dialog.Overlay\",\n CONTENT: \"PitsiUINative.Dialog.Content\",\n CLOSE: \"PitsiUINative.Dialog.Close\",\n TITLE: \"PitsiUINative.Dialog.Title\",\n DESCRIPTION: \"PitsiUINative.Dialog.Description\",\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Dialog internal state for animation coordination\n */\nexport type DialogState = \"idle\" | \"open\" | \"close\";\n\n/**\n * Context value for dialog animation state\n */\nexport interface DialogAnimationContextValue {\n /** Animation progress shared value (0=idle, 1=open, 2=close) */\n progress: SharedValue;\n /** Dragging state shared value */\n isDragging: SharedValue;\n /** Gesture release animation running state shared value */\n isGestureReleaseAnimationRunning: SharedValue;\n}\n\n/**\n * Dialog Root component props\n */\nexport interface DialogRootProps extends DialogPrimitivesTypes.RootProps {\n /**\n * The content of the dialog\n */\n children?: ReactNode;\n /**\n * Animation configuration for dialog root\n * - `\"disable-all\"`: Disable all animations including children\n * - `false` or `\"disabled\"`: Disable only root animations\n * - `true` or `undefined`: Use default animations\n */\n animation?: AnimationRootDisableAll;\n}\n\n/**\n * Dialog Trigger component props\n */\nexport interface DialogTriggerProps extends DialogPrimitivesTypes.TriggerProps {\n /**\n * The trigger element content\n */\n children?: ReactNode;\n}\n\n/**\n * Dialog Portal component props\n */\nexport interface DialogPortalProps extends DialogPrimitivesTypes.PortalProps {\n /**\n * When true, uses a regular View instead of FullWindowOverlay on iOS.\n * Enables React Native element inspector but overlay won't appear above native modals.\n * @default false\n */\n disableFullWindowOverlay?: boolean;\n /**\n * Controls whether VoiceOver treats the overlay window as a modal container.\n * When `false`, VoiceOver can still access elements behind the overlay.\n * When `true`, VoiceOver is restricted to elements inside the overlay.\n * @default false\n * @platform ios\n * @unstable This prop maps directly to the native `accessibilityViewIsModal`\n * on the container view and may change in a future react-native-screens release.\n */\n unstable_accessibilityContainerViewIsModal?: boolean;\n /**\n * Additional CSS class for the portal container\n */\n className?: string;\n /**\n * Additional style for the portal container\n */\n style?: StyleProp;\n /**\n * The portal content\n */\n children: ReactNode;\n}\n\n/**\n * Animation configuration for Dialog Overlay component\n */\nexport type DialogOverlayAnimation = PopupOverlayAnimation;\n\n/**\n * Dialog Overlay component props\n */\nexport interface DialogOverlayProps extends Omit {\n /**\n * Additional CSS class for the overlay\n *\n * @note The following style properties are occupied by animations and cannot be set via className:\n * - `opacity` - Animated for overlay show/hide transitions (idle: 0, open: 1, close: 0)\n *\n * To customize this property, use the `animation` prop:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.\n */\n className?: string;\n /**\n * Animation configuration for overlay\n * - `false` or `\"disabled\"`: Disable all animations\n * - `true` or `undefined`: Use default animations\n * - `object`: Custom animation configuration\n */\n animation?: DialogOverlayAnimation;\n /**\n * Whether animated styles (react-native-reanimated) are active\n * When `false`, the animated style is removed and you can implement custom logic\n * This prop should only be used when you want to write custom styling logic instead of the default animated styles\n * @default true\n */\n isAnimatedStyleActive?: boolean;\n}\n\n/**\n * Animation configuration for Dialog Content component\n * Reuses PopupDialogContentAnimation since they share the same animation behavior\n */\nexport type DialogContentAnimation = PopupDialogContentAnimation;\n\n/**\n * Dialog Content component props\n */\nexport interface DialogContentProps extends Omit {\n /**\n * Additional CSS class for the content container\n *\n * @note The following style properties are occupied by animations and cannot be set via className:\n * - `opacity` - Animated for content show/hide transitions (idle: 0, open: 1, close: 0)\n * - `transform` (specifically `scale`) - Animated for content show/hide transitions (idle: 0.97, open: 1, close: 0.97)\n *\n * To customize these properties, use the `animation` prop:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.\n */\n className?: string;\n /**\n * The dialog content\n */\n children?: ReactNode;\n /**\n * Animation configuration for content\n * - `false` or `\"disabled\"`: Disable all animations\n * - `true` or `undefined`: Use default animations\n * - `object`: Custom animation configuration\n */\n animation?: DialogContentAnimation;\n /**\n * Whether the dialog content can be swiped to dismiss\n * @default true\n */\n isSwipeable?: boolean;\n}\n\n/**\n * Dialog Close component props\n *\n * Extends CloseButtonProps, allowing full override of all close button props.\n * Automatically handles dialog close functionality when pressed.\n */\nexport type DialogCloseProps = CloseButtonProps;\n\n/**\n * Dialog Title component props\n */\nexport interface DialogTitleProps extends TextProps {\n /**\n * Additional CSS class for the title\n */\n className?: string;\n}\n\n/**\n * Dialog Description component props\n */\nexport interface DialogDescriptionProps extends TextProps {\n /**\n * Additional CSS class for the description\n */\n className?: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst portal = tv({\n base: \"absolute inset-0 justify-center p-5\",\n});\n\n/**\n * Overlay style definition\n *\n * @note ANIMATED PROPERTIES (cannot be set via className):\n * The following property is animated and cannot be overridden using Tailwind classes:\n * - `opacity` - Animated for overlay show/hide transitions (idle: 0, open: 1, close: 0)\n *\n * To customize this property, use the `animation` prop on `Dialog.Overlay`:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and apply your own via className or style prop,\n * set `isAnimatedStyleActive={false}` on `Dialog.Overlay`.\n */\nconst overlay = tv({\n base: \"absolute inset-0 bg-backdrop\",\n});\n\n/**\n * Content style definition\n *\n * @note ANIMATED PROPERTIES (cannot be set via className):\n * The following properties are animated and cannot be overridden using Tailwind classes:\n * - `opacity` - Animated for content show/hide transitions (idle: 0, open: 1, close: 0)\n * - `transform` (specifically `scale`) - Animated for content show/hide transitions (idle: 0.97, open: 1, close: 0.97)\n *\n * To customize these properties, use the `animation` prop on `Dialog.Content`:\n * ```tsx\n * \n * ```\n *\n * To completely disable animated styles and apply your own via className or style prop,\n * set `isAnimatedStyleActive={false}` on `Dialog.Content`.\n */\nconst content = tv({\n base: \"bg-overlay p-5 rounded-3xl shadow-overlay\",\n});\n\nconst label = tv({\n base: \"text-lg font-medium text-foreground\",\n});\n\nconst description = tv({\n base: \"text-base text-muted\",\n});\n\nexport const dialogClassNames = combineStyles({\n portal,\n overlay,\n content,\n label,\n description,\n});\n\nexport const dialogStyleSheet = StyleSheet.create({\n contentContainer: {\n borderCurve: \"continuous\",\n },\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Animation\n * -----------------------------------------------------------------------------------------------*/\nconst [DialogAnimationProvider, useDialogAnimation] = createContext({\n name: \"DialogAnimationContext\",\n});\n\nexport { DialogAnimationProvider, useDialogAnimation };\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\nconst AnimatedOverlay = Animated.createAnimatedComponent(DialogPrimitives.Overlay);\n\nconst useDialog = DialogPrimitives.useRootContext;\n\n// --------------------------------------------------\n\nconst DialogRoot = forwardRef(\n ({ children, isOpen, isDefaultOpen, onOpenChange, animation, ...props }, ref) => {\n const { progress, isDragging, isGestureReleaseAnimationRunning, isAllAnimationsDisabled } =\n usePopupRootAnimation({\n animation,\n });\n\n const animationContextValue = useMemo(\n () => ({\n progress,\n isDragging,\n isGestureReleaseAnimationRunning,\n }),\n [progress, isDragging, isGestureReleaseAnimationRunning],\n );\n\n const animationSettingsContextValue = useMemo(\n () => ({\n isAllAnimationsDisabled,\n }),\n [isAllAnimationsDisabled],\n );\n\n return (\n \n \n \n {children}\n \n \n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst DialogTrigger = forwardRef(\n (props, ref) => {\n return ;\n },\n);\n\n// --------------------------------------------------\n\nconst DialogPortal = ({\n className,\n children,\n style,\n disableFullWindowOverlay = false,\n unstable_accessibilityContainerViewIsModal,\n ...props\n}: DialogPortalProps) => {\n const animationSettingsContext = useAnimationSettings();\n const animationContext = useDialogAnimation();\n\n const portalClassName = dialogClassNames.portal({ className });\n\n return (\n \n \n \n \n \n {children}\n \n \n \n \n \n );\n};\n\n// --------------------------------------------------\n\nconst DialogOverlay = forwardRef(\n ({ className, style, animation, isAnimatedStyleActive = true, ...props }, ref) => {\n const { isOpen } = useDialog();\n\n const { progress, isDragging, isGestureReleaseAnimationRunning } = useDialogAnimation();\n\n const overlayClassName = dialogClassNames.overlay({ className });\n\n const { rContainerStyle, entering, exiting } = usePopupOverlayAnimation({\n progress,\n isDragging,\n isGestureReleaseAnimationRunning,\n animation,\n });\n\n if (!isOpen) {\n return null;\n }\n\n const overlayStyle = isAnimatedStyleActive ? [rContainerStyle, style] : style;\n\n return (\n \n \n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst DialogContent = forwardRef(\n ({ className, style, children, animation, isSwipeable = true, ...props }, ref) => {\n const { isOpen, onOpenChange } = useDialog();\n\n const { progress, isDragging, isGestureReleaseAnimationRunning } = useDialogAnimation();\n\n const contentClassName = dialogClassNames.content({ className });\n\n const dragContainerRef = useRef(null);\n\n const { contentY, contentHeight, panGesture, rDragContainerStyle, entering, exiting } =\n usePopupDialogContentAnimation({\n progress,\n isDragging,\n isGestureReleaseAnimationRunning,\n isOpen,\n onOpenChange,\n animation,\n isSwipeable,\n });\n\n useLayoutEffect(() => {\n dragContainerRef.current?.measure((_x, _y, _width, height, _pageX, pageY) => {\n contentY.set(pageY);\n contentHeight.set(height);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [contentY.set, contentHeight.set]);\n\n return (\n \n \n \n \n {children}\n \n \n \n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst DialogClose = forwardRef((props, ref) => {\n const { onPress: onPressProp, ...restProps } = props;\n const { onOpenChange } = useDialog();\n\n const onPress = (ev: GestureResponderEvent) => {\n onOpenChange(false);\n if (typeof onPressProp === \"function\") {\n onPressProp(ev);\n }\n };\n\n return ;\n});\n\n// --------------------------------------------------\n\nconst DialogTitle = forwardRef(\n ({ className, children, ...props }, ref) => {\n const { nativeID } = useDialog();\n const titleClassName = dialogClassNames.label({ className });\n\n return (\n \n {children}\n \n );\n },\n);\n\n// --------------------------------------------------\n\nconst DialogDescription = forwardRef(\n ({ className, children, ...props }, ref) => {\n const { nativeID } = useDialog();\n\n const descriptionClassName = dialogClassNames.description({\n className,\n });\n\n return (\n \n {children}\n \n );\n },\n);\n\n// --------------------------------------------------\n\nDialogRoot.displayName = DISPLAY_NAME.ROOT;\nDialogTrigger.displayName = DISPLAY_NAME.TRIGGER;\nDialogPortal.displayName = DISPLAY_NAME.PORTAL;\nDialogOverlay.displayName = DISPLAY_NAME.OVERLAY;\nDialogContent.displayName = DISPLAY_NAME.CONTENT;\nDialogClose.displayName = DISPLAY_NAME.CLOSE;\nDialogTitle.displayName = DISPLAY_NAME.TITLE;\nDialogDescription.displayName = DISPLAY_NAME.DESCRIPTION;\n\n/**\n * Compound Dialog component with sub-components\n *\n * @component Dialog.Root - Main container that manages open/close state.\n * Provides the dialog context to child components.\n *\n * @component Dialog.Trigger - Button or element that opens the dialog.\n * Accepts any pressable element as children.\n *\n * @component Dialog.Portal - Portal container for dialog overlay and content.\n * Renders children in a portal with centered layout.\n *\n * @component Dialog.Overlay - Background overlay that covers the screen.\n * Typically closes the dialog when clicked.\n *\n * @component Dialog.Content - The dialog content container.\n * Contains the main dialog UI elements.\n *\n * @component Dialog.Close - Close button for the dialog.\n * Can accept custom children or uses default close icon.\n *\n * @component Dialog.Title - The dialog title text.\n * Automatically linked for accessibility.\n *\n * @component Dialog.Description - The dialog description text.\n * Automatically linked for accessibility.\n *\n * @see Full documentation: https://pitsiui.com/docs/native/components/dialog\n */\nconst Dialog = Object.assign(DialogRoot, {\n /** @optional Trigger element to open the dialog */\n Trigger: DialogTrigger,\n /** @optional Portal container for overlay and content */\n Portal: DialogPortal,\n /** @optional Background overlay */\n Overlay: DialogOverlay,\n /** @optional Main dialog content container */\n Content: DialogContent,\n /** @optional Close button for the dialog */\n Close: DialogClose,\n /** @optional Dialog title text */\n Title: DialogTitle,\n /** @optional Dialog description text */\n Description: DialogDescription,\n});\n\nexport { useDialog };\nexport default Dialog;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/dialog/dialog.tsx" }, { "path": "registry/native-ui/src/components/dialog/index.ts", "content": "export type {\n DialogAnimationContextValue,\n DialogCloseProps,\n DialogContentAnimation,\n DialogContentProps,\n DialogDescriptionProps,\n DialogOverlayAnimation,\n DialogOverlayProps,\n DialogPortalProps,\n DialogRootProps,\n DialogState,\n DialogTitleProps,\n DialogTriggerProps,\n} from \"./dialog\";\nexport {\n DialogAnimationProvider,\n default as Dialog,\n dialogClassNames,\n dialogStyleSheet,\n useDialog,\n useDialogAnimation,\n} from \"./dialog\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/dialog/index.ts" }, { "path": "registry/native-ui/src/components/disclosure-group/demos/index.tsx", "content": "import { Disclosure, DisclosureGroup, Separator, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n Preview PitsiUI Native\n \n \n \n \n \n Preview native components on your device.\n \n \n \n \n \n \n \n Download App\n \n \n \n \n \n Available on iOS and Android devices.\n \n \n \n \n );\n}\n\nexport { Basic as Controlled };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure-group/demos/index.tsx" }, { "path": "registry/native-ui/src/components/disclosure-group/disclosure-group.tsx", "content": "import { createContext, forwardRef, type ReactNode, useCallback, useMemo, useState } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport type DisclosureKey = string | number;\n\nexport const disclosureGroupVariants = tv({\n base: \"w-full\",\n});\n\nexport type DisclosureGroupVariants = VariantProps;\n\nexport type DisclosureGroupContextValue = {\n expandedKeys: Set;\n setExpanded: (key: DisclosureKey, isExpanded: boolean) => void;\n};\n\nexport const DisclosureGroupContext = createContext(\n undefined,\n);\n\nexport interface DisclosureGroupRootProps\n extends Omit,\n DisclosureGroupVariants {\n allowsMultipleExpanded?: boolean;\n children?: ReactNode | ((props: { expandedKeys: Set }) => ReactNode);\n defaultExpandedKeys?: Iterable;\n expandedKeys?: Set;\n onExpandedChange?: (keys: Set) => void;\n}\n\nconst DisclosureGroupRoot = forwardRef(\n (\n {\n allowsMultipleExpanded = true,\n children,\n className,\n defaultExpandedKeys,\n expandedKeys,\n onExpandedChange,\n ...props\n },\n ref,\n ) => {\n const [internalKeys, setInternalKeys] = useState(\n () => new Set(defaultExpandedKeys),\n );\n const selectedKeys = expandedKeys ?? internalKeys;\n const rootClassName = disclosureGroupVariants({ className });\n\n const setExpanded = useCallback(\n (key: DisclosureKey, isExpanded: boolean) => {\n const nextKeys = new Set(allowsMultipleExpanded ? selectedKeys : []);\n\n if (isExpanded) {\n nextKeys.add(key);\n } else {\n nextKeys.delete(key);\n }\n\n if (!expandedKeys) {\n setInternalKeys(nextKeys);\n }\n onExpandedChange?.(nextKeys);\n },\n [allowsMultipleExpanded, selectedKeys, expandedKeys, onExpandedChange],\n );\n\n const contextValue = useMemo(\n () => ({\n expandedKeys: selectedKeys,\n setExpanded,\n }),\n [selectedKeys, setExpanded],\n );\n\n return (\n \n \n {typeof children === \"function\" ? children({ expandedKeys: selectedKeys }) : children}\n \n \n );\n },\n);\n\nDisclosureGroupRoot.displayName = \"PitsiUINative.DisclosureGroupRoot\";\n\nexport { DisclosureGroupRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure-group/disclosure-group.tsx" }, { "path": "registry/native-ui/src/components/disclosure-group/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { DisclosureGroupRoot } from \"./disclosure-group\";\n\nexport const DisclosureGroup = Object.assign(DisclosureGroupRoot, {\n Root: DisclosureGroupRoot,\n});\n\nexport type DisclosureGroup = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n DisclosureGroupContextValue,\n DisclosureGroupRootProps,\n DisclosureGroupRootProps as DisclosureGroupProps,\n DisclosureGroupVariants,\n DisclosureKey,\n} from \"./disclosure-group\";\nexport {\n DisclosureGroupContext,\n DisclosureGroupRoot,\n disclosureGroupVariants,\n} from \"./disclosure-group\";\nexport type {\n UseDisclosureGroupNavigationProps,\n UseDisclosureGroupNavigationReturn,\n} from \"./use-disclosure-group-navigation\";\nexport { useDisclosureGroupNavigation } from \"./use-disclosure-group-navigation\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure-group/index.ts" }, { "path": "registry/native-ui/src/components/disclosure-group/use-disclosure-group-navigation.ts", "content": "import { useMemo } from \"react\";\n\nimport type { DisclosureKey } from \"./disclosure-group\";\n\nexport type UseDisclosureGroupNavigationProps = {\n expandedKeys: Set;\n itemIds: DisclosureKey[];\n onExpandedChange: (keys: Set) => void;\n};\n\nexport type UseDisclosureGroupNavigationReturn = {\n isNextDisabled: boolean;\n isPrevDisabled: boolean;\n onNext: () => void;\n onPrevious: () => void;\n};\n\nexport function useDisclosureGroupNavigation({\n expandedKeys,\n itemIds,\n onExpandedChange,\n}: UseDisclosureGroupNavigationProps): UseDisclosureGroupNavigationReturn {\n return useMemo(() => {\n const currentKey = Array.from(expandedKeys).at(-1);\n const currentIndex = currentKey === undefined ? -1 : itemIds.indexOf(currentKey);\n\n const setIndex = (index: number) => {\n const nextKey = itemIds[index];\n if (nextKey !== undefined) {\n onExpandedChange(new Set([nextKey]));\n }\n };\n\n return {\n isNextDisabled: currentIndex >= itemIds.length - 1,\n isPrevDisabled: currentIndex <= 0,\n onNext: () => setIndex(Math.min(itemIds.length - 1, currentIndex + 1)),\n onPrevious: () => setIndex(Math.max(0, currentIndex - 1)),\n };\n }, [expandedKeys, itemIds, onExpandedChange]);\n}\n", "type": "registry:hook", "target": "@components/pitsi-ui/native-ui/src/components/disclosure-group/use-disclosure-group-navigation.ts" }, { "path": "registry/native-ui/src/components/disclosure/demos/index.tsx", "content": "import { useState } from \"react\";\n\nimport { Button, Disclosure, Text } from \"../..\";\n\nexport function Basic() {\n const [isExpanded, setExpanded] = useState(true);\n\n return (\n \n \n \n \n \n \n \n \n \n Scan this QR code with your camera app to preview the PitsiUI native components.\n \n \n \n \n );\n}\n\nexport { Basic as CustomRenderFunction };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure/demos/index.tsx" }, { "path": "registry/native-ui/src/components/disclosure/disclosure.tsx", "content": "import {\n createContext,\n forwardRef,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { DisclosureGroupContext, type DisclosureKey } from \"../disclosure-group\";\nimport { IconChevronDown } from \"../icons\";\nimport { Text } from \"../text\";\n\nexport const disclosureVariants = tv({\n slots: {\n root: \"relative\",\n heading: \"flex-row\",\n trigger: \"flex-row items-center gap-2\",\n content: \"overflow-hidden\",\n body: \"p-2\",\n indicator: \"ml-auto\",\n },\n});\n\nexport type DisclosureVariants = VariantProps;\n\ntype DisclosureContextValue = {\n isDisabled: boolean;\n isExpanded: boolean;\n slots: ReturnType;\n toggle: () => void;\n};\n\nconst DisclosureContext = createContext(undefined);\n\nfunction useDisclosureContext() {\n const context = useContext(DisclosureContext);\n\n if (!context) {\n throw new Error(\"Disclosure compound components must be rendered inside Disclosure.Root.\");\n }\n\n return context;\n}\n\nexport interface DisclosureRootProps\n extends Omit,\n DisclosureVariants {\n children?: ReactNode | ((props: { isExpanded: boolean; isDisabled: boolean }) => ReactNode);\n defaultExpanded?: boolean;\n id?: DisclosureKey;\n isDisabled?: boolean;\n isExpanded?: boolean;\n onExpandedChange?: (isExpanded: boolean) => void;\n}\n\nconst DisclosureRoot = forwardRef(\n (\n {\n children,\n className,\n defaultExpanded = false,\n id,\n isDisabled = false,\n isExpanded,\n onExpandedChange,\n ...props\n },\n ref,\n ) => {\n const group = useContext(DisclosureGroupContext);\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const slots = useMemo(() => disclosureVariants(), []);\n const groupExpanded = id !== undefined ? group?.expandedKeys.has(id) : undefined;\n const expanded = isExpanded ?? groupExpanded ?? internalExpanded;\n\n const setExpanded = useCallback(\n (nextExpanded: boolean) => {\n if (isExpanded === undefined && groupExpanded === undefined) {\n setInternalExpanded(nextExpanded);\n }\n if (id !== undefined && group) {\n group.setExpanded(id, nextExpanded);\n }\n onExpandedChange?.(nextExpanded);\n },\n [isExpanded, groupExpanded, id, group, onExpandedChange],\n );\n\n const contextValue = useMemo(\n () => ({\n isDisabled,\n isExpanded: expanded,\n slots,\n toggle: () => {\n if (!isDisabled) setExpanded(!expanded);\n },\n }),\n [expanded, isDisabled, slots, setExpanded],\n );\n\n const renderProps = {\n isDisabled,\n isExpanded: expanded,\n };\n\n return (\n \n \n {typeof children === \"function\" ? children(renderProps) : children}\n \n \n );\n },\n);\n\nDisclosureRoot.displayName = \"PitsiUINative.DisclosureRoot\";\n\nexport interface DisclosureHeadingProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DisclosureHeading = forwardRef(\n ({ children, className, ...props }, ref) => {\n const { slots } = useDisclosureContext();\n\n return (\n \n {children}\n \n );\n },\n);\n\nDisclosureHeading.displayName = \"PitsiUINative.DisclosureHeading\";\n\nexport interface DisclosureTriggerProps extends Omit {\n children?: ReactNode | ((props: { isExpanded: boolean; isDisabled: boolean }) => ReactNode);\n className?: string;\n isDisabled?: boolean;\n}\n\nconst DisclosureTrigger = forwardRef(\n ({ children, className, isDisabled, onPress, ...props }, ref) => {\n const disclosure = useDisclosureContext();\n const disabled = isDisabled ?? disclosure.isDisabled;\n\n return (\n {\n disclosure.toggle();\n onPress?.(event);\n }}\n {...props}\n >\n {typeof children === \"function\" ? (\n children({ isDisabled: disabled, isExpanded: disclosure.isExpanded })\n ) : typeof children === \"string\" || typeof children === \"number\" ? (\n {children}\n ) : (\n children\n )}\n \n );\n },\n);\n\nDisclosureTrigger.displayName = \"PitsiUINative.DisclosureTrigger\";\n\nexport interface DisclosureContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DisclosureContent = forwardRef(\n ({ children, className, ...props }, ref) => {\n const { isExpanded, slots } = useDisclosureContext();\n\n if (!isExpanded) return null;\n\n return (\n \n {children}\n \n );\n },\n);\n\nDisclosureContent.displayName = \"PitsiUINative.DisclosureContent\";\n\nexport interface DisclosureBodyContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DisclosureBody = forwardRef(\n ({ children, className, ...props }, ref) => {\n const { slots } = useDisclosureContext();\n\n return (\n \n {children}\n \n );\n },\n);\n\nDisclosureBody.displayName = \"PitsiUINative.DisclosureBody\";\n\nexport interface DisclosureIndicatorProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DisclosureIndicator = forwardRef(\n ({ children, className, ...props }, ref) => {\n const { isExpanded, slots } = useDisclosureContext();\n\n return (\n \n {children ?? }\n \n );\n },\n);\n\nDisclosureIndicator.displayName = \"PitsiUINative.DisclosureIndicator\";\n\nexport {\n DisclosureBody,\n DisclosureContent,\n DisclosureHeading,\n DisclosureIndicator,\n DisclosureRoot,\n DisclosureTrigger,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure/disclosure.tsx" }, { "path": "registry/native-ui/src/components/disclosure/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DisclosureBody,\n DisclosureContent,\n DisclosureHeading,\n DisclosureIndicator,\n DisclosureRoot,\n DisclosureTrigger,\n} from \"./disclosure\";\n\nexport const Disclosure = Object.assign(DisclosureRoot, {\n Body: DisclosureBody,\n Content: DisclosureContent,\n Heading: DisclosureHeading,\n Indicator: DisclosureIndicator,\n Root: DisclosureRoot,\n Trigger: DisclosureTrigger,\n});\n\nexport type Disclosure = {\n BodyProps: ComponentProps;\n ContentProps: ComponentProps;\n HeadingProps: ComponentProps;\n IndicatorProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n DisclosureBodyContentProps,\n DisclosureContentProps,\n DisclosureHeadingProps,\n DisclosureIndicatorProps,\n DisclosureRootProps,\n DisclosureRootProps as DisclosureProps,\n DisclosureTriggerProps,\n DisclosureVariants,\n} from \"./disclosure\";\nexport {\n DisclosureBody,\n DisclosureContent,\n DisclosureHeading,\n DisclosureIndicator,\n DisclosureRoot,\n DisclosureTrigger,\n disclosureVariants,\n} from \"./disclosure\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/disclosure/index.ts" }, { "path": "registry/native-ui/src/components/docs-ui/index.ts", "content": "// Docs UI — documentation site composites (sidebars, search, code blocks, MDX rendering).\nexport {};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/docs-ui/index.ts" }, { "path": "registry/native-ui/src/components/drawer/demos/index.tsx", "content": "import { Button, Drawer } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n \n \n \n \n Drawer title\n \n Drawer body content.\n \n \n \n \n \n \n \n );\n}\n\nexport { Basic as Placements };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/drawer/demos/index.tsx" }, { "path": "registry/native-ui/src/components/drawer/drawer.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport {\n SheetBackdrop,\n type SheetBackdropProps,\n SheetBody,\n type SheetBodyProps,\n SheetClose,\n type SheetCloseProps,\n SheetContent,\n type SheetContentProps,\n SheetDialog,\n type SheetDialogProps,\n SheetFooter,\n type SheetFooterProps,\n SheetHeader,\n type SheetHeaderProps,\n SheetRoot,\n type SheetRootProps,\n SheetTitle,\n type SheetTitleProps,\n SheetTrigger,\n type SheetTriggerProps,\n sheetVariants,\n} from \"../sheet\";\n\ntype DrawerPlacement = \"bottom\" | \"left\" | \"right\" | \"top\";\n\nexport const drawerVariants = tv({\n slots: {\n handle: \"items-center justify-center pb-2\",\n handleBar: \"h-1 w-9 rounded-full bg-separator\",\n },\n variants: {\n placement: {\n bottom: {},\n left: {},\n right: {},\n top: {},\n },\n variant: {\n blur: {},\n opaque: {},\n transparent: {},\n },\n },\n defaultVariants: {\n placement: \"bottom\",\n variant: \"opaque\",\n },\n});\n\nexport type DrawerVariants = VariantProps;\n\nexport type DrawerRootProps = SheetRootProps;\nexport type DrawerTriggerProps = SheetTriggerProps;\nexport type DrawerBackdropProps = SheetBackdropProps;\nexport type DrawerContentProps = Omit & {\n placement?: DrawerPlacement;\n};\nexport type DrawerDialogProps = Omit & {\n placement?: DrawerPlacement;\n};\nexport type DrawerHeaderProps = SheetHeaderProps;\nexport type DrawerHeadingProps = SheetTitleProps;\nexport type DrawerBodyProps = SheetBodyProps;\nexport type DrawerFooterProps = SheetFooterProps;\nexport type DrawerCloseTriggerProps = SheetCloseProps;\n\nexport interface DrawerHandleProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DrawerRoot = SheetRoot;\nconst DrawerTrigger = SheetTrigger;\nconst DrawerBackdrop = SheetBackdrop;\nconst DrawerHeader = SheetHeader;\nconst DrawerHeading = SheetTitle;\nconst DrawerBody = SheetBody;\nconst DrawerFooter = SheetFooter;\nconst DrawerCloseTrigger = SheetClose;\n\nconst DrawerContent = forwardRef(\n ({ placement = \"bottom\", ...props }, ref) => (\n \n ),\n);\n\nDrawerContent.displayName = \"PitsiUINative.DrawerContent\";\n\nconst DrawerDialog = forwardRef(\n ({ className, placement = \"bottom\", ...props }, ref) => {\n const slots = sheetVariants({ side: placement });\n\n return (\n \n );\n },\n);\n\nDrawerDialog.displayName = \"PitsiUINative.DrawerDialog\";\n\nconst DrawerHandle = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = drawerVariants();\n\n return (\n \n {children ?? }\n \n );\n },\n);\n\nDrawerHandle.displayName = \"PitsiUINative.DrawerHandle\";\n\nexport {\n DrawerBackdrop,\n DrawerBody,\n DrawerCloseTrigger,\n DrawerContent,\n DrawerDialog,\n DrawerFooter,\n DrawerHandle,\n DrawerHeader,\n DrawerHeading,\n DrawerRoot,\n DrawerTrigger,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/drawer/drawer.tsx" }, { "path": "registry/native-ui/src/components/drawer/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DrawerBackdrop,\n DrawerBody,\n DrawerCloseTrigger,\n DrawerContent,\n DrawerDialog,\n DrawerFooter,\n DrawerHandle,\n DrawerHeader,\n DrawerHeading,\n DrawerRoot,\n DrawerTrigger,\n} from \"./drawer\";\n\nexport const Drawer = Object.assign(DrawerRoot, {\n Backdrop: DrawerBackdrop,\n Body: DrawerBody,\n CloseTrigger: DrawerCloseTrigger,\n Content: DrawerContent,\n Dialog: DrawerDialog,\n Footer: DrawerFooter,\n Handle: DrawerHandle,\n Header: DrawerHeader,\n Heading: DrawerHeading,\n Root: DrawerRoot,\n Trigger: DrawerTrigger,\n});\n\nexport type Drawer = {\n BackdropProps: ComponentProps;\n BodyProps: ComponentProps;\n CloseTriggerProps: ComponentProps;\n ContentProps: ComponentProps;\n DialogProps: ComponentProps;\n FooterProps: ComponentProps;\n HandleProps: ComponentProps;\n HeaderProps: ComponentProps;\n HeadingProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n DrawerBackdropProps,\n DrawerBodyProps,\n DrawerCloseTriggerProps,\n DrawerContentProps,\n DrawerDialogProps,\n DrawerFooterProps,\n DrawerHandleProps,\n DrawerHeaderProps,\n DrawerHeadingProps,\n DrawerRootProps,\n DrawerRootProps as DrawerProps,\n DrawerTriggerProps,\n DrawerVariants,\n} from \"./drawer\";\nexport {\n DrawerBackdrop,\n DrawerBody,\n DrawerCloseTrigger,\n DrawerContent,\n DrawerDialog,\n DrawerFooter,\n DrawerHandle,\n DrawerHeader,\n DrawerHeading,\n DrawerRoot,\n DrawerTrigger,\n drawerVariants,\n} from \"./drawer\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/drawer/index.ts" }, { "path": "registry/native-ui/src/components/dropdown/dropdown.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport {\n ContextMenuItem as DropdownItem,\n ContextMenuItemIndicator as DropdownItemIndicator,\n type ContextMenuItemIndicatorProps as DropdownItemIndicatorProps,\n type ContextMenuItemProps as DropdownItemProps,\n ContextMenuSubmenuIndicator as DropdownSubmenuIndicator,\n type ContextMenuSubmenuIndicatorProps as DropdownSubmenuIndicatorProps,\n ContextMenuSubTrigger as DropdownSubmenuTrigger,\n type ContextMenuSubTriggerProps as DropdownSubmenuTriggerProps,\n} from \"../context-menu\";\nimport { Text } from \"../text\";\n\nexport const dropdownVariants = tv({\n slots: {\n menu: \"gap-1\",\n popover: \"min-w-48 gap-1 rounded-2xl border border-border bg-background p-1\",\n root: \"relative\",\n section: \"gap-1 py-1\",\n trigger: \"min-h-10 flex-row items-center gap-2 rounded-xl px-3 py-2\",\n triggerText: \"text-sm text-foreground\",\n },\n});\n\nexport type DropdownVariants = VariantProps;\n\nfunction renderText(children: ReactNode, className: string) {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return {children};\n }\n return children;\n}\n\nexport interface DropdownRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DropdownRoot = forwardRef(({ className, ...props }, ref) => {\n const slots = dropdownVariants();\n return ;\n});\n\nexport interface DropdownTriggerProps extends PressableProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DropdownTrigger = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = dropdownVariants();\n return (\n \n {renderText(children, slots.triggerText())}\n \n );\n },\n);\n\nexport interface DropdownPopoverProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DropdownPopover = forwardRef(({ className, ...props }, ref) => {\n const slots = dropdownVariants();\n return ;\n});\n\nexport interface DropdownMenuProps extends Omit {\n children?: ReactNode | ((item: TValue) => ReactNode);\n className?: string;\n items?: Iterable;\n}\n\nfunction DropdownMenuInner(\n { children, className, items: _items, ...props }: DropdownMenuProps,\n ref: React.ForwardedRef,\n) {\n const slots = dropdownVariants();\n return (\n \n {typeof children === \"function\" ? null : children}\n \n );\n}\n\nconst DropdownMenu = forwardRef(DropdownMenuInner) as (\n props: DropdownMenuProps & { ref?: React.ForwardedRef },\n) => React.ReactElement | null;\n\nexport interface DropdownSectionProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst DropdownSection = forwardRef(({ className, ...props }, ref) => {\n const slots = dropdownVariants();\n return ;\n});\n\nexport type {\n DropdownItemIndicatorProps,\n DropdownItemProps,\n DropdownSubmenuIndicatorProps,\n DropdownSubmenuTriggerProps,\n};\nexport {\n DropdownItem,\n DropdownItemIndicator,\n DropdownMenu,\n DropdownPopover,\n DropdownRoot,\n DropdownSection,\n DropdownSubmenuIndicator,\n DropdownSubmenuTrigger,\n DropdownTrigger,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/dropdown/dropdown.tsx" }, { "path": "registry/native-ui/src/components/dropdown/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n DropdownItem,\n DropdownItemIndicator,\n DropdownMenu,\n DropdownPopover,\n DropdownRoot,\n DropdownSection,\n DropdownSubmenuIndicator,\n DropdownSubmenuTrigger,\n DropdownTrigger,\n} from \"./dropdown\";\n\nexport const Dropdown = Object.assign(DropdownRoot, {\n Item: DropdownItem,\n ItemIndicator: DropdownItemIndicator,\n Menu: DropdownMenu,\n Popover: DropdownPopover,\n Root: DropdownRoot,\n Section: DropdownSection,\n SubmenuIndicator: DropdownSubmenuIndicator,\n SubmenuTrigger: DropdownSubmenuTrigger,\n Trigger: DropdownTrigger,\n});\n\nexport type Dropdown = {\n ItemIndicatorProps: ComponentProps;\n ItemProps: ComponentProps;\n MenuProps: ComponentProps;\n PopoverProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n SectionProps: ComponentProps;\n SubmenuIndicatorProps: ComponentProps;\n SubmenuTriggerProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n DropdownItemIndicatorProps,\n DropdownItemProps,\n DropdownMenuProps,\n DropdownPopoverProps,\n DropdownRootProps,\n DropdownRootProps as DropdownProps,\n DropdownSectionProps,\n DropdownSubmenuIndicatorProps,\n DropdownSubmenuTriggerProps,\n DropdownTriggerProps,\n DropdownVariants,\n} from \"./dropdown\";\n\nexport {\n DropdownItem,\n DropdownItemIndicator,\n DropdownMenu,\n DropdownPopover,\n DropdownRoot,\n DropdownSection,\n DropdownSubmenuIndicator,\n DropdownSubmenuTrigger,\n DropdownTrigger,\n dropdownVariants,\n} from \"./dropdown\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/dropdown/index.ts" }, { "path": "registry/native-ui/src/components/empty-state/demos/index.tsx", "content": "import { Button, EmptyState, Text } from \"../..\";\n\nexport function Default() {\n return (\n \n \n \n 0\n \n Your inbox is empty\n \n Once you start receiving messages, they will appear here.\n \n \n \n \n \n \n );\n}\n\nexport { Default as Basic };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/empty-state/demos/index.tsx" }, { "path": "registry/native-ui/src/components/empty-state/empty-state.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text, type TextProps } from \"../text\";\n\nexport const emptyStateVariants = tv({\n slots: {\n root: \"min-w-0 flex-1 items-center justify-center gap-6 rounded-2xl border border-dashed border-border p-6\",\n header: \"max-w-sm items-center gap-2 text-center\",\n media: \"mb-2 shrink-0 items-center justify-center\",\n title: \"text-center text-base font-medium text-foreground\",\n description: \"text-center text-sm leading-relaxed text-muted\",\n content: \"w-full max-w-sm min-w-0 items-center gap-2\",\n },\n variants: {\n media: {\n default: {},\n icon: {\n media: \"size-10 rounded-xl bg-default\",\n },\n },\n },\n defaultVariants: {\n media: \"default\",\n },\n});\n\nexport type EmptyStateVariants = VariantProps;\n\nexport interface EmptyStateRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst EmptyStateRoot = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = emptyStateVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateRoot.displayName = \"PitsiUINative.EmptyStateRoot\";\n\nexport interface EmptyStateHeaderProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst EmptyStateHeader = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = emptyStateVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateHeader.displayName = \"PitsiUINative.EmptyStateHeader\";\n\nexport interface EmptyStateMediaProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n variant?: EmptyStateVariants[\"media\"];\n}\n\nconst EmptyStateMedia = forwardRef(\n ({ children, className, variant = \"default\", ...props }, ref) => {\n const slots = emptyStateVariants({ media: variant });\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateMedia.displayName = \"PitsiUINative.EmptyStateMedia\";\n\nexport interface EmptyStateTitleProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst EmptyStateTitle = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = emptyStateVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateTitle.displayName = \"PitsiUINative.EmptyStateTitle\";\n\nexport interface EmptyStateDescriptionProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst EmptyStateDescription = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = emptyStateVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateDescription.displayName = \"PitsiUINative.EmptyStateDescription\";\n\nexport interface EmptyStateContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst EmptyStateContent = forwardRef(\n ({ children, className, ...props }, ref) => {\n const slots = emptyStateVariants();\n\n return (\n \n {children}\n \n );\n },\n);\n\nEmptyStateContent.displayName = \"PitsiUINative.EmptyStateContent\";\n\nexport {\n EmptyStateContent,\n EmptyStateDescription,\n EmptyStateHeader,\n EmptyStateMedia,\n EmptyStateRoot,\n EmptyStateTitle,\n};\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/empty-state/empty-state.tsx" }, { "path": "registry/native-ui/src/components/empty-state/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n EmptyStateContent,\n EmptyStateDescription,\n EmptyStateHeader,\n EmptyStateMedia,\n EmptyStateRoot,\n EmptyStateTitle,\n} from \"./empty-state\";\n\nexport const EmptyState = Object.assign(EmptyStateRoot, {\n Content: EmptyStateContent,\n Description: EmptyStateDescription,\n Header: EmptyStateHeader,\n Media: EmptyStateMedia,\n Root: EmptyStateRoot,\n Title: EmptyStateTitle,\n});\n\nexport type EmptyState = {\n ContentProps: ComponentProps;\n DescriptionProps: ComponentProps;\n HeaderProps: ComponentProps;\n MediaProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TitleProps: ComponentProps;\n};\n\nexport type {\n EmptyStateContentProps,\n EmptyStateDescriptionProps,\n EmptyStateHeaderProps,\n EmptyStateMediaProps,\n EmptyStateRootProps,\n EmptyStateRootProps as EmptyStateProps,\n EmptyStateTitleProps,\n EmptyStateVariants,\n} from \"./empty-state\";\nexport {\n EmptyStateContent,\n EmptyStateDescription,\n EmptyStateHeader,\n EmptyStateMedia,\n EmptyStateRoot,\n EmptyStateTitle,\n emptyStateVariants,\n} from \"./empty-state\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/empty-state/index.ts" }, { "path": "registry/native-ui/src/components/error-message/demos/index.tsx", "content": "import { useMemo, useState } from \"react\";\nimport { View } from \"react-native\";\nimport type { Key } from \"../..\";\nimport { Description, ErrorMessage, Label, Tag, TagGroup } from \"../..\";\n\nconst categories = [\n { id: \"news\", label: \"News\" },\n { id: \"travel\", label: \"Travel\" },\n { id: \"gaming\", label: \"Gaming\" },\n { id: \"shopping\", label: \"Shopping\" },\n];\n\nfunction RequiredCategories() {\n const [selected, setSelected] = useState<\"all\" | Set>(new Set());\n const isInvalid = useMemo(\n () => selected !== \"all\" && Array.from(selected).length === 0,\n [selected],\n );\n\n return (\n \n \n \n {categories.map((category) => (\n \n {category.label}\n \n ))}\n \n Select at least one category\n \n {isInvalid ? Please select at least one category : null}\n \n \n );\n}\n\nexport function Basic() {\n return ;\n}\n\nexport function WithTagGroup() {\n return ;\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/error-message/demos/index.tsx" }, { "path": "registry/native-ui/src/components/error-message/error-message.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport type { Text as NativeText, TextProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nexport const errorMessageVariants = tv({\n base: \"text-xs text-danger\",\n});\n\nexport type ErrorMessageVariants = VariantProps;\n\nexport interface ErrorMessageRootProps extends TextProps, ErrorMessageVariants {\n children?: ReactNode;\n className?: string;\n}\n\nconst ErrorMessageRoot = forwardRef(\n ({ children, className, ...props }, ref) => {\n if (!children) return null;\n\n return (\n \n {children}\n \n );\n },\n);\n\nErrorMessageRoot.displayName = \"PitsiUINative.ErrorMessage\";\n\nexport { ErrorMessageRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/error-message/error-message.tsx" }, { "path": "registry/native-ui/src/components/error-message/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { ErrorMessageRoot } from \"./error-message\";\n\nexport const ErrorMessage = Object.assign(ErrorMessageRoot, {\n Root: ErrorMessageRoot,\n});\n\nexport type ErrorMessage = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n ErrorMessageRootProps,\n ErrorMessageRootProps as ErrorMessageProps,\n ErrorMessageVariants,\n} from \"./error-message\";\nexport { ErrorMessageRoot, errorMessageVariants } from \"./error-message\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/error-message/index.ts" }, { "path": "registry/native-ui/src/components/field-error/demos/index.tsx", "content": "import { useState } from \"react\";\n\nimport { FieldError, Input, Label, TextField } from \"../..\";\n\nexport function Basic() {\n const [value, setValue] = useState(\"jr\");\n const isInvalid = value.length > 0 && value.length < 3;\n\n return (\n \n \n \n Username must be at least 3 characters\n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field-error/demos/index.tsx" }, { "path": "registry/native-ui/src/components/field-error/field-error.tsx", "content": "import { forwardRef } from \"react\";\nimport type { TextProps, TextStyle, ViewProps, ViewStyle } from \"react-native\";\nimport Animated, {\n type AnimatedProps,\n Easing,\n type EntryOrExitLayoutType,\n FadeIn,\n FadeOut,\n} from \"react-native-reanimated\";\nimport { tv } from \"tailwind-variants\";\nimport { HeroText } from \"../../helpers/internal/components\";\nimport { useFormField } from \"../../helpers/internal/contexts\";\nimport { useCombinedAnimationDisabledState } from \"../../helpers/internal/hooks\";\nimport type {\n AnimationRoot,\n AnimationValue,\n ElementSlots,\n ViewRef,\n} from \"../../helpers/internal/types\";\nimport {\n childrenToString,\n combineStyles,\n getAnimationValueProperty,\n getIsAnimationDisabledValue,\n getRootAnimationState,\n} from \"../../helpers/internal/utils\";\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Display names for the FieldError component parts\n */\nexport const DISPLAY_NAME = {\n ROOT: \"PitsiUINative.FieldError\",\n};\n\n/**\n * Animation duration for focus/blur transitions\n */\nexport const ANIMATION_DURATION = 150;\n\n/**\n * Animation easing function for focus/blur transitions\n */\nexport const ANIMATION_EASING = Easing.out(Easing.ease);\n\n/**\n * Default entering animation configuration\n */\nexport const ENTERING_ANIMATION_CONFIG =\n FadeIn.duration(ANIMATION_DURATION).easing(ANIMATION_EASING);\n\n/**\n * Default exiting animation configuration\n */\nexport const EXITING_ANIMATION_CONFIG = FadeOut.duration(ANIMATION_DURATION / 1.5).easing(\n ANIMATION_EASING,\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nconst root = tv({\n slots: {\n container: \"\",\n text: \"text-sm text-danger\",\n },\n variants: {\n isInsideField: {\n true: {\n container: \"px-1.5\",\n text: \"\",\n },\n },\n },\n});\n\nexport const fieldErrorClassNames = combineStyles({\n root,\n});\n\nexport type FieldErrorSlots = keyof ReturnType;\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Animation configuration for FieldError root component\n */\nexport type FieldErrorRootAnimation = AnimationRoot<{\n entering?: AnimationValue<{\n /**\n * Custom entering animation for field error\n */\n value?: EntryOrExitLayoutType;\n }>;\n exiting?: AnimationValue<{\n /**\n * Custom exiting animation for field error\n */\n value?: EntryOrExitLayoutType;\n }>;\n}>;\n\n/**\n * Props for the FieldError root component\n */\nexport interface FieldErrorRootProps\n extends Omit, \"entering\" | \"exiting\"> {\n /**\n * The content of the error field\n * When passed as string, it will be wrapped with Text component\n */\n children?: React.ReactNode;\n\n /**\n * Controls the visibility of the error field (overrides context)\n * When false, the field error is hidden\n * @default undefined - uses form-item-state context value\n */\n isInvalid?: boolean;\n\n /**\n * Additional CSS class for styling\n */\n className?: string;\n\n /**\n * Additional CSS classes for different parts of the component\n */\n classNames?: ElementSlots;\n\n /**\n * Styles for different parts of the field error\n */\n styles?: {\n container?: ViewStyle;\n text?: TextStyle;\n };\n\n /**\n * Additional props to pass to the Text component when children is a string\n */\n textProps?: TextProps;\n\n /**\n * Animation configuration for field error\n * - `false` or `\"disabled\"`: Disable all animations\n * - `true` or `undefined`: Use default animations\n * - `object`: Custom animation configuration\n */\n animation?: FieldErrorRootAnimation;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Utils (animation)\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Animation hook for FieldError root component\n * Handles entering and exiting animations for error messages\n */\nexport function useFieldErrorRootAnimation(options: {\n animation: FieldErrorRootAnimation | undefined;\n}) {\n const { animation } = options;\n\n const { animationConfig, isAnimationDisabled } = getRootAnimationState(animation);\n\n const isAllAnimationsDisabled = useCombinedAnimationDisabledState(animation);\n\n const isAnimationDisabledValue = getIsAnimationDisabledValue({\n isAnimationDisabled,\n isAllAnimationsDisabled,\n });\n\n const enteringValue = getAnimationValueProperty({\n animationValue: animationConfig?.entering,\n property: \"value\",\n defaultValue: ENTERING_ANIMATION_CONFIG,\n });\n\n const exitingValue = getAnimationValueProperty({\n animationValue: animationConfig?.exiting,\n property: \"value\",\n defaultValue: EXITING_ANIMATION_CONFIG,\n });\n\n return {\n entering: isAnimationDisabledValue ? undefined : enteringValue,\n exiting: isAnimationDisabledValue ? undefined : exitingValue,\n };\n}\n\n/* -------------------------------------------------------------------------------------------------\n * FieldError.Root\n * -----------------------------------------------------------------------------------------------*/\nconst FieldErrorRoot = forwardRef((props, ref) => {\n const {\n children,\n className,\n classNames,\n style,\n styles,\n textProps,\n isInvalid: localIsInvalid,\n animation,\n ...restProps\n } = props;\n\n const formField = useFormField();\n\n // Merge form field state with local props (local takes precedence)\n const isInvalid = localIsInvalid !== undefined ? localIsInvalid : (formField?.isInvalid ?? false);\n\n const isInsideField = formField?.hasFieldPadding ?? false;\n\n const { container, text } = fieldErrorClassNames.root({\n isInsideField,\n });\n\n const containerClassName = container({\n className: [className, classNames?.container],\n });\n\n const textClassName = text({\n className: [classNames?.text, textProps?.className],\n });\n\n const { entering, exiting } = useFieldErrorRootAnimation({ animation });\n\n if (!isInvalid) return null;\n\n const stringifiedChildren = childrenToString(children);\n const renderedChildren = stringifiedChildren ? (\n \n {stringifiedChildren}\n \n ) : (\n children\n );\n\n return (\n \n {renderedChildren}\n \n );\n});\n\nFieldErrorRoot.displayName = DISPLAY_NAME.ROOT;\n\n/* -------------------------------------------------------------------------------------------------\n * Compound export\n *\n * FieldError component for displaying validation errors\n *\n * @component FieldError - Error message container with entering/exiting animations.\n * Automatically wraps string children with Text component.\n * Hidden when isInvalid is false.\n * -----------------------------------------------------------------------------------------------*/\nconst FieldError = FieldErrorRoot;\n\nexport { FieldError };\nexport default FieldError;\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field-error/field-error.tsx" }, { "path": "registry/native-ui/src/components/field-error/index.ts", "content": "export type {\n FieldErrorRootAnimation,\n FieldErrorRootProps,\n FieldErrorSlots,\n} from \"./field-error\";\nexport {\n ANIMATION_DURATION,\n ANIMATION_EASING,\n default,\n ENTERING_ANIMATION_CONFIG,\n EXITING_ANIMATION_CONFIG,\n FieldError,\n fieldErrorClassNames,\n useFieldErrorRootAnimation,\n} from \"./field-error\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field-error/index.ts" }, { "path": "registry/native-ui/src/components/field/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Field, Input } from \"../..\";\n\nexport function Default() {\n return (\n \n Email\n \n \n \n We will never share your email.\n \n );\n}\n\nexport function Invalid() {\n return (\n \n \n Email\n \n \n \n Please enter a valid email address.\n \n \n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field/demos/index.tsx" }, { "path": "registry/native-ui/src/components/field/field.tsx", "content": "import { createContext, forwardRef, type ReactNode, useContext, useMemo } from \"react\";\nimport { type Text as NativeText, type TextProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { Text } from \"../text\";\n\nconst fieldVariants = tv({\n defaultVariants: {\n disabled: false,\n invalid: false,\n required: false,\n },\n slots: {\n base: \"flex-col gap-1.5\",\n control: \"flex-col gap-1.5\",\n description: \"text-xs text-muted\",\n error: \"text-xs text-danger\",\n label: \"text-sm font-medium text-foreground\",\n },\n variants: {\n disabled: {\n false: {},\n true: {\n base: \"opacity-disabled\",\n },\n },\n invalid: {\n false: {},\n true: {\n label: \"text-danger\",\n },\n },\n required: {\n false: {},\n true: {},\n },\n },\n});\n\nexport type FieldVariants = VariantProps;\n\ninterface FieldContextValue {\n disabled: boolean;\n invalid: boolean;\n required: boolean;\n slots: ReturnType;\n}\n\nconst FieldContext = createContext(null);\n\nexport function useFieldContext() {\n return useContext(FieldContext);\n}\n\nexport interface FieldRootProps extends ViewProps {\n children: ReactNode;\n className?: string;\n disabled?: boolean;\n invalid?: boolean;\n required?: boolean;\n}\n\nconst FieldRoot = forwardRef(\n ({ children, className, disabled = false, invalid = false, required = false, ...props }, ref) => {\n const slots = useMemo(\n () => fieldVariants({ disabled, invalid, required }),\n [disabled, invalid, required],\n );\n const context = useMemo(\n () => ({ disabled, invalid, required, slots }),\n [disabled, invalid, required, slots],\n );\n\n return (\n \n \n {children}\n \n \n );\n },\n);\n\nFieldRoot.displayName = \"PitsiUINative.Field\";\n\nexport interface FieldLabelProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst FieldLabel = forwardRef(\n ({ children, className, ...props }, ref) => {\n const context = useFieldContext();\n\n return (\n \n {children}\n {context?.required ? * : null}\n \n );\n },\n);\n\nFieldLabel.displayName = \"PitsiUINative.Field.Label\";\n\nexport interface FieldControlProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst FieldControl = forwardRef(\n ({ children, className, ...props }, ref) => {\n const context = useFieldContext();\n\n return (\n \n {children}\n \n );\n },\n);\n\nFieldControl.displayName = \"PitsiUINative.Field.Control\";\n\nexport interface FieldDescriptionProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst FieldDescription = forwardRef(\n ({ children, className, ...props }, ref) => {\n const context = useFieldContext();\n\n return (\n \n {children}\n \n );\n },\n);\n\nFieldDescription.displayName = \"PitsiUINative.Field.Description\";\n\nexport interface FieldErrorProps extends TextProps {\n children?: ReactNode;\n className?: string;\n}\n\nconst FieldError = forwardRef(\n ({ children, className, ...props }, ref) => {\n const context = useFieldContext();\n\n if (!context?.invalid && !children) return null;\n\n return (\n \n {children}\n \n );\n },\n);\n\nFieldError.displayName = \"PitsiUINative.Field.Error\";\n\nexport { FieldControl, FieldDescription, FieldError, FieldLabel, FieldRoot, fieldVariants };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field/field.tsx" }, { "path": "registry/native-ui/src/components/field/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport {\n FieldControl,\n FieldDescription,\n FieldError as FieldInlineError,\n FieldLabel,\n FieldRoot,\n} from \"./field\";\n\nexport const Field = Object.assign(FieldRoot, {\n Control: FieldControl,\n Description: FieldDescription,\n Error: FieldInlineError,\n Label: FieldLabel,\n Root: FieldRoot,\n});\n\nexport type Field = {\n ControlProps: ComponentProps;\n DescriptionProps: ComponentProps;\n ErrorProps: ComponentProps;\n LabelProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type {\n FieldControlProps,\n FieldDescriptionProps,\n FieldErrorProps as FieldInlineErrorProps,\n FieldLabelProps,\n FieldRootProps,\n FieldRootProps as FieldProps,\n FieldVariants,\n} from \"./field\";\nexport {\n FieldControl,\n FieldDescription,\n FieldError as FieldInlineError,\n FieldLabel,\n FieldRoot,\n fieldVariants,\n useFieldContext,\n} from \"./field\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/field/index.ts" }, { "path": "registry/native-ui/src/components/form/demos/index.tsx", "content": "import { View } from \"react-native\";\n\nimport { Button, Field, Form, Input } from \"../..\";\n\nexport function Basic() {\n return (\n
\n \n Email\n \n \n \n Password\n \n \n \n \n \n \n
\n );\n}\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/form/demos/index.tsx" }, { "path": "registry/native-ui/src/components/form/form.tsx", "content": "import { forwardRef, type ReactNode } from \"react\";\nimport { View, type ViewProps } from \"react-native\";\n\nexport interface FormRootProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n onReset?: () => void;\n onSubmit?: () => void;\n}\n\nconst FormRoot = forwardRef(\n ({ children, className, onReset: _onReset, onSubmit: _onSubmit, ...props }, ref) => {\n return (\n \n {children}\n \n );\n },\n);\n\nFormRoot.displayName = \"PitsiUINative.Form\";\n\nexport { FormRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/form/form.tsx" }, { "path": "registry/native-ui/src/components/form/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { FormRoot } from \"./form\";\n\nexport const Form = Object.assign(FormRoot, {\n Root: FormRoot,\n});\n\nexport type Form = {\n Props: ComponentProps;\n RootProps: ComponentProps;\n};\n\nexport type { FormRootProps, FormRootProps as FormProps } from \"./form\";\nexport { FormRoot };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/form/index.ts" }, { "path": "registry/native-ui/src/components/hover-card/demos/index.tsx", "content": "import { Button, HoverCard, Text } from \"../..\";\n\nexport function Basic() {\n return (\n \n \n \n \n \n Pitsi UI\n Native primitives and app templates.\n \n \n );\n}\n\nexport { Basic as Controlled, Basic as Delays, Basic as Placements };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/hover-card/demos/index.tsx" }, { "path": "registry/native-ui/src/components/hover-card/hover-card.tsx", "content": "import { createContext, forwardRef, type ReactNode, useContext, useMemo, useState } from \"react\";\nimport { Pressable, type PressableProps, View, type ViewProps } from \"react-native\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const hoverCardVariants = tv({\n slots: {\n content: \"min-w-56 gap-2 rounded-2xl border border-border bg-background p-4 shadow-sm\",\n root: \"relative gap-2\",\n trigger: \"self-start\",\n },\n});\n\nexport type HoverCardVariants = VariantProps;\n\ntype HoverCardContextValue = {\n open: boolean;\n setOpen: (open: boolean) => void;\n slots: ReturnType;\n};\n\nconst HoverCardContext = createContext(undefined);\n\nfunction useHoverCardContext() {\n const context = useContext(HoverCardContext);\n\n if (!context) {\n throw new Error(\"HoverCard compound components must be rendered inside HoverCard.Root.\");\n }\n\n return context;\n}\n\nexport interface HoverCardRootProps extends Omit {\n children?: ReactNode;\n className?: string;\n closeDelay?: number;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n open?: boolean;\n openDelay?: number;\n}\n\nconst HoverCardRoot = forwardRef(\n (\n {\n children,\n className,\n closeDelay: _closeDelay,\n defaultOpen = false,\n onOpenChange,\n open,\n openDelay: _openDelay,\n ...props\n },\n ref,\n ) => {\n const slots = useMemo(() => hoverCardVariants(), []);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const currentOpen = open ?? internalOpen;\n\n const setOpen = (nextOpen: boolean) => {\n if (open === undefined) {\n setInternalOpen(nextOpen);\n }\n onOpenChange?.(nextOpen);\n };\n\n return (\n \n \n {children}\n \n \n );\n },\n);\n\nHoverCardRoot.displayName = \"PitsiUINative.HoverCardRoot\";\n\nexport interface HoverCardTriggerProps extends Omit {\n children?: ReactNode;\n className?: string;\n}\n\nconst HoverCardTrigger = forwardRef(\n ({ children, className, onBlur, onFocus, onPress, ...props }, ref) => {\n const { open, setOpen, slots } = useHoverCardContext();\n\n return (\n {\n onBlur?.(event);\n setOpen(false);\n }}\n onFocus={(event) => {\n onFocus?.(event);\n setOpen(true);\n }}\n onPress={(event) => {\n onPress?.(event);\n setOpen(!open);\n }}\n {...props}\n >\n {children}\n \n );\n },\n);\n\nHoverCardTrigger.displayName = \"PitsiUINative.HoverCardTrigger\";\n\nexport interface HoverCardContentProps extends ViewProps {\n children?: ReactNode;\n className?: string;\n offset?: number;\n placement?: \"bottom\" | \"left\" | \"right\" | \"top\";\n}\n\nconst HoverCardContent = forwardRef(\n ({ children, className, offset: _offset, placement: _placement, ...props }, ref) => {\n const { open, slots } = useHoverCardContext();\n\n if (!open) {\n return null;\n }\n\n return (\n \n {children}\n \n );\n },\n);\n\nHoverCardContent.displayName = \"PitsiUINative.HoverCardContent\";\n\nexport { HoverCardContent, HoverCardRoot, HoverCardTrigger };\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/hover-card/hover-card.tsx" }, { "path": "registry/native-ui/src/components/hover-card/index.ts", "content": "import type { ComponentProps } from \"react\";\n\nimport { HoverCardContent, HoverCardRoot, HoverCardTrigger } from \"./hover-card\";\n\nexport const HoverCard = Object.assign(HoverCardRoot, {\n Content: HoverCardContent,\n Root: HoverCardRoot,\n Trigger: HoverCardTrigger,\n});\n\nexport type HoverCard = {\n ContentProps: ComponentProps;\n Props: ComponentProps;\n RootProps: ComponentProps;\n TriggerProps: ComponentProps;\n};\n\nexport type {\n HoverCardContentProps,\n HoverCardRootProps,\n HoverCardRootProps as HoverCardProps,\n HoverCardTriggerProps,\n HoverCardVariants,\n} from \"./hover-card\";\n\nexport { HoverCardContent, HoverCardRoot, HoverCardTrigger, hoverCardVariants } from \"./hover-card\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/hover-card/index.ts" }, { "path": "registry/native-ui/src/components/icons.tsx", "content": "import { forwardRef } from \"react\";\nimport { Text as NativeText, type TextProps, type TextStyle } from \"react-native\";\n\nexport interface IconProps extends TextProps {\n color?: string;\n height?: number;\n size?: number;\n width?: number;\n}\n\nfunction createTextIcon(displayName: string, glyph: string) {\n const Icon = forwardRef(\n ({ color, height, size, style, width, ...props }, ref) => {\n const resolvedSize = size ?? height ?? width ?? 16;\n const iconStyle: TextStyle = {\n color: color ?? \"currentColor\",\n fontSize: resolvedSize,\n lineHeight: resolvedSize,\n textAlign: \"center\",\n };\n\n return (\n \n {glyph}\n \n );\n },\n );\n\n Icon.displayName = `PitsiUINative.${displayName}`;\n\n return Icon;\n}\n\nexport const IconChevronDown = createTextIcon(\"IconChevronDown\", \"v\");\nexport const IconChevronLeft = createTextIcon(\"IconChevronLeft\", \"<\");\nexport const IconChevronRight = createTextIcon(\"IconChevronRight\", \">\");\nexport const ExternalLinkIcon = createTextIcon(\"ExternalLinkIcon\", \"^\");\nexport const CircleDashedIcon = createTextIcon(\"CircleDashedIcon\", \"o\");\nexport const CloseIcon = createTextIcon(\"CloseIcon\", \"x\");\nexport const InfoIcon = createTextIcon(\"InfoIcon\", \"i\");\nexport const WarningIcon = createTextIcon(\"WarningIcon\", \"!\");\nexport const DangerIcon = createTextIcon(\"DangerIcon\", \"!\");\nexport const SuccessIcon = createTextIcon(\"SuccessIcon\", \"ok\");\nexport const IconMinus = createTextIcon(\"IconMinus\", \"-\");\nexport const IconPlus = createTextIcon(\"IconPlus\", \"+\");\nexport const IconSearch = createTextIcon(\"IconSearch\", \"?\");\nexport const IconCalendar = createTextIcon(\"IconCalendar\", \"#\");\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/icons.tsx" }, { "path": "registry/native-ui/src/components/index.ts", "content": "// Components barrel including hand-built native components and web parity fallbacks.\nexport * from \"./accordion\";\nexport * from \"./alert\";\nexport * from \"./alert-dialog\";\nexport * from \"./aspect-ratio\";\nexport * from \"./autocomplete\";\nexport * from \"./avatar\";\nexport * from \"./badge\";\nexport * from \"./bottom-sheet\";\nexport * from \"./breadcrumbs\";\nexport * from \"./button\";\nexport * from \"./button-group\";\nexport * from \"./card\";\nexport * from \"./chart\";\nexport * from \"./checkbox\";\nexport * from \"./checkbox-group\";\nexport * from \"./chip\";\nexport * from \"./close-button\";\nexport * from \"./color-area\";\nexport * from \"./color-field\";\nexport * from \"./color-input-group\";\nexport * from \"./color-picker\";\nexport * from \"./color-slider\";\nexport * from \"./color-swatch\";\nexport * from \"./color-swatch-picker\";\nexport * from \"./combo-box\";\nexport * from \"./command\";\nexport * from \"./context-menu\";\nexport * from \"./control-field\";\nexport * from \"./description\";\nexport * from \"./dialog\";\nexport * from \"./disclosure\";\nexport * from \"./disclosure-group\";\nexport * from \"./docs-ui\";\nexport * from \"./drawer\";\nexport * from \"./dropdown\";\nexport * from \"./empty-state\";\nexport * from \"./error-message\";\nexport * from \"./field\";\nexport * from \"./field-error\";\nexport * from \"./form\";\nexport * from \"./hover-card\";\nexport * from \"./icons\";\nexport * from \"./input\";\nexport * from \"./input-group\";\nexport * from \"./input-otp\";\nexport * from \"./kbd\";\nexport * from \"./label\";\nexport * from \"./link\";\nexport * from \"./link-button\";\nexport * from \"./list-box\";\nexport * from \"./list-box-item\";\nexport * from \"./list-box-section\";\nexport * from \"./list-group\";\nexport * from \"./menu\";\nexport type {\n MenuItemRootProps,\n MenuItemSubmenuIndicatorProps,\n MenuItemVariants,\n} from \"./menu-item\";\nexport {\n MenuItem,\n MenuItemIndicator,\n MenuItemRoot,\n MenuItemSubmenuIndicator,\n menuItemVariants,\n} from \"./menu-item\";\nexport type {\n MenuSectionRootProps,\n MenuSectionRootProps as MenuSectionProps,\n MenuSectionVariants,\n} from \"./menu-section\";\nexport { MenuSection, MenuSectionRoot, menuSectionVariants } from \"./menu-section\";\nexport * from \"./meter\";\nexport * from \"./modal\";\nexport type {\n AccordionBodyProps,\n AccordionHeadingProps,\n AccordionPanelProps,\n AccordionProps,\n AccordionVariants,\n AlertProps,\n AlertVariants,\n AvatarProps,\n AvatarVariants,\n ButtonProps,\n ButtonVariants,\n CalendarCellIndicatorProps,\n CalendarCellProps,\n CalendarGridBodyProps,\n CalendarGridHeaderProps,\n CalendarGridProps,\n CalendarHeaderCellProps,\n CalendarHeaderProps,\n CalendarHeadingProps,\n CalendarNavButtonProps,\n CalendarProps,\n CalendarRootProps,\n CalendarVariants,\n CalendarYearPickerCellProps,\n CalendarYearPickerCellRenderProps,\n CalendarYearPickerGridBodyProps,\n CalendarYearPickerGridProps,\n CalendarYearPickerTriggerHeadingProps,\n CalendarYearPickerTriggerIndicatorProps,\n CalendarYearPickerTriggerProps,\n CalendarYearPickerTriggerRenderProps,\n CalendarYearPickerVariants,\n CardContentProps,\n CardProps,\n CardVariants,\n CheckboxContentProps,\n CheckboxControlProps,\n CheckboxRootProps,\n CheckboxVariants,\n ChipRootProps,\n ChipVariants,\n CloseButtonRootProps,\n CloseButtonVariants,\n CodeProps,\n Color,\n ColorAxes,\n ColorChannel,\n ColorChannelRange,\n ColorFormat,\n ColorSpace,\n DateFieldProps,\n DateFieldRootProps,\n DateFieldVariants,\n DateInputGroupInputContainerProps,\n DateInputGroupInputProps,\n DateInputGroupPrefixProps,\n DateInputGroupProps,\n DateInputGroupRootProps,\n DateInputGroupSegmentProps,\n DateInputGroupSuffixProps,\n DateInputGroupVariants,\n DatePickerPopoverProps,\n DatePickerProps,\n DatePickerRootProps,\n DatePickerTriggerIndicatorProps,\n DatePickerTriggerProps,\n DatePickerVariants,\n DateRange,\n DateRangePickerPopoverProps,\n DateRangePickerProps,\n DateRangePickerRangeSeparatorProps,\n DateRangePickerRootProps,\n DateRangePickerTriggerIndicatorProps,\n DateRangePickerTriggerProps,\n DateRangePickerVariants,\n DateValue,\n DescriptionRootProps,\n DescriptionVariants,\n Direction,\n FieldErrorProps,\n FieldErrorVariants,\n FormProps,\n HeaderProps,\n HeadingProps,\n InputGroupRootProps,\n InputGroupTextAreaProps,\n InputGroupVariants,\n InputOTPProps,\n InputOTPVariants,\n InputRootProps,\n InputVariants,\n Key,\n LabelRootProps,\n LabelVariants,\n MenuProps,\n MenuVariants,\n Orientation,\n ParagraphProps,\n PopoverDialogProps,\n PopoverHeadingProps,\n PopoverProps,\n PopoverVariants,\n PressEvent,\n ProseProps,\n RadioContentProps,\n RadioControlProps,\n RadioGroupRootProps,\n RadioGroupVariants,\n RadioRootProps,\n RadioVariants,\n RangeCalendarCellIndicatorProps,\n RangeCalendarCellProps,\n RangeCalendarGridBodyProps,\n RangeCalendarGridHeaderProps,\n RangeCalendarGridProps,\n RangeCalendarHeaderCellProps,\n RangeCalendarHeaderProps,\n RangeCalendarHeadingProps,\n RangeCalendarNavButtonProps,\n RangeCalendarProps,\n RangeCalendarRootProps,\n RangeCalendarVariants,\n RangeValue,\n RouterConfig,\n ScrollShadowRootProps,\n ScrollShadowVariants,\n SearchFieldRootProps,\n SearchFieldVariants,\n SelectIndicatorProps,\n Selection,\n SelectPopoverProps,\n SelectProps,\n SelectVariants,\n SeparatorRootProps,\n SeparatorVariants,\n SidebarContextProps,\n SidebarMenuButtonProps,\n SkeletonRootProps,\n SkeletonVariants,\n SliderMarksProps,\n SliderRootProps,\n SliderVariants,\n SortDescriptor,\n SpinnerRootProps,\n SpinnerVariants,\n SurfaceProps,\n SurfaceVariants,\n SwitchControlProps,\n SwitchIconProps,\n SwitchRootProps,\n SwitchVariants,\n TabIndicatorProps,\n TabListContainerProps,\n TabListProps,\n TabPanelProps,\n TabProps,\n TabSeparatorProps,\n TabsRootProps,\n TabsVariants,\n TagGroupListProps,\n TagGroupRootProps,\n TagGroupVariants,\n TextRootProps,\n TextVariants,\n TimeValue,\n ToastCloseButtonProps,\n ToastContentProps,\n ToastContentValue,\n ToastIndicatorProps,\n ToastProps,\n ToastQueueOptions,\n ToastVariants,\n UseScrollShadowProps,\n ValidationResult,\n YearPickerContextValue,\n YearPickerStateContextValue,\n} from \"./native-parity\";\nexport {\n AccordionBody,\n AccordionHeading,\n AccordionIndicator,\n AccordionItem,\n AccordionPanel,\n AccordionRoot,\n AccordionTrigger,\n AlertContent,\n AlertDescription,\n AlertIndicator,\n AlertRoot,\n AlertTitle,\n AvatarFallback,\n AvatarImage,\n AvatarRoot,\n accordionVariants,\n alertVariants,\n avatarVariants,\n ButtonRoot,\n buttonVariants,\n Calendar,\n CalendarCell,\n CalendarCellIndicator,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n CalendarHeaderCell,\n CalendarHeading,\n CalendarNavButton,\n CalendarRoot,\n CalendarYearPicker,\n CalendarYearPickerCell,\n CalendarYearPickerGrid,\n CalendarYearPickerGridBody,\n CalendarYearPickerTrigger,\n CalendarYearPickerTriggerHeading,\n CalendarYearPickerTriggerIndicator,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardRoot,\n CardTitle,\n CheckboxContent,\n CheckboxControl,\n CheckboxIndicator,\n CheckboxRoot,\n ChipLabel,\n ChipRoot,\n CloseButtonRoot,\n Code,\n Collection,\n calendarVariants,\n calendarYearPickerVariants,\n cardVariants,\n checkboxVariants,\n chipVariants,\n closeButtonVariants,\n DateField,\n DateFieldRoot,\n DateInputGroup,\n DateInputGroupInput,\n DateInputGroupInputContainer,\n DateInputGroupPrefix,\n DateInputGroupRoot,\n DateInputGroupSegment,\n DateInputGroupSuffix,\n DatePicker,\n DatePickerPopover,\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerTriggerIndicator,\n DateRangePicker,\n DateRangePickerPopover,\n DateRangePickerRangeSeparator,\n DateRangePickerRoot,\n DateRangePickerTrigger,\n DateRangePickerTriggerIndicator,\n DEFAULT_GAP,\n DEFAULT_MAX_VISIBLE_TOAST,\n DEFAULT_TOAST_TIMEOUT,\n DescriptionRoot,\n dateFieldVariants,\n dateInputGroupVariants,\n datePickerVariants,\n dateRangePickerVariants,\n descriptionVariants,\n FieldErrorRoot,\n fieldErrorVariants,\n getLocalizationScript,\n Heading,\n I18nProvider,\n InputGroupInput,\n InputGroupPrefix,\n InputGroupRoot,\n InputGroupSuffix,\n InputGroupTextArea,\n InputOTPGroup,\n InputOTPRoot,\n InputOTPSeparator,\n InputOTPSlot,\n InputRoot,\n inputGroupVariants,\n inputOTPVariants,\n inputVariants,\n isRTL,\n LabelRoot,\n ListBoxLoadMoreItem,\n ListLayout,\n labelVariants,\n MenuRoot,\n menuVariants,\n Paragraph,\n PopoverArrow,\n PopoverContent,\n PopoverDialog,\n PopoverHeading,\n PopoverRoot,\n PopoverTrigger,\n Prose,\n parseColor,\n popoverVariants,\n RadioContent,\n RadioControl,\n RadioGroupRoot,\n RadioIndicator,\n RadioRoot,\n RangeCalendar,\n RangeCalendarCell,\n RangeCalendarCellIndicator,\n RangeCalendarGrid,\n RangeCalendarGridBody,\n RangeCalendarGridHeader,\n RangeCalendarHeader,\n RangeCalendarHeaderCell,\n RangeCalendarHeading,\n RangeCalendarNavButton,\n RangeCalendarRoot,\n RouterProvider,\n radioGroupVariants,\n radioVariants,\n rangeCalendarVariants,\n ScrollShadowRoot,\n SearchFieldClearButton,\n SearchFieldGroup,\n SearchFieldInput,\n SearchFieldRoot,\n SearchFieldSearchIcon,\n SelectIndicator,\n SelectPopover,\n SelectRoot,\n SelectTrigger,\n SelectValue,\n SeparatorRoot,\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarRoot,\n SidebarSeparator,\n SidebarTrigger,\n SkeletonRoot,\n SliderFill,\n SliderMarks,\n SliderOutput,\n SliderRoot,\n SliderThumb,\n SliderTrack,\n SpinnerRoot,\n SurfaceContext,\n SurfaceRoot,\n SwitchContent,\n SwitchControl,\n SwitchIcon,\n SwitchRoot,\n SwitchThumb,\n scrollShadowVariants,\n searchFieldVariants,\n selectVariants,\n separatorVariants,\n sidebarMenuButtonVariants,\n skeletonVariants,\n sliderVariants,\n spinnerVariants,\n surfaceVariants,\n switchVariants,\n Tab,\n TabIndicator,\n TabList,\n TabListContainer,\n TableLayout,\n TabPanel,\n TabSeparator,\n TabsRoot,\n TagGroupContext,\n TagGroupList,\n TagGroupRoot,\n TextRoot,\n ToastActionButton,\n ToastCloseButton,\n ToastContent,\n ToastDescription,\n ToastIndicator,\n ToastQueue,\n ToastTitle,\n tabsVariants,\n tagGroupVariants,\n textVariants,\n toast,\n toastQueue,\n toastVariants,\n useFilter,\n useLocale,\n useScrollShadow,\n useSidebar,\n useYearPicker,\n useYearPickerState,\n Virtualizer,\n YearPickerContext,\n YearPickerStateContext,\n} from \"./native-parity\";\nexport * from \"./number-field\";\nexport * from \"./pagination\";\nexport * from \"./popover\";\nexport * from \"./pressable-feedback\";\nexport * from \"./progress-bar\";\nexport * from \"./progress-circle\";\nexport * from \"./radio\";\nexport * from \"./radio-group\";\nexport * from \"./resizable\";\nexport * from \"./scroll-area\";\nexport * from \"./scroll-shadow\";\nexport * from \"./search-field\";\nexport * from \"./select\";\nexport * from \"./separator\";\nexport * from \"./sheet\";\nexport * from \"./skeleton\";\nexport * from \"./skeleton-group\";\nexport * from \"./slider\";\nexport * from \"./spinner\";\nexport * from \"./sub-menu\";\nexport * from \"./surface\";\nexport * from \"./switch\";\nexport * from \"./table\";\nexport * from \"./tabs\";\nexport * from \"./tag\";\nexport * from \"./tag-group\";\nexport * from \"./text\";\nexport * from \"./text-area\";\nexport * from \"./text-field\";\nexport type { TextAreaRootProps, TextAreaVariants } from \"./textarea\";\nexport { TextAreaRoot, textAreaVariants } from \"./textarea\";\nexport type { TextFieldProps, TextFieldRootProps, TextFieldVariants } from \"./textfield\";\nexport { TextFieldContext, TextFieldRoot, textFieldVariants } from \"./textfield\";\nexport * from \"./time-field\";\nexport * from \"./toast\";\nexport * from \"./toggle\";\nexport * from \"./toggle-button\";\nexport * from \"./toggle-button-group\";\nexport * from \"./tooltip\";\n", "type": "registry:item", "target": "@components/pitsi-ui/native-ui/src/components/index.ts" }, { "path": "registry/native-ui/src/components/input-group/demos/index.tsx", "content": "import { useState } from \"react\";\nimport { Alert, View } from \"react-native\";\n\nimport {\n Button,\n FieldError,\n InputGroup,\n Label,\n Spinner,\n Surface,\n Text,\n TextArea,\n TextField,\n} from \"../..\";\n\nfunction TextPrefix({ children }: { children: string }) {\n return {children};\n}\n\nfunction BaseInputGroup({\n disabled = false,\n invalid = false,\n placeholder = \"Search\",\n variant,\n}: {\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n variant?: \"primary\" | \"secondary\";\n}) {\n return (\n \n \n \n );\n}\n\nexport function Default() {\n return ;\n}\n\nexport function Disabled() {\n return ;\n}\n\nexport function FullWidth() {\n return (\n \n \n \n );\n}\n\nexport function Invalid() {\n return (\n \n \n \n \n Enter a valid value.\n \n );\n}\n\nexport function OnSurface() {\n return (\n \n \n \n );\n}\n\nexport function PasswordWithToggle() {\n const [visible, setVisible] = useState(false);\n\n return (\n \n \n \n \n \n \n );\n}\n\nexport function Required() {\n return (\n \n \n \n \n \n \n );\n}\n\nexport function Variants() {\n return (\n \n \n \n \n );\n}\n\nexport function WithBadgeSuffix() {\n return (\n \n \n \n Public\n \n \n );\n}\n\nexport function WithCopySuffix() {\n return (\n \n \n \n \n \n \n );\n}\n\nexport function WithIconPrefixAndCopySuffix() {\n return (\n \n \n @\n \n \n \n \n \n \n );\n}\n\nexport function WithIconPrefixAndTextSuffix() {\n return (\n \n \n $\n \n \n \n USD\n \n \n );\n}\n\nexport function WithKeyboardShortcut() {\n return (\n \n \n \n Cmd K\n \n \n );\n}\n\nexport function WithLoadingSuffix() {\n return (\n \n \n \n \n \n \n );\n}\n\nexport function WithPrefixAndSuffix() {\n return (\n \n \n https://\n \n \n \n .com\n \n \n );\n}\n\nexport function WithPrefixIcon() {\n return (\n \n \n ?\n \n \n \n );\n}\n\nexport function WithSuffixIcon() {\n return (\n \n \n \n @\n \n \n );\n}\n\nexport function WithTextPrefix() {\n return (\n \n \n https://\n \n \n \n );\n}\n\nexport function WithTextSuffix() {\n return (\n \n \n \n kg\n \n \n );\n}\n\nexport function WithTextArea() {\n return (\n \n \n