@tamagui/web 1.88.13 → 1.89.0-1706308641099

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/createComponent.js +1 -1
  3. package/dist/cjs/createComponent.js.map +1 -1
  4. package/dist/cjs/helpers/getSplitStyles.js +1 -1
  5. package/dist/cjs/helpers/getSplitStyles.js.map +1 -1
  6. package/dist/cjs/helpers/getSplitStyles.native.js +1 -1
  7. package/dist/cjs/helpers/getSplitStyles.native.js.map +1 -1
  8. package/dist/esm/Tamagui.mjs +43 -0
  9. package/dist/esm/config.mjs +51 -0
  10. package/dist/esm/constants/accessibilityDirectMap.mjs +50 -0
  11. package/dist/esm/constants/constants.mjs +16 -0
  12. package/dist/esm/constants/isDevTools.mjs +7 -0
  13. package/dist/esm/contexts/ComponentContext.mjs +13 -0
  14. package/dist/esm/createComponent.js +1 -1
  15. package/dist/esm/createComponent.js.map +1 -1
  16. package/dist/esm/createComponent.mjs +771 -0
  17. package/dist/esm/createFont.mjs +18 -0
  18. package/dist/esm/createShorthands.mjs +4 -0
  19. package/dist/esm/createTamagui.mjs +206 -0
  20. package/dist/esm/createTheme.mjs +2 -0
  21. package/dist/esm/createTokens.mjs +5 -0
  22. package/dist/esm/createVariable.mjs +48 -0
  23. package/dist/esm/createVariables.mjs +35 -0
  24. package/dist/esm/defaultComponentState.mjs +16 -0
  25. package/dist/esm/helpers/ThemeManager.mjs +156 -0
  26. package/dist/esm/helpers/ThemeManagerContext.mjs +3 -0
  27. package/dist/esm/helpers/createMediaStyle.mjs +71 -0
  28. package/dist/esm/helpers/createShallowSetState.mjs +17 -0
  29. package/dist/esm/helpers/createStyledContext.mjs +35 -0
  30. package/dist/esm/helpers/defaultOffset.mjs +5 -0
  31. package/dist/esm/helpers/expandStyle.mjs +38 -0
  32. package/dist/esm/helpers/expandStyles.mjs +15 -0
  33. package/dist/esm/helpers/getExpandedShorthands.mjs +9 -0
  34. package/dist/esm/helpers/getFontLanguage.mjs +2 -0
  35. package/dist/esm/helpers/getGroupPropParts.mjs +13 -0
  36. package/dist/esm/helpers/getSplitStyles.js +1 -1
  37. package/dist/esm/helpers/getSplitStyles.js.map +1 -1
  38. package/dist/esm/helpers/getSplitStyles.mjs +643 -0
  39. package/dist/esm/helpers/getSplitStyles.native.js +1 -1
  40. package/dist/esm/helpers/getSplitStyles.native.js.map +1 -1
  41. package/dist/esm/helpers/getStylesAtomic.mjs +150 -0
  42. package/dist/esm/helpers/getThemeCSSRules.mjs +87 -0
  43. package/dist/esm/helpers/getVariantExtras.mjs +43 -0
  44. package/dist/esm/helpers/insertStyleRule.mjs +177 -0
  45. package/dist/esm/helpers/isObj.mjs +2 -0
  46. package/dist/esm/helpers/isTamaguiComponent.mjs +5 -0
  47. package/dist/esm/helpers/isTamaguiElement.mjs +4 -0
  48. package/dist/esm/helpers/log.mjs +4 -0
  49. package/dist/esm/helpers/matchMedia.mjs +11 -0
  50. package/dist/esm/helpers/mergeProps.mjs +21 -0
  51. package/dist/esm/helpers/mergeVariants.mjs +16 -0
  52. package/dist/esm/helpers/normalizeColor.mjs +17 -0
  53. package/dist/esm/helpers/normalizeShadow.mjs +23 -0
  54. package/dist/esm/helpers/normalizeStyle.mjs +23 -0
  55. package/dist/esm/helpers/normalizeStylePropKeys.mjs +2 -0
  56. package/dist/esm/helpers/normalizeValueWithProperty.mjs +32 -0
  57. package/dist/esm/helpers/objectIdentityKey.mjs +15 -0
  58. package/dist/esm/helpers/propMapper.mjs +239 -0
  59. package/dist/esm/helpers/proxyThemeToParents.mjs +36 -0
  60. package/dist/esm/helpers/proxyThemeVariables.mjs +12 -0
  61. package/dist/esm/helpers/pseudoDescriptors.mjs +34 -0
  62. package/dist/esm/helpers/registerCSSVariable.mjs +7 -0
  63. package/dist/esm/helpers/themeable.mjs +33 -0
  64. package/dist/esm/helpers/themes.mjs +14 -0
  65. package/dist/esm/helpers/timer.mjs +8 -0
  66. package/dist/esm/hooks/useConfiguration.mjs +20 -0
  67. package/dist/esm/hooks/useDisableSSR.mjs +5 -0
  68. package/dist/esm/hooks/useIsTouchDevice.mjs +4 -0
  69. package/dist/esm/hooks/useMedia.mjs +146 -0
  70. package/dist/esm/hooks/useProps.mjs +40 -0
  71. package/dist/esm/hooks/useTheme.mjs +222 -0
  72. package/dist/esm/hooks/useThemeName.mjs +15 -0
  73. package/dist/esm/index.mjs +61 -0
  74. package/dist/esm/inject-styles.mjs +13 -0
  75. package/dist/esm/insertFont.mjs +44 -0
  76. package/dist/esm/interfaces/CSSColorNames.mjs +0 -0
  77. package/dist/esm/interfaces/GetRef.mjs +0 -0
  78. package/dist/esm/interfaces/KeyTypes.mjs +0 -0
  79. package/dist/esm/interfaces/RNExclusiveTypes.mjs +0 -0
  80. package/dist/esm/interfaces/Role.mjs +0 -0
  81. package/dist/esm/interfaces/TamaguiComponentEvents.mjs +0 -0
  82. package/dist/esm/interfaces/TamaguiComponentPropsBaseBase.mjs +0 -0
  83. package/dist/esm/interfaces/TamaguiComponentState.mjs +0 -0
  84. package/dist/esm/interfaces/WebOnlyPressEvents.mjs +0 -0
  85. package/dist/esm/internalWithTheme.mjs +14 -0
  86. package/dist/esm/setupHooks.mjs +5 -0
  87. package/dist/esm/setupReactNative.mjs +24 -0
  88. package/dist/esm/styled.mjs +56 -0
  89. package/dist/esm/type-utils.mjs +0 -0
  90. package/dist/esm/types.mjs +2 -0
  91. package/dist/esm/views/Configuration.mjs +12 -0
  92. package/dist/esm/views/FontLanguage.mjs +13 -0
  93. package/dist/esm/views/FontLanguage.types.mjs +0 -0
  94. package/dist/esm/views/Slot.mjs +53 -0
  95. package/dist/esm/views/Stack.mjs +10 -0
  96. package/dist/esm/views/TamaguiProvider.mjs +32 -0
  97. package/dist/esm/views/Text.mjs +64 -0
  98. package/dist/esm/views/Theme.mjs +104 -0
  99. package/dist/esm/views/ThemeDebug.mjs +57 -0
  100. package/dist/esm/views/ThemeProvider.mjs +20 -0
  101. package/dist/esm/views/View.mjs +9 -0
  102. package/package.json +10 -10
  103. package/src/createComponent.tsx +1 -1
  104. package/src/helpers/getSplitStyles.tsx +5 -0
  105. package/types/helpers/getSplitStyles.d.ts.map +1 -1
