@tamagui/core 1.0.1-beta.148 → 1.0.1-beta.151

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 (37) hide show
  1. package/dist/cjs/constants/platform.js.map +2 -2
  2. package/dist/cjs/createComponent.js +161 -52
  3. package/dist/cjs/createComponent.js.map +2 -2
  4. package/dist/cjs/createFont.js +2 -1
  5. package/dist/cjs/createFont.js.map +2 -2
  6. package/dist/cjs/helpers/getSplitStyles.js +60 -50
  7. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  8. package/dist/cjs/helpers/mergeTransform.js.map +2 -2
  9. package/dist/cjs/hooks/useFeatures.js +0 -120
  10. package/dist/cjs/hooks/useFeatures.js.map +2 -2
  11. package/dist/cjs/insertFont.js +1 -1
  12. package/dist/cjs/insertFont.js.map +2 -2
  13. package/dist/cjs/types.js.map +1 -1
  14. package/dist/esm/constants/platform.js.map +2 -2
  15. package/dist/esm/createComponent.js +169 -55
  16. package/dist/esm/createComponent.js.map +2 -2
  17. package/dist/esm/createFont.js +2 -1
  18. package/dist/esm/createFont.js.map +2 -2
  19. package/dist/esm/helpers/getSplitStyles.js +60 -50
  20. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  21. package/dist/esm/helpers/mergeTransform.js.map +2 -2
  22. package/dist/esm/hooks/useFeatures.js +0 -120
  23. package/dist/esm/hooks/useFeatures.js.map +2 -2
  24. package/dist/esm/insertFont.js +1 -1
  25. package/dist/esm/insertFont.js.map +2 -2
  26. package/package.json +10 -9
  27. package/src/constants/platform.ts +1 -0
  28. package/src/createComponent.tsx +246 -57
  29. package/src/createFont.ts +4 -1
  30. package/src/helpers/getSplitStyles.tsx +73 -65
  31. package/src/helpers/mergeTransform.ts +2 -0
  32. package/src/insertFont.ts +1 -1
  33. package/src/types.tsx +7 -5
  34. package/types/helpers/getSplitStyles.d.ts +1 -0
  35. package/types/hooks/useFeatures.d.ts +0 -1
  36. package/types/types.d.ts +11 -3
  37. package/src/hooks/useFeatures.tsx +0 -289
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/constants/platform.ts"],
4
- "sourcesContent": ["import { useEffect, useLayoutEffect } from 'react'\nimport { Platform } from 'react-native'\n\nexport const isAndroid = Platform?.OS === 'android'\nexport const isIOS = Platform?.OS === 'ios'\nexport const isWeb = process.env.TAMAGUI_TARGET === 'web'\nexport const isWindowDefined = typeof window !== 'undefined'\nexport const isSSR = isWeb && !isWindowDefined\nexport const isClient = isWeb && isWindowDefined\n\nexport const isRSC = process.env.ENABLE_RSC\n ? // note this is statically analyzed so no funny business, just access it without optional chaining\n // @ts-ignore\n import.meta.env\n ? // @ts-ignore\n import.meta.env.SSR\n : false\n : false\n\nconst idFn = () => {}\nexport const useIsomorphicLayoutEffect = isRSC ? idFn : isSSR ? useEffect : useLayoutEffect\nexport const isChrome = typeof navigator !== 'undefined' && /Chrome/.test(navigator.userAgent || '')\nexport const isWebTouchable = isClient && 'ontouchstart' in window\nexport const isTouchable = !isWeb || isWebTouchable\n"],
5
- "mappings": "AAAA;AAAA;AACA;AAEO,MAAM,YAAY,uCAAU,QAAO;AACnC,MAAM,QAAQ,uCAAU,QAAO;AAC/B,MAAM,QAAQ,QAAQ,IAAI,mBAAmB;AAC7C,MAAM,kBAAkB,OAAO,WAAW;AAC1C,MAAM,QAAQ,SAAS,CAAC;AACxB,MAAM,WAAW,SAAS;AAE1B,MAAM,QAAQ,QAAQ,IAAI,aAG7B,YAAY,MAEV,YAAY,IAAI,MAChB,QACF;AAEJ,MAAM,OAAO,MAAM;AAAC;AACb,MAAM,4BAA4B,QAAQ,OAAO,QAAQ,YAAY;AACrE,MAAM,WAAW,OAAO,cAAc,eAAe,SAAS,KAAK,UAAU,aAAa,EAAE;AAC5F,MAAM,iBAAiB,YAAY,kBAAkB;AACrD,MAAM,cAAc,CAAC,SAAS;",
4
+ "sourcesContent": ["import { useEffect, useLayoutEffect } from 'react'\nimport { Platform } from 'react-native'\n\nexport const isAndroid = Platform?.OS === 'android'\nexport const isIOS = Platform?.OS === 'ios'\nexport const isWeb = process.env.TAMAGUI_TARGET === 'web'\nexport const isWindowDefined = typeof window !== 'undefined'\nexport const isSSR = isWeb && !isWindowDefined\nexport const isClient = isWeb && isWindowDefined\n\n// may want to move to VITE_RSC_BUILD\nexport const isRSC = process.env.ENABLE_RSC\n ? // note this is statically analyzed so no funny business, just access it without optional chaining\n // @ts-ignore\n import.meta.env\n ? // @ts-ignore\n import.meta.env.SSR\n : false\n : false\n\nconst idFn = () => {}\nexport const useIsomorphicLayoutEffect = isRSC ? idFn : isSSR ? useEffect : useLayoutEffect\nexport const isChrome = typeof navigator !== 'undefined' && /Chrome/.test(navigator.userAgent || '')\nexport const isWebTouchable = isClient && 'ontouchstart' in window\nexport const isTouchable = !isWeb || isWebTouchable\n"],
5
+ "mappings": "AAAA;AAAA;AACA;AAEO,MAAM,YAAY,uCAAU,QAAO;AACnC,MAAM,QAAQ,uCAAU,QAAO;AAC/B,MAAM,QAAQ,QAAQ,IAAI,mBAAmB;AAC7C,MAAM,kBAAkB,OAAO,WAAW;AAC1C,MAAM,QAAQ,SAAS,CAAC;AACxB,MAAM,WAAW,SAAS;AAG1B,MAAM,QAAQ,QAAQ,IAAI,aAG7B,YAAY,MAEV,YAAY,IAAI,MAChB,QACF;AAEJ,MAAM,OAAO,MAAM;AAAC;AACb,MAAM,4BAA4B,QAAQ,OAAO,QAAQ,YAAY;AACrE,MAAM,WAAW,OAAO,cAAc,eAAe,SAAS,KAAK,UAAU,aAAa,EAAE;AAC5F,MAAM,iBAAiB,YAAY,kBAAkB;AACrD,MAAM,cAAc,CAAC,SAAS;",
6
6
  "names": []
