@hanzogui/web 7.3.2 → 8.0.0
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.
- package/.turbo/turbo-build.log +2 -0
- package/dist/cjs/_withStableStyle.cjs +2 -2
- package/dist/cjs/_withStableStyle.native.js +2 -2
- package/dist/cjs/_withStableStyle.native.js.map +1 -1
- package/dist/cjs/config.cjs +18 -10
- package/dist/cjs/config.native.js +19 -10
- package/dist/cjs/config.native.js.map +1 -1
- package/dist/cjs/constants/constants.cjs +1 -1
- package/dist/cjs/constants/constants.native.js +1 -1
- package/dist/cjs/constants/constants.native.js.map +1 -1
- package/dist/cjs/createComponent.cjs +68 -28
- package/dist/cjs/createComponent.native.js +75 -30
- package/dist/cjs/createComponent.native.js.map +1 -1
- package/dist/cjs/createGui.cjs +1 -1
- package/dist/cjs/createGui.native.js +1 -1
- package/dist/cjs/createGui.native.js.map +1 -1
- package/dist/cjs/eventHandling.cjs +2 -2
- package/dist/cjs/eventHandling.native.js +73 -54
- package/dist/cjs/eventHandling.native.js.map +1 -1
- package/dist/cjs/helpers/createDesignSystem.cjs +2 -2
- package/dist/cjs/helpers/defaultAnimationDriver.cjs +1 -1
- package/dist/cjs/helpers/defaultAnimationDriver.native.js +1 -1
- package/dist/cjs/helpers/expandStyle.cjs +46 -5
- package/dist/cjs/helpers/expandStyle.native.js +36 -30
- package/dist/cjs/helpers/expandStyle.native.js.map +1 -1
- package/dist/cjs/helpers/getGroupPropParts.cjs +1 -1
- package/dist/cjs/helpers/getGroupPropParts.native.js +1 -1
- package/dist/cjs/helpers/getSplitStyles.cjs +76 -31
- package/dist/cjs/helpers/getSplitStyles.native.js +140 -85
- package/dist/cjs/helpers/getSplitStyles.native.js.map +1 -1
- package/dist/cjs/helpers/getTokenForKey.cjs +5 -5
- package/dist/cjs/helpers/getTokenForKey.native.js +5 -5
- package/dist/cjs/helpers/getTokenForKey.native.js.map +1 -1
- package/dist/cjs/helpers/getVariantExtras.cjs +7 -3
- package/dist/cjs/helpers/getVariantExtras.native.js +7 -3
- package/dist/cjs/helpers/getVariantExtras.native.js.map +1 -1
- package/dist/cjs/helpers/insertStyleRule.cjs +4 -4
- package/dist/cjs/helpers/insertStyleRule.native.js +3 -3
- package/dist/cjs/helpers/insertStyleRule.native.js.map +1 -1
- package/dist/cjs/helpers/mainThreadPressEvents.native.js +32 -4
- package/dist/cjs/helpers/mainThreadPressEvents.native.js.map +1 -1
- package/dist/cjs/helpers/normalizeStyle.cjs +22 -1
- package/dist/cjs/helpers/normalizeStyle.native.js +41 -1
- package/dist/cjs/helpers/normalizeStyle.native.js.map +1 -1
- package/dist/cjs/helpers/platformResolveValue.cjs +1 -1
- package/dist/cjs/helpers/platformResolveValue.native.js +1 -1
- package/dist/cjs/helpers/platformResolveValue.native.js.map +1 -1
- package/dist/cjs/helpers/pointerEvents.native.js +26 -20
- package/dist/cjs/helpers/pointerEvents.native.js.map +1 -1
- package/dist/cjs/helpers/propMapper.cjs +31 -7
- package/dist/cjs/helpers/propMapper.native.js +70 -20
- package/dist/cjs/helpers/propMapper.native.js.map +1 -1
- package/dist/cjs/helpers/resolveSafeArea.native.js +1 -1
- package/dist/cjs/helpers/resolveSafeArea.native.js.map +1 -1
- package/dist/cjs/helpers/styleOriginalValues.cjs +28 -0
- package/dist/cjs/helpers/styleOriginalValues.native.js +31 -0
- package/dist/cjs/helpers/styleOriginalValues.native.js.map +1 -0
- package/dist/cjs/helpers/styleProvenance.cjs +43 -0
- package/dist/cjs/helpers/styleProvenance.native.js +46 -0
- package/dist/cjs/helpers/styleProvenance.native.js.map +1 -0
- package/dist/cjs/helpers/wrapStyleTags.cjs +35 -11
- package/dist/cjs/helpers/wrapStyleTags.native.js.map +1 -1
- package/dist/cjs/hooks/getThemeProxied.cjs +1 -1
- package/dist/cjs/hooks/getThemeProxied.native.js +4 -4
- package/dist/cjs/hooks/getThemeProxied.native.js.map +1 -1
- package/dist/cjs/hooks/useComponentState.cjs +29 -3
- package/dist/cjs/hooks/useComponentState.native.js +30 -4
- package/dist/cjs/hooks/useComponentState.native.js.map +1 -1
- package/dist/cjs/hooks/useMedia.cjs +107 -42
- package/dist/cjs/hooks/useMedia.native.js +149 -60
- package/dist/cjs/hooks/useMedia.native.js.map +1 -1
- package/dist/cjs/hooks/useTheme.cjs +18 -5
- package/dist/cjs/hooks/useTheme.native.js +19 -5
- package/dist/cjs/hooks/useTheme.native.js.map +1 -1
- package/dist/cjs/hooks/useThemeState.cjs +143 -72
- package/dist/cjs/hooks/useThemeState.native.js +155 -74
- package/dist/cjs/hooks/useThemeState.native.js.map +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.native.js +3 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/opacityModifier.test-d.cjs +36 -0
- package/dist/cjs/opacityModifier.test-d.native.js +39 -0
- package/dist/cjs/opacityModifier.test-d.native.js.map +1 -0
- package/dist/cjs/styledNonStyleProps.test-d.cjs +63 -0
- package/dist/cjs/styledNonStyleProps.test-d.native.js +66 -0
- package/dist/cjs/styledNonStyleProps.test-d.native.js.map +1 -0
- package/dist/cjs/views/GuiProvider.cjs +2 -2
- package/dist/cjs/views/Text.cjs +1 -0
- package/dist/cjs/views/Text.native.js +1 -0
- package/dist/cjs/views/Text.native.js.map +1 -1
- package/dist/cjs/views/Theme.cjs +1 -1
- package/dist/cjs/views/Theme.native.js +1 -1
- package/dist/cjs/views/Theme.native.js.map +1 -1
- package/dist/esm/_withStableStyle.mjs +2 -2
- package/dist/esm/_withStableStyle.mjs.map +1 -1
- package/dist/esm/_withStableStyle.native.js +2 -2
- package/dist/esm/_withStableStyle.native.js.map +1 -1
- package/dist/esm/config.mjs +18 -11
- package/dist/esm/config.mjs.map +1 -1
- package/dist/esm/config.native.js +19 -11
- package/dist/esm/config.native.js.map +1 -1
- package/dist/esm/constants/constants.mjs +1 -1
- package/dist/esm/constants/constants.native.js +1 -1
- package/dist/esm/constants/constants.native.js.map +1 -1
- package/dist/esm/createComponent.mjs +74 -35
- package/dist/esm/createComponent.mjs.map +1 -1
- package/dist/esm/createComponent.native.js +90 -42
- package/dist/esm/createComponent.native.js.map +1 -1
- package/dist/esm/createGui.mjs +6 -6
- package/dist/esm/createGui.mjs.map +1 -1
- package/dist/esm/createGui.native.js +6 -6
- package/dist/esm/createGui.native.js.map +1 -1
- package/dist/esm/eventHandling.mjs +2 -2
- package/dist/esm/eventHandling.mjs.map +1 -1
- package/dist/esm/eventHandling.native.js +74 -55
- package/dist/esm/eventHandling.native.js.map +1 -1
- package/dist/esm/helpers/createDesignSystem.mjs +2 -2
- package/dist/esm/helpers/createDesignSystem.mjs.map +1 -1
- package/dist/esm/helpers/createDesignSystem.native.js +1 -2
- package/dist/esm/helpers/createDesignSystem.native.js.map +1 -1
- package/dist/esm/helpers/defaultAnimationDriver.mjs +1 -1
- package/dist/esm/helpers/defaultAnimationDriver.mjs.map +1 -1
- package/dist/esm/helpers/defaultAnimationDriver.native.js +1 -1
- package/dist/esm/helpers/expandStyle.mjs +47 -8
- package/dist/esm/helpers/expandStyle.mjs.map +1 -1
- package/dist/esm/helpers/expandStyle.native.js +36 -30
- package/dist/esm/helpers/expandStyle.native.js.map +1 -1
- package/dist/esm/helpers/expandStyles.mjs.map +1 -1
- package/dist/esm/helpers/expandStyles.native.js.map +1 -1
- package/dist/esm/helpers/getGroupPropParts.mjs +1 -1
- package/dist/esm/helpers/getGroupPropParts.mjs.map +1 -1
- package/dist/esm/helpers/getGroupPropParts.native.js +1 -1
- package/dist/esm/helpers/getSplitStyles.mjs +86 -45
- package/dist/esm/helpers/getSplitStyles.mjs.map +1 -1
- package/dist/esm/helpers/getSplitStyles.native.js +146 -98
- package/dist/esm/helpers/getSplitStyles.native.js.map +1 -1
- package/dist/esm/helpers/getThemeCSSRules.mjs +1 -1
- package/dist/esm/helpers/getThemeCSSRules.mjs.map +1 -1
- package/dist/esm/helpers/getTokenForKey.mjs +5 -5
- package/dist/esm/helpers/getTokenForKey.mjs.map +1 -1
- package/dist/esm/helpers/getTokenForKey.native.js +5 -5
- package/dist/esm/helpers/getTokenForKey.native.js.map +1 -1
- package/dist/esm/helpers/getVariantExtras.mjs +7 -3
- package/dist/esm/helpers/getVariantExtras.mjs.map +1 -1
- package/dist/esm/helpers/getVariantExtras.native.js +7 -3
- package/dist/esm/helpers/getVariantExtras.native.js.map +1 -1
- package/dist/esm/helpers/insertStyleRule.mjs +4 -6
- package/dist/esm/helpers/insertStyleRule.mjs.map +1 -1
- package/dist/esm/helpers/insertStyleRule.native.js +0 -26
- package/dist/esm/helpers/insertStyleRule.native.js.map +1 -1
- package/dist/esm/helpers/isActivePlatform.mjs.map +1 -1
- package/dist/esm/helpers/isActivePlatform.native.js.map +1 -1
- package/dist/esm/helpers/log.mjs.map +1 -1
- package/dist/esm/helpers/log.native.js.map +1 -1
- package/dist/esm/helpers/mainThreadPressEvents.native.js +32 -4
- package/dist/esm/helpers/mainThreadPressEvents.native.js.map +1 -1
- package/dist/esm/helpers/normalizeStyle.mjs +22 -1
- package/dist/esm/helpers/normalizeStyle.mjs.map +1 -1
- package/dist/esm/helpers/normalizeStyle.native.js +41 -1
- package/dist/esm/helpers/normalizeStyle.native.js.map +1 -1
- package/dist/esm/helpers/platformResolveValue.mjs +1 -1
- package/dist/esm/helpers/platformResolveValue.mjs.map +1 -1
- package/dist/esm/helpers/platformResolveValue.native.js +1 -1
- package/dist/esm/helpers/platformResolveValue.native.js.map +1 -1
- package/dist/esm/helpers/pointerEvents.native.js +26 -20
- package/dist/esm/helpers/pointerEvents.native.js.map +1 -1
- package/dist/esm/helpers/propMapper.mjs +32 -11
- package/dist/esm/helpers/propMapper.mjs.map +1 -1
- package/dist/esm/helpers/propMapper.native.js +71 -22
- package/dist/esm/helpers/propMapper.native.js.map +1 -1
- package/dist/esm/helpers/resolveSafeArea.native.js +1 -1
- package/dist/esm/helpers/resolveSafeArea.native.js.map +1 -1
- package/dist/esm/helpers/skipProps.mjs +0 -1
- package/dist/esm/helpers/skipProps.mjs.map +1 -1
- package/dist/esm/helpers/skipProps.native.js +0 -1
- package/dist/esm/helpers/skipProps.native.js.map +1 -1
- package/dist/esm/helpers/styleOriginalValues.mjs +3 -0
- package/dist/esm/helpers/styleOriginalValues.mjs.map +1 -0
- package/dist/esm/helpers/styleOriginalValues.native.js +3 -0
- package/dist/esm/helpers/styleOriginalValues.native.js.map +1 -0
- package/dist/esm/helpers/styleProvenance.mjs +16 -0
- package/dist/esm/helpers/styleProvenance.mjs.map +1 -0
- package/dist/esm/helpers/styleProvenance.native.js +16 -0
- package/dist/esm/helpers/styleProvenance.native.js.map +1 -0
- package/dist/esm/helpers/useRenderElement.mjs.map +1 -1
- package/dist/esm/helpers/useRenderElement.native.js.map +1 -1
- package/dist/esm/helpers/wrapStyleTags.mjs +35 -11
- package/dist/esm/helpers/wrapStyleTags.mjs.map +1 -1
- package/dist/esm/helpers/wrapStyleTags.native.js +0 -2
- package/dist/esm/helpers/wrapStyleTags.native.js.map +1 -1
- package/dist/esm/hooks/getThemeProxied.mjs +2 -5
- package/dist/esm/hooks/getThemeProxied.mjs.map +1 -1
- package/dist/esm/hooks/getThemeProxied.native.js +5 -5
- package/dist/esm/hooks/getThemeProxied.native.js.map +1 -1
- package/dist/esm/hooks/useComponentState.mjs +31 -5
- package/dist/esm/hooks/useComponentState.mjs.map +1 -1
- package/dist/esm/hooks/useComponentState.native.js +32 -6
- package/dist/esm/hooks/useComponentState.native.js.map +1 -1
- package/dist/esm/hooks/useMedia.mjs +108 -43
- package/dist/esm/hooks/useMedia.mjs.map +1 -1
- package/dist/esm/hooks/useMedia.native.js +150 -61
- package/dist/esm/hooks/useMedia.native.js.map +1 -1
- package/dist/esm/hooks/useTheme.mjs +18 -5
- package/dist/esm/hooks/useTheme.mjs.map +1 -1
- package/dist/esm/hooks/useTheme.native.js +19 -5
- package/dist/esm/hooks/useTheme.native.js.map +1 -1
- package/dist/esm/hooks/useThemeState.mjs +141 -70
- package/dist/esm/hooks/useThemeState.mjs.map +1 -1
- package/dist/esm/hooks/useThemeState.native.js +154 -73
- package/dist/esm/hooks/useThemeState.native.js.map +1 -1
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +4 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +4 -4
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/insertFont.mjs.map +1 -1
- package/dist/esm/insertFont.native.js +0 -1
- package/dist/esm/insertFont.native.js.map +1 -1
- package/dist/esm/opacityModifier.test-d.mjs +37 -0
- package/dist/esm/opacityModifier.test-d.mjs.map +1 -0
- package/dist/esm/opacityModifier.test-d.native.js +37 -0
- package/dist/esm/opacityModifier.test-d.native.js.map +1 -0
- package/dist/esm/styledNonStyleProps.test-d.mjs +64 -0
- package/dist/esm/styledNonStyleProps.test-d.mjs.map +1 -0
- package/dist/esm/styledNonStyleProps.test-d.native.js +64 -0
- package/dist/esm/styledNonStyleProps.test-d.native.js.map +1 -0
- package/dist/esm/views/GuiProvider.mjs +2 -2
- package/dist/esm/views/GuiProvider.mjs.map +1 -1
- package/dist/esm/views/GuiProvider.native.js +6 -6
- package/dist/esm/views/GuiProvider.native.js.map +1 -1
- package/dist/esm/views/Text.mjs +1 -0
- package/dist/esm/views/Text.mjs.map +1 -1
- package/dist/esm/views/Text.native.js +1 -0
- package/dist/esm/views/Text.native.js.map +1 -1
- package/dist/esm/views/Theme.mjs +1 -1
- package/dist/esm/views/Theme.mjs.map +1 -1
- package/dist/esm/views/Theme.native.js +1 -1
- package/dist/esm/views/Theme.native.js.map +1 -1
- package/dist/esm/views/ThemeProvider.mjs.map +1 -1
- package/dist/esm/views/ThemeProvider.native.js +2 -4
- package/dist/esm/views/ThemeProvider.native.js.map +1 -1
- package/inject-styles/index.cjs +2 -0
- package/inject-styles/index.js +2 -0
- package/package.json +27 -40
- package/src/_withStableStyle.tsx +9 -3
- package/src/config.ts +24 -14
- package/src/constants/accessibilityDirectMap.tsx +1 -1
- package/src/constants/constants.ts +1 -1
- package/src/createComponent.tsx +161 -26
- package/src/createGui.ts +2 -2
- package/src/eventHandling.native.ts +143 -52
- package/src/eventHandling.ts +4 -2
- package/src/helpers/createDesignSystem.ts +2 -2
- package/src/helpers/createMediaStyle.ts +1 -1
- package/src/helpers/defaultAnimationDriver.tsx +1 -1
- package/src/helpers/expandStyle.ts +108 -40
- package/src/helpers/getGroupPropParts.ts +1 -1
- package/src/helpers/getSplitStyles.tsx +178 -72
- package/src/helpers/getTokenForKey.ts +5 -5
- package/src/helpers/getVariantExtras.tsx +5 -4
- package/src/helpers/insertStyleRule.tsx +7 -7
- package/src/helpers/mainThreadPressEvents.native.ts +42 -2
- package/src/helpers/mergeProps.ts +1 -1
- package/src/helpers/normalizeStyle.ts +23 -1
- package/src/helpers/platformResolveValue.native.ts +4 -1
- package/src/helpers/platformResolveValue.ts +5 -1
- package/src/helpers/pointerEvents.native.ts +26 -19
- package/src/helpers/propMapper.ts +61 -6
- package/src/helpers/resolveSafeArea.native.ts +1 -1
- package/src/helpers/styleOriginalValues.ts +2 -0
- package/src/helpers/styleProvenance.ts +49 -0
- package/src/helpers/wrapStyleTags.tsx +63 -20
- package/src/hooks/getThemeProxied.ts +14 -8
- package/src/hooks/useComponentState.ts +56 -4
- package/src/hooks/useMedia.tsx +156 -43
- package/src/hooks/useTheme.tsx +28 -6
- package/src/hooks/useThemeState.ts +284 -142
- package/src/index.ts +9 -1
- package/src/interfaces/GuiComponentPropsBaseBase.tsx +2 -2
- package/src/opacityModifier.test-d.ts +65 -0
- package/src/styled.tsx +1 -1
- package/src/styledNonStyleProps.test-d.ts +106 -0
- package/src/types.tsx +120 -22
- package/src/views/GuiProvider.tsx +2 -2
- package/src/views/Text.tsx +1 -0
- package/src/views/Theme.tsx +4 -1
- package/tsconfig.json +44 -0
- package/tsconfig.test.json +9 -0
- package/types/_withStableStyle.d.ts.map +1 -1
- package/types/config.d.ts +3 -1
- package/types/config.d.ts.map +1 -1
- package/types/constants/constants.d.ts +1 -1
- package/types/constants/constants.d.ts.map +1 -1
- package/types/createComponent.d.ts.map +1 -1
- package/types/eventHandling.d.ts +2 -2
- package/types/eventHandling.d.ts.map +1 -1
- package/types/eventHandling.native.d.ts +3 -3
- package/types/eventHandling.native.d.ts.map +1 -1
- package/types/helpers/expandStyle.d.ts +2 -1
- package/types/helpers/expandStyle.d.ts.map +1 -1
- package/types/helpers/getSplitStyles.d.ts +4 -2
- package/types/helpers/getSplitStyles.d.ts.map +1 -1
- package/types/helpers/getVariantExtras.d.ts.map +1 -1
- package/types/helpers/mainThreadPressEvents.native.d.ts.map +1 -1
- package/types/helpers/normalizeStyle.d.ts.map +1 -1
- package/types/helpers/platformResolveValue.d.ts.map +1 -1
- package/types/helpers/platformResolveValue.native.d.ts.map +1 -1
- package/types/helpers/pointerEvents.native.d.ts.map +1 -1
- package/types/helpers/propMapper.d.ts.map +1 -1
- package/types/helpers/styleOriginalValues.d.ts +2 -0
- package/types/helpers/styleOriginalValues.d.ts.map +1 -0
- package/types/helpers/styleProvenance.d.ts +11 -0
- package/types/helpers/styleProvenance.d.ts.map +1 -0
- package/types/helpers/wrapStyleTags.d.ts +1 -1
- package/types/helpers/wrapStyleTags.d.ts.map +1 -1
- package/types/hooks/getThemeProxied.d.ts.map +1 -1
- package/types/hooks/useComponentState.d.ts +2 -1
- package/types/hooks/useComponentState.d.ts.map +1 -1
- package/types/hooks/useMedia.d.ts.map +1 -1
- package/types/hooks/useTheme.d.ts +1 -1
- package/types/hooks/useTheme.d.ts.map +1 -1
- package/types/hooks/useThemeState.d.ts +1 -1
- package/types/hooks/useThemeState.d.ts.map +1 -1
- package/types/index.d.ts +3 -3
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/GuiComponentPropsBaseBase.d.ts +2 -2
- package/types/types.d.ts +33 -16
- package/types/types.d.ts.map +1 -1
- package/types/views/Configuration.d.ts +1 -1
- package/types/views/Configuration.d.ts.map +1 -1
- package/types/views/FontLanguage.d.ts +1 -1
- package/types/views/FontLanguage.native.d.ts +1 -2
- package/types/views/FontLanguage.native.d.ts.map +1 -1
- package/types/views/GuiProvider.d.ts +1 -2
- package/types/views/GuiProvider.d.ts.map +1 -1
- package/types/views/GuiRoot.d.ts +1 -1
- package/types/views/GuiRoot.d.ts.map +1 -1
- package/types/views/Slot.d.ts +1 -1
- package/types/views/Text.d.ts.map +1 -1
- package/types/views/Theme.d.ts.map +1 -1
- package/types/views/ThemeProvider.d.ts +1 -1
- package/types/views/ThemeProvider.d.ts.map +1 -1
- package/vitest.config.d.ts +3 -0
- package/vitest.config.d.ts.map +1 -0
- package/vitest.config.ts +14 -0
- package/LICENSE +0 -42
|
@@ -2,7 +2,10 @@ import type { GetStyleState, SplitStyleProps } from '../types'
|
|
|
2
2
|
import { getTokenForKey } from './getTokenForKey'
|
|
3
3
|
import { parseNativeStyle } from './parseNativeStyle'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// includes the optional `/NN` opacity-modifier suffix ($color9/50) so
|
|
6
|
+
// getTokenForKey receives it and can apply the alpha — without it the token
|
|
7
|
+
// resolves but the bare `/50` is left behind in the parsed gradient string
|
|
8
|
+
const tokenPattern = /(\$[\w.-]+(?:\/[\d.]+)?)/g
|
|
6
9
|
|
|
7
10
|
// keys that need native object parsing (DynamicColorIOS support)
|
|
8
11
|
const nativeParseKeys: Record<string, boolean> = {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { GetStyleState, SplitStyleProps } from '../types'
|
|
2
2
|
import { getTokenForKey } from './getTokenForKey'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// includes the optional `/NN` opacity-modifier suffix ($color9/50) so
|
|
5
|
+
// getTokenForKey receives it and can apply the alpha — without it the token
|
|
6
|
+
// resolves but the bare `/50` is left behind in the CSS string, which makes
|
|
7
|
+
// the whole declaration invalid
|
|
8
|
+
const tokenPattern = /(\$[\w.-]+(?:\/[\d.]+)?)/g
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* web: resolves embedded $tokens in compound CSS strings via simple regex replacement.
|
|
@@ -25,13 +25,20 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
25
25
|
onPointerEnter ||
|
|
26
26
|
onPointerLeave
|
|
27
27
|
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
// single ref-bag (was three separate useRef slots) — one hook slot per
|
|
29
|
+
// component instead of three. isInside = pointer within bounds (enter/leave),
|
|
30
|
+
// layout = measured bounds, isCaptured = setPointerCapture state for moves.
|
|
31
|
+
const ref = useRef<{
|
|
32
|
+
isInside: boolean
|
|
33
|
+
layout: { width: number; height: number }
|
|
34
|
+
isCaptured: boolean
|
|
35
|
+
} | null>(null)
|
|
36
|
+
if (!ref.current) {
|
|
37
|
+
ref.current = { isInside: false, layout: { width: 0, height: 0 }, isCaptured: false }
|
|
38
|
+
}
|
|
33
39
|
|
|
34
40
|
if (!hasPointerEvents) return
|
|
41
|
+
const bag = ref.current
|
|
35
42
|
|
|
36
43
|
// create normalized event with setPointerCapture support
|
|
37
44
|
const createNormalizedEvent = (e: any) => {
|
|
@@ -49,10 +56,10 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
49
56
|
nativeEvent: touch,
|
|
50
57
|
target: {
|
|
51
58
|
setPointerCapture: (_pointerId: number) => {
|
|
52
|
-
|
|
59
|
+
bag.isCaptured = true
|
|
53
60
|
},
|
|
54
61
|
releasePointerCapture: (_pointerId: number) => {
|
|
55
|
-
|
|
62
|
+
bag.isCaptured = false
|
|
56
63
|
},
|
|
57
64
|
},
|
|
58
65
|
}
|
|
@@ -69,7 +76,7 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
69
76
|
// pointer up
|
|
70
77
|
if (onPointerUp) {
|
|
71
78
|
viewProps.onTouchEnd = composeEventHandlers(viewProps.onTouchEnd, (e: any) => {
|
|
72
|
-
|
|
79
|
+
bag.isCaptured = false // auto-release on up
|
|
73
80
|
onPointerUp(createNormalizedEvent(e))
|
|
74
81
|
})
|
|
75
82
|
}
|
|
@@ -78,12 +85,12 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
78
85
|
if (onPointerMove) {
|
|
79
86
|
viewProps.onTouchMove = composeEventHandlers(viewProps.onTouchMove, (e: any) => {
|
|
80
87
|
const { locationX, locationY } = e.nativeEvent
|
|
81
|
-
const { width, height } =
|
|
88
|
+
const { width, height } = bag.layout
|
|
82
89
|
const isInBounds =
|
|
83
90
|
locationX >= 0 && locationX <= width && locationY >= 0 && locationY <= height
|
|
84
91
|
|
|
85
92
|
// fire if captured OR in bounds (matches web behavior)
|
|
86
|
-
if (
|
|
93
|
+
if (bag.isCaptured || isInBounds) {
|
|
87
94
|
onPointerMove(createNormalizedEvent(e))
|
|
88
95
|
}
|
|
89
96
|
})
|
|
@@ -92,7 +99,7 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
92
99
|
// pointer cancel
|
|
93
100
|
if (onPointerCancel) {
|
|
94
101
|
viewProps.onTouchCancel = composeEventHandlers(viewProps.onTouchCancel, (e: any) => {
|
|
95
|
-
|
|
102
|
+
bag.isCaptured = false
|
|
96
103
|
onPointerCancel(createNormalizedEvent(e))
|
|
97
104
|
})
|
|
98
105
|
}
|
|
@@ -101,7 +108,7 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
101
108
|
if (onPointerEnter || onPointerLeave || onPointerMove) {
|
|
102
109
|
// track layout for bounds checking
|
|
103
110
|
viewProps.onLayout = composeEventHandlers(viewProps.onLayout, (e: any) => {
|
|
104
|
-
|
|
111
|
+
bag.layout = {
|
|
105
112
|
width: e.nativeEvent.layout.width,
|
|
106
113
|
height: e.nativeEvent.layout.height,
|
|
107
114
|
}
|
|
@@ -112,9 +119,9 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
112
119
|
if (onPointerEnter) {
|
|
113
120
|
viewProps.onTouchStart = composeEventHandlers(viewProps.onTouchStart, (e: any) => {
|
|
114
121
|
const { locationX, locationY } = e.nativeEvent
|
|
115
|
-
const { width, height } =
|
|
122
|
+
const { width, height } = bag.layout
|
|
116
123
|
if (locationX >= 0 && locationX <= width && locationY >= 0 && locationY <= height) {
|
|
117
|
-
|
|
124
|
+
bag.isInside = true
|
|
118
125
|
onPointerEnter(createNormalizedEvent(e))
|
|
119
126
|
}
|
|
120
127
|
})
|
|
@@ -124,18 +131,18 @@ export function usePointerEvents(props: any, viewProps: any) {
|
|
|
124
131
|
if (onPointerLeave) {
|
|
125
132
|
viewProps.onTouchMove = composeEventHandlers(viewProps.onTouchMove, (e: any) => {
|
|
126
133
|
const { locationX, locationY } = e.nativeEvent
|
|
127
|
-
const { width, height } =
|
|
134
|
+
const { width, height } = bag.layout
|
|
128
135
|
const isInside =
|
|
129
136
|
locationX >= 0 && locationX <= width && locationY >= 0 && locationY <= height
|
|
130
|
-
if (
|
|
131
|
-
|
|
137
|
+
if (bag.isInside && !isInside) {
|
|
138
|
+
bag.isInside = false
|
|
132
139
|
onPointerLeave(createNormalizedEvent(e))
|
|
133
140
|
}
|
|
134
141
|
})
|
|
135
142
|
|
|
136
143
|
viewProps.onTouchEnd = composeEventHandlers(viewProps.onTouchEnd, (e: any) => {
|
|
137
|
-
if (
|
|
138
|
-
|
|
144
|
+
if (bag.isInside) {
|
|
145
|
+
bag.isInside = false
|
|
139
146
|
onPointerLeave(createNormalizedEvent(e))
|
|
140
147
|
}
|
|
141
148
|
})
|
|
@@ -24,6 +24,7 @@ import { pseudoDescriptors } from './pseudoDescriptors'
|
|
|
24
24
|
import { resolveCompoundTokens } from './resolveCompoundTokens'
|
|
25
25
|
import { isRemValue, resolveRem } from './resolveRem'
|
|
26
26
|
import { skipProps } from './skipProps'
|
|
27
|
+
import { styleOriginalValues } from './styleOriginalValues'
|
|
27
28
|
|
|
28
29
|
export { getTokenForKey } from './getTokenForKey'
|
|
29
30
|
|
|
@@ -42,11 +43,36 @@ export const propMapper: PropMapper = (key, value, styleState, disabled, map) =>
|
|
|
42
43
|
const { conf, styleProps, staticConfig } = styleState
|
|
43
44
|
const { variants } = staticConfig
|
|
44
45
|
|
|
46
|
+
// "unset" is a CSS-wide keyword: valid CSS on web, but React Native
|
|
47
|
+
// style props reject it (e.g. aspectRatio throws "must be a number, a
|
|
48
|
+
// ratio string or `auto`"). On native, clear anything an earlier prop or
|
|
49
|
+
// styled default already merged for this key — matching web, where unset
|
|
50
|
+
// resets toward initial — then drop the value so RN never sees it.
|
|
51
|
+
if (process.env.GUI_TARGET === 'native' && value === 'unset') {
|
|
52
|
+
const expandedKey =
|
|
53
|
+
(!styleProps.disableExpandShorthands && conf.shorthands[key]) || key
|
|
54
|
+
const expanded = styleProps.noExpand
|
|
55
|
+
? null
|
|
56
|
+
: expandStyle(expandedKey, value, conf.settings.styleCompat || 'web')
|
|
57
|
+
if (styleState.style) {
|
|
58
|
+
if (expanded) {
|
|
59
|
+
for (const [nkey] of expanded) {
|
|
60
|
+
delete styleState.style[nkey]
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
delete styleState.style[expandedKey]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
if (!styleProps.noExpand) {
|
|
46
70
|
if (variants && key in variants) {
|
|
47
71
|
const variantValue = resolveVariants(key, value, styleProps, styleState, '')
|
|
48
72
|
if (variantValue) {
|
|
49
|
-
variantValue.forEach(([key, value]) =>
|
|
73
|
+
variantValue.forEach(([key, value, originalValue]) => {
|
|
74
|
+
map(key, value, originalValue)
|
|
75
|
+
})
|
|
50
76
|
return
|
|
51
77
|
}
|
|
52
78
|
}
|
|
@@ -105,13 +131,15 @@ export const propMapper: PropMapper = (key, value, styleState, disabled, map) =>
|
|
|
105
131
|
styleState.fontFamily = fontToken
|
|
106
132
|
}
|
|
107
133
|
|
|
108
|
-
const expanded = styleProps.noExpand
|
|
134
|
+
const expanded = styleProps.noExpand
|
|
135
|
+
? null
|
|
136
|
+
: expandStyle(key, value, conf.settings.styleCompat || 'web')
|
|
109
137
|
|
|
110
138
|
if (expanded) {
|
|
111
139
|
const max = expanded.length
|
|
112
140
|
for (let i = 0; i < max; i++) {
|
|
113
|
-
const [nkey, nvalue] = expanded[i]
|
|
114
|
-
map(nkey, nvalue, originalValue)
|
|
141
|
+
const [nkey, nvalue, noriginalValue] = expanded[i]
|
|
142
|
+
map(nkey, nvalue, noriginalValue ?? originalValue)
|
|
115
143
|
}
|
|
116
144
|
} else {
|
|
117
145
|
map(key, value, originalValue)
|
|
@@ -205,13 +233,14 @@ const resolveVariants: StyleResolver = (
|
|
|
205
233
|
console.info(` expanding styles from `, variantValue, `to`, expanded)
|
|
206
234
|
}
|
|
207
235
|
const next = Object.entries(expanded)
|
|
236
|
+
const originalValues = styleOriginalValues.get(expanded)
|
|
208
237
|
|
|
209
238
|
// store any changed font family (only support variables for now)
|
|
210
239
|
if (fontFamilyResult && fontFamilyResult[0] === '$') {
|
|
211
240
|
setLastFontFamilyToken(getVariableValue(fontFamilyResult))
|
|
212
241
|
}
|
|
213
242
|
|
|
214
|
-
return next
|
|
243
|
+
return next.map(([key, value]) => [key, value, originalValues?.[key]])
|
|
215
244
|
}
|
|
216
245
|
}
|
|
217
246
|
|
|
@@ -249,6 +278,7 @@ const resolveTokensAndVariants: StyleResolver<object> = (
|
|
|
249
278
|
const { conf, staticConfig, debug, theme } = styleState
|
|
250
279
|
const { variants } = staticConfig
|
|
251
280
|
const res = {}
|
|
281
|
+
let originalValues: Record<string, any> | undefined
|
|
252
282
|
|
|
253
283
|
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
254
284
|
console.info(` - resolveTokensAndVariants`, key, value)
|
|
@@ -262,6 +292,9 @@ const resolveTokensAndVariants: StyleResolver<object> = (
|
|
|
262
292
|
continue
|
|
263
293
|
}
|
|
264
294
|
|
|
295
|
+
originalValues ||= {}
|
|
296
|
+
originalValues[subKey] = val
|
|
297
|
+
|
|
265
298
|
// Track context overrides for any key that's in context props (issues #3670, #3676)
|
|
266
299
|
// Store the ORIGINAL token value (like '$8') before resolution so that
|
|
267
300
|
// children's functional variants can look up token values
|
|
@@ -291,13 +324,24 @@ const resolveTokensAndVariants: StyleResolver<object> = (
|
|
|
291
324
|
|
|
292
325
|
// apply, merging sub-styles
|
|
293
326
|
if (variantOut) {
|
|
294
|
-
for (const [key, val] of variantOut) {
|
|
327
|
+
for (const [key, val, originalVal] of variantOut) {
|
|
295
328
|
if (val == null) continue
|
|
296
329
|
if (key in pseudoDescriptors) {
|
|
297
330
|
res[key] ??= {}
|
|
298
331
|
Object.assign(res[key], val)
|
|
332
|
+
const subOriginalValues = styleOriginalValues.get(val)
|
|
333
|
+
if (subOriginalValues) {
|
|
334
|
+
styleOriginalValues.set(res[key], {
|
|
335
|
+
...styleOriginalValues.get(res[key]),
|
|
336
|
+
...subOriginalValues,
|
|
337
|
+
})
|
|
338
|
+
}
|
|
299
339
|
} else {
|
|
300
340
|
res[key] = val
|
|
341
|
+
if (originalVal !== undefined) {
|
|
342
|
+
originalValues ||= {}
|
|
343
|
+
originalValues[key] = originalVal
|
|
344
|
+
}
|
|
301
345
|
}
|
|
302
346
|
}
|
|
303
347
|
}
|
|
@@ -335,6 +379,13 @@ const resolveTokensAndVariants: StyleResolver<object> = (
|
|
|
335
379
|
// sub-objects: media queries, pseudos, shadowOffset
|
|
336
380
|
res[subKey] ??= {}
|
|
337
381
|
Object.assign(res[subKey], subObject)
|
|
382
|
+
const subOriginalValues = styleOriginalValues.get(subObject)
|
|
383
|
+
if (subOriginalValues) {
|
|
384
|
+
styleOriginalValues.set(res[subKey], {
|
|
385
|
+
...styleOriginalValues.get(res[subKey]),
|
|
386
|
+
...subOriginalValues,
|
|
387
|
+
})
|
|
388
|
+
}
|
|
338
389
|
} else {
|
|
339
390
|
// nullish values cant be tokens, need no extra parsing
|
|
340
391
|
res[subKey] = val
|
|
@@ -354,6 +405,10 @@ const resolveTokensAndVariants: StyleResolver<object> = (
|
|
|
354
405
|
}
|
|
355
406
|
}
|
|
356
407
|
|
|
408
|
+
if (originalValues) {
|
|
409
|
+
styleOriginalValues.set(res, originalValues)
|
|
410
|
+
}
|
|
411
|
+
|
|
357
412
|
return res
|
|
358
413
|
}
|
|
359
414
|
|
|
@@ -10,7 +10,7 @@ export function resolveSafeAreaValue(value: string): number | undefined {
|
|
|
10
10
|
if (!edge) return undefined
|
|
11
11
|
|
|
12
12
|
const g = globalThis as any
|
|
13
|
-
const state = g.
|
|
13
|
+
const state = g.__hanzogui_native_safe_area_state__
|
|
14
14
|
if (state?.enabled && state.initialMetrics) {
|
|
15
15
|
return state.initialMetrics.insets[edge]
|
|
16
16
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// developer-tools contract: exact token provenance for a component's final
|
|
2
|
+
// winning native style object. hanzogui only records it in development when
|
|
3
|
+
// GUI_ENABLE_STYLE_TOKEN_PROVENANCE=1.
|
|
4
|
+
//
|
|
5
|
+
// this is a pure inspection side channel. it records, per resolved style key,
|
|
6
|
+
// which token produced the value and the full theme name that resolved it
|
|
7
|
+
// (e.g. { backgroundColor: { token: '$background', theme: 'light_accent' } }).
|
|
8
|
+
// a literal value produces NO entry, which is how a literal that happens to
|
|
9
|
+
// equal a token value stays distinguishable from the token.
|
|
10
|
+
//
|
|
11
|
+
// the data is attached as a NON-ENUMERABLE, symbol-keyed property so it never
|
|
12
|
+
// changes the style object's enumerable keys or the React Native output, and
|
|
13
|
+
// hanzogui's own rendering never reads it back. this mirrors the
|
|
14
|
+
// `styleOriginalValues` WeakMap precedent (metadata beside the style, keyed off
|
|
15
|
+
// to the side), but uses an own-property so a cross-package consumer can read it
|
|
16
|
+
// without importing hanzogui.
|
|
17
|
+
//
|
|
18
|
+
// consumers read the property by the SAME registered symbol —
|
|
19
|
+
// `Symbol.for(STYLE_TOKEN_PROVENANCE_KEY)` — which shares one global registry
|
|
20
|
+
// per realm, so no shared module import is required.
|
|
21
|
+
|
|
22
|
+
export const STYLE_TOKEN_PROVENANCE_KEY = 'hanzogui.styleTokenProvenance'
|
|
23
|
+
|
|
24
|
+
const provenanceSymbol = /* @__PURE__ */ Symbol.for(STYLE_TOKEN_PROVENANCE_KEY)
|
|
25
|
+
|
|
26
|
+
export type StyleTokenBinding = {
|
|
27
|
+
/** original token string before resolution, e.g. '$background' or '$color9' */
|
|
28
|
+
token: string
|
|
29
|
+
/** full resolved theme name that produced the value, e.g. 'light_accent' */
|
|
30
|
+
theme: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type StyleTokenProvenance = Record<string, StyleTokenBinding>
|
|
34
|
+
|
|
35
|
+
export function setStyleTokenProvenance(style: object, provenance: StyleTokenProvenance) {
|
|
36
|
+
Object.defineProperty(style, provenanceSymbol, {
|
|
37
|
+
value: provenance,
|
|
38
|
+
enumerable: false,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getStyleTokenProvenance(
|
|
45
|
+
style: object | null | undefined
|
|
46
|
+
): StyleTokenProvenance | undefined {
|
|
47
|
+
if (!style) return undefined
|
|
48
|
+
return (style as Record<symbol, StyleTokenProvenance>)[provenanceSymbol]
|
|
49
|
+
}
|
|
@@ -1,31 +1,74 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
1
2
|
import { StyleObjectIdentifier, StyleObjectRules } from '@hanzogui/helpers'
|
|
2
3
|
import type { StyleObject } from '../types'
|
|
3
4
|
|
|
4
5
|
// turns out this is pretty slow, creating a bunch of extra tags...
|
|
5
6
|
|
|
7
|
+
const styleTagCache = new Map<
|
|
8
|
+
string,
|
|
9
|
+
{
|
|
10
|
+
element: ReactNode
|
|
11
|
+
len: number
|
|
12
|
+
first: string | undefined
|
|
13
|
+
last: string | undefined
|
|
14
|
+
}
|
|
15
|
+
>()
|
|
16
|
+
|
|
17
|
+
let clearStyleTagCacheQueued = false
|
|
18
|
+
|
|
19
|
+
function queueStyleTagCacheClear() {
|
|
20
|
+
if (clearStyleTagCacheQueued) return
|
|
21
|
+
|
|
22
|
+
clearStyleTagCacheQueued = true
|
|
23
|
+
queueMicrotask(() => {
|
|
24
|
+
styleTagCache.clear()
|
|
25
|
+
clearStyleTagCacheQueued = false
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getCachedStyleTag(styleObject: StyleObject) {
|
|
30
|
+
const identifier = styleObject[StyleObjectIdentifier]
|
|
31
|
+
const rules = styleObject[StyleObjectRules]
|
|
32
|
+
const cached = styleTagCache.get(identifier)
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
cached &&
|
|
36
|
+
cached.len === rules.length &&
|
|
37
|
+
cached.first === rules[0] &&
|
|
38
|
+
cached.last === rules[rules.length - 1]
|
|
39
|
+
) {
|
|
40
|
+
return cached.element
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const element = (
|
|
44
|
+
<style
|
|
45
|
+
key={identifier}
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
href={`t_${identifier}`}
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
precedence="default"
|
|
50
|
+
// we remove after first render in favor of inserting to a global stylesheet (faster)
|
|
51
|
+
suppressHydrationWarning
|
|
52
|
+
>
|
|
53
|
+
{rules.join('\n')}
|
|
54
|
+
</style>
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
styleTagCache.set(identifier, {
|
|
58
|
+
element,
|
|
59
|
+
len: rules.length,
|
|
60
|
+
first: rules[0],
|
|
61
|
+
last: rules[rules.length - 1],
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return element
|
|
65
|
+
}
|
|
66
|
+
|
|
6
67
|
export function getStyleTags(styles: StyleObject[]) {
|
|
7
68
|
if (process.env.GUI_TARGET !== 'native') {
|
|
8
69
|
if (styles.length) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{styles.map((styleObject) => {
|
|
12
|
-
const identifier = styleObject[StyleObjectIdentifier]
|
|
13
|
-
return (
|
|
14
|
-
<style
|
|
15
|
-
key={identifier}
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
href={`t_${identifier}`}
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
precedence="default"
|
|
20
|
-
// we remove after first render in favor of inserting to a global stylesheet (faster)
|
|
21
|
-
suppressHydrationWarning
|
|
22
|
-
>
|
|
23
|
-
{styleObject[StyleObjectRules].join('\n')}
|
|
24
|
-
</style>
|
|
25
|
-
)
|
|
26
|
-
})}
|
|
27
|
-
</>
|
|
28
|
-
)
|
|
70
|
+
queueStyleTagCacheClear()
|
|
71
|
+
return <>{styles.map(getCachedStyleTag)}</>
|
|
29
72
|
}
|
|
30
73
|
}
|
|
31
74
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { supportsDynamicColorIOS } from '@hanzogui/constants'
|
|
2
2
|
import type { MutableRefObject } from 'react'
|
|
3
3
|
import { getConfig, getSetting } from '../config'
|
|
4
4
|
import { getVariable } from '../createVariable'
|
|
@@ -113,7 +113,7 @@ export function getThemeProxied(
|
|
|
113
113
|
...value,
|
|
114
114
|
get val() {
|
|
115
115
|
// when they touch the actual value we only track it if its a variable (web), its ignored!
|
|
116
|
-
if (!globalThis.
|
|
116
|
+
if (!globalThis.hanzoguiAvoidTracking) {
|
|
117
117
|
// always track .val - not scheme optimized since they're getting raw value
|
|
118
118
|
track(key, false)
|
|
119
119
|
}
|
|
@@ -126,23 +126,29 @@ export function getThemeProxied(
|
|
|
126
126
|
const { name, scheme } = curState
|
|
127
127
|
|
|
128
128
|
if (process.env.GUI_TARGET === 'native') {
|
|
129
|
-
// ios can avoid re-rendering for scheme changes (light↔dark) when using DynamicColorIOS
|
|
130
|
-
//
|
|
129
|
+
// ios can avoid re-rendering for scheme changes (light↔dark) when using DynamicColorIOS.
|
|
130
|
+
// DynamicColorIOS always resolves by the OS appearance, so this is only correct for a
|
|
131
|
+
// subtree that follows the OS scheme. it does NOT work when a <Theme> forces a scheme
|
|
132
|
+
// away from the OS/root — at any depth. `inverses` counts scheme flips from the root, so
|
|
133
|
+
// `inverses === 0` is exactly "this subtree still follows the OS". isInverse alone was
|
|
134
|
+
// wrong: a sub-theme keeping its parent's forced scheme (dark_blue under a forced dark,
|
|
135
|
+
// light root) has isInverse=false yet must NOT optimize, or iOS would pick the OS-scheme
|
|
136
|
+
// value (light) instead of the forced dark value.
|
|
131
137
|
const fastSchemeChange = getSetting('fastSchemeChange')
|
|
132
138
|
const rootMatchesSystem = doesRootSchemeMatchSystem()
|
|
133
139
|
const shouldOptimize =
|
|
134
140
|
scheme &&
|
|
135
141
|
platform !== 'web' &&
|
|
136
|
-
|
|
142
|
+
supportsDynamicColorIOS &&
|
|
137
143
|
!curProps.deopt &&
|
|
138
|
-
!curState.
|
|
144
|
+
!curState.inverses &&
|
|
139
145
|
fastSchemeChange &&
|
|
140
146
|
rootMatchesSystem
|
|
141
147
|
|
|
142
148
|
if (process.env.NODE_ENV === 'development' && curProps.debug === 'verbose') {
|
|
143
149
|
console.info(
|
|
144
150
|
` 🎨 useTheme().get(${key}) theme=${name} scheme=${scheme}`,
|
|
145
|
-
`\n shouldOptimize=${shouldOptimize} (
|
|
151
|
+
`\n shouldOptimize=${shouldOptimize} (dynamicColorIOS=${supportsDynamicColorIOS} deopt=${curProps.deopt} inverses=${curState.inverses} fastScheme=${fastSchemeChange} rootMatch=${rootMatchesSystem})`
|
|
146
152
|
)
|
|
147
153
|
}
|
|
148
154
|
|
|
@@ -177,7 +183,7 @@ export function getThemeProxied(
|
|
|
177
183
|
if (process.env.NODE_ENV === 'development' && curProps.debug) {
|
|
178
184
|
console.info(
|
|
179
185
|
` 🎨 useTheme().get(${key}) tracking key (not optimizing)`,
|
|
180
|
-
`\n platform=${platform}
|
|
186
|
+
`\n platform=${platform} dynamicColorIOS=${supportsDynamicColorIOS} deopt=${curProps.deopt} fastScheme=${fastSchemeChange}`
|
|
181
187
|
)
|
|
182
188
|
}
|
|
183
189
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isServer, isWeb } from '@hanzogui/constants'
|
|
2
|
-
import {
|
|
1
|
+
import { getPlatformDriver, isServer, isWeb } from '@hanzogui/constants'
|
|
2
|
+
import { mergeIfNotShallowEqual } from '@hanzogui/is-equal-shallow'
|
|
3
3
|
import { useDidFinishSSR, useIsClientOnly } from '@hanzogui/use-did-finish-ssr'
|
|
4
4
|
import { useRef, useState } from 'react'
|
|
5
5
|
import { getSetting } from '../config'
|
|
@@ -63,8 +63,22 @@ export const useComponentState = (
|
|
|
63
63
|
curStateRef.hasAnimated = true
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
// a renderer platform driver with native pseudo states (react-native-gpui)
|
|
67
|
+
// makes ANY component with runtime pseudo styles ride the animation-driver
|
|
68
|
+
// emitter path — no per-site transition/animation prop required. the flip is
|
|
69
|
+
// driver-sourced (hover) or event-sourced (press/focus) but either way applies
|
|
70
|
+
// through the emitter with zero React commits; with no transition declared it
|
|
71
|
+
// resolves instant (see createComponent's effectiveTransition default).
|
|
72
|
+
const platformPseudo = Boolean(
|
|
73
|
+
!isHOC &&
|
|
74
|
+
useAnimations &&
|
|
75
|
+
animationDriver?.avoidReRenders &&
|
|
76
|
+
getPlatformDriver()?.pseudo &&
|
|
77
|
+
('hoverStyle' in props || 'pressStyle' in props || 'focusStyle' in props)
|
|
78
|
+
)
|
|
79
|
+
|
|
66
80
|
const willBeAnimatedClient = (() => {
|
|
67
|
-
const next = !!(hasAnimationProp && !isHOC && useAnimations)
|
|
81
|
+
const next = !!((hasAnimationProp || platformPseudo) && !isHOC && useAnimations)
|
|
68
82
|
return Boolean(next || curStateRef.hasAnimated)
|
|
69
83
|
})()
|
|
70
84
|
|
|
@@ -162,7 +176,44 @@ export const useComponentState = (
|
|
|
162
176
|
|
|
163
177
|
const groupName = props.group as any as string | undefined
|
|
164
178
|
|
|
165
|
-
|
|
179
|
+
// hoisted shallow-set closure: created once per component instance and
|
|
180
|
+
// reused every render. drops the useCallback hook that useCreateShallowSetState
|
|
181
|
+
// would otherwise add. setState from useState is stable per instance so we
|
|
182
|
+
// can safely capture it. debug is read off stateRef at call time.
|
|
183
|
+
//
|
|
184
|
+
// important: this lives on `baseSetStateShallow`, not `setStateShallow`.
|
|
185
|
+
// createComponent's avoidReRenders path overwrites `stateRef.current.setStateShallow`
|
|
186
|
+
// with an emitter wrapper and captures this base as its real-re-render escape hatch.
|
|
187
|
+
// if the base shared the `setStateShallow` field, on the 2nd+ render this hook would
|
|
188
|
+
// read back the wrapper, the wrapper's escape hatch would point at itself, and a real
|
|
189
|
+
// re-render (e.g. unmounted 'should-enter' -> false) would never reach React, leaving
|
|
190
|
+
// enter animations stuck at opacity 0.
|
|
191
|
+
if (!stateRef.current.baseSetStateShallow) {
|
|
192
|
+
const r = stateRef.current
|
|
193
|
+
r.baseSetStateShallow = (stateOrGetState: any) => {
|
|
194
|
+
setState((prev: any) => {
|
|
195
|
+
const next =
|
|
196
|
+
typeof stateOrGetState === 'function' ? stateOrGetState(prev) : stateOrGetState
|
|
197
|
+
const update = mergeIfNotShallowEqual(prev, next)
|
|
198
|
+
if (process.env.NODE_ENV === 'development') {
|
|
199
|
+
const dbg = (r as any).__debug
|
|
200
|
+
if (dbg && update !== prev) {
|
|
201
|
+
console.groupCollapsed(`setStateShallow CHANGE`, '=>', update)
|
|
202
|
+
console.info(`previously`, prev)
|
|
203
|
+
console.trace()
|
|
204
|
+
console.groupEnd()
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return update
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (process.env.NODE_ENV === 'development') {
|
|
212
|
+
;(stateRef.current as any).__debug = props.debug
|
|
213
|
+
}
|
|
214
|
+
const setStateShallow = stateRef.current.baseSetStateShallow!
|
|
215
|
+
if (process.env.NODE_ENV === 'development' && globalThis.time)
|
|
216
|
+
globalThis.time`state-useCreateShallowSetState`
|
|
166
217
|
|
|
167
218
|
// set enter/exit variants onto our new props object
|
|
168
219
|
if (presenceState && isAnimated && isHydrated && staticConfig.variants) {
|
|
@@ -247,6 +298,7 @@ export const useComponentState = (
|
|
|
247
298
|
outputStyle,
|
|
248
299
|
willBeAnimated,
|
|
249
300
|
willBeAnimatedClient,
|
|
301
|
+
platformPseudo,
|
|
250
302
|
}
|
|
251
303
|
}
|
|
252
304
|
|