// re-exports all of @tamagui/web just adds hooks export * from '@tamagui/web' import { createMedia } from '@tamagui/react-native-media-driver' import { isWeb } from '@tamagui/constants' import { createMeasure, createMeasureInWindow, createMeasureLayout, enable, useElementLayout, } from '@tamagui/use-element-layout' import type { StackNonStyleProps, StackStyleBase, TamaDefer, TamaguiComponent, TamaguiElement, TamaguiProviderProps, TamaguiTextElement, TextNonStyleProps, TextProps, TextStylePropsBase, } from '@tamagui/web' import { TamaguiProvider as WebTamaguiProvider, Text as WebText, View as WebView, createTamagui as createTamaguiWeb, setupHooks, useIsomorphicLayoutEffect, } from '@tamagui/web' import { createOptimizedView } from './createOptimizedView' import { getBaseViews } from './getBaseViews' import type { RNTextProps, RNViewProps } from './reactNativeTypes' // helpful for usage outside of tamagui export { LayoutMeasurementController, registerLayoutNode, setOnLayoutStrategy, type LayoutEvent, } from '@tamagui/use-element-layout' // adds extra types to View/Stack/Text: type RNExclusiveViewProps = Omit export interface RNTamaguiViewNonStyleProps extends StackNonStyleProps, RNExclusiveViewProps {} type RNTamaguiView = TamaguiComponent< TamaDefer, TamaguiElement, RNTamaguiViewNonStyleProps, StackStyleBase, {} > type RNExclusiveTextProps = Omit export interface RNTamaguiTextNonStyleProps extends TextNonStyleProps, RNExclusiveTextProps {} type RNTamaguiText = TamaguiComponent< TamaDefer, TamaguiTextElement, RNTamaguiTextNonStyleProps, TextStylePropsBase, {} > // fixes issues with TS saying internal type usage is breaking // see https://discord.com/channels/909986013848412191/1146150253490348112/1146150253490348112 export * from './reactNativeTypes' // adds useElementLayout enable export const TamaguiProvider = (props: TamaguiProviderProps) => { useIsomorphicLayoutEffect(() => { enable() }, []) return } // automate using the react native media driver export const createTamagui: typeof createTamaguiWeb = (conf) => { if (!isWeb) { if (conf.media) { conf.media = createMedia(conf.media) } } return createTamaguiWeb(conf) } const baseViews = getBaseViews() // setup internal hooks: setupHooks({ getBaseViews, setElementProps: (node) => { if (process.env.TAMAGUI_TARGET === 'web') { // web only if (node && !node['measure']) { node.measure ||= createMeasure(node) node.measureInWindow ||= createMeasureInWindow(node) node.measureLayout ||= createMeasureLayout(node) } } }, usePropsTransform(elementType, propsIn, stateRef, willHydrate) { if (process.env.TAMAGUI_TARGET === 'web') { const isDOM = typeof elementType === 'string' // replicate react-native-web functionality const { // remove event props handles by useResponderEvents onMoveShouldSetResponder, onMoveShouldSetResponderCapture, onResponderEnd, onResponderGrant, onResponderMove, onResponderReject, onResponderRelease, onResponderStart, onResponderTerminate, onResponderTerminationRequest, onScrollShouldSetResponder, onScrollShouldSetResponderCapture, onSelectionChangeShouldSetResponder, onSelectionChangeShouldSetResponderCapture, onStartShouldSetResponder, onStartShouldSetResponderCapture, // android collapsable, focusable, // deprecated, accessible, accessibilityDisabled, onLayout, hrefAttrs, ...plainDOMProps } = propsIn if (willHydrate || isDOM) { useElementLayout(stateRef, !isDOM ? undefined : (onLayout as any)) // responder events removed for web - use native pointer/touch events instead // the onResponder* props are stripped above and not passed to DOM } if (isDOM) { // TODO move into getSplitStyles if (plainDOMProps.href && hrefAttrs) { const { download, rel, target } = hrefAttrs if (download != null) { plainDOMProps.download = download } if (rel) { plainDOMProps.rel = rel } if (typeof target === 'string') { plainDOMProps.target = target.charAt(0) !== '_' ? `_${target}` : target } } return plainDOMProps } } }, // attempt at properly fixing RN input, but just doesnt work on RN ...(process.env.TAMAGUI_TARGET === 'native' && { useChildren(elementType, children, viewProps) { if (process.env.NODE_ENV === 'test') { // test mode - just use regular views since optimizations cause weirdness return } if (elementType === baseViews.View && baseViews.TextAncestor) { // optimize view return createOptimizedView(children, viewProps, baseViews) } }, }), }) // overwrite web versions: // putting at the end ensures it overwrites in dist/cjs/index.js export const View = WebView as any as RNTamaguiView export const Text = WebText as any as RNTamaguiText // easily test type declaration output and if it gets messy: // export const X = styled(WebView, { // variants: { // abc: { // true: {}, // }, // } as const, // }) // export const Y = styled(X, { // variants: { // zys: { // true: {}, // }, // } as const, // }) // export const Z = styled(Y, { // variants: { // xxx: { // true: {}, // }, // } as const, // }) // export const A = styled(Z, { // variants: {} as const, // }) // const zz = // const variants = { // fullscreen: { // true: {}, // }, // elevation: { // '...size': () => ({}), // ':number': () => ({}), // }, // } as const // export const YStack = styled(View, { // flexDirection: 'column', // variants, // }) // import { TextInput } from 'react-native' // export const InputFrame = styled( // TextInput, // { // name: 'Input', // backgroundColor: 'green', // variants: { // // unstyled: { // // false: {}, // // }, // size: { // '...size': () => ({}), // }, // // disabled: { // // ':boolean': () => ({}) // // }, // } as const, // // defaultVariants: { // // unstyled: process.env.TAMAGUI_HEADLESS === '1' ? true : false, // // }, // }, // { // isText: true, // accept: { // placeholderTextColor: 'color', // }, // } // ) // export const StyledInputFrame = styled(InputFrame, { // fontSize: 16, // fontFamily: '$silkscreen', // color: '$color5', // minWidth: 0, // borderWidth: 0, // borderColor: 'transparent', // variants: { // unset: { // false: { // borderWidth: 2, // py: 12, // px: 14, // borderRadius: 6, // bg: '$color3', // focusStyle: { // bg: '$color4', // margin: 0, // }, // }, // }, // } as const, // defaultVariants: { // unset: false, // }, // }) // export const StyledStyledInputFrame = styled( // StyledInputFrame, // { // fontSize: 16, // fontFamily: '$silkscreen', // color: '$color5', // minWidth: 0, // borderWidth: 0, // borderColor: 'transparent', // variants: { // unset: { // false: { // borderWidth: 2, // py: 12, // px: 14, // borderRadius: 6, // bg: '$color3', // focusStyle: { // bg: '$color4', // margin: 0, // }, // }, // }, // } as const, // defaultVariants: { // unset: false, // }, // }, // { // inlineProps: new Set(['id', 'testID']), // } // ) // export const DepthTest = () =>