7
7
  }
@@ -18,7 +18,8 @@ import React, {
18
18
  forwardRef,
19
19
  memo,
20
20
  useCallback,
21
- useContext
21
+ useContext,
22
+ useEffect
22
23
  } from "react";
23
24
  import { StyleSheet, Text, View } from "react-native";
24
25
  import { getConfig, onConfiguredOnce } from "./config";
@@ -30,12 +31,15 @@ import { assignNativePropsToWeb } from "./helpers/assignNativePropsToWeb";
30
31
  import { getReturnVariablesAs } from "./helpers/createPropMapper";
31
32
  import { createShallowUpdate } from "./helpers/createShallowUpdate";
32
33
  import { extendStaticConfig, parseStaticConfig } from "./helpers/extendStaticConfig";
33
- import { insertSplitStyles, useSplitStyles } from "./helpers/getSplitStyles";
34
+ import {
35
+ getSubStyle,
36
+ insertSplitStyles,
37
+ useSplitStyles
38
+ } from "./helpers/getSplitStyles";
34
39
  import { getAllSelectors } from "./helpers/insertStyleRule";
35
40
  import { mergeProps } from "./helpers/mergeProps";
36
41
  import { proxyThemeVariables } from "./helpers/proxyThemeVariables";
37
- import { useFeatures } from "./hooks/useFeatures";
38
- import { mediaState } from "./hooks/useMedia";
42
+ import { addMediaQueryListener, mediaState, removeMediaQueryListener } from "./hooks/useMedia";
39
43
  import { usePressable } from "./hooks/usePressable";
40
44
  import { useServerRef, useServerState } from "./hooks/useServerHooks";
41
45
  import { getThemeManager, useTheme } from "./hooks/useTheme";
@@ -68,6 +72,7 @@ function mergeShorthands({ defaultProps }, { shorthands }) {
68
72
  }
69
73
  let initialTheme;
70
74
  let config;
