@nexub/react-native 0.0.0-stage → 2.2.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.
Files changed (134) hide show
  1. package/README.md +113 -2
  2. package/lib/module/components/actions.js +222 -0
  3. package/lib/module/components/actions.js.map +1 -0
  4. package/lib/module/components/containers.js +300 -0
  5. package/lib/module/components/containers.js.map +1 -0
  6. package/lib/module/components/display.js +299 -0
  7. package/lib/module/components/display.js.map +1 -0
  8. package/lib/module/components/feedback.js +484 -0
  9. package/lib/module/components/feedback.js.map +1 -0
  10. package/lib/module/components/inputs.js +792 -0
  11. package/lib/module/components/inputs.js.map +1 -0
  12. package/lib/module/components/mobile.js +818 -0
  13. package/lib/module/components/mobile.js.map +1 -0
  14. package/lib/module/components/overlays.js +421 -0
  15. package/lib/module/components/overlays.js.map +1 -0
  16. package/lib/module/components/shared.js +57 -0
  17. package/lib/module/components/shared.js.map +1 -0
  18. package/lib/module/hooks/useControllableState.js +23 -0
  19. package/lib/module/hooks/useControllableState.js.map +1 -0
  20. package/lib/module/index.js +31 -0
  21. package/lib/module/index.js.map +1 -0
  22. package/lib/module/package.json +1 -0
  23. package/lib/module/patterns/app.js +709 -0
  24. package/lib/module/patterns/app.js.map +1 -0
  25. package/lib/module/patterns/auth.js +224 -0
  26. package/lib/module/patterns/auth.js.map +1 -0
  27. package/lib/module/patterns/home.js +201 -0
  28. package/lib/module/patterns/home.js.map +1 -0
  29. package/lib/module/patterns/index.js +8 -0
  30. package/lib/module/patterns/index.js.map +1 -0
  31. package/lib/module/patterns/money.js +419 -0
  32. package/lib/module/patterns/money.js.map +1 -0
  33. package/lib/module/primitives/Icon.js +17 -0
  34. package/lib/module/primitives/Icon.js.map +1 -0
  35. package/lib/module/primitives/Layout.js +79 -0
  36. package/lib/module/primitives/Layout.js.map +1 -0
  37. package/lib/module/primitives/Pressable.js +79 -0
  38. package/lib/module/primitives/Pressable.js.map +1 -0
  39. package/lib/module/primitives/ScreenContainer.js +58 -0
  40. package/lib/module/primitives/ScreenContainer.js.map +1 -0
  41. package/lib/module/primitives/Surface.js +57 -0
  42. package/lib/module/primitives/Surface.js.map +1 -0
  43. package/lib/module/primitives/Text.js +70 -0
  44. package/lib/module/primitives/Text.js.map +1 -0
  45. package/lib/module/theme/ThemeProvider.js +127 -0
  46. package/lib/module/theme/ThemeProvider.js.map +1 -0
  47. package/lib/module/theme/fonts.js +56 -0
  48. package/lib/module/theme/fonts.js.map +1 -0
  49. package/lib/module/theme/haptics.js +56 -0
  50. package/lib/module/theme/haptics.js.map +1 -0
  51. package/lib/module/theme/motion.js +89 -0
  52. package/lib/module/theme/motion.js.map +1 -0
  53. package/lib/module/theme/navigation.js +99 -0
  54. package/lib/module/theme/navigation.js.map +1 -0
  55. package/lib/typescript/components/actions.d.ts +53 -0
  56. package/lib/typescript/components/actions.d.ts.map +1 -0
  57. package/lib/typescript/components/containers.d.ts +59 -0
  58. package/lib/typescript/components/containers.d.ts.map +1 -0
  59. package/lib/typescript/components/display.d.ts +68 -0
  60. package/lib/typescript/components/display.d.ts.map +1 -0
  61. package/lib/typescript/components/feedback.d.ts +96 -0
  62. package/lib/typescript/components/feedback.d.ts.map +1 -0
  63. package/lib/typescript/components/inputs.d.ts +141 -0
  64. package/lib/typescript/components/inputs.d.ts.map +1 -0
  65. package/lib/typescript/components/mobile.d.ts +173 -0
  66. package/lib/typescript/components/mobile.d.ts.map +1 -0
  67. package/lib/typescript/components/overlays.d.ts +74 -0
  68. package/lib/typescript/components/overlays.d.ts.map +1 -0
  69. package/lib/typescript/components/shared.d.ts +20 -0
  70. package/lib/typescript/components/shared.d.ts.map +1 -0
  71. package/lib/typescript/hooks/useControllableState.d.ts +6 -0
  72. package/lib/typescript/hooks/useControllableState.d.ts.map +1 -0
  73. package/lib/typescript/index.d.ts +39 -0
  74. package/lib/typescript/index.d.ts.map +1 -0
  75. package/lib/typescript/package.json +1 -0
  76. package/lib/typescript/patterns/app.d.ts +139 -0
  77. package/lib/typescript/patterns/app.d.ts.map +1 -0
  78. package/lib/typescript/patterns/auth.d.ts +54 -0
  79. package/lib/typescript/patterns/auth.d.ts.map +1 -0
  80. package/lib/typescript/patterns/home.d.ts +50 -0
  81. package/lib/typescript/patterns/home.d.ts.map +1 -0
  82. package/lib/typescript/patterns/index.d.ts +9 -0
  83. package/lib/typescript/patterns/index.d.ts.map +1 -0
  84. package/lib/typescript/patterns/money.d.ts +106 -0
  85. package/lib/typescript/patterns/money.d.ts.map +1 -0
  86. package/lib/typescript/primitives/Icon.d.ts +12 -0
  87. package/lib/typescript/primitives/Icon.d.ts.map +1 -0
  88. package/lib/typescript/primitives/Layout.d.ts +26 -0
  89. package/lib/typescript/primitives/Layout.d.ts.map +1 -0
  90. package/lib/typescript/primitives/Pressable.d.ts +21 -0
  91. package/lib/typescript/primitives/Pressable.d.ts.map +1 -0
  92. package/lib/typescript/primitives/ScreenContainer.d.ts +25 -0
  93. package/lib/typescript/primitives/ScreenContainer.d.ts.map +1 -0
  94. package/lib/typescript/primitives/Surface.d.ts +23 -0
  95. package/lib/typescript/primitives/Surface.d.ts.map +1 -0
  96. package/lib/typescript/primitives/Text.d.ts +21 -0
  97. package/lib/typescript/primitives/Text.d.ts.map +1 -0
  98. package/lib/typescript/theme/ThemeProvider.d.ts +69 -0
  99. package/lib/typescript/theme/ThemeProvider.d.ts.map +1 -0
  100. package/lib/typescript/theme/fonts.d.ts +25 -0
  101. package/lib/typescript/theme/fonts.d.ts.map +1 -0
  102. package/lib/typescript/theme/haptics.d.ts +3 -0
  103. package/lib/typescript/theme/haptics.d.ts.map +1 -0
  104. package/lib/typescript/theme/motion.d.ts +79 -0
  105. package/lib/typescript/theme/motion.d.ts.map +1 -0
  106. package/lib/typescript/theme/navigation.d.ts +158 -0
  107. package/lib/typescript/theme/navigation.d.ts.map +1 -0
  108. package/package.json +138 -3
  109. package/src/components/actions.tsx +259 -0
  110. package/src/components/containers.tsx +352 -0
  111. package/src/components/display.tsx +345 -0
  112. package/src/components/feedback.tsx +541 -0
  113. package/src/components/inputs.tsx +899 -0
  114. package/src/components/mobile.tsx +883 -0
  115. package/src/components/overlays.tsx +488 -0
  116. package/src/components/shared.ts +54 -0
  117. package/src/hooks/useControllableState.ts +27 -0
  118. package/src/index.ts +177 -0
  119. package/src/patterns/app.tsx +715 -0
  120. package/src/patterns/auth.tsx +266 -0
  121. package/src/patterns/home.tsx +211 -0
  122. package/src/patterns/index.ts +59 -0
  123. package/src/patterns/money.tsx +458 -0
  124. package/src/primitives/Icon.tsx +15 -0
  125. package/src/primitives/Layout.tsx +71 -0
  126. package/src/primitives/Pressable.tsx +97 -0
  127. package/src/primitives/ScreenContainer.tsx +65 -0
  128. package/src/primitives/Surface.tsx +75 -0
  129. package/src/primitives/Text.tsx +79 -0
  130. package/src/theme/ThemeProvider.tsx +210 -0
  131. package/src/theme/fonts.ts +52 -0
  132. package/src/theme/haptics.ts +57 -0
  133. package/src/theme/motion.ts +105 -0
  134. package/src/theme/navigation.ts +68 -0
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ import * as React from 'react';
4
+ import { ScrollView, View } from 'react-native';
5
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
+ import { useTheme } from "../theme/ThemeProvider.js";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ /**
9
+ * The root of every screen: background, edge-to-edge safe-area insets and
10
+ * content padding. With `scroll`, iOS adjusts insets itself
11
+ * (contentInsetAdjustmentBehavior) so native large titles collapse.
12
+ */
13
+ export function ScreenContainer({
14
+ scroll = true,
15
+ edges = ['left', 'right', 'bottom'],
16
+ background = 'surface',
17
+ padding = '4',
18
+ gap = '4',
19
+ contentStyle,
20
+ children,
21
+ style,
22
+ ...rest
23
+ }) {
24
+ const {
25
+ roles,
26
+ tokens
27
+ } = useTheme();
28
+ const insets = useSafeAreaInsets();
29
+ const pad = tokens.spacing[padding];
30
+ const inner = {
31
+ paddingTop: pad + (edges.includes('top') ? insets.top : 0),
32
+ paddingBottom: pad + (edges.includes('bottom') ? insets.bottom : 0),
33
+ paddingStart: pad + (edges.includes('left') ? insets.left : 0),
34
+ paddingEnd: pad + (edges.includes('right') ? insets.right : 0),
35
+ gap: tokens.spacing[gap]
36
+ };
37
+ if (!scroll) {
38
+ return /*#__PURE__*/_jsx(View, {
39
+ style: [{
40
+ flex: 1,
41
+ backgroundColor: roles[background]
42
+ }, inner, contentStyle, style],
43
+ children: children
44
+ });
45
+ }
46
+ return /*#__PURE__*/_jsx(ScrollView, {
47
+ contentInsetAdjustmentBehavior: "automatic",
48
+ keyboardShouldPersistTaps: "handled",
49
+ style: [{
50
+ flex: 1,
51
+ backgroundColor: roles[background]
52
+ }, style],
53
+ contentContainerStyle: [inner, contentStyle],
54
+ ...rest,
55
+ children: children
56
+ });
57
+ }
58
+ //# sourceMappingURL=ScreenContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","ScrollView","View","useSafeAreaInsets","useTheme","jsx","_jsx","ScreenContainer","scroll","edges","background","padding","gap","contentStyle","children","style","rest","roles","tokens","insets","pad","spacing","inner","paddingTop","includes","top","paddingBottom","bottom","paddingStart","left","paddingEnd","right","flex","backgroundColor","contentInsetAdjustmentBehavior","keyboardShouldPersistTaps","contentContainerStyle"],"sourceRoot":"../../../src","sources":["primitives/ScreenContainer.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,UAAU,EAAEC,IAAI,QAA8C,cAAc;AACrF,SAASC,iBAAiB,QAAmB,gCAAgC;AAC7E,SAASC,QAAQ,QAAuB,2BAAwB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAiBjE;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAAC;EAC9BC,MAAM,GAAG,IAAI;EACbC,KAAK,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;EACnCC,UAAU,GAAG,SAAS;EACtBC,OAAO,GAAG,GAAG;EACbC,GAAG,GAAG,GAAG;EACTC,YAAY;EACZC,QAAQ;EACRC,KAAK;EACL,GAAGC;AACiB,CAAC,EAAE;EACvB,MAAM;IAAEC,KAAK;IAAEC;EAAO,CAAC,GAAGd,QAAQ,CAAC,CAAC;EACpC,MAAMe,MAAM,GAAGhB,iBAAiB,CAAC,CAAC;EAClC,MAAMiB,GAAG,GAAGF,MAAM,CAACG,OAAO,CAACV,OAAO,CAAC;EACnC,MAAMW,KAAgB,GAAG;IACvBC,UAAU,EAAEH,GAAG,IAAIX,KAAK,CAACe,QAAQ,CAAC,KAAK,CAAC,GAAGL,MAAM,CAACM,GAAG,GAAG,CAAC,CAAC;IAC1DC,aAAa,EAAEN,GAAG,IAAIX,KAAK,CAACe,QAAQ,CAAC,QAAQ,CAAC,GAAGL,MAAM,CAACQ,MAAM,GAAG,CAAC,CAAC;IACnEC,YAAY,EAAER,GAAG,IAAIX,KAAK,CAACe,QAAQ,CAAC,MAAM,CAAC,GAAGL,MAAM,CAACU,IAAI,GAAG,CAAC,CAAC;IAC9DC,UAAU,EAAEV,GAAG,IAAIX,KAAK,CAACe,QAAQ,CAAC,OAAO,CAAC,GAAGL,MAAM,CAACY,KAAK,GAAG,CAAC,CAAC;IAC9DnB,GAAG,EAAEM,MAAM,CAACG,OAAO,CAACT,GAAG;EACzB,CAAC;EACD,IAAI,CAACJ,MAAM,EAAE;IACX,oBACEF,IAAA,CAACJ,IAAI;MAACa,KAAK,EAAE,CAAC;QAAEiB,IAAI,EAAE,CAAC;QAAEC,eAAe,EAAEhB,KAAK,CAACP,UAAU;MAAE,CAAC,EAAEY,KAAK,EAAET,YAAY,EAAEE,KAAK,CAAE;MAAAD,QAAA,EACxFA;IAAQ,CACL,CAAC;EAEX;EACA,oBACER,IAAA,CAACL,UAAU;IACTiC,8BAA8B,EAAC,WAAW;IAC1CC,yBAAyB,EAAC,SAAS;IACnCpB,KAAK,EAAE,CAAC;MAAEiB,IAAI,EAAE,CAAC;MAAEC,eAAe,EAAEhB,KAAK,CAACP,UAAU;IAAE,CAAC,EAAEK,KAAK,CAAE;IAChEqB,qBAAqB,EAAE,CAACd,KAAK,EAAET,YAAY,CAAE;IAAA,GACzCG,IAAI;IAAAF,QAAA,EAEPA;EAAQ,CACC,CAAC;AAEjB","ignoreList":[]}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ import * as React from 'react';
4
+ import { Platform, StyleSheet, View } from 'react-native';
5
+ import { useTheme } from "../theme/ThemeProvider.js";
6
+
7
+ // Optional peer: native Liquid Glass on iOS 26+. Everything else gets the solid fallback.
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ let Glass;
10
+ try {
11
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- optional peer, must not fail when absent
12
+ Glass = require('expo-glass-effect');
13
+ } catch {
14
+ Glass = undefined;
15
+ }
16
+ const liquidGlass = Platform.OS === 'ios' && !!Glass?.isLiquidGlassAvailable();
17
+ /**
18
+ * A tonal surface. `material="glass"` is native Liquid Glass on iOS 26+, and
19
+ * `surface-elevated` + hairline elsewhere, or whenever glass is 'off' (user
20
+ * setting or Reduce Transparency).
21
+ */
22
+ export function Surface({
23
+ tone = 'surface',
24
+ elevation = 0,
25
+ material = 'solid',
26
+ radius,
27
+ style,
28
+ ...rest
29
+ }) {
30
+ const theme = useTheme();
31
+ const borderRadius = typeof radius === 'string' ? theme.tokens.shape[radius] : radius;
32
+ const glass = material === 'glass' && theme.glass !== 'off';
33
+ if (glass && liquidGlass && Glass) {
34
+ return /*#__PURE__*/_jsx(Glass.GlassView, {
35
+ glassEffectStyle: theme.glass === 'clear' ? 'clear' : 'regular',
36
+ tintColor: theme.glass === 'tinted' ? theme.roles['surface-elevated'] : undefined,
37
+ colorScheme: theme.scheme,
38
+ style: [{
39
+ borderRadius,
40
+ boxShadow: theme.elevation(elevation)
41
+ }, style],
42
+ ...rest
43
+ });
44
+ }
45
+ return /*#__PURE__*/_jsx(View, {
46
+ style: [{
47
+ backgroundColor: theme.roles[material === 'glass' ? 'surface-elevated' : tone],
48
+ borderRadius,
49
+ boxShadow: theme.elevation(elevation)
50
+ }, material === 'glass' && {
51
+ borderWidth: StyleSheet.hairlineWidth,
52
+ borderColor: theme.roles['outline-variant']
53
+ }, style],
54
+ ...rest
55
+ });
56
+ }
57
+ //# sourceMappingURL=Surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Platform","StyleSheet","View","useTheme","jsx","_jsx","Glass","require","undefined","liquidGlass","OS","isLiquidGlassAvailable","Surface","tone","elevation","material","radius","style","rest","theme","borderRadius","tokens","shape","glass","GlassView","glassEffectStyle","tintColor","roles","colorScheme","scheme","boxShadow","backgroundColor","borderWidth","hairlineWidth","borderColor"],"sourceRoot":"../../../src","sources":["primitives/Surface.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAwB,cAAc;AAEzE,SAASC,QAAQ,QAA4C,2BAAwB;;AAErF;AAAA,SAAAC,GAAA,IAAAC,IAAA;AACA,IAAIC,KAAqD;AACzD,IAAI;EACF;EACAA,KAAK,GAAGC,OAAO,CAAC,mBAAmB,CAAC;AACtC,CAAC,CAAC,MAAM;EACND,KAAK,GAAGE,SAAS;AACnB;AACA,MAAMC,WAAW,GAAGT,QAAQ,CAACU,EAAE,KAAK,KAAK,IAAI,CAAC,CAACJ,KAAK,EAAEK,sBAAsB,CAAC,CAAC;AAgB9E;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAOA,CAAC;EACtBC,IAAI,GAAG,SAAS;EAChBC,SAAS,GAAG,CAAC;EACbC,QAAQ,GAAG,OAAO;EAClBC,MAAM;EACNC,KAAK;EACL,GAAGC;AACS,CAAC,EAAE;EACf,MAAMC,KAAK,GAAGhB,QAAQ,CAAC,CAAC;EACxB,MAAMiB,YAAY,GAAG,OAAOJ,MAAM,KAAK,QAAQ,GAAGG,KAAK,CAACE,MAAM,CAACC,KAAK,CAACN,MAAM,CAAC,GAAGA,MAAM;EACrF,MAAMO,KAAK,GAAGR,QAAQ,KAAK,OAAO,IAAII,KAAK,CAACI,KAAK,KAAK,KAAK;EAE3D,IAAIA,KAAK,IAAId,WAAW,IAAIH,KAAK,EAAE;IACjC,oBACED,IAAA,CAACC,KAAK,CAACkB,SAAS;MACdC,gBAAgB,EAAEN,KAAK,CAACI,KAAK,KAAK,OAAO,GAAG,OAAO,GAAG,SAAU;MAChEG,SAAS,EAAEP,KAAK,CAACI,KAAK,KAAK,QAAQ,GAAGJ,KAAK,CAACQ,KAAK,CAAC,kBAAkB,CAAC,GAAGnB,SAAU;MAClFoB,WAAW,EAAET,KAAK,CAACU,MAAO;MAC1BZ,KAAK,EAAE,CAAC;QAAEG,YAAY;QAAEU,SAAS,EAAEX,KAAK,CAACL,SAAS,CAACA,SAAS;MAAE,CAAC,EAAEG,KAAK,CAAE;MAAA,GACpEC;IAAI,CACT,CAAC;EAEN;EACA,oBACEb,IAAA,CAACH,IAAI;IACHe,KAAK,EAAE,CACL;MACEc,eAAe,EAAEZ,KAAK,CAACQ,KAAK,CAACZ,QAAQ,KAAK,OAAO,GAAG,kBAAkB,GAAGF,IAAI,CAAC;MAC9EO,YAAY;MACZU,SAAS,EAAEX,KAAK,CAACL,SAAS,CAACA,SAAS;IACtC,CAAC,EACDC,QAAQ,KAAK,OAAO,IAAI;MACtBiB,WAAW,EAAE/B,UAAU,CAACgC,aAAa;MACrCC,WAAW,EAAEf,KAAK,CAACQ,KAAK,CAAC,iBAAiB;IAC5C,CAAC,EACDV,KAAK,CACL;IAAA,GACEC;EAAI,CACT,CAAC;AAEN","ignoreList":[]}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ import * as React from 'react';
4
+ import { Text as RNText } from 'react-native';
5
+ import { fontStyle } from "../theme/fonts.js";
6
+ import { useTheme } from "../theme/ThemeProvider.js";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ // iOS Dynamic Type: each role follows its Apple text style's scaling curve.
9
+ const RAMP = {
10
+ 'display-lg': 'largeTitle',
11
+ 'display-md': 'largeTitle',
12
+ 'display-sm': 'largeTitle',
13
+ 'headline-lg': 'title1',
14
+ 'headline-md': 'title2',
15
+ 'headline-sm': 'title3',
16
+ 'title-lg': 'title3',
17
+ 'title-md': 'headline',
18
+ 'title-sm': 'subheadline',
19
+ 'body-lg': 'body',
20
+ 'body-md': 'body',
21
+ 'body-sm': 'footnote',
22
+ 'label-lg': 'subheadline',
23
+ 'label-md': 'footnote',
24
+ 'label-sm': 'caption1'
25
+ };
26
+
27
+ // Big type already reads at large sizes; cap it so it doesn't push content off
28
+ // screen. Body, title and label roles scale without a cap (WCAG 1.4.4).
29
+ const cap = role => role.startsWith('display') ? 1.3 : role.startsWith('headline') ? 1.6 : undefined;
30
+ export function Text({
31
+ variant = 'body-md',
32
+ color = 'on-surface',
33
+ tabular,
34
+ family,
35
+ style,
36
+ ...rest
37
+ }) {
38
+ const {
39
+ roles,
40
+ tokens,
41
+ fonts
42
+ } = useTheme();
43
+ const t = tokens.type[variant];
44
+ return /*#__PURE__*/_jsx(RNText, {
45
+ dynamicTypeRamp: RAMP[variant],
46
+ maxFontSizeMultiplier: cap(variant),
47
+ style: [{
48
+ ...fontStyle(family ?? t.family, t.weight, fonts),
49
+ fontSize: t.size,
50
+ lineHeight: t.lineHeight,
51
+ letterSpacing: t.letterSpacing,
52
+ color: roles[color]
53
+ }, tabular && {
54
+ fontVariant: ['tabular-nums']
55
+ }, style],
56
+ ...rest
57
+ });
58
+ }
59
+ /** Text announced as a heading. @default variant 'headline-sm' */
60
+ export function Heading({
61
+ variant = 'headline-sm',
62
+ ...rest
63
+ }) {
64
+ return /*#__PURE__*/_jsx(Text, {
65
+ accessibilityRole: "header",
66
+ variant: variant,
67
+ ...rest
68
+ });
69
+ }
70
+ //# sourceMappingURL=Text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Text","RNText","fontStyle","useTheme","jsx","_jsx","RAMP","cap","role","startsWith","undefined","variant","color","tabular","family","style","rest","roles","tokens","fonts","t","type","dynamicTypeRamp","maxFontSizeMultiplier","weight","fontSize","size","lineHeight","letterSpacing","fontVariant","Heading","accessibilityRole"],"sourceRoot":"../../../src","sources":["primitives/Text.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,IAAI,IAAIC,MAAM,QAAuC,cAAc;AAE5E,SAASC,SAAS,QAAyB,mBAAgB;AAC3D,SAASC,QAAQ,QAAuB,2BAAwB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAIjE;AACA,MAAMC,IAAkC,GAAG;EACzC,YAAY,EAAE,YAAY;EAC1B,YAAY,EAAE,YAAY;EAC1B,YAAY,EAAE,YAAY;EAC1B,aAAa,EAAE,QAAQ;EACvB,aAAa,EAAE,QAAQ;EACvB,aAAa,EAAE,QAAQ;EACvB,UAAU,EAAE,QAAQ;EACpB,UAAU,EAAE,UAAU;EACtB,UAAU,EAAE,aAAa;EACzB,SAAS,EAAE,MAAM;EACjB,SAAS,EAAE,MAAM;EACjB,SAAS,EAAE,UAAU;EACrB,UAAU,EAAE,aAAa;EACzB,UAAU,EAAE,UAAU;EACtB,UAAU,EAAE;AACd,CAAC;;AAED;AACA;AACA,MAAMC,GAAG,GAAIC,IAAoB,IAC/BA,IAAI,CAACC,UAAU,CAAC,SAAS,CAAC,GAAG,GAAG,GAAGD,IAAI,CAACC,UAAU,CAAC,UAAU,CAAC,GAAG,GAAG,GAAGC,SAAS;AAalF,OAAO,SAASV,IAAIA,CAAC;EACnBW,OAAO,GAAG,SAAS;EACnBC,KAAK,GAAG,YAAY;EACpBC,OAAO;EACPC,MAAM;EACNC,KAAK;EACL,GAAGC;AACM,CAAC,EAAE;EACZ,MAAM;IAAEC,KAAK;IAAEC,MAAM;IAAEC;EAAM,CAAC,GAAGhB,QAAQ,CAAC,CAAC;EAC3C,MAAMiB,CAAC,GAAGF,MAAM,CAACG,IAAI,CAACV,OAAO,CAAC;EAC9B,oBACEN,IAAA,CAACJ,MAAM;IACLqB,eAAe,EAAEhB,IAAI,CAACK,OAAO,CAAE;IAC/BY,qBAAqB,EAAEhB,GAAG,CAACI,OAAO,CAAE;IACpCI,KAAK,EAAE,CACL;MACE,GAAGb,SAAS,CAACY,MAAM,IAAIM,CAAC,CAACN,MAAM,EAAEM,CAAC,CAACI,MAAM,EAAEL,KAAK,CAAC;MACjDM,QAAQ,EAAEL,CAAC,CAACM,IAAI;MAChBC,UAAU,EAAEP,CAAC,CAACO,UAAU;MACxBC,aAAa,EAAER,CAAC,CAACQ,aAAa;MAC9BhB,KAAK,EAAEK,KAAK,CAACL,KAAK;IACpB,CAAC,EACDC,OAAO,IAAI;MAAEgB,WAAW,EAAE,CAAC,cAAc;IAAE,CAAC,EAC5Cd,KAAK,CACL;IAAA,GACEC;EAAI,CACT,CAAC;AAEN;AAIA;AACA,OAAO,SAASc,OAAOA,CAAC;EAAEnB,OAAO,GAAG,aAAa;EAAE,GAAGK;AAAmB,CAAC,EAAE;EAC1E,oBAAOX,IAAA,CAACL,IAAI;IAAC+B,iBAAiB,EAAC,QAAQ;IAACpB,OAAO,EAAEA,OAAQ;IAAA,GAAKK;EAAI,CAAG,CAAC;AACxE","ignoreList":[]}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+
3
+ import * as React from 'react';
4
+ import { AccessibilityInfo, AppState, Platform, StyleSheet, View, useColorScheme } from 'react-native';
5
+ import { native } from '@nexub/tokens/native';
6
+ import { createSeedRoles } from '@nexub/tokens/seed';
7
+ import { defaultMessages, directionOf } from '@nexub/core';
8
+ import { playHaptic } from "./haptics.js";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const ThemeContext = /*#__PURE__*/React.createContext(null);
11
+
12
+ // AccessibilityInfo reads that fire no change event (contrast): re-read on foreground.
13
+ function useForegroundSetting(read, enabled) {
14
+ const [on, setOn] = React.useState(false);
15
+ React.useEffect(() => {
16
+ if (!enabled || !read) return;
17
+ const get = () => read().then(setOn, () => setOn(false));
18
+ get();
19
+ const sub = AppState.addEventListener('change', s => s === 'active' && get());
20
+ return () => sub.remove();
21
+ }, [enabled, read]);
22
+ return on;
23
+ }
24
+ function useSetting(read, event) {
25
+ const [on, setOn] = React.useState(false);
26
+ React.useEffect(() => {
27
+ read().then(setOn, () => setOn(false));
28
+ const sub = AccessibilityInfo.addEventListener(event, setOn);
29
+ return () => sub.remove();
30
+ }, [read, event]);
31
+ return on;
32
+ }
33
+ const a11y = AccessibilityInfo;
34
+ const readHighContrast = Platform.OS === 'ios' ? a11y.isDarkerSystemColorsEnabled?.bind(a11y) : a11y.isHighTextContrastEnabled?.bind(a11y);
35
+ const readReduceMotion = () => AccessibilityInfo.isReduceMotionEnabled();
36
+ const readReduceTransparency = () => Platform.OS === 'ios' ? AccessibilityInfo.isReduceTransparencyEnabled() : Promise.resolve(false);
37
+
38
+ /**
39
+ * Theme, accessibility preferences, locale and strings for every
40
+ * @nexub/react-native component. Wrap the app once, inside the safe-area provider.
41
+ */
42
+ export function NexubNativeProvider({
43
+ scheme: schemeProp = 'system',
44
+ contrast: contrastProp = 'system',
45
+ product,
46
+ seed,
47
+ seedTarget = 'primary',
48
+ glass = 'balanced',
49
+ haptics = true,
50
+ fonts = 'nexub',
51
+ locale = 'en',
52
+ dir,
53
+ messages,
54
+ children
55
+ }) {
56
+ const system = useColorScheme();
57
+ const scheme = schemeProp === 'system' ? system === 'dark' ? 'dark' : 'light' : schemeProp;
58
+ const systemHigh = useForegroundSetting(readHighContrast, contrastProp === 'system');
59
+ const contrast = contrastProp === 'system' ? systemHigh ? 'high' : 'standard' : contrastProp;
60
+ const reducedMotion = useSetting(readReduceMotion, 'reduceMotionChanged');
61
+ const reduceTransparency = useSetting(readReduceTransparency, 'reduceTransparencyChanged');
62
+ const resolvedDir = dir ?? directionOf(locale);
63
+ const theme = React.useMemo(() => {
64
+ const roles = {
65
+ ...native.color.roles[contrast][scheme],
66
+ ...(product ? native.color.products[product][contrast][scheme] : {}),
67
+ ...(seed ? createSeedRoles(seed, {
68
+ contrast,
69
+ target: seedTarget
70
+ })[scheme] : {})
71
+ };
72
+ return {
73
+ scheme,
74
+ contrast,
75
+ product,
76
+ roles,
77
+ tokens: native,
78
+ elevation: level => level ? native.elevation[level][scheme] : undefined,
79
+ glass: reduceTransparency ? 'off' : glass,
80
+ reducedMotion,
81
+ haptics,
82
+ fonts,
83
+ locale,
84
+ dir: resolvedDir,
85
+ messages: {
86
+ ...defaultMessages,
87
+ ...messages
88
+ }
89
+ };
90
+ }, [scheme, contrast, product, seed, seedTarget, glass, reduceTransparency, reducedMotion, haptics, fonts, locale, resolvedDir, messages]);
91
+ return /*#__PURE__*/_jsx(ThemeContext.Provider, {
92
+ value: theme,
93
+ children: /*#__PURE__*/_jsx(View, {
94
+ style: [styles.root, {
95
+ direction: resolvedDir
96
+ }],
97
+ children: children
98
+ })
99
+ });
100
+ }
101
+ const styles = StyleSheet.create({
102
+ root: {
103
+ flex: 1
104
+ }
105
+ });
106
+
107
+ /** The active theme. Throws outside NexubNativeProvider. */
108
+ export function useTheme() {
109
+ const theme = React.useContext(ThemeContext);
110
+ if (!theme) throw new Error('@nexub/react-native: wrap your app in <NexubNativeProvider>.');
111
+ return theme;
112
+ }
113
+
114
+ /** Shorthand for `useTheme().roles`. */
115
+ export const useRoles = () => useTheme().roles;
116
+
117
+ /** The active strings: defaults merged with the provider's overrides. */
118
+ export const useNexubMessages = () => useTheme().messages;
119
+
120
+ /** Plays a semantic haptic, unless the user turned haptics off. */
121
+ export function useHaptics() {
122
+ const {
123
+ haptics
124
+ } = useTheme();
125
+ return React.useCallback(token => haptics && playHaptic(token), [haptics]);
126
+ }
127
+ //# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","AccessibilityInfo","AppState","Platform","StyleSheet","View","useColorScheme","native","createSeedRoles","defaultMessages","directionOf","playHaptic","jsx","_jsx","ThemeContext","createContext","useForegroundSetting","read","enabled","on","setOn","useState","useEffect","get","then","sub","addEventListener","s","remove","useSetting","event","a11y","readHighContrast","OS","isDarkerSystemColorsEnabled","bind","isHighTextContrastEnabled","readReduceMotion","isReduceMotionEnabled","readReduceTransparency","isReduceTransparencyEnabled","Promise","resolve","NexubNativeProvider","scheme","schemeProp","contrast","contrastProp","product","seed","seedTarget","glass","haptics","fonts","locale","dir","messages","children","system","systemHigh","reducedMotion","reduceTransparency","resolvedDir","theme","useMemo","roles","color","products","target","tokens","elevation","level","undefined","Provider","value","style","styles","root","direction","create","flex","useTheme","useContext","Error","useRoles","useNexubMessages","useHaptics","useCallback","token"],"sourceRoot":"../../../src","sources":["theme/ThemeProvider.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ // Nexub faces as static TTFs (OFL) from @expo-google-fonts, one file per weight.
4
+ // Load them once at startup: const [ready] = useFonts(nexubFonts) (expo-font).
5
+ // Per-weight subpaths don't import expo-font, so bare RN apps can load the same
6
+ // files with their own loader.
7
+ import { Inter_400Regular } from '@expo-google-fonts/inter/400Regular';
8
+ import { Inter_500Medium } from '@expo-google-fonts/inter/500Medium';
9
+ import { Inter_600SemiBold } from '@expo-google-fonts/inter/600SemiBold';
10
+ import { Inter_700Bold } from '@expo-google-fonts/inter/700Bold';
11
+ import { PlusJakartaSans_600SemiBold } from '@expo-google-fonts/plus-jakarta-sans/600SemiBold';
12
+ import { PlusJakartaSans_700Bold } from '@expo-google-fonts/plus-jakarta-sans/700Bold';
13
+ import { PlusJakartaSans_800ExtraBold } from '@expo-google-fonts/plus-jakarta-sans/800ExtraBold';
14
+ import { GeistMono_400Regular } from '@expo-google-fonts/geist-mono/400Regular';
15
+ export const nexubFonts = {
16
+ Inter_400Regular,
17
+ Inter_500Medium,
18
+ Inter_600SemiBold,
19
+ Inter_700Bold,
20
+ PlusJakartaSans_600SemiBold,
21
+ PlusJakartaSans_700Bold,
22
+ PlusJakartaSans_800ExtraBold,
23
+ GeistMono_400Regular
24
+ };
25
+ const SANS = {
26
+ 400: 'Inter_400Regular',
27
+ 500: 'Inter_500Medium',
28
+ 600: 'Inter_600SemiBold',
29
+ 700: 'Inter_700Bold',
30
+ 800: 'Inter_700Bold'
31
+ };
32
+ const DISPLAY = {
33
+ 400: 'PlusJakartaSans_600SemiBold',
34
+ 500: 'PlusJakartaSans_600SemiBold',
35
+ 600: 'PlusJakartaSans_600SemiBold',
36
+ 700: 'PlusJakartaSans_700Bold',
37
+ 800: 'PlusJakartaSans_800ExtraBold'
38
+ };
39
+
40
+ /**
41
+ * Style for a family + weight. With static files the weight lives in the file
42
+ * name, so `fontWeight` is only set for the system font (Android picks the
43
+ * wrong file when both are set).
44
+ */
45
+ export function fontStyle(family, weight, source) {
46
+ if (source === 'system') return {
47
+ fontWeight: String(weight)
48
+ };
49
+ if (family === 'mono') return {
50
+ fontFamily: 'GeistMono_400Regular'
51
+ };
52
+ return {
53
+ fontFamily: (family === 'display' ? DISPLAY : SANS)[weight] ?? SANS[400]
54
+ };
55
+ }
56
+ //# sourceMappingURL=fonts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Inter_400Regular","Inter_500Medium","Inter_600SemiBold","Inter_700Bold","PlusJakartaSans_600SemiBold","PlusJakartaSans_700Bold","PlusJakartaSans_800ExtraBold","GeistMono_400Regular","nexubFonts","SANS","DISPLAY","fontStyle","family","weight","source","fontWeight","String","fontFamily"],"sourceRoot":"../../../src","sources":["theme/fonts.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA,SAASA,gBAAgB,QAAQ,qCAAqC;AACtE,SAASC,eAAe,QAAQ,oCAAoC;AACpE,SAASC,iBAAiB,QAAQ,sCAAsC;AACxE,SAASC,aAAa,QAAQ,kCAAkC;AAChE,SAASC,2BAA2B,QAAQ,kDAAkD;AAC9F,SAASC,uBAAuB,QAAQ,8CAA8C;AACtF,SAASC,4BAA4B,QAAQ,mDAAmD;AAChG,SAASC,oBAAoB,QAAQ,0CAA0C;AAE/E,OAAO,MAAMC,UAAU,GAAG;EACxBR,gBAAgB;EAChBC,eAAe;EACfC,iBAAiB;EACjBC,aAAa;EACbC,2BAA2B;EAC3BC,uBAAuB;EACvBC,4BAA4B;EAC5BC;AACF,CAAC;AAKD,MAAME,IAA4B,GAAG;EACnC,GAAG,EAAE,kBAAkB;EACvB,GAAG,EAAE,iBAAiB;EACtB,GAAG,EAAE,mBAAmB;EACxB,GAAG,EAAE,eAAe;EACpB,GAAG,EAAE;AACP,CAAC;AACD,MAAMC,OAA+B,GAAG;EACtC,GAAG,EAAE,6BAA6B;EAClC,GAAG,EAAE,6BAA6B;EAClC,GAAG,EAAE,6BAA6B;EAClC,GAAG,EAAE,yBAAyB;EAC9B,GAAG,EAAE;AACP,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,SAASA,CAACC,MAAkB,EAAEC,MAAc,EAAEC,MAAkB,EAAE;EAChF,IAAIA,MAAM,KAAK,QAAQ,EAAE,OAAO;IAAEC,UAAU,EAAEC,MAAM,CAACH,MAAM;EAAW,CAAC;EACvE,IAAID,MAAM,KAAK,MAAM,EAAE,OAAO;IAAEK,UAAU,EAAE;EAAuB,CAAC;EACpE,OAAO;IAAEA,UAAU,EAAE,CAACL,MAAM,KAAK,SAAS,GAAGF,OAAO,GAAGD,IAAI,EAAEI,MAAM,CAAC,IAAIJ,IAAI,CAAC,GAAG;EAAE,CAAC;AACrF","ignoreList":[]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ import { Platform } from 'react-native';
4
+
5
+ // Semantic haptics (MOBILE_PLAN.md §4.4). Apple's rule: never on plain taps,
6
+ // never the only feedback. Android uses the platform constants, not the
7
+ // vibrator-based impact API.
8
+
9
+ // Optional peer: without expo-haptics every haptic is a no-op.
10
+ let H;
11
+ try {
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- optional peer, must not fail when absent
13
+ H = require('expo-haptics');
14
+ } catch {
15
+ H = undefined;
16
+ }
17
+ const ANDROID = {
18
+ selection: 'Segment_Tick',
19
+ toggleOn: 'Toggle_On',
20
+ toggleOff: 'Toggle_Off',
21
+ confirm: 'Confirm',
22
+ reject: 'Reject',
23
+ warning: 'Reject',
24
+ snap: 'Gesture_End'
25
+ };
26
+ export function playHaptic(token) {
27
+ if (!H) return;
28
+ const done = () => {};
29
+ if (Platform.OS === 'android') {
30
+ H.performAndroidHapticsAsync(H.AndroidHaptics[ANDROID[token]]).catch(done);
31
+ return;
32
+ }
33
+ if (Platform.OS !== 'ios') return;
34
+ switch (token) {
35
+ case 'selection':
36
+ H.selectionAsync().catch(done);
37
+ break;
38
+ case 'toggleOn':
39
+ case 'toggleOff':
40
+ H.impactAsync(H.ImpactFeedbackStyle.Light).catch(done);
41
+ break;
42
+ case 'snap':
43
+ H.impactAsync(H.ImpactFeedbackStyle.Medium).catch(done);
44
+ break;
45
+ case 'confirm':
46
+ H.notificationAsync(H.NotificationFeedbackType.Success).catch(done);
47
+ break;
48
+ case 'reject':
49
+ H.notificationAsync(H.NotificationFeedbackType.Error).catch(done);
50
+ break;
51
+ case 'warning':
52
+ H.notificationAsync(H.NotificationFeedbackType.Warning).catch(done);
53
+ break;
54
+ }
55
+ }
56
+ //# sourceMappingURL=haptics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","H","require","undefined","ANDROID","selection","toggleOn","toggleOff","confirm","reject","warning","snap","playHaptic","token","done","OS","performAndroidHapticsAsync","AndroidHaptics","catch","selectionAsync","impactAsync","ImpactFeedbackStyle","Light","Medium","notificationAsync","NotificationFeedbackType","Success","Error","Warning"],"sourceRoot":"../../../src","sources":["theme/haptics.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;;AAEvC;AACA;AACA;;AAIA;AACA,IAAIC,CAA4C;AAChD,IAAI;EACF;EACAA,CAAC,GAAGC,OAAO,CAAC,cAAc,CAAC;AAC7B,CAAC,CAAC,MAAM;EACND,CAAC,GAAGE,SAAS;AACf;AAEA,MAAMC,OAAO,GAAG;EACdC,SAAS,EAAE,cAAc;EACzBC,QAAQ,EAAE,WAAW;EACrBC,SAAS,EAAE,YAAY;EACvBC,OAAO,EAAE,SAAS;EAClBC,MAAM,EAAE,QAAQ;EAChBC,OAAO,EAAE,QAAQ;EACjBC,IAAI,EAAE;AACR,CAAU;AAEV,OAAO,SAASC,UAAUA,CAACC,KAAkB,EAAQ;EACnD,IAAI,CAACZ,CAAC,EAAE;EACR,MAAMa,IAAI,GAAGA,CAAA,KAAM,CAAC,CAAC;EACrB,IAAId,QAAQ,CAACe,EAAE,KAAK,SAAS,EAAE;IAC7Bd,CAAC,CAACe,0BAA0B,CAACf,CAAC,CAACgB,cAAc,CAACb,OAAO,CAACS,KAAK,CAAC,CAAC,CAAC,CAACK,KAAK,CAACJ,IAAI,CAAC;IAC1E;EACF;EACA,IAAId,QAAQ,CAACe,EAAE,KAAK,KAAK,EAAE;EAC3B,QAAQF,KAAK;IACX,KAAK,WAAW;MACdZ,CAAC,CAACkB,cAAc,CAAC,CAAC,CAACD,KAAK,CAACJ,IAAI,CAAC;MAC9B;IACF,KAAK,UAAU;IACf,KAAK,WAAW;MACdb,CAAC,CAACmB,WAAW,CAACnB,CAAC,CAACoB,mBAAmB,CAACC,KAAK,CAAC,CAACJ,KAAK,CAACJ,IAAI,CAAC;MACtD;IACF,KAAK,MAAM;MACTb,CAAC,CAACmB,WAAW,CAACnB,CAAC,CAACoB,mBAAmB,CAACE,MAAM,CAAC,CAACL,KAAK,CAACJ,IAAI,CAAC;MACvD;IACF,KAAK,SAAS;MACZb,CAAC,CAACuB,iBAAiB,CAACvB,CAAC,CAACwB,wBAAwB,CAACC,OAAO,CAAC,CAACR,KAAK,CAACJ,IAAI,CAAC;MACnE;IACF,KAAK,QAAQ;MACXb,CAAC,CAACuB,iBAAiB,CAACvB,CAAC,CAACwB,wBAAwB,CAACE,KAAK,CAAC,CAACT,KAAK,CAACJ,IAAI,CAAC;MACjE;IACF,KAAK,SAAS;MACZb,CAAC,CAACuB,iBAAiB,CAACvB,CAAC,CAACwB,wBAAwB,CAACG,OAAO,CAAC,CAACV,KAAK,CAACJ,IAAI,CAAC;MACnE;EACJ;AACF","ignoreList":[]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ import { Easing, FadeIn, FadeInDown, FadeInUp, FadeOut, FadeOutDown, FadeOutUp, LinearTransition, ReduceMotion, SlideOutLeft, SlideOutRight, ZoomIn, ZoomOut } from 'react-native-reanimated';
4
+ import { native } from '@nexub/tokens/native';
5
+
6
+ // Layout-animation presets built from the same spring tokens as the web
7
+ // (`motion.spring.*` → CSS linear() there, Reanimated springs here).
8
+ // Enter rides `spatial` (position and size, a hair of settle); exit is quicker
9
+ // on `effects` and never overshoots. Every preset honours the OS Reduce Motion
10
+ // setting (ReduceMotion.System): the change lands without travel.
11
+
12
+ /** `withSpring` config for a spring token, honouring Reduce Motion. */
13
+ export function nxSpring(family = 'spatial', speed = 'default') {
14
+ return {
15
+ ...native.motion.spring[family][speed],
16
+ reduceMotion: ReduceMotion.System
17
+ };
18
+ }
19
+ const ENTER = {
20
+ fade: FadeIn,
21
+ up: FadeInUp,
22
+ down: FadeInDown,
23
+ scale: ZoomIn
24
+ };
25
+ const EXIT = {
26
+ fade: FadeOut,
27
+ up: FadeOutUp,
28
+ down: FadeOutDown,
29
+ scale: ZoomOut
30
+ };
31
+
32
+ /**
33
+ * Settle time of a spring token (ms): when it is within 0.1% of rest. The
34
+ * same rule @nexub/tokens uses for the CSS spring durations.
35
+ */
36
+ export function springSettleMs({
37
+ stiffness,
38
+ damping,
39
+ mass
40
+ }) {
41
+ const dt = 1 / 1000;
42
+ let x = 0;
43
+ let v = 0;
44
+ let still = 0;
45
+ for (let t = 0; t < 3; t += dt) {
46
+ const a = (stiffness * (1 - x) - damping * v) / mass;
47
+ v += a * dt;
48
+ x += v * dt;
49
+ still = Math.abs(1 - x) < 0.001 && Math.abs(v) < 0.01 ? still + 1 : 0;
50
+ if (still > 16) return Math.round((t - 0.016) * 1000);
51
+ }
52
+ return 3000;
53
+ }
54
+
55
+ // Enter and exit run as timed animations lasting the spring token's settle
56
+ // time, on the system decelerate / accelerate curves: Reanimated's
57
+ // physics-spring entering animations (`springify()` with stiffness/damping)
58
+ // left entering views invisible on iOS. Layout transitions move views that are
59
+ // already visible, so they keep the physics spring.
60
+ const decelerate = Easing.bezier(0, 0, 0.2, 1);
61
+ const accelerate = Easing.bezier(0.4, 0, 1, 1);
62
+
63
+ /**
64
+ * `entering` animation, timed to the spatial spring.
65
+ * `up` rises into place (rows, toasts from below); `down` drops in (banners).
66
+ *
67
+ * ```tsx
68
+ * <Animated.View entering={nxEnter('up')} exiting={nxExit('down')} layout={nxLayout()} />
69
+ * ```
70
+ */
71
+ export function nxEnter(kind = 'fade', speed = 'default') {
72
+ return ENTER[kind].duration(springSettleMs(native.motion.spring.spatial[speed])).easing(decelerate).reduceMotion(ReduceMotion.System);
73
+ }
74
+
75
+ /**
76
+ * `exiting` animation, timed to the effects spring: quicker than enter.
77
+ * `start` / `end` slide out toward that edge (swipe-to-delete), following RTL.
78
+ */
79
+ export function nxExit(kind = 'fade', speed = 'fast', rtl = false) {
80
+ const builder = kind === 'start' || kind === 'end' ? kind === 'start' !== rtl ? SlideOutLeft : SlideOutRight : EXIT[kind];
81
+ return builder.duration(springSettleMs(native.motion.spring.effects[speed])).easing(accelerate).reduceMotion(ReduceMotion.System);
82
+ }
83
+
84
+ /** `layout` transition: siblings glide to their new place on the spatial spring. */
85
+ export function nxLayout(speed = 'default') {
86
+ const s = native.motion.spring.spatial[speed];
87
+ return LinearTransition.springify().stiffness(s.stiffness).damping(s.damping).mass(s.mass).reduceMotion(ReduceMotion.System);
88
+ }
89
+ //# sourceMappingURL=motion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Easing","FadeIn","FadeInDown","FadeInUp","FadeOut","FadeOutDown","FadeOutUp","LinearTransition","ReduceMotion","SlideOutLeft","SlideOutRight","ZoomIn","ZoomOut","native","nxSpring","family","speed","motion","spring","reduceMotion","System","ENTER","fade","up","down","scale","EXIT","springSettleMs","stiffness","damping","mass","dt","x","v","still","t","a","Math","abs","round","decelerate","bezier","accelerate","nxEnter","kind","duration","spatial","easing","nxExit","rtl","builder","effects","nxLayout","s","springify"],"sourceRoot":"../../../src","sources":["theme/motion.ts"],"mappings":"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","ignoreList":[]}