@@ -0,0 +1,771 @@
1
+ import { composeRefs } from "@tamagui/compose-refs";
2
+ import { isClient, isServer, isWeb } from "@tamagui/constants";
3
+ import { composeEventHandlers, validStyles } from "@tamagui/helpers";
4
+ import { useDidFinishSSR } from "@tamagui/use-did-finish-ssr";
5
+ import React, { Children, Fragment, createElement, forwardRef, memo, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
6
+ import { devConfig, getConfig, onConfiguredOnce } from "./config.mjs";
7
+ import { stackDefaultStyles } from "./constants/constants.mjs";
8
+ import { ComponentContext } from "./contexts/ComponentContext.mjs";
9
+ import { didGetVariableValue, setDidGetVariableValue } from "./createVariable.mjs";
10
+ import { defaultComponentState, defaultComponentStateMounted, defaultComponentStateShouldEnter } from "./defaultComponentState.mjs";
11
+ import { createShallowSetState, mergeIfNotShallowEqual } from "./helpers/createShallowSetState.mjs";
12
+ import { useSplitStyles } from "./helpers/getSplitStyles.mjs";
13
+ import { isObj } from "./helpers/isObj.mjs";
14
+ import { log } from "./helpers/log.mjs";
15
+ import { mergeProps } from "./helpers/mergeProps.mjs";
16
+ import { themeable } from "./helpers/themeable.mjs";
17
+ import { mediaKeyMatch, setMediaShouldUpdate, useMedia } from "./hooks/useMedia.mjs";
18
+ import { useThemeWithState } from "./hooks/useTheme.mjs";
19
+ import { hooks } from "./setupHooks.mjs";
20
+ import { Slot } from "./views/Slot.mjs";
21
+ import { getThemedChildren } from "./views/Theme.mjs";
22
+ import { ThemeDebug } from "./views/ThemeDebug.mjs";
23
+ import { jsx } from "react/jsx-runtime";
24
+ let tamaguiConfig, time, debugKeyListeners, startVisualizer;
25
+ const mouseUps = /* @__PURE__ */new Set();
26
+ if (typeof document < "u") {
27
+ const cancelTouches = () => {
28
+ mouseUps.forEach(x => x()), mouseUps.clear();
29
+ };
30
+ addEventListener("mouseup", cancelTouches), addEventListener("touchend", cancelTouches), addEventListener("touchcancel", cancelTouches), process.env.NODE_ENV === "development" && (startVisualizer = () => {
31
+ const devVisualizerConfig = devConfig?.visualizer;
32
+ if (devVisualizerConfig) {
33
+ debugKeyListeners = /* @__PURE__ */new Set();
34
+ let tm,
35
+ isShowing = !1;
36
+ const options = {
37
+ key: "Alt",
38
+ delay: 800,
39
+ ...(typeof devVisualizerConfig == "object" ? devVisualizerConfig : {})
40
+ };
41
+ document.addEventListener("blur", () => {
42
+ clearTimeout(tm);
43
+ }), document.addEventListener("keydown", ({
44
+ key,
45
+ defaultPrevented
46
+ }) => {
47
+ defaultPrevented || (clearTimeout(tm), key === options.key && (tm = setTimeout(() => {
48
+ isShowing = !0, debugKeyListeners?.forEach(l => l(!0));
49
+ }, options.delay)));
50
+ }), document.addEventListener("keyup", ({
51
+ key,
52
+ defaultPrevented
53
+ }) => {
54
+ defaultPrevented || key === options.key && (clearTimeout(tm), isShowing && debugKeyListeners?.forEach(l => l(!1)));
55
+ });
56
+ }
57
+ });
58
+ }
59
+ let BaseText, BaseView;
60
+ function createComponent(staticConfig) {
61
+ const {
62
+ componentName
63
+ } = staticConfig;
64
+ let config = null,
65
+ defaultProps = staticConfig.defaultProps;
66
+ onConfiguredOnce(conf => {
67
+ if (config = conf, componentName) {
68
+ const defaultForComponent = conf.defaultProps?.[componentName];
69
+ defaultForComponent && (defaultProps = {
70
+ ...defaultForComponent,
71
+ ...defaultProps
72
+ });
73
+ }
74
+ });
75
+ const {
76
+ Component,
77
+ isText,
78
+ isInput,
79
+ isZStack,
80
+ isHOC,
81
+ validStyles: validStyles2 = {},
82
+ variants = {}
83
+ } = staticConfig;
84
+ process.env.NODE_ENV === "development" && staticConfig.defaultProps?.debug && process.env.IS_STATIC !== "is_static" && log(`\u{1F41B} [${componentName || "Component"}]`, {
85
+ staticConfig,
86
+ defaultProps,
87
+ defaultPropsKeyOrder: defaultProps ? Object.keys(defaultProps) : []
88
+ });
89
+ const component = forwardRef((propsIn, forwardedRef) => {
90
+ const internalID = process.env.NODE_ENV === "development" ? useId() : "";
91
+ process.env.NODE_ENV === "development" && startVisualizer && (startVisualizer(), startVisualizer = void 0), process.env.NODE_ENV === "test" && propsIn["data-test-renders"] && (propsIn["data-test-renders"].current ??= 0, propsIn["data-test-renders"].current += 1);
92
+ const componentContext = useContext(ComponentContext);
93
+ let styledContextProps, overriddenContextProps, contextValue;
94
+ const {
95
+ context
96
+ } = staticConfig;
97
+ if (context) {
98
+ contextValue = useContext(context);
99
+ const {
100
+ inverseShorthands
101
+ } = getConfig();
102
+ for (const key in context.props) {
103
+ const propVal =
104
+ // because its after default props but before props this annoying amount of checks
105
+ propsIn[key] ?? propsIn[inverseShorthands[key]] ?? defaultProps?.[key] ?? defaultProps?.[inverseShorthands[key]];
106
+ propVal === void 0 ? contextValue && (key in validStyles2 || key in variants) && (styledContextProps ||= {}, styledContextProps[key] = contextValue[key]) : (overriddenContextProps ||= {}, overriddenContextProps[key] = propVal);
107
+ }
108
+ }
109
+ const curDefaultProps = styledContextProps ? {
110
+ ...defaultProps,
111
+ ...styledContextProps
112
+ } : defaultProps;
113
+ let props = propsIn;
114
+ curDefaultProps && (props = mergeProps(curDefaultProps, propsIn));
115
+ const debugProp = props.debug,
116
+ componentName2 = props.componentName || staticConfig.componentName;
117
+ process.env.NODE_ENV === "development" && isClient && useEffect(() => {
118
+ let overlay = null;
119
+ const debugVisualizerHandler = (show = !1) => {
120
+ const node = curState.host;
121
+ if (node) if (show) {
122
+ overlay = document.createElement("span"), overlay.style.inset = "0px", overlay.style.zIndex = "1000000", overlay.style.position = "absolute", overlay.style.borderColor = "red", overlay.style.borderWidth = "1px", overlay.style.borderStyle = "dotted";
123
+ const dataAt = node.getAttribute("data-at") || "",
124
+ dataIn = node.getAttribute("data-in") || "",
125
+ tooltip = document.createElement("span");
126
+ tooltip.style.position = "absolute", tooltip.style.top = "0px", tooltip.style.left = "0px", tooltip.style.padding = "3px", tooltip.style.background = "rgba(0,0,0,0.75)", tooltip.style.color = "rgba(255,255,255,1)", tooltip.style.fontSize = "12px", tooltip.style.lineHeight = "12px", tooltip.style.fontFamily = "monospace", tooltip.style.webkitFontSmoothing = "none", tooltip.innerText = `${componentName2 || ""} ${dataAt} ${dataIn}`.trim(), overlay.appendChild(tooltip), node.appendChild(overlay);
127
+ } else overlay && node.removeChild(overlay);
128
+ };
129
+ return debugKeyListeners ||= /* @__PURE__ */new Set(), debugKeyListeners.add(debugVisualizerHandler), () => {
130
+ debugKeyListeners?.delete(debugVisualizerHandler);
131
+ };
132
+ }, [componentName2]), !process.env.TAMAGUI_IS_CORE_NODE && process.env.NODE_ENV === "development" && debugProp === "profile" && !time && (time = require("@tamagui/timer").timer().start()), process.env.NODE_ENV === "development" && time && time`start (ignore)`, process.env.NODE_ENV === "development" && time && time`did-finish-ssr`;
133
+ const stateRef = useRef({});
134
+ process.env.NODE_ENV === "development" && time && time`stateref`;
135
+ const animationsConfig = componentContext.animationDriver,
136
+ useAnimations = animationsConfig?.useAnimations,
137
+ hasAnimationProp = !!("animation" in props || props.style && hasAnimatedStyleValue(props.style)),
138
+ supportsCSSVars = animationsConfig?.supportsCSSVars,
139
+ curState = stateRef.current,
140
+ willBeAnimatedClient = !!(!!(hasAnimationProp && !isHOC && useAnimations) || curState.hasAnimated),
141
+ willBeAnimated = !isServer && willBeAnimatedClient;
142
+ willBeAnimated && !curState.hasAnimated && (curState.hasAnimated = !0);
143
+ const isHydrated = config?.disableSSR ? !0 : useDidFinishSSR(),
144
+ presence = willBeAnimated && animationsConfig?.usePresence?.() || null,
145
+ presenceState = presence?.[2],
146
+ isExiting = presenceState?.isPresent === !1,
147
+ isEntering = presenceState?.isPresent === !0 && presenceState.initial !== !1,
148
+ hasEnterStyle = !!props.enterStyle,
149
+ hasRNAnimation = hasAnimationProp && animationsConfig?.isReactNative,
150
+ isReactNative = staticConfig.isReactNative;
151
+ let isAnimated = willBeAnimated;
152
+ !isReactNative && hasRNAnimation && !isHOC && !isHydrated && (isAnimated = !1, curState.willHydrate = !0), process.env.NODE_ENV === "development" && time && time`pre-use-state`;
153
+ const hasEnterState = hasEnterStyle || isEntering,
154
+ needsToMount = !isHydrated || !curState.host,
155
+ initialState = hasEnterState ? needsToMount ? defaultComponentStateShouldEnter : defaultComponentState : defaultComponentStateMounted,
156
+ states = useState(initialState),
157
+ state = props.forceStyle ? {
158
+ ...states[0],
159
+ [props.forceStyle]: !0
160
+ } : states[0],
161
+ setState = states[1];
162
+ let setStateShallow = createShallowSetState(setState, debugProp);
163
+ if (isHydrated && state.unmounted === "should-enter" && (state.unmounted = !0), presenceState && isAnimated && isHydrated && staticConfig.variants) {
164
+ process.env.NODE_ENV === "development" && debugProp === "verbose" && console.warn(`has presenceState ${JSON.stringify(presenceState)}`);
165
+ const {
166
+ enterVariant,
167
+ exitVariant,
168
+ enterExitVariant,
169
+ custom
170
+ } = presenceState;
171
+ isObj(custom) && Object.assign(props, custom);
172
+ const exv = exitVariant ?? enterExitVariant,
173
+ env = enterVariant ?? enterExitVariant;
174
+ state.unmounted && env && staticConfig.variants[env] ? (process.env.NODE_ENV === "development" && debugProp === "verbose" && console.warn(`Animating presence ENTER "${env}"`), props[env] = !0) : isExiting && exv && (process.env.NODE_ENV === "development" && debugProp === "verbose" && console.warn(`Animating presence EXIT "${exv}"`), props[exv] = exitVariant !== enterExitVariant);
175
+ }
176
+ const shouldAvoidClasses = !!(!isWeb || isAnimated && !supportsCSSVars || !staticConfig.acceptsClassName ||
177
+ // on server for SSR and animation compat added the && isHydrated but perhaps we want
178
+ // disableClassName="until-hydrated" to be more straightforward
179
+ // see issue if not, Button sets disableClassName to true <Button animation="" /> with
180
+ // the react-native driver errors because it tries to animate var(--color) to rbga(..)
181
+ propsIn.disableClassName && isHydrated),
182
+ shouldForcePseudo = !!propsIn.forceStyle,
183
+ noClassNames = shouldAvoidClasses || shouldForcePseudo,
184
+ groupName = props.group,
185
+ groupClassName = groupName ? `t_group_${props.group}` : "";
186
+ if (groupName && !curState.group) {
187
+ const listeners = /* @__PURE__ */new Set();
188
+ curState.group = {
189
+ listeners,
190
+ emit(name, state2) {
191
+ listeners.forEach(l => l(name, state2));
192
+ },
193
+ subscribe(cb) {
194
+ return listeners.add(cb), () => {
195
+ listeners.delete(cb);
196
+ };
197
+ }
198
+ };
199
+ }
200
+ if (groupName) {
201
+ const groupContextState = componentContext.groups.state,
202
+ og = setStateShallow;
203
+ setStateShallow = state2 => {
204
+ og(state2), curState.group.emit(groupName, {
205
+ pseudo: state2
206
+ });
207
+ const next = {
208
+ ...groupContextState[groupName],
209
+ ...state2
210
+ };
211
+ groupContextState[groupName] = next;
212
+ };
213
+ }
214
+ process.env.NODE_ENV === "development" && time && time`use-state`;
215
+ const componentNameFinal = props.componentName || componentName2,
216
+ componentClassName = props.asChild || !componentNameFinal ? "" : `is_${componentNameFinal}`,
217
+ hasTextAncestor = !!(isWeb && isText && componentContext.inText),
218
+ isDisabled = props.disabled ?? props.accessibilityState?.disabled;
219
+ process.env.NODE_ENV === "development" && time && time`use-context`;
220
+ const element = isWeb && (!Component || typeof Component == "string") && props.tag || Component;
221
+ let elementType = isText ? BaseText || element || "span" : BaseView || element || (hasTextAncestor ? "span" : "div");
222
+ animationsConfig && isAnimated && (elementType = animationsConfig[isText ? "Text" : "View"] || elementType);
223
+ const disableTheme = props["data-disable-theme"] || isHOC;
224
+ process.env.NODE_ENV === "development" && time && time`theme-props`, props.themeShallow && (curState.themeShallow = !0);
225
+ const themeStateProps = {
226
+ name: props.theme,
227
+ componentName: componentName2,
228
+ disable: disableTheme,
229
+ shallow: curState.themeShallow,
230
+ inverse: props.themeInverse,
231
+ debug: debugProp
232
+ };
233
+ if (typeof curState.isListeningToTheme == "boolean" && (themeStateProps.shouldUpdate = () => stateRef.current.isListeningToTheme), process.env.NODE_ENV === "development" && debugProp && debugProp !== "profile") {
234
+ const name = `${componentName2 || Component?.displayName || Component?.name || "[Unnamed Component]"}`,
235
+ type = (hasEnterStyle ? "(hasEnter)" : "") + (isAnimated ? "(animated)" : "") + (isReactNative ? "(rnw)" : "") + (presenceState?.isPresent === !1 ? "(EXIT)" : ""),
236
+ dataIs = propsIn["data-is"] || "",
237
+ banner = `${internalID} ${name}${dataIs ? ` ${dataIs}` : ""} ${type}`;
238
+ if (console.info(`%c ${banner} (hydrated: ${isHydrated}) (unmounted: ${state.unmounted})`, "background: green; color: white;"), isServer) log({
239
+ noClassNames,
240
+ isAnimated,
241
+ shouldAvoidClasses,
242
+ isWeb,
243
+ supportsCSSVars
244
+ });else {
245
+ console.groupEnd();
246
+ const stateLog = `${`${state.press || state.pressIn ? " PRESS " : ""}`}${state.hover ? " HOVER " : ""}${state.focus ? " FOCUS" : " "}`,
247
+ ch = propsIn.children;
248
+ let childLog = typeof ch == "string" ? ch.length > 4 ? ch.slice(0, 4) + "..." : ch : "";
249
+ childLog.length && (childLog = `(children: ${childLog})`), console.groupCollapsed(`${childLog}${stateLog}Props:`), log("props in:", propsIn), log("final props:", props), log({
250
+ state,
251
+ staticConfig,
252
+ elementType,
253
+ themeStateProps
254
+ }), log({
255
+ contextProps: styledContextProps,
256
+ overriddenContextProps
257
+ }), log({
258
+ presence,
259
+ isAnimated,
260
+ isHOC,
261
+ hasAnimationProp,
262
+ useAnimations
263
+ }), console.groupEnd();
264
+ }
265
+ }
266
+ process.env.NODE_ENV === "development" && time && time`pre-theme-media`;
267
+ const [themeState, theme] = useThemeWithState(themeStateProps);
268
+ elementType = Component || elementType;
269
+ const isStringElement = typeof elementType == "string";
270
+ process.env.NODE_ENV === "development" && time && time`theme`;
271
+ const mediaState = useMedia(stateRef, componentContext);
272
+ process.env.NODE_ENV === "development" && time && time`media`, setDidGetVariableValue(!1);
273
+ const resolveValues =
274
+ // if HOC + mounted + has animation prop, resolve as value so it passes non-variable to child
275
+ isAnimated && !supportsCSSVars || isHOC && state.unmounted == !1 && hasAnimationProp ? "value" : "auto",
276
+ styleProps = {
277
+ mediaState,
278
+ noClassNames,
279
+ resolveValues,
280
+ isExiting,
281
+ isAnimated
282
+ },
283
+ splitStyles = useSplitStyles(props, staticConfig, theme, themeState?.state?.name || "", state, styleProps, null, componentContext, elementType, debugProp);
284
+ props.group && props.untilMeasured === "hide" && !curState.hasMeasured && (splitStyles.style.opacity = 0), process.env.NODE_ENV === "development" && time && time`split-styles`, curState.isListeningToTheme = splitStyles.dynamicThemeAccess;
285
+ const isMediaArray = splitStyles.hasMedia && Array.isArray(splitStyles.hasMedia),
286
+ shouldListenForMedia = didGetVariableValue() || isMediaArray || noClassNames && splitStyles.hasMedia === !0,
287
+ mediaListeningKeys = isMediaArray ? splitStyles.hasMedia : null;
288
+ setMediaShouldUpdate(stateRef, {
289
+ enabled: shouldListenForMedia,
290
+ keys: mediaListeningKeys
291
+ });
292
+ const {
293
+ viewProps: viewPropsIn,
294
+ pseudos,
295
+ style: splitStylesStyle,
296
+ classNames,
297
+ space
298
+ } = splitStyles,
299
+ propsWithAnimation = props;
300
+ let animationStyles;
301
+ if (
302
+ // if it supports css vars we run it on server too to get matching initial style
303
+ (supportsCSSVars ? willBeAnimatedClient : willBeAnimated) && useAnimations && !isHOC) {
304
+ const animations = useAnimations({
305
+ props: propsWithAnimation,
306
+ // if hydrating, send empty style
307
+ style: splitStylesStyle,
308
+ presence,
309
+ componentState: state,
310
+ styleProps,
311
+ theme: themeState.state?.theme,
312
+ pseudos: pseudos || null,
313
+ staticConfig,
314
+ stateRef
315
+ });
316
+ (isAnimated || supportsCSSVars) && animations && (animationStyles = animations.style), process.env.NODE_ENV === "development" && time && time`animations`;
317
+ }
318
+ const {
319
+ asChild,
320
+ children,
321
+ themeShallow,
322
+ spaceDirection: _spaceDirection,
323
+ disabled: disabledProp,
324
+ onPress,
325
+ onLongPress,
326
+ onPressIn,
327
+ onPressOut,
328
+ onHoverIn,
329
+ onHoverOut,
330
+ onMouseUp,
331
+ onMouseDown,
332
+ onMouseEnter,
333
+ onMouseLeave,
334
+ onFocus,
335
+ onBlur,
336
+ separator,
337
+ // ignore from here on out
338
+ forceStyle: _forceStyle,
339
+ // @ts-ignore for next/link compat etc
340
+ onClick,
341
+ theme: _themeProp,
342
+ // @ts-ignore
343
+ defaultVariants,
344
+ ...nonTamaguiProps
345
+ } = viewPropsIn;
346
+ process.env.NODE_ENV === "development" && props.untilMeasured && !props.group && console.warn(`You set the untilMeasured prop without setting group. This doesn't work, be sure to set untilMeasured on the parent that sets group, not the children that use the $group- prop.
347
+
348
+ If you meant to do this, you can disable this warning - either change untilMeasured and group at the same time, or do group={conditional ? 'name' : undefined}`), process.env.NODE_ENV === "development" && time && time`destructure`;
349
+ const disabled = props.accessibilityState?.disabled ||
350
+ // @ts-expect-error (comes from core)
351
+ props.accessibilityDisabled;
352
+ let viewProps = nonTamaguiProps;
353
+ hasAnimationProp && props.tag && !props.role && !props.accessibilityRole && (viewProps.role = props.tag), isHOC && _themeProp && (viewProps.theme = _themeProp), groupName && (nonTamaguiProps.onLayout = composeEventHandlers(nonTamaguiProps.onLayout, e => {
354
+ stateRef.current.group.emit(groupName, {
355
+ layout: e.nativeEvent.layout
356
+ }), !stateRef.current.hasMeasured && props.untilMeasured === "hide" && setState(prev => ({
357
+ ...prev
358
+ })), stateRef.current.hasMeasured = !0;
359
+ })), viewProps = hooks.usePropsTransform?.(elementType, nonTamaguiProps, stateRef, curState.willHydrate) ?? nonTamaguiProps, curState.composedRef || (curState.composedRef = composeRefs(x => stateRef.current.host = x, forwardedRef)), viewProps.ref = curState.composedRef, process.env.NODE_ENV === "development" && !isReactNative && !isText && isWeb && !isHOC && Children.toArray(props.children).forEach(item => {
360
+ typeof item == "string" && item !== `
361
+ ` && console.error(`Unexpected text node: ${item}. A text node cannot be a child of a <View>.`);
362
+ }), process.env.NODE_ENV === "development" && time && time`events-hooks`;
363
+ const {
364
+ pseudoGroups,
365
+ mediaGroups
366
+ } = splitStyles;
367
+ curState.unPress || (curState.unPress = () => setStateShallow({
368
+ press: !1,
369
+ pressIn: !1
370
+ }));
371
+ const unPress = curState.unPress,
372
+ shouldEnter = state.unmounted;
373
+ useEffect(() => {
374
+ if (shouldEnter) {
375
+ setStateShallow({
376
+ unmounted: !1
377
+ });
378
+ return;
379
+ }
380
+ let disposeGroupsListener;
381
+ if (pseudoGroups || mediaGroups) {
382
+ const current = {
383
+ pseudo: {},
384
+ media: {}
385
+ };
386
+ disposeGroupsListener = componentContext.groups.subscribe((name, {
387
+ layout,
388
+ pseudo
389
+ }) => {
390
+ if (pseudo && pseudoGroups?.has(name)) Object.assign(current.pseudo, pseudo), persist();else if (layout && mediaGroups) {
391
+ const mediaState2 = getMediaState(mediaGroups, layout),
392
+ next = mergeIfNotShallowEqual(current.media, mediaState2);
393
+ next !== current.media && (Object.assign(current.media, next), persist());
394
+ }
395
+ function persist() {
396
+ setStateShallow({
397
+ // force it to be referentially different so it always updates
398
+ group: {
399
+ ...state.group,
400
+ [name]: current
401
+ }
402
+ });
403
+ }
404
+ });
405
+ }
406
+ return () => {
407
+ disposeGroupsListener?.(), mouseUps.delete(unPress);
408
+ };
409
+ }, [shouldEnter, pseudoGroups ? Object.keys([...pseudoGroups]).join("") : 0, mediaGroups ? Object.keys([...mediaGroups]).join("") : 0]);
410
+ let fontFamily = isText || isInput ? splitStyles.fontFamily || staticConfig.defaultProps?.fontFamily : null;
411
+ fontFamily && fontFamily[0] === "$" && (fontFamily = fontFamily.slice(1));
412
+ const fontFamilyClassName = fontFamily ? `font_${fontFamily}` : "",
413
+ style = animationStyles || splitStyles.style;
414
+ let className;
415
+ if (!(asChild === "except-style" || asChild === "except-style-web")) {
416
+ let classList = [];
417
+ if (componentName2 && classList.push(componentClassName), fontFamilyClassName && classList.push(fontFamilyClassName), classNames && classList.push(Object.values(classNames).join(" ")), groupClassName && classList.push(groupClassName), className = classList.join(" "), isAnimated && !supportsCSSVars && isReactNative) viewProps.style = style;else if (isReactNative) {
418
+ const cnStyles = {
419
+ $$css: !0
420
+ };
421
+ for (const name of className.split(" ")) cnStyles[name] = name;
422
+ viewProps.style = [...(Array.isArray(style) ? style : [style]), cnStyles];
423
+ } else className && (viewProps.className = className), viewProps.style = style;
424
+ }
425
+ const runtimePressStyle = !disabled && noClassNames && pseudos?.pressStyle,
426
+ runtimeFocusStyle = !disabled && noClassNames && pseudos?.focusStyle,
427
+ attachFocus = !!(runtimePressStyle || runtimeFocusStyle || onFocus || onBlur),
428
+ attachPress = !!(groupName || runtimePressStyle || onPress || onPressOut || onPressIn || onLongPress || onClick),
429
+ runtimeHoverStyle = !disabled && noClassNames && pseudos?.hoverStyle,
430
+ needsHoverState = runtimeHoverStyle || onHoverIn || onHoverOut,
431
+ isHoverable = isWeb && !!(groupName || needsHoverState || onMouseEnter || onMouseLeave),
432
+ shouldAttach = !!(attachFocus || attachPress || isHoverable || runtimePressStyle || runtimeHoverStyle || runtimeFocusStyle);
433
+ process.env.NODE_ENV === "development" && time && time`events-setup`;
434
+ const events = shouldAttach && !isDisabled && !props.asChild ? {
435
+ onPressOut: attachPress ? e => {
436
+ unPress(), onPressOut?.(e), onMouseUp?.(e);
437
+ } : void 0,
438
+ ...((isHoverable || attachPress) && {
439
+ onMouseEnter: e => {
440
+ const next = {};
441
+ needsHoverState && (next.hover = !0), runtimePressStyle && state.pressIn && (next.press = !0), setStateShallow(next), onHoverIn?.(e), onMouseEnter?.(e);
442
+ },
443
+ onMouseLeave: e => {
444
+ const next = {};
445
+ mouseUps.add(unPress), needsHoverState && (next.hover = !1), runtimePressStyle && state.pressIn && (next.press = !1, next.pressIn = !1), setStateShallow(next), onHoverOut?.(e), onMouseLeave?.(e);
446
+ }
447
+ }),
448
+ onPressIn: attachPress ? e => {
449
+ runtimePressStyle && setStateShallow({
450
+ press: !0,
451
+ pressIn: !0
452
+ }), onPressIn?.(e), onMouseDown?.(e), isWeb && mouseUps.add(unPress);
453
+ } : void 0,
454
+ onPress: attachPress ? e => {
455
+ unPress(), isWeb && onClick?.(e), onPress?.(e), onLongPress?.(e);
456
+ } : void 0,
457
+ ...(attachFocus && {
458
+ onFocus: e => {
459
+ setStateShallow({
460
+ focus: !0
461
+ }), onFocus?.(e);
462
+ },
463
+ onBlur: e => {
464
+ setStateShallow({
465
+ focus: !1
466
+ }), onBlur?.(e);
467
+ }
468
+ })
469
+ } : null;
470
+ events && !isReactNative && Object.assign(viewProps, getWebEvents(events)), process.env.NODE_ENV === "development" && time && time`events`, process.env.NODE_ENV === "development" && debugProp === "verbose" && log("events", {
471
+ events,
472
+ isHoverable,
473
+ attachPress
474
+ }), hooks.useEvents?.(viewProps, events, splitStyles, setStateShallow, staticConfig);
475
+ const direction = props.spaceDirection || "both";
476
+ process.env.NODE_ENV === "development" && time && time`hooks`;
477
+ let content = !children || asChild ? children : spacedChildren({
478
+ separator,
479
+ children,
480
+ space,
481
+ direction,
482
+ isZStack,
483
+ debug: debugProp
484
+ });
485
+ if (asChild) {
486
+ elementType = Slot;
487
+ {
488
+ const passEvents = getWebEvents({
489
+ onPress,
490
+ onLongPress,
491
+ onPressIn,
492
+ onPressOut,
493
+ onHoverIn,
494
+ onHoverOut,
495
+ onMouseUp,
496
+ onMouseDown,
497
+ onMouseEnter,
498
+ onMouseLeave
499
+ }, asChild === "web" || asChild === "except-style-web");
500
+ Object.assign(viewProps, passEvents);
501
+ }
502
+ }
503
+ process.env.NODE_ENV === "development" && time && time`spaced-as-child`;
504
+ let useChildrenResult;
505
+ hooks.useChildren && (useChildrenResult = hooks.useChildren(elementType, content, viewProps, events, staticConfig)), useChildrenResult ? content = useChildrenResult : content = createElement(elementType, viewProps, content);
506
+ const ResetPresence = config?.animations?.ResetPresence;
507
+ ResetPresence && willBeAnimated && (hasEnterStyle || presenceState) && content && typeof content != "string" && (content = /* @__PURE__ */jsx(ResetPresence, {
508
+ children: content
509
+ })), process.env.NODE_ENV === "development" && time && time`create-element`;
510
+ const groupState = curState.group,
511
+ subGroupContext = useMemo(() => {
512
+ if (!(!groupState || !groupName)) return groupState.listeners.clear(), {
513
+ ...componentContext.groups,
514
+ // change reference so as we mutate it doesn't affect siblings etc
515
+ state: {
516
+ ...componentContext.groups.state,
517
+ [groupName]: {
518
+ pseudo: defaultComponentStateMounted,
519
+ // capture just initial width and height if they exist
520
+ // will have top, left, width, height (not x, y)
521
+ layout: {
522
+ width: fromPx(splitStyles.style.width),
523
+ height: fromPx(splitStyles.style.height)
524
+ }
525
+ }
526
+ },
527
+ emit: groupState.emit,
528
+ subscribe: groupState.subscribe
529
+ };
530
+ }, [groupName]);
531
+ if (groupName && subGroupContext && (content = /* @__PURE__ */jsx(ComponentContext.Provider, {
532
+ ...componentContext,
533
+ groups: subGroupContext,
534
+ children: content
535
+ })), process.env.NODE_ENV === "development" && time && time`group-context`, content = disableTheme ? content : getThemedChildren(themeState, content, themeStateProps, !1), process.env.NODE_ENV === "development" && time && time`themed-children`, process.env.NODE_ENV === "development" && props.debug === "visualize" && (content = /* @__PURE__ */jsx(ThemeDebug, {
536
+ themeState,
537
+ themeProps: props,
538
+ children: content
539
+ })), isReactNative && !asChild && (content = /* @__PURE__ */jsx("span", {
540
+ ...(isHydrated ? {
541
+ className: "_dsp_contents",
542
+ ...(events && getWebEvents(events))
543
+ } : {
544
+ className: "_dsp_contents"
545
+ }),
546
+ children: content
547
+ })), staticConfig.context) {
548
+ const contextProps = staticConfig.context.props;
549
+ for (const key in contextProps) (key in style || key in viewProps) && (overriddenContextProps ||= {}, overriddenContextProps[key] = style[key] ?? viewProps[key]);
550
+ }
551
+ if (overriddenContextProps) {
552
+ const Provider = staticConfig.context.Provider;
553
+ content = /* @__PURE__ */jsx(Provider, {
554
+ ...contextValue,
555
+ ...overriddenContextProps,
556
+ children: content
557
+ });
558
+ }
559
+ if (process.env.NODE_ENV === "development" && debugProp && debugProp !== "profile") {
560
+ console.groupCollapsed(`render <${typeof elementType == "string" ? elementType : "Component"} /> (${internalID}) with props`);
561
+ try {
562
+ log("viewProps", viewProps), log("children", content), typeof window < "u" && (log("props in", propsIn, "mapped to", props, "in order", Object.keys(props)), log({
563
+ animationStyles,
564
+ classNames,
565
+ content,
566
+ defaultProps,
567
+ elementType,
568
+ events,
569
+ initialState,
570
+ isAnimated,
571
+ isMediaArray,
572
+ isStringElement,
573
+ mediaListeningKeys,
574
+ pseudos,
575
+ shouldAttach,
576
+ shouldAvoidClasses,
577
+ shouldForcePseudo,
578
+ shouldListenForMedia,
579
+ splitStyles,
580
+ splitStylesStyle,
581
+ state,
582
+ stateRef,
583
+ staticConfig,
584
+ styleProps,
585
+ tamaguiConfig,
586
+ themeState,
587
+ viewProps,
588
+ willBeAnimated
589
+ }));
590
+ } catch {}
591
+ if (console.groupEnd(), debugProp === "break") debugger;
592
+ }
593
+ return process.env.NODE_ENV === "development" && time && (time`rest`, globalThis.willPrint || (globalThis.willPrint = !0, setTimeout(() => {
594
+ delete globalThis.willPrint, time.print(), time = null;
595
+ }, 50))), content;
596
+ });
597
+ staticConfig.componentName && (component.displayName = staticConfig.componentName);
598
+ let res = component;
599
+ (process.env.TAMAGUI_FORCE_MEMO || staticConfig.memo) && (res = memo(res)), res.staticConfig = staticConfig;
600
+ function extendStyledConfig(extended) {
601
+ return {
602
+ ...staticConfig,
603
+ ...extended,
604
+ neverFlatten: !0,
605
+ isHOC: !0,
606
+ isStyledHOC: !1
607
+ };
608
+ }
609
+ function extractable(Component2, extended) {
610
+ return Component2.staticConfig = extendStyledConfig(extended), Component2.styleable = styleable, Component2;
611
+ }
612
+ function styleable(Component2, options) {
613
+ let out = Component2.render?.length === 2 ? Component2 : forwardRef(Component2);
614
+ const extendedConfig = extendStyledConfig(options?.staticConfig);
615
+ return out = options?.disableTheme ? out : themeable(out, extendedConfig), process.env.TAMAGUI_MEMOIZE_STYLEABLE && (out = memo(out)), out.staticConfig = extendedConfig, out.styleable = styleable, out;
616
+ }
617
+ return res.extractable = extractable, res.styleable = styleable, res;
618
+ }
619
+ function getWebEvents(events, webStyle = !0) {
620
+ return {
621
+ onMouseEnter: events.onHoverIn ?? events.onMouseEnter,
622
+ onMouseLeave: events.onHoverOut ?? events.onMouseLeave,
623
+ [webStyle ? "onClick" : "onPress"]: events.onPress,
624
+ onMouseDown: events.onPressIn,
625
+ onMouseUp: events.onPressOut,
626
+ onTouchStart: events.onPressIn,
627
+ onTouchEnd: events.onPressOut,
628
+ onFocus: events.onFocus,
629
+ onBlur: events.onBlur
630
+ };
631
+ }
632
+ function Unspaced(props) {
633
+ return props.children;
634
+ }
635
+ Unspaced.isUnspaced = !0;
636
+ const getSpacerSize = (size, {
637
+ tokens
638
+ }) => {
639
+ size = size === !0 ? "$true" : size;
640
+ const sizePx = tokens.space[size] ?? size;
641
+ return {
642
+ width: sizePx,
643
+ height: sizePx,
644
+ minWidth: sizePx,
645
+ minHeight: sizePx
646
+ };
647
+ },
648
+ Spacer = createComponent({
649
+ acceptsClassName: !0,
650
+ memo: !0,
651
+ componentName: "Spacer",
652
+ validStyles,
653
+ defaultProps: {
654
+ ...stackDefaultStyles,
655
+ // avoid nesting issues
656
+ tag: "span",
657
+ size: !0,
658
+ pointerEvents: "none"
659
+ },
660
+ variants: {
661
+ size: {
662
+ "...": getSpacerSize
663
+ },
664
+ flex: {
665
+ true: {
666
+ flexGrow: 1
667
+ }
668
+ },
669
+ direction: {
670
+ horizontal: {
671
+ height: 0,
672
+ minHeight: 0
673
+ },
674
+ vertical: {
675
+ width: 0,
676
+ minWidth: 0
677
+ },
678
+ both: {}
679
+ }
680
+ }
681
+ });
682
+ function spacedChildren(props) {
683
+ const {
684
+ isZStack,
685
+ children,
686
+ space,
687
+ direction,
688
+ spaceFlex,
689
+ separator
690
+ } = props,
691
+ hasSpace = !!(space || spaceFlex),
692
+ hasSeparator = separator != null;
693
+ if (!(hasSpace || hasSeparator || isZStack)) return children;
694
+ const childrenList = Children.toArray(children);
695
+ if (childrenList.length <= 1 && !isZStack && !childrenList[0]?.type?.shouldForwardSpace) return childrenList;
696
+ const final = [];
697
+ for (let [index, child] of childrenList.entries()) {
698
+ const isEmpty = child == null || Array.isArray(child) && child.length === 0;
699
+ if (!isEmpty && React.isValidElement(child) && child.type?.shouldForwardSpace && (child = React.cloneElement(child, {
700
+ space,
701
+ spaceFlex,
702
+ separator,
703
+ key: child.key
704
+ })), isEmpty || !child || child.key && !isZStack ? final.push(child) : final.push( /* @__PURE__ */jsx(Fragment, {
705
+ children: isZStack ? /* @__PURE__ */jsx(AbsoluteFill, {
706
+ children: child
707
+ }) : child
708
+ }, index)), isUnspaced(child) && index === 0 || isZStack) continue;
709
+ const next = childrenList[index + 1];
710
+ next && !isUnspaced(next) && (separator ? (hasSpace && final.push(createSpacer({
711
+ key: `_${index}_00tmgui`,
712
+ direction,
713
+ space,
714
+ spaceFlex
715
+ })), final.push(React.isValidElement(separator) ? React.cloneElement(separator, {
716
+ key: `sep_${index}`
717
+ }) : separator), hasSpace && final.push(createSpacer({
718
+ key: `_${index}01tmgui`,
719
+ direction,
720
+ space,
721
+ spaceFlex
722
+ }))) : final.push(createSpacer({
723
+ key: `_${index}02tmgui`,
724
+ direction,
725
+ space,
726
+ spaceFlex
727
+ })));
728
+ }
729
+ return process.env.NODE_ENV === "development" && props.debug && log(" Spaced children", final, props), final;
730
+ }
731
+ function createSpacer({
732
+ key,
733
+ direction,
734
+ space,
735
+ spaceFlex
736
+ }) {
737
+ return /* @__PURE__ */jsx(Spacer, {
738
+ size: space,
739
+ direction,
740
+ ...(typeof spaceFlex < "u" && {
741
+ flex: spaceFlex === !0 ? 1 : spaceFlex === !1 ? 0 : spaceFlex
742
+ })
743
+ }, key);
744
+ }
745
+ function isUnspaced(child) {
746
+ const t = child?.type;
747
+ return t?.isVisuallyHidden || t?.isUnspaced;
748
+ }
749
+ const AbsoluteFill = createComponent({
750
+ defaultProps: {
751
+ ...stackDefaultStyles,
752
+ flexDirection: "column",
753
+ position: "absolute",
754
+ top: 0,
755
+ right: 0,
756
+ bottom: 0,
757
+ left: 0,
758
+ pointerEvents: "box-none"
759
+ }
760
+ });
761
+ function hasAnimatedStyleValue(style) {
762
+ return Object.keys(style).some(k => {
763
+ const val = style[k];
764
+ return val && typeof val == "object" && "_animation" in val;
765
+ });
766
+ }
767
+ function getMediaState(mediaGroups, layout) {
768
+ return Object.fromEntries([...mediaGroups].map(mediaKey => [mediaKey, mediaKeyMatch(mediaKey, layout)]));
769
+ }
770
+ const fromPx = val => typeof val != "string" ? val : +val.replace("px", "");
771
+ export { Spacer, Unspaced, createComponent, mouseUps, spacedChildren };