75
+ let mediaPropNames = [];
71
76
  function createComponent(configIn, ParentComponent) {
72
77
  const staticConfig = (() => {
73
78
  const next = extendStaticConfig(configIn, ParentComponent);
@@ -87,7 +92,7 @@ function createComponent(configIn, ParentComponent) {
87
92
  let tamaguiDefaultProps;
88
93
  let initialSplitStyles;
89
94
  const component = forwardRef((propsIn, forwardedRef) => {
90
- var _a, _b, _c, _d;
95
+ var _a, _b, _c, _d, _e, _f, _g;
91
96
  let props;
92
97
  if (tamaguiDefaultProps && !propsIn.asChild) {
93
98
  props = mergeProps(tamaguiDefaultProps, propsIn)[0];
@@ -136,23 +141,54 @@ function createComponent(configIn, ParentComponent) {
136
141
  }
137
142
  }
138
143
  }
139
- const { viewProps: viewPropsIn, pseudos, medias, style, classNames } = splitStyles;
144
+ const { viewProps: viewPropsIn, pseudos, medias, style, classNames, mediaKeys } = splitStyles;
145
+ useIsomorphicLayoutEffect(() => {
146
+ for (const key of mediaKeys) {
147
+ addMediaQueryListener(key, forceUpdate);
148
+ }
149
+ return () => {
150
+ for (const key of mediaKeys) {
151
+ removeMediaQueryListener(key, forceUpdate);
152
+ }
153
+ };
154
+ }, [mediaKeys.join(",")]);
140
155
  const useAnimations = (_a = tamaguiConfig == null ? void 0 : tamaguiConfig.animations) == null ? void 0 : _a.useAnimations;
141
156
  const isAnimated = !!(useAnimations && props.animation);
142
157
  const hasEnterStyle = !!props.enterStyle;
143
158
  const animationFeatureStylesIn = props.animation ? { ...defaultNativeStyle, ...style } : null;
144
- const features = useFeatures(props, {
145
- forceUpdate,
146
- setStateShallow,
147
- useAnimations,
148
- state,
149
- style: animationFeatureStylesIn,
150
- pseudos,
151
- staticConfig,
152
- theme,
153
- hostRef,
154
- onDidAnimate: props.onDidAnimate
155
- });
159
+ const propsWithAnimation = props;
160
+ if (!isRSC && isAnimated) {
161
+ const animationState = useAnimations(propsWithAnimation, {
162
+ state,
163
+ pseudos,
164
+ onDidAnimate: props.onDidAnimate,
165
+ hostRef,
166
+ staticConfig,
167
+ getStyle({ isExiting, isEntering, exitVariant, enterVariant } = {}) {
168
+ var _a2, _b2, _c2, _d2;
169
+ const style2 = animationFeatureStylesIn;
170
+ const enterStyle = isEntering ? enterVariant && ((_a2 = staticConfig.variants) == null ? void 0 : _a2[enterVariant]["true"]) ? getSubStyle("", (_b2 = staticConfig.variants) == null ? void 0 : _b2[enterVariant]["true"], staticConfig, theme, props, state, tamaguiConfig) || pseudos.enterStyle : pseudos.enterStyle : null;
171
+ const exitStyle = isExiting ? exitVariant && ((_c2 = staticConfig.variants) == null ? void 0 : _c2[exitVariant]["true"]) ? getSubStyle("", (_d2 = staticConfig.variants) == null ? void 0 : _d2[exitVariant]["true"], staticConfig, theme, props, state, tamaguiConfig) || pseudos.exitStyle : pseudos.exitStyle : null;
172
+ ensureBaseHasDefaults(style2, pseudos.hoverStyle, pseudos.focusStyle, pseudos.pressStyle, pseudos.pressStyle);
173
+ enterStyle && isEntering && merge(style2, enterStyle);
174
+ state.hover && pseudos.hoverStyle && merge(style2, pseudos.hoverStyle);
175
+ state.focus && pseudos.focusStyle && merge(style2, pseudos.focusStyle);
176
+ state.press && pseudos.pressStyle && merge(style2, pseudos.pressStyle);
177
+ exitStyle && isExiting && merge(style2, exitStyle);
178
+ if (process.env.NODE_ENV === "development") {
179
+ if (props["debug"]) {
180
+ console.log("animation style", style2);
181
+ }
182
+ }
183
+ return style2;
184
+ }
185
+ });
186
+ if (animationState !== state.animation) {
187
+ setStateShallow({
188
+ animation: animationState
189
+ });
190
+ }
191
+ }
156
192
  const {
157
193
  tag,
158
194
  hitSlop,
@@ -284,7 +320,14 @@ function createComponent(configIn, ParentComponent) {
284
320
  onStartShouldSetResponderCapture
285
321
  });
286
322
  const platformMethodsRef = usePlatformMethods(viewProps);
287
- const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef);
323
+ const shouldSetMounted = Boolean(isClient && (hasEnterStyle || props.animation) && !state.mounted);
324
+ const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef, shouldSetMounted ? () => {
325
+ setTimeout(() => {
326
+ setStateShallow({
327
+ mounted: true
328
+ });
329
+ }, 10);
330
+ } : void 0);
288
331
  viewProps.ref = setRef;
289
332
  }
290
333
  if (props.href != void 0 && hrefAttrs != void 0) {
@@ -329,26 +372,13 @@ function createComponent(configIn, ParentComponent) {
329
372
  }
330
373
  });
331
374
  }
