number-flow-react-native 0.1.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 (245) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/lib/module/core/constants.js +21 -0
  4. package/lib/module/core/constants.js.map +1 -0
  5. package/lib/module/core/intlHelpers.js +310 -0
  6. package/lib/module/core/intlHelpers.js.map +1 -0
  7. package/lib/module/core/layout.js +71 -0
  8. package/lib/module/core/layout.js.map +1 -0
  9. package/lib/module/core/mask.js +50 -0
  10. package/lib/module/core/mask.js.map +1 -0
  11. package/lib/module/core/numerals/detection.js +105 -0
  12. package/lib/module/core/numerals/detection.js.map +1 -0
  13. package/lib/module/core/numerals/digits.js +128 -0
  14. package/lib/module/core/numerals/digits.js.map +1 -0
  15. package/lib/module/core/numerals/index.js +5 -0
  16. package/lib/module/core/numerals/index.js.map +1 -0
  17. package/lib/module/core/numerals/tables.js +114 -0
  18. package/lib/module/core/numerals/tables.js.map +1 -0
  19. package/lib/module/core/superscript.js +31 -0
  20. package/lib/module/core/superscript.js.map +1 -0
  21. package/lib/module/core/timeLayout.js +98 -0
  22. package/lib/module/core/timeLayout.js.map +1 -0
  23. package/lib/module/core/timeTypes.js +4 -0
  24. package/lib/module/core/timeTypes.js.map +1 -0
  25. package/lib/module/core/timing.js +45 -0
  26. package/lib/module/core/timing.js.map +1 -0
  27. package/lib/module/core/types.js +58 -0
  28. package/lib/module/core/types.js.map +1 -0
  29. package/lib/module/core/useAccessibilityAnnouncement.js +27 -0
  30. package/lib/module/core/useAccessibilityAnnouncement.js.map +1 -0
  31. package/lib/module/core/useAnimatedX.js +25 -0
  32. package/lib/module/core/useAnimatedX.js.map +1 -0
  33. package/lib/module/core/useAnimationLifecycle.js +37 -0
  34. package/lib/module/core/useAnimationLifecycle.js.map +1 -0
  35. package/lib/module/core/useCanAnimate.js +22 -0
  36. package/lib/module/core/useCanAnimate.js.map +1 -0
  37. package/lib/module/core/useContinuousSpin.js +89 -0
  38. package/lib/module/core/useContinuousSpin.js.map +1 -0
  39. package/lib/module/core/useDebouncedWidths.js +74 -0
  40. package/lib/module/core/useDebouncedWidths.js.map +1 -0
  41. package/lib/module/core/useDigitAnimation.js +138 -0
  42. package/lib/module/core/useDigitAnimation.js.map +1 -0
  43. package/lib/module/core/useFlowPipeline.js +85 -0
  44. package/lib/module/core/useFlowPipeline.js.map +1 -0
  45. package/lib/module/core/useFormattedValue.js +28 -0
  46. package/lib/module/core/useFormattedValue.js.map +1 -0
  47. package/lib/module/core/useLayoutDiff.js +59 -0
  48. package/lib/module/core/useLayoutDiff.js.map +1 -0
  49. package/lib/module/core/useNumberFormatting.js +158 -0
  50. package/lib/module/core/useNumberFormatting.js.map +1 -0
  51. package/lib/module/core/useSlotOpacity.js +53 -0
  52. package/lib/module/core/useSlotOpacity.js.map +1 -0
  53. package/lib/module/core/useTimeFormatting.js +74 -0
  54. package/lib/module/core/useTimeFormatting.js.map +1 -0
  55. package/lib/module/core/useTimingResolution.js +21 -0
  56. package/lib/module/core/useTimingResolution.js.map +1 -0
  57. package/lib/module/core/useWorkletFormatting.js +49 -0
  58. package/lib/module/core/useWorkletFormatting.js.map +1 -0
  59. package/lib/module/core/utils.js +132 -0
  60. package/lib/module/core/utils.js.map +1 -0
  61. package/lib/module/core/warnings.js +10 -0
  62. package/lib/module/core/warnings.js.map +1 -0
  63. package/lib/module/index.js +7 -0
  64. package/lib/module/index.js.map +1 -0
  65. package/lib/module/native/DigitSlot.js +163 -0
  66. package/lib/module/native/DigitSlot.js.map +1 -0
  67. package/lib/module/native/NumberFlow.js +244 -0
  68. package/lib/module/native/NumberFlow.js.map +1 -0
  69. package/lib/module/native/SymbolSlot.js +52 -0
  70. package/lib/module/native/SymbolSlot.js.map +1 -0
  71. package/lib/module/native/TimeFlow.js +270 -0
  72. package/lib/module/native/TimeFlow.js.map +1 -0
  73. package/lib/module/native/index.js +5 -0
  74. package/lib/module/native/index.js.map +1 -0
  75. package/lib/module/native/renderSlots.js +108 -0
  76. package/lib/module/native/renderSlots.js.map +1 -0
  77. package/lib/module/native/types.js +4 -0
  78. package/lib/module/native/types.js.map +1 -0
  79. package/lib/module/native/useMeasuredGlyphMetrics.js +156 -0
  80. package/lib/module/native/useMeasuredGlyphMetrics.js.map +1 -0
  81. package/lib/module/package.json +1 -0
  82. package/lib/module/skia/DigitSlot.js +171 -0
  83. package/lib/module/skia/DigitSlot.js.map +1 -0
  84. package/lib/module/skia/SkiaNumberFlow.js +430 -0
  85. package/lib/module/skia/SkiaNumberFlow.js.map +1 -0
  86. package/lib/module/skia/SkiaTimeFlow.js +226 -0
  87. package/lib/module/skia/SkiaTimeFlow.js.map +1 -0
  88. package/lib/module/skia/SymbolSlot.js +92 -0
  89. package/lib/module/skia/SymbolSlot.js.map +1 -0
  90. package/lib/module/skia/index.js +6 -0
  91. package/lib/module/skia/index.js.map +1 -0
  92. package/lib/module/skia/renderSlots.js +131 -0
  93. package/lib/module/skia/renderSlots.js.map +1 -0
  94. package/lib/module/skia/useGlyphMetrics.js +72 -0
  95. package/lib/module/skia/useGlyphMetrics.js.map +1 -0
  96. package/lib/module/skia/useScrubbing.js +165 -0
  97. package/lib/module/skia/useScrubbing.js.map +1 -0
  98. package/lib/module/skia/useSkiaFont.js +23 -0
  99. package/lib/module/skia/useSkiaFont.js.map +1 -0
  100. package/lib/typescript/core/constants.d.ts +15 -0
  101. package/lib/typescript/core/constants.d.ts.map +1 -0
  102. package/lib/typescript/core/intlHelpers.d.ts +10 -0
  103. package/lib/typescript/core/intlHelpers.d.ts.map +1 -0
  104. package/lib/typescript/core/layout.d.ts +22 -0
  105. package/lib/typescript/core/layout.d.ts.map +1 -0
  106. package/lib/typescript/core/mask.d.ts +18 -0
  107. package/lib/typescript/core/mask.d.ts.map +1 -0
  108. package/lib/typescript/core/numerals/detection.d.ts +17 -0
  109. package/lib/typescript/core/numerals/detection.d.ts.map +1 -0
  110. package/lib/typescript/core/numerals/digits.d.ts +43 -0
  111. package/lib/typescript/core/numerals/digits.d.ts.map +1 -0
  112. package/lib/typescript/core/numerals/index.d.ts +3 -0
  113. package/lib/typescript/core/numerals/index.d.ts.map +1 -0
  114. package/lib/typescript/core/numerals/tables.d.ts +32 -0
  115. package/lib/typescript/core/numerals/tables.d.ts.map +1 -0
  116. package/lib/typescript/core/superscript.d.ts +16 -0
  117. package/lib/typescript/core/superscript.d.ts.map +1 -0
  118. package/lib/typescript/core/timeLayout.d.ts +19 -0
  119. package/lib/typescript/core/timeLayout.d.ts.map +1 -0
  120. package/lib/typescript/core/timeTypes.d.ts +80 -0
  121. package/lib/typescript/core/timeTypes.d.ts.map +1 -0
  122. package/lib/typescript/core/timing.d.ts +6 -0
  123. package/lib/typescript/core/timing.d.ts.map +1 -0
  124. package/lib/typescript/core/types.d.ts +165 -0
  125. package/lib/typescript/core/types.d.ts.map +1 -0
  126. package/lib/typescript/core/useAccessibilityAnnouncement.d.ts +10 -0
  127. package/lib/typescript/core/useAccessibilityAnnouncement.d.ts.map +1 -0
  128. package/lib/typescript/core/useAnimatedX.d.ts +9 -0
  129. package/lib/typescript/core/useAnimatedX.d.ts.map +1 -0
  130. package/lib/typescript/core/useAnimationLifecycle.d.ts +14 -0
  131. package/lib/typescript/core/useAnimationLifecycle.d.ts.map +1 -0
  132. package/lib/typescript/core/useCanAnimate.d.ts +14 -0
  133. package/lib/typescript/core/useCanAnimate.d.ts.map +1 -0
  134. package/lib/typescript/core/useContinuousSpin.d.ts +23 -0
  135. package/lib/typescript/core/useContinuousSpin.d.ts.map +1 -0
  136. package/lib/typescript/core/useDebouncedWidths.d.ts +17 -0
  137. package/lib/typescript/core/useDebouncedWidths.d.ts.map +1 -0
  138. package/lib/typescript/core/useDigitAnimation.d.ts +38 -0
  139. package/lib/typescript/core/useDigitAnimation.d.ts.map +1 -0
  140. package/lib/typescript/core/useFlowPipeline.d.ts +46 -0
  141. package/lib/typescript/core/useFlowPipeline.d.ts.map +1 -0
  142. package/lib/typescript/core/useFormattedValue.d.ts +14 -0
  143. package/lib/typescript/core/useFormattedValue.d.ts.map +1 -0
  144. package/lib/typescript/core/useLayoutDiff.d.ts +18 -0
  145. package/lib/typescript/core/useLayoutDiff.d.ts.map +1 -0
  146. package/lib/typescript/core/useNumberFormatting.d.ts +18 -0
  147. package/lib/typescript/core/useNumberFormatting.d.ts.map +1 -0
  148. package/lib/typescript/core/useSlotOpacity.d.ts +18 -0
  149. package/lib/typescript/core/useSlotOpacity.d.ts.map +1 -0
  150. package/lib/typescript/core/useTimeFormatting.d.ts +22 -0
  151. package/lib/typescript/core/useTimeFormatting.d.ts.map +1 -0
  152. package/lib/typescript/core/useTimingResolution.d.ts +13 -0
  153. package/lib/typescript/core/useTimingResolution.d.ts.map +1 -0
  154. package/lib/typescript/core/useWorkletFormatting.d.ts +14 -0
  155. package/lib/typescript/core/useWorkletFormatting.d.ts.map +1 -0
  156. package/lib/typescript/core/utils.d.ts +44 -0
  157. package/lib/typescript/core/utils.d.ts.map +1 -0
  158. package/lib/typescript/core/warnings.d.ts +2 -0
  159. package/lib/typescript/core/warnings.d.ts.map +1 -0
  160. package/lib/typescript/index.d.ts +8 -0
  161. package/lib/typescript/index.d.ts.map +1 -0
  162. package/lib/typescript/native/DigitSlot.d.ts +27 -0
  163. package/lib/typescript/native/DigitSlot.d.ts.map +1 -0
  164. package/lib/typescript/native/NumberFlow.d.ts +3 -0
  165. package/lib/typescript/native/NumberFlow.d.ts.map +1 -0
  166. package/lib/typescript/native/SymbolSlot.d.ts +19 -0
  167. package/lib/typescript/native/SymbolSlot.d.ts.map +1 -0
  168. package/lib/typescript/native/TimeFlow.d.ts +3 -0
  169. package/lib/typescript/native/TimeFlow.d.ts.map +1 -0
  170. package/lib/typescript/native/index.d.ts +3 -0
  171. package/lib/typescript/native/index.d.ts.map +1 -0
  172. package/lib/typescript/native/renderSlots.d.ts +31 -0
  173. package/lib/typescript/native/renderSlots.d.ts.map +1 -0
  174. package/lib/typescript/native/types.d.ts +36 -0
  175. package/lib/typescript/native/types.d.ts.map +1 -0
  176. package/lib/typescript/native/useMeasuredGlyphMetrics.d.ts +8 -0
  177. package/lib/typescript/native/useMeasuredGlyphMetrics.d.ts.map +1 -0
  178. package/lib/typescript/package.json +1 -0
  179. package/lib/typescript/skia/DigitSlot.d.ts +35 -0
  180. package/lib/typescript/skia/DigitSlot.d.ts.map +1 -0
  181. package/lib/typescript/skia/SkiaNumberFlow.d.ts +3 -0
  182. package/lib/typescript/skia/SkiaNumberFlow.d.ts.map +1 -0
  183. package/lib/typescript/skia/SkiaTimeFlow.d.ts +3 -0
  184. package/lib/typescript/skia/SkiaTimeFlow.d.ts.map +1 -0
  185. package/lib/typescript/skia/SymbolSlot.d.ts +26 -0
  186. package/lib/typescript/skia/SymbolSlot.d.ts.map +1 -0
  187. package/lib/typescript/skia/index.d.ts +6 -0
  188. package/lib/typescript/skia/index.d.ts.map +1 -0
  189. package/lib/typescript/skia/renderSlots.d.ts +40 -0
  190. package/lib/typescript/skia/renderSlots.d.ts.map +1 -0
  191. package/lib/typescript/skia/useGlyphMetrics.d.ts +16 -0
  192. package/lib/typescript/skia/useGlyphMetrics.d.ts.map +1 -0
  193. package/lib/typescript/skia/useScrubbing.d.ts +59 -0
  194. package/lib/typescript/skia/useScrubbing.d.ts.map +1 -0
  195. package/lib/typescript/skia/useSkiaFont.d.ts +13 -0
  196. package/lib/typescript/skia/useSkiaFont.d.ts.map +1 -0
  197. package/package.json +104 -0
  198. package/src/core/constants.ts +20 -0
  199. package/src/core/intlHelpers.ts +351 -0
  200. package/src/core/layout.ts +108 -0
  201. package/src/core/mask.ts +72 -0
  202. package/src/core/numerals/detection.ts +112 -0
  203. package/src/core/numerals/digits.ts +102 -0
  204. package/src/core/numerals/index.ts +9 -0
  205. package/src/core/numerals/tables.ts +112 -0
  206. package/src/core/superscript.ts +27 -0
  207. package/src/core/timeLayout.ts +119 -0
  208. package/src/core/timeTypes.ts +88 -0
  209. package/src/core/timing.ts +60 -0
  210. package/src/core/types.ts +189 -0
  211. package/src/core/useAccessibilityAnnouncement.ts +27 -0
  212. package/src/core/useAnimatedX.ts +30 -0
  213. package/src/core/useAnimationLifecycle.ts +54 -0
  214. package/src/core/useCanAnimate.ts +21 -0
  215. package/src/core/useContinuousSpin.ts +112 -0
  216. package/src/core/useDebouncedWidths.ts +93 -0
  217. package/src/core/useDigitAnimation.ts +192 -0
  218. package/src/core/useFlowPipeline.ts +126 -0
  219. package/src/core/useFormattedValue.ts +32 -0
  220. package/src/core/useLayoutDiff.ts +71 -0
  221. package/src/core/useNumberFormatting.ts +164 -0
  222. package/src/core/useSlotOpacity.ts +66 -0
  223. package/src/core/useTimeFormatting.ts +95 -0
  224. package/src/core/useTimingResolution.ts +47 -0
  225. package/src/core/useWorkletFormatting.ts +59 -0
  226. package/src/core/utils.ts +149 -0
  227. package/src/core/warnings.ts +8 -0
  228. package/src/index.ts +15 -0
  229. package/src/native/DigitSlot.tsx +203 -0
  230. package/src/native/NumberFlow.tsx +287 -0
  231. package/src/native/SymbolSlot.tsx +68 -0
  232. package/src/native/TimeFlow.tsx +287 -0
  233. package/src/native/index.ts +2 -0
  234. package/src/native/renderSlots.tsx +150 -0
  235. package/src/native/types.ts +40 -0
  236. package/src/native/useMeasuredGlyphMetrics.tsx +205 -0
  237. package/src/skia/DigitSlot.tsx +221 -0
  238. package/src/skia/SkiaNumberFlow.tsx +506 -0
  239. package/src/skia/SkiaTimeFlow.tsx +257 -0
  240. package/src/skia/SymbolSlot.tsx +120 -0
  241. package/src/skia/index.ts +5 -0
  242. package/src/skia/renderSlots.tsx +180 -0
  243. package/src/skia/useGlyphMetrics.ts +79 -0
  244. package/src/skia/useScrubbing.ts +223 -0
  245. package/src/skia/useSkiaFont.ts +25 -0
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+
3
+ import { useMemo } from "react";
4
+ import { getOrCreateFormatter, safeFormatToParts } from "./intlHelpers.js";
5
+ import { detectOutputZeroCodePoint, localeDigitValue } from "./numerals/index.js";
6
+ /**
7
+ * Transforms `Intl.NumberFormat.formatToParts()` output into a flat array of
8
+ * stably-keyed single-character parts. Integer digits are keyed right-to-left
9
+ * (ones = `integer:0`, tens = `integer:1`, etc.) so that the ones place always
10
+ * maps to the same React key regardless of digit count. Fraction digits are
11
+ * keyed left-to-right from the decimal point (`fraction:0` = tenths, etc.).
12
+ *
13
+ * This keying ensures correct animation behavior when digits are added/removed
14
+ * (e.g., 9→10: ones place spins 9→0, tens place enters as new digit).
15
+ */
16
+ export function formatToKeyedParts(value, formatter, locales, prefix = "", suffix = "") {
17
+ const rawParts = safeFormatToParts(formatter, value, locales);
18
+
19
+ /**
20
+ * Detect the actual zero codepoint from the formatted output rather than
21
+ * trusting resolvedOptions().numberingSystem. Hermes may report "arab" but
22
+ * output Latin digits, or vice versa. Output-based detection is always correct.
23
+ */
24
+ const rawString = rawParts.map(p => p.value).join("");
25
+ const zeroCP = detectOutputZeroCodePoint(rawString);
26
+
27
+ // Step 1: Flatten all parts into single characters with their source type
28
+
29
+ const flatChars = [];
30
+ for (const char of prefix) {
31
+ flatChars.push({
32
+ sourceType: "prefix",
33
+ char
34
+ });
35
+ }
36
+ for (const part of rawParts) {
37
+ // Merge signs into unified types.
38
+ // The fallback parser emits extended types (exponentMinusSign, etc.)
39
+ // that aren't in Intl.NumberFormatPart["type"], so we widen to string.
40
+ const partType = part.type;
41
+ const type = partType === "minusSign" || partType === "plusSign" ? "sign" : partType === "exponentMinusSign" || partType === "exponentPlusSign" ? "exponentSign" : partType;
42
+
43
+ // Replace exponentSeparator "E" with ×10 display
44
+ if (type === "exponentSeparator") {
45
+ flatChars.push({
46
+ sourceType: "exponentSeparator",
47
+ char: "\u00D7"
48
+ });
49
+ flatChars.push({
50
+ sourceType: "exponentSeparator",
51
+ char: "1"
52
+ });
53
+ flatChars.push({
54
+ sourceType: "exponentSeparator",
55
+ char: "0"
56
+ });
57
+ continue;
58
+ }
59
+
60
+ // Flatten digit sequences into individual characters
61
+ if (type === "integer" || type === "fraction" || type === "exponentInteger") {
62
+ for (const char of part.value) {
63
+ flatChars.push({
64
+ sourceType: type,
65
+ char
66
+ });
67
+ }
68
+ } else {
69
+ flatChars.push({
70
+ sourceType: type,
71
+ char: part.value
72
+ });
73
+ }
74
+ }
75
+ for (const char of suffix) {
76
+ flatChars.push({
77
+ sourceType: "suffix",
78
+ char
79
+ });
80
+ }
81
+
82
+ // Step 2: Key characters — integers+groups RTL, everything else LTR
83
+ const result = new Array(flatChars.length);
84
+ const counts = {};
85
+ const nextKey = type => `${type}:${counts[type] = (counts[type] ?? -1) + 1}`;
86
+
87
+ // Find all integer + group indices (they form one contiguous block to key RTL)
88
+ const integerGroupIndices = [];
89
+ for (let i = 0; i < flatChars.length; i++) {
90
+ if (flatChars[i].sourceType === "integer" || flatChars[i].sourceType === "group") {
91
+ integerGroupIndices.push(i);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Key integer digits and group separators RTL — rightmost integer digit
97
+ * gets "integer:0" (ones place), next gets "integer:1" (tens), etc.
98
+ */
99
+ for (let i = integerGroupIndices.length - 1; i >= 0; i--) {
100
+ const idx = integerGroupIndices[i];
101
+ const fc = flatChars[idx];
102
+ const isDigit = fc.sourceType === "integer";
103
+ result[idx] = {
104
+ key: nextKey(fc.sourceType),
105
+ type: isDigit ? "digit" : "symbol",
106
+ char: fc.char,
107
+ digitValue: isDigit ? localeDigitValue(fc.char.charCodeAt(0), zeroCP) : -1
108
+ };
109
+ }
110
+
111
+ // Find all exponent integer indices (key RTL, same logic as mantissa integers)
112
+ const exponentIntegerIndices = [];
113
+ for (let i = 0; i < flatChars.length; i++) {
114
+ if (flatChars[i].sourceType === "exponentInteger") {
115
+ exponentIntegerIndices.push(i);
116
+ }
117
+ }
118
+ for (let i = exponentIntegerIndices.length - 1; i >= 0; i--) {
119
+ const idx = exponentIntegerIndices[i];
120
+ const fc = flatChars[idx];
121
+ result[idx] = {
122
+ key: nextKey("exponentInteger"),
123
+ type: "digit",
124
+ char: fc.char,
125
+ digitValue: localeDigitValue(fc.char.charCodeAt(0), zeroCP)
126
+ };
127
+ }
128
+
129
+ // Key everything else LTR (fraction, decimal, prefix, suffix, exponentSeparator, exponentSign, etc.)
130
+ for (let i = 0; i < flatChars.length; i++) {
131
+ if (result[i]) continue; // already keyed (integer, group, or exponentInteger)
132
+ const fc = flatChars[i];
133
+ const isDigit = fc.sourceType === "fraction";
134
+ result[i] = {
135
+ key: nextKey(fc.sourceType),
136
+ type: isDigit ? "digit" : "symbol",
137
+ char: fc.char,
138
+ digitValue: isDigit ? localeDigitValue(fc.char.charCodeAt(0), zeroCP) : -1
139
+ };
140
+ }
141
+ return result;
142
+ }
143
+
144
+ /**
145
+ * Hook that formats a numeric value into stably-keyed character parts.
146
+ * Uses Intl.NumberFormat.formatToParts() with RTL integer keying.
147
+ */
148
+ export function useNumberFormatting(value, format, locales, prefix, suffix) {
149
+ // Serialize format/locales to a stable string — avoids re-runs when callers pass inline objects
150
+ const formatKey = useMemo(() => JSON.stringify([locales, format]), [locales, format]);
151
+ return useMemo(() => {
152
+ if (value === undefined) return [];
153
+ const formatter = getOrCreateFormatter(locales, format);
154
+ return formatToKeyedParts(value, formatter, locales, prefix, suffix);
155
+ // eslint-disable-next-line react-hooks/exhaustive-deps
156
+ }, [value, prefix, suffix, formatKey]);
157
+ }
158
+ //# sourceMappingURL=useNumberFormatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","getOrCreateFormatter","safeFormatToParts","detectOutputZeroCodePoint","localeDigitValue","formatToKeyedParts","value","formatter","locales","prefix","suffix","rawParts","rawString","map","p","join","zeroCP","flatChars","char","push","sourceType","part","partType","type","result","Array","length","counts","nextKey","integerGroupIndices","i","idx","fc","isDigit","key","digitValue","charCodeAt","exponentIntegerIndices","useNumberFormatting","format","formatKey","JSON","stringify","undefined"],"sourceRoot":"../../../src","sources":["core/useNumberFormatting.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,oBAAoB,EAAEC,iBAAiB,QAAQ,kBAAe;AACvE,SAASC,yBAAyB,EAAEC,gBAAgB,QAAQ,qBAAY;AAGxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAChCC,KAAa,EACbC,SAA4B,EAC5BC,OAAyC,EACzCC,MAAM,GAAG,EAAE,EACXC,MAAM,GAAG,EAAE,EACE;EACb,MAAMC,QAAQ,GAAGT,iBAAiB,CAACK,SAAS,EAAED,KAAK,EAAEE,OAAO,CAAC;;EAE7D;AACF;AACA;AACA;AACA;EACE,MAAMI,SAAS,GAAGD,QAAQ,CAACE,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAACR,KAAK,CAAC,CAACS,IAAI,CAAC,EAAE,CAAC;EACvD,MAAMC,MAAM,GAAGb,yBAAyB,CAACS,SAAS,CAAC;;EAEnD;;EAMA,MAAMK,SAAqB,GAAG,EAAE;EAEhC,KAAK,MAAMC,IAAI,IAAIT,MAAM,EAAE;IACzBQ,SAAS,CAACE,IAAI,CAAC;MAAEC,UAAU,EAAE,QAAQ;MAAEF;IAAK,CAAC,CAAC;EAChD;EAEA,KAAK,MAAMG,IAAI,IAAIV,QAAQ,EAAE;IAC3B;IACA;IACA;IACA,MAAMW,QAAQ,GAAGD,IAAI,CAACE,IAAc;IACpC,MAAMA,IAAI,GACRD,QAAQ,KAAK,WAAW,IAAIA,QAAQ,KAAK,UAAU,GAC/C,MAAM,GACNA,QAAQ,KAAK,mBAAmB,IAAIA,QAAQ,KAAK,kBAAkB,GACjE,cAAc,GACdA,QAAQ;;IAEhB;IACA,IAAIC,IAAI,KAAK,mBAAmB,EAAE;MAChCN,SAAS,CAACE,IAAI,CAAC;QAAEC,UAAU,EAAE,mBAAmB;QAAEF,IAAI,EAAE;MAAS,CAAC,CAAC;MACnED,SAAS,CAACE,IAAI,CAAC;QAAEC,UAAU,EAAE,mBAAmB;QAAEF,IAAI,EAAE;MAAI,CAAC,CAAC;MAC9DD,SAAS,CAACE,IAAI,CAAC;QAAEC,UAAU,EAAE,mBAAmB;QAAEF,IAAI,EAAE;MAAI,CAAC,CAAC;MAC9D;IACF;;IAEA;IACA,IAAIK,IAAI,KAAK,SAAS,IAAIA,IAAI,KAAK,UAAU,IAAIA,IAAI,KAAK,iBAAiB,EAAE;MAC3E,KAAK,MAAML,IAAI,IAAIG,IAAI,CAACf,KAAK,EAAE;QAC7BW,SAAS,CAACE,IAAI,CAAC;UAAEC,UAAU,EAAEG,IAAI;UAAEL;QAAK,CAAC,CAAC;MAC5C;IACF,CAAC,MAAM;MACLD,SAAS,CAACE,IAAI,CAAC;QAAEC,UAAU,EAAEG,IAAI;QAAEL,IAAI,EAAEG,IAAI,CAACf;MAAM,CAAC,CAAC;IACxD;EACF;EAEA,KAAK,MAAMY,IAAI,IAAIR,MAAM,EAAE;IACzBO,SAAS,CAACE,IAAI,CAAC;MAAEC,UAAU,EAAE,QAAQ;MAAEF;IAAK,CAAC,CAAC;EAChD;;EAEA;EACA,MAAMM,MAAmB,GAAG,IAAIC,KAAK,CAACR,SAAS,CAACS,MAAM,CAAC;EACvD,MAAMC,MAA8B,GAAG,CAAC,CAAC;EAEzC,MAAMC,OAAO,GAAIL,IAAY,IAAK,GAAGA,IAAI,IAAKI,MAAM,CAACJ,IAAI,CAAC,GAAG,CAACI,MAAM,CAACJ,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAG;;EAExF;EACA,MAAMM,mBAA6B,GAAG,EAAE;EACxC,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGb,SAAS,CAACS,MAAM,EAAEI,CAAC,EAAE,EAAE;IACzC,IAAIb,SAAS,CAACa,CAAC,CAAC,CAACV,UAAU,KAAK,SAAS,IAAIH,SAAS,CAACa,CAAC,CAAC,CAACV,UAAU,KAAK,OAAO,EAAE;MAChFS,mBAAmB,CAACV,IAAI,CAACW,CAAC,CAAC;IAC7B;EACF;;EAEA;AACF;AACA;AACA;EACE,KAAK,IAAIA,CAAC,GAAGD,mBAAmB,CAACH,MAAM,GAAG,CAAC,EAAEI,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;IACxD,MAAMC,GAAG,GAAGF,mBAAmB,CAACC,CAAC,CAAC;IAClC,MAAME,EAAE,GAAGf,SAAS,CAACc,GAAG,CAAC;IACzB,MAAME,OAAO,GAAGD,EAAE,CAACZ,UAAU,KAAK,SAAS;IAC3CI,MAAM,CAACO,GAAG,CAAC,GAAG;MACZG,GAAG,EAAEN,OAAO,CAACI,EAAE,CAACZ,UAAU,CAAC;MAC3BG,IAAI,EAAEU,OAAO,GAAG,OAAO,GAAG,QAAQ;MAClCf,IAAI,EAAEc,EAAE,CAACd,IAAI;MACbiB,UAAU,EAAEF,OAAO,GAAG7B,gBAAgB,CAAC4B,EAAE,CAACd,IAAI,CAACkB,UAAU,CAAC,CAAC,CAAC,EAAEpB,MAAM,CAAC,GAAG,CAAC;IAC3E,CAAC;EACH;;EAEA;EACA,MAAMqB,sBAAgC,GAAG,EAAE;EAC3C,KAAK,IAAIP,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGb,SAAS,CAACS,MAAM,EAAEI,CAAC,EAAE,EAAE;IACzC,IAAIb,SAAS,CAACa,CAAC,CAAC,CAACV,UAAU,KAAK,iBAAiB,EAAE;MACjDiB,sBAAsB,CAAClB,IAAI,CAACW,CAAC,CAAC;IAChC;EACF;EAEA,KAAK,IAAIA,CAAC,GAAGO,sBAAsB,CAACX,MAAM,GAAG,CAAC,EAAEI,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;IAC3D,MAAMC,GAAG,GAAGM,sBAAsB,CAACP,CAAC,CAAC;IACrC,MAAME,EAAE,GAAGf,SAAS,CAACc,GAAG,CAAC;IACzBP,MAAM,CAACO,GAAG,CAAC,GAAG;MACZG,GAAG,EAAEN,OAAO,CAAC,iBAAiB,CAAC;MAC/BL,IAAI,EAAE,OAAO;MACbL,IAAI,EAAEc,EAAE,CAACd,IAAI;MACbiB,UAAU,EAAE/B,gBAAgB,CAAC4B,EAAE,CAACd,IAAI,CAACkB,UAAU,CAAC,CAAC,CAAC,EAAEpB,MAAM;IAC5D,CAAC;EACH;;EAEA;EACA,KAAK,IAAIc,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGb,SAAS,CAACS,MAAM,EAAEI,CAAC,EAAE,EAAE;IACzC,IAAIN,MAAM,CAACM,CAAC,CAAC,EAAE,SAAS,CAAC;IACzB,MAAME,EAAE,GAAGf,SAAS,CAACa,CAAC,CAAC;IACvB,MAAMG,OAAO,GAAGD,EAAE,CAACZ,UAAU,KAAK,UAAU;IAC5CI,MAAM,CAACM,CAAC,CAAC,GAAG;MACVI,GAAG,EAAEN,OAAO,CAACI,EAAE,CAACZ,UAAU,CAAC;MAC3BG,IAAI,EAAEU,OAAO,GAAG,OAAO,GAAG,QAAQ;MAClCf,IAAI,EAAEc,EAAE,CAACd,IAAI;MACbiB,UAAU,EAAEF,OAAO,GAAG7B,gBAAgB,CAAC4B,EAAE,CAACd,IAAI,CAACkB,UAAU,CAAC,CAAC,CAAC,EAAEpB,MAAM,CAAC,GAAG,CAAC;IAC3E,CAAC;EACH;EAEA,OAAOQ,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASc,mBAAmBA,CACjChC,KAAyB,EACzBiC,MAA4C,EAC5C/B,OAAyC,EACzCC,MAAc,EACdC,MAAc,EACD;EACb;EACA,MAAM8B,SAAS,GAAGxC,OAAO,CAAC,MAAMyC,IAAI,CAACC,SAAS,CAAC,CAAClC,OAAO,EAAE+B,MAAM,CAAC,CAAC,EAAE,CAAC/B,OAAO,EAAE+B,MAAM,CAAC,CAAC;EAErF,OAAOvC,OAAO,CAAC,MAAM;IACnB,IAAIM,KAAK,KAAKqC,SAAS,EAAE,OAAO,EAAE;IAClC,MAAMpC,SAAS,GAAGN,oBAAoB,CAACO,OAAO,EAAE+B,MAAM,CAAC;IACvD,OAAOlC,kBAAkB,CAACC,KAAK,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,MAAM,CAAC;IACpE;EACF,CAAC,EAAE,CAACJ,KAAK,EAAEG,MAAM,EAAEC,MAAM,EAAE8B,SAAS,CAAC,CAAC;AACxC","ignoreList":[]}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ import { useLayoutEffect, useRef, useState } from "react";
4
+ import { makeMutable, runOnJS, withTiming } from "react-native-reanimated";
5
+
6
+ /**
7
+ * We use makeMutable (via useState) instead of useSharedValue because
8
+ * useSharedValue's cleanup calls cancelAnimation, which kills in-flight
9
+ * animations when the component re-renders in StrictMode.
10
+ */
11
+
12
+ export function useSlotOpacity({
13
+ entering,
14
+ exiting,
15
+ opacityTiming,
16
+ exitKey,
17
+ onExitComplete,
18
+ onExitingStart
19
+ }) {
20
+ const [slotOpacity] = useState(() => makeMutable(entering ? 0 : 1));
21
+ const prevStateRef = useRef(null);
22
+ const currentState = entering ? "entering" : exiting ? "exiting" : "active";
23
+ useLayoutEffect(() => {
24
+ if (currentState === prevStateRef.current) return;
25
+ const wasInitial = prevStateRef.current === null;
26
+ prevStateRef.current = currentState;
27
+ if (currentState === "entering") {
28
+ slotOpacity.value = withTiming(1, {
29
+ duration: opacityTiming.duration,
30
+ easing: opacityTiming.easing
31
+ });
32
+ } else if (currentState === "exiting") {
33
+ slotOpacity.value = withTiming(0, {
34
+ duration: opacityTiming.duration,
35
+ easing: opacityTiming.easing
36
+ }, finished => {
37
+ "worklet";
38
+
39
+ if (finished && onExitComplete && exitKey) {
40
+ runOnJS(onExitComplete)(exitKey);
41
+ }
42
+ });
43
+ onExitingStart?.();
44
+ } else if (!wasInitial) {
45
+ slotOpacity.value = withTiming(1, {
46
+ duration: opacityTiming.duration,
47
+ easing: opacityTiming.easing
48
+ });
49
+ }
50
+ }, [currentState, opacityTiming, exitKey, onExitComplete, onExitingStart, slotOpacity]);
51
+ return slotOpacity;
52
+ }
53
+ //# sourceMappingURL=useSlotOpacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useLayoutEffect","useRef","useState","makeMutable","runOnJS","withTiming","useSlotOpacity","entering","exiting","opacityTiming","exitKey","onExitComplete","onExitingStart","slotOpacity","prevStateRef","currentState","current","wasInitial","value","duration","easing","finished"],"sourceRoot":"../../../src","sources":["core/useSlotOpacity.ts"],"mappings":";;AAAA,SAASA,eAAe,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AACzD,SAASC,WAAW,EAAEC,OAAO,EAAoBC,UAAU,QAAQ,yBAAyB;;AAG5F;AACA;AACA;AACA;AACA;;AAWA,OAAO,SAASC,cAAcA,CAAC;EAC7BC,QAAQ;EACRC,OAAO;EACPC,aAAa;EACbC,OAAO;EACPC,cAAc;EACdC;AACoB,CAAC,EAAuB;EAC5C,MAAM,CAACC,WAAW,CAAC,GAAGX,QAAQ,CAAC,MAAMC,WAAW,CAACI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EACnE,MAAMO,YAAY,GAAGb,MAAM,CAA2C,IAAI,CAAC;EAC3E,MAAMc,YAAY,GAAGR,QAAQ,GAAG,UAAU,GAAGC,OAAO,GAAG,SAAS,GAAG,QAAQ;EAE3ER,eAAe,CAAC,MAAM;IACpB,IAAIe,YAAY,KAAKD,YAAY,CAACE,OAAO,EAAE;IAC3C,MAAMC,UAAU,GAAGH,YAAY,CAACE,OAAO,KAAK,IAAI;IAChDF,YAAY,CAACE,OAAO,GAAGD,YAAY;IAEnC,IAAIA,YAAY,KAAK,UAAU,EAAE;MAC/BF,WAAW,CAACK,KAAK,GAAGb,UAAU,CAAC,CAAC,EAAE;QAChCc,QAAQ,EAAEV,aAAa,CAACU,QAAQ;QAChCC,MAAM,EAAEX,aAAa,CAACW;MACxB,CAAC,CAAC;IACJ,CAAC,MAAM,IAAIL,YAAY,KAAK,SAAS,EAAE;MACrCF,WAAW,CAACK,KAAK,GAAGb,UAAU,CAC5B,CAAC,EACD;QACEc,QAAQ,EAAEV,aAAa,CAACU,QAAQ;QAChCC,MAAM,EAAEX,aAAa,CAACW;MACxB,CAAC,EACAC,QAAQ,IAAK;QACZ,SAAS;;QACT,IAAIA,QAAQ,IAAIV,cAAc,IAAID,OAAO,EAAE;UACzCN,OAAO,CAACO,cAAc,CAAC,CAACD,OAAO,CAAC;QAClC;MACF,CACF,CAAC;MACDE,cAAc,GAAG,CAAC;IACpB,CAAC,MAAM,IAAI,CAACK,UAAU,EAAE;MACtBJ,WAAW,CAACK,KAAK,GAAGb,UAAU,CAAC,CAAC,EAAE;QAChCc,QAAQ,EAAEV,aAAa,CAACU,QAAQ;QAChCC,MAAM,EAAEX,aAAa,CAACW;MACxB,CAAC,CAAC;IACJ;EACF,CAAC,EAAE,CAACL,YAAY,EAAEN,aAAa,EAAEC,OAAO,EAAEC,cAAc,EAAEC,cAAc,EAAEC,WAAW,CAAC,CAAC;EAEvF,OAAOA,WAAW;AACpB","ignoreList":[]}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ import { useMemo } from "react";
4
+ import { digitPart, symbolPart } from "./types.js";
5
+
6
+ /**
7
+ * Converts 24h hours (0-23) to 12h display value (1-12).
8
+ * 0 → 12 (12 AM), 1-12 → as-is, 13-23 → subtract 12.
9
+ */
10
+ export function to12Hour(h) {
11
+ if (h === 0) return 12;
12
+ if (h > 12) return h - 12;
13
+ return h;
14
+ }
15
+
16
+ /**
17
+ * Builds a time display into stably-keyed character parts.
18
+ *
19
+ * Each digit position gets a fixed semantic key (h10, h1, m10, m1, s10, s1)
20
+ * regardless of the actual value. This ensures correct enter/exit animation
21
+ * behavior — e.g. when hours go from 9→10, the h10 key *enters* (fades in)
22
+ * rather than shifting all existing positions.
23
+ */
24
+ export function formatTimeToKeyedParts(hours, minutes, seconds, is24Hour, padHours) {
25
+ const parts = [];
26
+ const hasHours = hours !== undefined;
27
+ const hasSeconds = seconds !== undefined;
28
+ if (hasHours) {
29
+ const displayHours = is24Hour ? hours : to12Hour(hours);
30
+ const h10 = Math.floor(displayHours / 10);
31
+ const h1 = displayHours % 10;
32
+
33
+ // Hours tens digit — only shown if >= 10 or padding is on
34
+ if (h10 > 0 || padHours) {
35
+ parts.push(digitPart("h10", h10));
36
+ }
37
+ parts.push(digitPart("h1", h1));
38
+ parts.push(symbolPart("sep", ":"));
39
+ }
40
+ const m10 = Math.floor(minutes / 10);
41
+ const m1 = minutes % 10;
42
+ parts.push(digitPart("m10", m10));
43
+ parts.push(digitPart("m1", m1));
44
+ if (hasSeconds) {
45
+ parts.push(symbolPart("sep2", ":"));
46
+ const s10 = Math.floor(seconds / 10);
47
+ const s1 = seconds % 10;
48
+ parts.push(digitPart("s10", s10));
49
+ parts.push(digitPart("s1", s1));
50
+ }
51
+
52
+ /**
53
+ * Each character gets a value-dependent key so AM→PM triggers exit/enter crossfade.
54
+ * Characters are emitted individually for correct glyph width measurement.
55
+ */
56
+ if (hasHours && !is24Hour) {
57
+ const label = hours < 12 ? "AM" : "PM";
58
+ parts.push(symbolPart("ampm-sp", " "));
59
+ for (let i = 0; i < label.length; i++) {
60
+ parts.push(symbolPart(`ampm:${label}:${i}`, label[i]));
61
+ }
62
+ }
63
+ return parts;
64
+ }
65
+
66
+ /**
67
+ * Hook that formats time values into stably-keyed character parts.
68
+ * Uses fixed positional keys (h10, h1, sep, m10, m1, etc.) instead of
69
+ * NumberFlow's RTL integer keying.
70
+ */
71
+ export function useTimeFormatting(hours, minutes, seconds, is24Hour, padHours) {
72
+ return useMemo(() => formatTimeToKeyedParts(hours, minutes, seconds, is24Hour, padHours), [hours, minutes, seconds, is24Hour, padHours]);
73
+ }
74
+ //# sourceMappingURL=useTimeFormatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","digitPart","symbolPart","to12Hour","h","formatTimeToKeyedParts","hours","minutes","seconds","is24Hour","padHours","parts","hasHours","undefined","hasSeconds","displayHours","h10","Math","floor","h1","push","m10","m1","s10","s1","label","i","length","useTimeFormatting"],"sourceRoot":"../../../src","sources":["core/useTimeFormatting.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ import { DEFAULT_OPACITY_TIMING, DEFAULT_SPIN_TIMING, DEFAULT_TRANSFORM_TIMING, ZERO_TIMING } from "./timing.js";
4
+ import { useCanAnimate } from "./useCanAnimate.js";
5
+ /**
6
+ * Resolves animation timing based on the `animated` prop and reduced-motion preference.
7
+ * When animations are disabled, all timings collapse to zero-duration.
8
+ */
9
+ export function useTimingResolution(animated, respectMotionPreference, spinTiming, opacityTiming, transformTiming) {
10
+ const canAnimate = useCanAnimate(respectMotionPreference);
11
+ const shouldAnimate = (animated ?? true) && canAnimate;
12
+ const resolvedSpinTiming = shouldAnimate ? spinTiming ?? DEFAULT_SPIN_TIMING : ZERO_TIMING;
13
+ const resolvedOpacityTiming = shouldAnimate ? opacityTiming ?? DEFAULT_OPACITY_TIMING : ZERO_TIMING;
14
+ const resolvedTransformTiming = shouldAnimate ? transformTiming ?? DEFAULT_TRANSFORM_TIMING : ZERO_TIMING;
15
+ return {
16
+ resolvedSpinTiming,
17
+ resolvedOpacityTiming,
18
+ resolvedTransformTiming
19
+ };
20
+ }
21
+ //# sourceMappingURL=useTimingResolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_OPACITY_TIMING","DEFAULT_SPIN_TIMING","DEFAULT_TRANSFORM_TIMING","ZERO_TIMING","useCanAnimate","useTimingResolution","animated","respectMotionPreference","spinTiming","opacityTiming","transformTiming","canAnimate","shouldAnimate","resolvedSpinTiming","resolvedOpacityTiming","resolvedTransformTiming"],"sourceRoot":"../../../src","sources":["core/useTimingResolution.ts"],"mappings":";;AACA,SACEA,sBAAsB,EACtBC,mBAAmB,EACnBC,wBAAwB,EACxBC,WAAW,QACN,aAAU;AACjB,SAASC,aAAa,QAAQ,oBAAiB;AAQ/C;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CACjCC,QAA6B,EAC7BC,uBAA4C,EAC5CC,UAAyB,EACzBC,aAA4B,EAC5BC,eAA8B,EACb;EACjB,MAAMC,UAAU,GAAGP,aAAa,CAACG,uBAAuB,CAAC;EACzD,MAAMK,aAAa,GAAG,CAACN,QAAQ,IAAI,IAAI,KAAKK,UAAU;EAEtD,MAAME,kBAAkB,GAAGD,aAAa,GACnCJ,UAAU,IAAIP,mBAAmB,GAClCE,WAAW;EAEf,MAAMW,qBAAqB,GAAGF,aAAa,GACtCH,aAAa,IAAIT,sBAAsB,GACxCG,WAAW;EAEf,MAAMY,uBAAuB,GAAGH,aAAa,GACxCF,eAAe,IAAIR,wBAAwB,GAC5CC,WAAW;EAEf,OAAO;IACLU,kBAAkB;IAClBC,qBAAqB;IACrBC;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ import { useState } from "react";
4
+ import { makeMutable, useAnimatedReaction } from "react-native-reanimated";
5
+ import { MAX_SLOTS } from "./constants.js";
6
+ import { localeDigitValue } from "./numerals/index.js";
7
+
8
+ /**
9
+ * Watches a SharedValue<string> and extracts per-digit numeric values on the
10
+ * UI thread. Returns an array of SharedValues indexed by digit position
11
+ * (0 = first digit, 1 = second digit, etc.), skipping non-digit characters.
12
+ *
13
+ * This enables zero-latency digit updates during chart scrubbing — the worklet
14
+ * writes directly to SharedValues without crossing the JS bridge.
15
+ *
16
+ * When sharedValue is empty (e.g., scrubbing ended), all slots are set to
17
+ * -1, signaling DigitSlots to fall back to prop-driven animated updates.
18
+ */
19
+ export function useWorkletFormatting(sharedValue, prefix, suffix, zeroCodePoint = 48) {
20
+ const [digitValues] = useState(() => Array.from({
21
+ length: MAX_SLOTS
22
+ }, () => makeMutable(-1)));
23
+ useAnimatedReaction(() => sharedValue?.value ?? "", (current, previous) => {
24
+ if (current === previous) return;
25
+ if (!current) {
26
+ for (let i = 0; i < MAX_SLOTS; i++) {
27
+ digitValues[i].value = -1;
28
+ }
29
+ return;
30
+ }
31
+ const fullText = prefix + current + suffix;
32
+ const len = fullText.length;
33
+ let digitIndex = 0;
34
+ for (let i = 0; i < len && digitIndex < MAX_SLOTS; i++) {
35
+ const code = fullText.charCodeAt(i);
36
+ const dv = localeDigitValue(code, zeroCodePoint);
37
+ if (dv >= 0) {
38
+ digitValues[digitIndex].value = dv;
39
+ digitIndex++;
40
+ }
41
+ }
42
+ for (let i = digitIndex; i < MAX_SLOTS; i++) {
43
+ digitValues[i].value = -1;
44
+ }
45
+ }, [prefix, suffix, zeroCodePoint]);
46
+ if (!sharedValue) return null;
47
+ return digitValues;
48
+ }
49
+ //# sourceMappingURL=useWorkletFormatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useState","makeMutable","useAnimatedReaction","MAX_SLOTS","localeDigitValue","useWorkletFormatting","sharedValue","prefix","suffix","zeroCodePoint","digitValues","Array","from","length","value","current","previous","i","fullText","len","digitIndex","code","charCodeAt","dv"],"sourceRoot":"../../../src","sources":["core/useWorkletFormatting.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,OAAO;AAChC,SAASC,WAAW,EAAoBC,mBAAmB,QAAQ,yBAAyB;AAC5F,SAASC,SAAS,QAAQ,gBAAa;AACvC,SAASC,gBAAgB,QAAQ,qBAAY;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAClCC,WAA4C,EAC5CC,MAAc,EACdC,MAAc,EACdC,aAAa,GAAG,EAAE,EACY;EAC9B,MAAM,CAACC,WAAW,CAAC,GAAGV,QAAQ,CAAC,MAAMW,KAAK,CAACC,IAAI,CAAC;IAAEC,MAAM,EAAEV;EAAU,CAAC,EAAE,MAAMF,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAE9FC,mBAAmB,CACjB,MAAMI,WAAW,EAAEQ,KAAK,IAAI,EAAE,EAC9B,CAACC,OAAO,EAAEC,QAAQ,KAAK;IACrB,IAAID,OAAO,KAAKC,QAAQ,EAAE;IAE1B,IAAI,CAACD,OAAO,EAAE;MACZ,KAAK,IAAIE,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGd,SAAS,EAAEc,CAAC,EAAE,EAAE;QAClCP,WAAW,CAACO,CAAC,CAAC,CAACH,KAAK,GAAG,CAAC,CAAC;MAC3B;MACA;IACF;IAEA,MAAMI,QAAQ,GAAGX,MAAM,GAAGQ,OAAO,GAAGP,MAAM;IAC1C,MAAMW,GAAG,GAAGD,QAAQ,CAACL,MAAM;IAC3B,IAAIO,UAAU,GAAG,CAAC;IAElB,KAAK,IAAIH,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGE,GAAG,IAAIC,UAAU,GAAGjB,SAAS,EAAEc,CAAC,EAAE,EAAE;MACtD,MAAMI,IAAI,GAAGH,QAAQ,CAACI,UAAU,CAACL,CAAC,CAAC;MACnC,MAAMM,EAAE,GAAGnB,gBAAgB,CAACiB,IAAI,EAAEZ,aAAa,CAAC;MAChD,IAAIc,EAAE,IAAI,CAAC,EAAE;QACXb,WAAW,CAACU,UAAU,CAAC,CAACN,KAAK,GAAGS,EAAE;QAClCH,UAAU,EAAE;MACd;IACF;IAEA,KAAK,IAAIH,CAAC,GAAGG,UAAU,EAAEH,CAAC,GAAGd,SAAS,EAAEc,CAAC,EAAE,EAAE;MAC3CP,WAAW,CAACO,CAAC,CAAC,CAACH,KAAK,GAAG,CAAC,CAAC;IAC3B;EACF,CAAC,EACD,CAACP,MAAM,EAAEC,MAAM,EAAEC,aAAa,CAChC,CAAC;EAED,IAAI,CAACH,WAAW,EAAE,OAAO,IAAI;EAC7B,OAAOI,WAAW;AACpB","ignoreList":[]}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+
3
+ import { DIGIT_COUNT } from "./constants.js";
4
+ /**
5
+ * Computes the signed modular offset for digit n relative to virtual
6
+ * scroll position c. Returns a value in [-half, half), where 0 means
7
+ * the digit is centered in the viewport.
8
+ *
9
+ * This is the Reanimated equivalent of NumberFlow's CSS:
10
+ * offset-raw: mod(length + n - mod(c, length), length)
11
+ * offset: offset-raw - length * round(down, offset-raw / (length/2), 1)
12
+ */
13
+ export function signedDigitOffset(n, c, digitCount = DIGIT_COUNT) {
14
+ "worklet";
15
+
16
+ const raw = ((n - c) % digitCount + digitCount) % digitCount;
17
+ const half = digitCount / 2;
18
+ return raw >= half ? raw - digitCount : raw;
19
+ }
20
+
21
+ /**
22
+ * Computes the roll delta for a digit transition, respecting the trend direction.
23
+ *
24
+ * For trend > 0 (always up): 8→2 = +4 (through 9,0,1,2), not -6
25
+ * For trend < 0 (always down): 2→8 = -6 (through 1,0,9,8), not +4
26
+ * For trend = 0 (auto): takes the shortest path
27
+ */
28
+ export function computeRollDelta(prev, next, trend, digitCount = DIGIT_COUNT) {
29
+ "worklet";
30
+
31
+ if (prev === next) return 0;
32
+
33
+ // Always roll up (positive delta)
34
+ if (trend > 0) {
35
+ return next >= prev ? next - prev : digitCount - prev + next;
36
+ }
37
+
38
+ // Always roll down (negative delta)
39
+ if (trend < 0) {
40
+ return next <= prev ? next - prev : -(digitCount - next + prev);
41
+ }
42
+
43
+ // Auto: shortest path
44
+ const half = digitCount / 2;
45
+ const diff = next - prev;
46
+ if (Math.abs(diff) <= half) return diff;
47
+ return diff > 0 ? diff - digitCount : diff + digitCount;
48
+ }
49
+
50
+ /**
51
+ * Resolves a TrendProp (static value or function) into a concrete Trend.
52
+ * When undefined, auto-detects direction from the value change.
53
+ */
54
+ export function resolveTrend(trendProp, prevValue, nextValue) {
55
+ const hasChange = prevValue !== undefined && nextValue !== undefined && prevValue !== nextValue;
56
+
57
+ // Static trend value — pass through
58
+ if (typeof trendProp === "number") {
59
+ return trendProp;
60
+ }
61
+
62
+ // Function trend — call with prev/next when there's an actual change
63
+ if (typeof trendProp === "function") {
64
+ return hasChange ? trendProp(prevValue, nextValue) : 0;
65
+ }
66
+
67
+ // Auto-detect from direction of change
68
+ return hasChange ? Math.sign(nextValue - prevValue) : 0;
69
+ }
70
+
71
+ /**
72
+ * Extracts the significance position from a digit's keyed part key.
73
+ * "integer:2" → 2 (hundreds), "fraction:0" → -1 (tenths).
74
+ * Returns undefined for non-digit keys (symbols, decimals, etc.).
75
+ */
76
+ export function parseDigitPosition(key) {
77
+ "worklet";
78
+
79
+ // Exponent digits are a separate domain — they don't cascade in continuous spin
80
+ if (key.startsWith("exponentInteger:")) return undefined;
81
+ if (key.startsWith("integer:")) {
82
+ return parseInt(key.slice(8), 10);
83
+ }
84
+ if (key.startsWith("fraction:")) {
85
+ return -(parseInt(key.slice(9), 10) + 1);
86
+ }
87
+
88
+ // Time digit keys — significance ordered: s1 < s10 < m1 < m10 < h1 < h10
89
+ switch (key) {
90
+ case "s1":
91
+ return 0;
92
+ case "s10":
93
+ return 1;
94
+ case "m1":
95
+ return 2;
96
+ case "m10":
97
+ return 3;
98
+ case "h1":
99
+ return 4;
100
+ case "h10":
101
+ return 5;
102
+ default:
103
+ return undefined;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Correct wheel size for each time digit position.
109
+ * s10/m10 only go 0-5, h10 only goes 0-2.
110
+ */
111
+ export const TIME_DIGIT_COUNTS = {
112
+ s1: 10,
113
+ s10: 6,
114
+ m1: 10,
115
+ m10: 6,
116
+ h1: 10,
117
+ h10: 3
118
+ };
119
+
120
+ /**
121
+ * Resolves the wheel size for a digit at a given key.
122
+ * Uses the `digits` prop for NumberFlow, or TIME_DIGIT_COUNTS for TimeFlow.
123
+ * Returns DIGIT_COUNT (10) when no constraint applies.
124
+ */
125
+ export function getDigitCount(digits, key) {
126
+ if (!digits) return DIGIT_COUNT;
127
+ const pos = parseDigitPosition(key);
128
+ if (pos === undefined || pos < 0) return DIGIT_COUNT;
129
+ const constraint = digits[pos];
130
+ return constraint ? constraint.max + 1 : DIGIT_COUNT;
131
+ }
132
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DIGIT_COUNT","signedDigitOffset","n","c","digitCount","raw","half","computeRollDelta","prev","next","trend","diff","Math","abs","resolveTrend","trendProp","prevValue","nextValue","hasChange","undefined","sign","parseDigitPosition","key","startsWith","parseInt","slice","TIME_DIGIT_COUNTS","s1","s10","m1","m10","h1","h10","getDigitCount","digits","pos","constraint","max"],"sourceRoot":"../../../src","sources":["core/utils.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ const warned = new Set();
4
+ export function warnOnce(key, message) {
5
+ if (__DEV__ && !warned.has(key)) {
6
+ warned.add(key);
7
+ console.warn(`[NumberFlow] ${message}`);
8
+ }
9
+ }
10
+ //# sourceMappingURL=warnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["warned","Set","warnOnce","key","message","__DEV__","has","add","console","warn"],"sourceRoot":"../../../src","sources":["core/warnings.ts"],"mappings":";;AAAA,MAAMA,MAAM,GAAG,IAAIC,GAAG,CAAS,CAAC;AAEhC,OAAO,SAASC,QAAQA,CAACC,GAAW,EAAEC,OAAe,EAAQ;EAC3D,IAAIC,OAAO,IAAI,CAACL,MAAM,CAACM,GAAG,CAACH,GAAG,CAAC,EAAE;IAC/BH,MAAM,CAACO,GAAG,CAACJ,GAAG,CAAC;IACfK,OAAO,CAACC,IAAI,CAAC,gBAAgBL,OAAO,EAAE,CAAC;EACzC;AACF","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ export { detectNumberingSystem, getDigitStrings, getZeroCodePoint } from "./core/numerals/index.js";
4
+ export { useCanAnimate } from "./core/useCanAnimate.js";
5
+ export { useFormattedValue } from "./core/useFormattedValue.js";
6
+ export { NumberFlow, TimeFlow } from "./native/index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["detectNumberingSystem","getDigitStrings","getZeroCodePoint","useCanAnimate","useFormattedValue","NumberFlow","TimeFlow"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,qBAAqB,EAAEC,eAAe,EAAEC,gBAAgB,QAAQ,0BAAiB;AAW1F,SAASC,aAAa,QAAQ,yBAAsB;AACpD,SAASC,iBAAiB,QAAQ,6BAA0B;AAC5D,SAASC,UAAU,EAAEC,QAAQ,QAAQ,mBAAU","ignoreList":[]}