332
- const internal = useServerRef();
333
- if (!internal.current) {
334
- internal.current = {
335
- isMounted: true
336
- };
375
+ if (!isRSC) {
376
+ useEffect(() => {
377
+ return () => {
378
+ mouseUps.delete(unPress);
379
+ };
380
+ }, []);
337
381
  }
338
- useIsomorphicLayoutEffect(() => {
339
- if (isClient && (hasEnterStyle || props.animation) && !state.mounted) {
340
- setStateShallow({
341
- mounted: true
342
- });
343
- }
344
- internal.current.isMounted = true;
345
- return () => {
346
- var _a2;
347
- mouseUps.delete(unPress);
348
- internal.current.isMounted = false;
349
- (_a2 = internal.current.unmountEffects) == null ? void 0 : _a2.forEach((cb) => cb());
350
- };
351
- }, [hasEnterStyle, props.animation]);
352
382
  let styles;
353
383
  const animationStyles = state.animation ? state.animation.style : null;
354
384
  if (isStringElement && shouldAvoidClasses && !shouldForcePseudo) {
@@ -365,11 +395,10 @@ function createComponent(configIn, ParentComponent) {
365
395
  ];
366
396
  if (!animationStyles && initialSplitStyles) {
367
397
  const initPseudos = initialSplitStyles.pseudos;
368
- const force = shouldForcePseudo;
369
398
  !state.mounted && addPseudoToStyles(styles, initPseudos, pseudos, "enterStyle");
370
- state.hover && addPseudoToStyles(styles, initPseudos, pseudos, "hoverStyle", force);
371
- state.focus && addPseudoToStyles(styles, initPseudos, pseudos, "focusStyle", force);
372
- state.press && addPseudoToStyles(styles, initPseudos, pseudos, "pressStyle", force);
399
+ state.hover && addPseudoToStyles(styles, initPseudos, pseudos, "hoverStyle", shouldForcePseudo);
400
+ state.focus && addPseudoToStyles(styles, initPseudos, pseudos, "focusStyle", shouldForcePseudo);
401
+ state.press && addPseudoToStyles(styles, initPseudos, pseudos, "pressStyle", shouldForcePseudo);
373
402
  }
374
403
  if (shouldForcePseudo) {
375
404
  const next = {};
@@ -413,7 +442,31 @@ function createComponent(configIn, ParentComponent) {
413
442
  viewProps.className = className;
414
443
  }
415
444
  viewProps.style = style2;
416
- } else {
445
+ }
446
+ if (process.env.TAMAGUI_TARGET === "native") {
447
+ if (splitStyles.fontFamily) {
448
+ const faceInfo = (_b = config.fontsParsed[splitStyles.fontFamily]) == null ? void 0 : _b.face;
449
+ if (faceInfo) {
450
+ const [weight, style2] = (() => {
451
+ var _a2, _b2;
452
+ let weight2;
453
+ let style3;
454
+ for (let i = styles.length; i >= 0; i--) {
455
+ weight2 ??= (_a2 = styles[i]) == null ? void 0 : _a2.fontWeight;
456
+ style3 ??= (_b2 = styles[i]) == null ? void 0 : _b2.fontStyle;
457
+ }
458
+ return [weight2 || "400", style3 || "normal"];
459
+ })();
460
+ const overrideFace = (_d = (_c = faceInfo[weight]) == null ? void 0 : _c[style2]) == null ? void 0 : _d.val;
461
+ if (overrideFace) {
462
+ for (const style3 of styles) {
463
+ if (style3 == null ? void 0 : style3.fontFamily) {
464
+ style3.fontFamily = overrideFace;
465
+ }
466
+ }
467
+ }
468
+ }
469
+ }
417
470
  viewProps.style = styles;
418
471
  }
419
472
  const initialPseudos = initialSplitStyles == null ? void 0 : initialSplitStyles.pseudos;
@@ -426,8 +479,6 @@ function createComponent(configIn, ParentComponent) {
426
479
  const pressOutKey = handlesPressEvents ? "onPressOut" : "onMouseUp";
427
480
  const shouldAttach = !asChild && (attachPress || attachHover || "pressStyle" in props || "onPress" in props || "onPressIn" in props || "onPressOut" in props || isWeb && ("hoverStyle" in props || "onHoverIn" in props || "onHoverOut" in props || "onMouseEnter" in props || "onMouseLeave" in props));
428
481
  const unPress = useCallback(() => {
429
- if (!internal.current.isMounted)
430
- return;
431
482
  setStateShallow({
432
483
  press: false,
433
484
  pressIn: false
@@ -490,7 +541,7 @@ function createComponent(configIn, ParentComponent) {
490
541
  } : null,
491
542
  ...!isWeb && {
492
543
  cancelable: !props.rejectResponderTermination,
493
- disabled: props.disabled !== null ? props.disabled : (_b = props.accessibilityState) == null ? void 0 : _b.disabled,
544
+ disabled: props.disabled !== null ? props.disabled : (_e = props.accessibilityState) == null ? void 0 : _e.disabled,
494
545
  hitSlop: props.hitSlop,
495
546
  delayLongPress: props.delayLongPress,
496
547
  delayPressIn: props.delayPressIn,
@@ -500,7 +551,7 @@ function createComponent(configIn, ParentComponent) {
500
551
  }
501
552
  } : null;
502
553
  let space = spaceProp;
503
- if (features.enabled.mediaQuery) {
554
+ if (mediaKeys.length) {
504
555
  for (const key in mediaState) {
505
556
  if (!mediaState[key])
506
557
  continue;
@@ -577,7 +628,7 @@ function createComponent(configIn, ParentComponent) {
577
628
  content = createElement(elementType, viewProps, childEls);
578
629
  if (process.env.TAMAGUI_TARGET === "web") {
579
630
  const isAnimatedRNWView = isAnimated && typeof elementType !== "string";
580
- const shouldWrapWithComponentTheme = isAnimatedRNWView && getReturnVariablesAs(props, splitStyleState) === "non-color-value";
631
+ const shouldWrapWithComponentTheme = !!theme.className && isAnimatedRNWView && getReturnVariablesAs(props, splitStyleState) === "non-color-value";
581
632
  const shouldWrapWithHover = Boolean(events || isRSC) && attachHover;
582
633
  if (shouldWrapWithHover || shouldWrapWithComponentTheme) {
583
634
  const themeClassName = shouldWrapWithComponentTheme ? `${theme.className}` : "";
@@ -604,12 +655,12 @@ function createComponent(configIn, ParentComponent) {
604
655
  console.log("children", content);
605
656
  console.groupEnd();
606
657
  if (typeof window !== "undefined") {
607
- console.log({ state, shouldProvideThemeManager, tamaguiDefaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: (_c = props.className) == null ? void 0 : _c.split(" "), classNamesOut: (_d = viewProps.className) == null ? void 0 : _d.split(" "), events, shouldAttach, styles, pseudos, content, childEls, shouldAvoidClasses, avoidClasses, animation: props.animation, style, defaultNativeStyle, initialSplitStyles, ...typeof window !== "undefined" ? { theme, themeClassName: theme.className, staticConfig, tamaguiConfig, events, shouldAvoidClasses, shouldForcePseudo, classNames: Object.fromEntries(Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])) } : null });
658
+ console.log({ state, shouldProvideThemeManager, tamaguiDefaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: (_f = props.className) == null ? void 0 : _f.split(" "), classNamesOut: (_g = viewProps.className) == null ? void 0 : _g.split(" "), events, shouldAttach, styles, pseudos, content, childEls, shouldAvoidClasses, avoidClasses, animation: props.animation, style, defaultNativeStyle, initialSplitStyles, ...typeof window !== "undefined" ? { theme, themeClassName: theme.className, staticConfig, tamaguiConfig, events, shouldAvoidClasses, shouldForcePseudo, classNames: Object.fromEntries(Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])) } : null });
608
659
  }
609
660
  console.groupEnd();
610
661
  }
611
662
  }
612
- return !isRSC && features.elements.length ? /* @__PURE__ */ React.createElement(React.Fragment, null, features.elements, content) : content;
663
+ return content;
613
664
  });
614
665
  if (staticConfig.componentName) {
615
666
  component.displayName = staticConfig.componentName;
@@ -645,7 +696,7 @@ function createComponent(configIn, ParentComponent) {
645
696
  resolveVariablesAs: "both",
646
697
  keepVariantsAsProps: true
647
698
  }, void 0, void 0, debug);
648
- const [defaults, defaultsClassnames] = mergeProps(component.defaultProps, initialSplitStyles.viewProps, true);
699
+ const [defaults2, defaultsClassnames] = mergeProps(component.defaultProps, initialSplitStyles.viewProps, true);
649
700
  initialSplitStyles.classNames = {
650
701
  ...parentClassNames,
651
702
  ...defaultsClassnames,
@@ -659,7 +710,7 @@ function createComponent(configIn, ParentComponent) {
659
710
  if (validPseudoKeys[key])
660
711
  continue;
661
712
  if (typeof val === "string" && val[0] === "$" || !validStyles2[key]) {
662
- defaults[key] = val;
713
+ defaults2[key] = val;
663
714
  } else {
664
715
  defaultNativeStyle[key] = val;
665
716
  }
@@ -668,8 +719,8 @@ function createComponent(configIn, ParentComponent) {
668
719
  defaultNativeStyleSheet = StyleSheet.create({
669
720
  base: defaultNativeStyle
670
721
  });
671
- if (Object.keys(defaults).length) {
672
- tamaguiDefaultProps = defaults;
722
+ if (Object.keys(defaults2).length) {
723
+ tamaguiDefaultProps = defaults2;
673
724
  }
674
725
  if (process.env.NODE_ENV === "development" && debug) {
675
726
  if (process.env.IS_STATIC !== "is_static") {
@@ -678,7 +729,7 @@ function createComponent(configIn, ParentComponent) {
678
729
  initialSplitStyles,
679
730
  tamaguiDefaultProps,
680
731
  defaultNativeStyle,
681
- defaults,
732
+ defaults: defaults2,
682
733
  defaultPropsIn
683
734
  });
684
735
  }
@@ -893,6 +944,69 @@ function mergeConfigDefaultProps(name, props, configDefaults, parentNames, conf)
893
944
  }
894
945
  return props;
895
946
  }
947
+ const defaults = {
948
+ left: 0,
949
+ right: 0,
950
+ top: 0,
951
+ bottom: 0,
952
+ opacity: 1,
953
+ translateX: 0,
954
+ translateY: 0,
955
+ skew: 0,
956
+ skewX: 0,
957
+ skewY: 0,
958
+ scale: 1,
959
+ rotate: "0deg",
960
+ rotateY: "0deg",
961
+ rotateX: "0deg"
962
+ };
963
+ function ensureBaseHasDefaults(base, ...pseudos) {
964
+ for (const pseudo of pseudos) {
965
+ if (!pseudo)
966
+ continue;
967
+ for (const key in pseudo) {
968
+ const val = pseudo[key];
969
+ if (key === "transform") {
970
+ if (typeof val === "string") {
971
+ continue;
972
+ }
973
+ for (const t of val) {
974
+ const tkey = Object.keys(t)[0];
975
+ const defaultVal = defaults[tkey];
976
+ const tDefaultVal = { [tkey]: defaultVal };
977
+ if (!base.transform) {
978
+ base.transform = [tDefaultVal];
979
+ } else {
980
+ if (!base.transform.find((x) => x[tkey])) {
981
+ base.transform.push(tDefaultVal);
982
+ }
983
+ }
984
+ }
985
+ } else {
986
+ if (!(key in base)) {
987
+ base[key] = defaults[key];
988
+ }
989
+ }
990
+ }
991
+ }
992
+ }
993
+ function merge(base, next) {
994
+ if (!next.transform || !base.transform) {
995
+ Object.assign(base, next);
996
+ return;
997
+ }
998
+ const { transform, ...rest } = next;
999
+ Object.assign(base, rest);
1000
+ for (const t of transform) {
1001
+ const key = Object.keys(t)[0];
1002
+ const existing = base.transform.find((x) => key in x);
1003
+ if (existing) {
1004
+ existing[key] = t[key];
1005
+ } else {
1006
+ base.transform.push(t);
1007
+ }
1008
+ }
1009
+ }
896
1010
  export {
897
1011
  Spacer,
898
1012
  Unspaced,