react-native-laminar 1.2.0 → 1.4.1

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 (147) hide show
  1. package/README.md +9 -2
  2. package/lib/commonjs/hooks/use-display-units.js +1 -0
  3. package/lib/commonjs/hooks/use-display-units.js.map +1 -1
  4. package/lib/commonjs/hooks/use-inline-auto-width.js +43 -10
  5. package/lib/commonjs/hooks/use-inline-auto-width.js.map +1 -1
  6. package/lib/commonjs/hooks/use-morph-motion.js +2 -1
  7. package/lib/commonjs/hooks/use-morph-motion.js.map +1 -1
  8. package/lib/commonjs/hooks/use-morph-text-style.js +4 -0
  9. package/lib/commonjs/hooks/use-morph-text-style.js.map +1 -1
  10. package/lib/commonjs/hooks/use-numeric-lanes.js +1 -0
  11. package/lib/commonjs/hooks/use-numeric-lanes.js.map +1 -1
  12. package/lib/commonjs/hooks/use-text-glyphs.js +28 -7
  13. package/lib/commonjs/hooks/use-text-glyphs.js.map +1 -1
  14. package/lib/commonjs/index.js +54 -11
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/model/display-units.js +7 -1
  17. package/lib/commonjs/model/display-units.js.map +1 -1
  18. package/lib/commonjs/model/numeric-lanes.js +4 -0
  19. package/lib/commonjs/model/numeric-lanes.js.map +1 -1
  20. package/lib/commonjs/model/text-keys.js +4 -0
  21. package/lib/commonjs/model/text-keys.js.map +1 -1
  22. package/lib/commonjs/motion/entry-exit-builders.js +78 -1
  23. package/lib/commonjs/motion/entry-exit-builders.js.map +1 -1
  24. package/lib/commonjs/motion/preset-map.js +7 -0
  25. package/lib/commonjs/motion/preset-map.js.map +1 -1
  26. package/lib/commonjs/view/glyph-run.js +21 -2
  27. package/lib/commonjs/view/glyph-run.js.map +1 -1
  28. package/lib/commonjs/view/morph-viewport.js +4 -0
  29. package/lib/commonjs/view/morph-viewport.js.map +1 -1
  30. package/lib/commonjs/view/number-lane.js +5 -1
  31. package/lib/commonjs/view/number-lane.js.map +1 -1
  32. package/lib/commonjs/view/number-run.js +4 -0
  33. package/lib/commonjs/view/number-run.js.map +1 -1
  34. package/lib/commonjs/view/slots-run.js +258 -0
  35. package/lib/commonjs/view/slots-run.js.map +1 -0
  36. package/lib/commonjs/view/text-run.js +35 -3
  37. package/lib/commonjs/view/text-run.js.map +1 -1
  38. package/lib/module/hooks/use-display-units.js +2 -0
  39. package/lib/module/hooks/use-display-units.js.map +1 -1
  40. package/lib/module/hooks/use-inline-auto-width.js +44 -11
  41. package/lib/module/hooks/use-inline-auto-width.js.map +1 -1
  42. package/lib/module/hooks/use-morph-motion.js +2 -1
  43. package/lib/module/hooks/use-morph-motion.js.map +1 -1
  44. package/lib/module/hooks/use-morph-text-style.js +4 -0
  45. package/lib/module/hooks/use-morph-text-style.js.map +1 -1
  46. package/lib/module/hooks/use-numeric-lanes.js +1 -0
  47. package/lib/module/hooks/use-numeric-lanes.js.map +1 -1
  48. package/lib/module/hooks/use-text-glyphs.js +28 -7
  49. package/lib/module/hooks/use-text-glyphs.js.map +1 -1
  50. package/lib/module/index.js +56 -12
  51. package/lib/module/index.js.map +1 -1
  52. package/lib/module/model/display-units.js +7 -1
  53. package/lib/module/model/display-units.js.map +1 -1
  54. package/lib/module/model/numeric-lanes.js +5 -0
  55. package/lib/module/model/numeric-lanes.js.map +1 -1
  56. package/lib/module/model/text-keys.js +4 -0
  57. package/lib/module/model/text-keys.js.map +1 -1
  58. package/lib/module/motion/entry-exit-builders.js +75 -0
  59. package/lib/module/motion/entry-exit-builders.js.map +1 -1
  60. package/lib/module/motion/preset-map.js +7 -0
  61. package/lib/module/motion/preset-map.js.map +1 -1
  62. package/lib/module/view/glyph-run.js +21 -2
  63. package/lib/module/view/glyph-run.js.map +1 -1
  64. package/lib/module/view/morph-viewport.js +4 -0
  65. package/lib/module/view/morph-viewport.js.map +1 -1
  66. package/lib/module/view/number-lane.js +5 -1
  67. package/lib/module/view/number-lane.js.map +1 -1
  68. package/lib/module/view/number-run.js +4 -0
  69. package/lib/module/view/number-run.js.map +1 -1
  70. package/lib/module/view/slots-run.js +253 -0
  71. package/lib/module/view/slots-run.js.map +1 -0
  72. package/lib/module/view/text-run.js +36 -4
  73. package/lib/module/view/text-run.js.map +1 -1
  74. package/lib/typescript/commonjs/hooks/use-display-units.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/hooks/use-inline-auto-width.d.ts +3 -1
  76. package/lib/typescript/commonjs/hooks/use-inline-auto-width.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/hooks/use-morph-motion.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/hooks/use-morph-text-style.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/hooks/use-numeric-lanes.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/hooks/use-text-glyphs.d.ts +2 -1
  81. package/lib/typescript/commonjs/hooks/use-text-glyphs.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/index.d.ts +1 -3
  83. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/model/display-units.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/model/numeric-lanes.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/model/text-keys.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/motion/entry-exit-builders.d.ts +13 -0
  88. package/lib/typescript/commonjs/motion/entry-exit-builders.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/motion/preset-map.d.ts.map +1 -1
  90. package/lib/typescript/commonjs/types.d.ts +12 -2
  91. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/view/glyph-run.d.ts +5 -2
  93. package/lib/typescript/commonjs/view/glyph-run.d.ts.map +1 -1
  94. package/lib/typescript/commonjs/view/morph-viewport.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/view/number-lane.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/view/number-run.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/view/slots-run.d.ts +15 -0
  98. package/lib/typescript/commonjs/view/slots-run.d.ts.map +1 -0
  99. package/lib/typescript/commonjs/view/text-run.d.ts +5 -1
  100. package/lib/typescript/commonjs/view/text-run.d.ts.map +1 -1
  101. package/lib/typescript/module/hooks/use-display-units.d.ts.map +1 -1
  102. package/lib/typescript/module/hooks/use-inline-auto-width.d.ts +3 -1
  103. package/lib/typescript/module/hooks/use-inline-auto-width.d.ts.map +1 -1
  104. package/lib/typescript/module/hooks/use-morph-motion.d.ts.map +1 -1
  105. package/lib/typescript/module/hooks/use-morph-text-style.d.ts.map +1 -1
  106. package/lib/typescript/module/hooks/use-numeric-lanes.d.ts.map +1 -1
  107. package/lib/typescript/module/hooks/use-text-glyphs.d.ts +2 -1
  108. package/lib/typescript/module/hooks/use-text-glyphs.d.ts.map +1 -1
  109. package/lib/typescript/module/index.d.ts +1 -3
  110. package/lib/typescript/module/index.d.ts.map +1 -1
  111. package/lib/typescript/module/model/display-units.d.ts.map +1 -1
  112. package/lib/typescript/module/model/numeric-lanes.d.ts.map +1 -1
  113. package/lib/typescript/module/model/text-keys.d.ts.map +1 -1
  114. package/lib/typescript/module/motion/entry-exit-builders.d.ts +13 -0
  115. package/lib/typescript/module/motion/entry-exit-builders.d.ts.map +1 -1
  116. package/lib/typescript/module/motion/preset-map.d.ts.map +1 -1
  117. package/lib/typescript/module/types.d.ts +12 -2
  118. package/lib/typescript/module/types.d.ts.map +1 -1
  119. package/lib/typescript/module/view/glyph-run.d.ts +5 -2
  120. package/lib/typescript/module/view/glyph-run.d.ts.map +1 -1
  121. package/lib/typescript/module/view/morph-viewport.d.ts.map +1 -1
  122. package/lib/typescript/module/view/number-lane.d.ts.map +1 -1
  123. package/lib/typescript/module/view/number-run.d.ts.map +1 -1
  124. package/lib/typescript/module/view/slots-run.d.ts +15 -0
  125. package/lib/typescript/module/view/slots-run.d.ts.map +1 -0
  126. package/lib/typescript/module/view/text-run.d.ts +5 -1
  127. package/lib/typescript/module/view/text-run.d.ts.map +1 -1
  128. package/package.json +11 -2
  129. package/src/hooks/use-display-units.ts +1 -0
  130. package/src/hooks/use-inline-auto-width.ts +55 -12
  131. package/src/hooks/use-morph-motion.ts +2 -1
  132. package/src/hooks/use-morph-text-style.ts +3 -0
  133. package/src/hooks/use-numeric-lanes.ts +1 -0
  134. package/src/hooks/use-text-glyphs.ts +48 -10
  135. package/src/index.tsx +98 -17
  136. package/src/model/display-units.ts +4 -1
  137. package/src/model/numeric-lanes.ts +3 -0
  138. package/src/model/text-keys.ts +3 -0
  139. package/src/motion/entry-exit-builders.ts +73 -0
  140. package/src/motion/preset-map.ts +4 -0
  141. package/src/types.ts +14 -2
  142. package/src/view/glyph-run.tsx +38 -13
  143. package/src/view/morph-viewport.tsx +3 -0
  144. package/src/view/number-lane.tsx +7 -2
  145. package/src/view/number-run.tsx +3 -0
  146. package/src/view/slots-run.tsx +385 -0
  147. package/src/view/text-run.tsx +77 -6
package/README.md CHANGED
@@ -134,10 +134,13 @@ Use `autoSize={false}` when the parent already defines the space and you only wa
134
134
  ```ts
135
135
  type LaminarProps = {
136
136
  text: string | number;
137
- variant?: "text" | "number";
137
+ variant?: "text" | "number" | "slots";
138
138
  fontSize?: number;
139
139
  color?: string;
140
140
  align?: "left" | "center" | "right";
141
+ leading?: ReactNode | Readonly<Record<string, ReactNode>>;
142
+ leadingKey?: string | number;
143
+ leadingGap?: number;
141
144
  style?: StyleProp<TextStyle>;
142
145
  containerStyle?: StyleProp<ViewStyle>;
143
146
  fontStyle?: StyleProp<TextStyle>;
@@ -152,10 +155,13 @@ type LaminarProps = {
152
155
  | Prop | Default | Description |
153
156
  | ------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------- |
154
157
  | `text` | Required | The value to display. Numbers are converted to strings internally. |
155
- | `variant` | `"text"` | `"text"` uses LCS glyph reconciliation. `"number"` uses right-aligned digit lanes. |
158
+ | `variant` | `"text"` | `"text"` uses LCS glyph reconciliation. `"number"` uses right-aligned digit lanes. `"slots"` rolls digits through slot columns using the same lanes. |
156
159
  | `fontSize` | Undefined | Convenience prop merged into the text style. |
157
160
  | `color` | Undefined | Convenience prop merged into the text style. |
158
161
  | `align` | `"left"` | Visual alignment for Laminar's viewport and animated glyph row. |
162
+ | `leading` | Undefined | Optional inline element, or text-keyed leading content, rendered in text mode. |
163
+ | `leadingKey` | Undefined | Advanced identity override for a direct leading element. |
164
+ | `leadingGap` | `0` | Spacing between the leading element and the first text glyph. |
159
165
  | `style` | Undefined | Text style applied after `fontSize` and `color`. |
160
166
  | `containerStyle` | Undefined | Advanced style override for the outer viewport shell. |
161
167
  | `fontStyle` | Undefined | Additional text style merged before `style`. |
@@ -179,6 +185,7 @@ type LaminarProps = {
179
185
  ```tsx
180
186
  <Laminar text={word} animationPreset="smooth" />
181
187
  <Laminar text={count} variant="number" animationPreset="snappy" />
188
+ <Laminar text={count} variant="slots" animationPreset="snappy" />
182
189
 
183
190
  // Override duration
184
191
  <Laminar text={word} animationPreset="default" animationDuration={520} />
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useDisplayUnits = void 0;
7
7
  var _react = require("react");
8
8
  var _displayUnits = require("../model/display-units");
9
+ // normalize the same units used by rendering before measurement reads them
9
10
  const useDisplayUnits = (value, enabled = true) => (0, _react.useMemo)(() =>
10
11
  // skip unit work when auto size is off
11
12
  enabled ? (0, _displayUnits.splitDisplayUnits)(value).map(_displayUnits.normalizeDisplayUnit) : [], [enabled, value]);
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_displayUnits","useDisplayUnits","value","enabled","useMemo","splitDisplayUnits","map","normalizeDisplayUnit","exports"],"sourceRoot":"../../../src","sources":["hooks/use-display-units.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAKO,MAAME,eAAe,GAAGA,CAC7BC,KAAa,EACbC,OAAO,GAAG,IAAI,KAEd,IAAAC,cAAO,EACL;AACE;AACAD,OAAO,GACH,IAAAE,+BAAiB,EAACH,KAAK,CAAC,CAACI,GAAG,CAACC,kCAAoB,CAAC,GAClD,EAAE,EACR,CAACJ,OAAO,EAAED,KAAK,CACjB,CAAC;AAACM,OAAA,CAAAP,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_displayUnits","useDisplayUnits","value","enabled","useMemo","splitDisplayUnits","map","normalizeDisplayUnit","exports"],"sourceRoot":"../../../src","sources":["hooks/use-display-units.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAKA;AACO,MAAME,eAAe,GAAGA,CAC7BC,KAAa,EACbC,OAAO,GAAG,IAAI,KAEd,IAAAC,cAAO,EACL;AACE;AACAD,OAAO,GACH,IAAAE,+BAAiB,EAACH,KAAK,CAAC,CAACI,GAAG,CAACC,kCAAoB,CAAC,GAClD,EAAE,EACR,CAACJ,OAAO,EAAED,KAAK,CACjB,CAAC;AAACM,OAAA,CAAAP,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -6,25 +6,26 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useInlineAutoWidth = void 0;
7
7
  var _react = require("react");
8
8
  var _reactNativeReanimated = require("react-native-reanimated");
9
+ const WIDTH_CACHE_LIMIT = 64;
10
+
11
+ // measure each content signature once and drive later changes through one width value
9
12
  const useInlineAutoWidth = ({
10
13
  enabled,
11
- driveToWidth
14
+ driveToWidth,
15
+ measurementKey
12
16
  }) => {
13
17
  const widthValue = (0, _reactNativeReanimated.useSharedValue)(0);
14
18
  const measuredWidthRef = (0, _react.useRef)(null);
15
19
  const bootstrappedRef = (0, _react.useRef)(false);
20
+ const widthCacheRef = (0, _react.useRef)(new Map());
16
21
  const [hasBootstrappedWidth, setHasBootstrappedWidth] = (0, _react.useState)(false);
17
- const captureLayout = (0, _react.useCallback)(event => {
18
- if (!enabled) {
19
- return;
20
- }
21
- const nextWidth = Math.max(0, Math.ceil(event.nativeEvent.layout.width));
22
+
23
+ // the first measurement establishes the shell without animating from zero
24
+ const applyWidth = (0, _react.useCallback)(nextWidth => {
22
25
  if (measuredWidthRef.current === nextWidth) {
23
26
  return;
24
27
  }
25
28
  measuredWidthRef.current = nextWidth;
26
-
27
- // snap the first width so mount does not animate from zero
28
29
  if (!bootstrappedRef.current) {
29
30
  bootstrappedRef.current = true;
30
31
  widthValue.value = nextWidth;
@@ -32,13 +33,45 @@ const useInlineAutoWidth = ({
32
33
  return;
33
34
  }
34
35
  widthValue.value = driveToWidth(nextWidth);
35
- }, [driveToWidth, enabled, widthValue]);
36
+ }, [driveToWidth, widthValue]);
37
+ const captureLayout = (0, _react.useCallback)(event => {
38
+ if (!enabled) {
39
+ return;
40
+ }
41
+
42
+ // round up so fractional native measurements cannot clip the final glyph
43
+ const nextWidth = Math.max(0, Math.ceil(event.nativeEvent.layout.width));
44
+
45
+ // delete before setting so a repeated key moves to the most recent position
46
+ widthCacheRef.current.delete(measurementKey);
47
+ if (widthCacheRef.current.size >= WIDTH_CACHE_LIMIT) {
48
+ // map insertion order gives the lru entry at the front
49
+ const oldestKey = widthCacheRef.current.keys().next().value;
50
+ if (oldestKey !== undefined) {
51
+ widthCacheRef.current.delete(oldestKey);
52
+ }
53
+ }
54
+ widthCacheRef.current.set(measurementKey, nextWidth);
55
+ applyWidth(nextWidth);
56
+ }, [applyWidth, enabled, measurementKey]);
57
+ const cachedWidth = widthCacheRef.current.get(measurementKey);
58
+
59
+ // a cached width can restore the shell before the hidden probe renders again
60
+ (0, _react.useEffect)(() => {
61
+ if (enabled && cachedWidth !== undefined) {
62
+ // promote cache hits so active states stay available longer
63
+ widthCacheRef.current.delete(measurementKey);
64
+ widthCacheRef.current.set(measurementKey, cachedWidth);
65
+ applyWidth(cachedWidth);
66
+ }
67
+ }, [applyWidth, cachedWidth, enabled, measurementKey]);
36
68
  const animatedWidthStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => enabled && hasBootstrappedWidth ? {
37
69
  width: widthValue.value
38
70
  } : {}, [enabled, hasBootstrappedWidth]);
39
71
  return {
40
72
  captureLayout,
41
- animatedWidthStyle
73
+ animatedWidthStyle,
74
+ shouldMeasure: enabled && cachedWidth === undefined
42
75
  };
43
76
  };
44
77
  exports.useInlineAutoWidth = useInlineAutoWidth;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_reactNativeReanimated","useInlineAutoWidth","enabled","driveToWidth","widthValue","useSharedValue","measuredWidthRef","useRef","bootstrappedRef","hasBootstrappedWidth","setHasBootstrappedWidth","useState","captureLayout","useCallback","event","nextWidth","Math","max","ceil","nativeEvent","layout","width","current","value","animatedWidthStyle","useAnimatedStyle","exports"],"sourceRoot":"../../../src","sources":["hooks/use-inline-auto-width.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,sBAAA,GAAAD,OAAA;AAOO,MAAME,kBAAkB,GAAGA,CAAC;EAAEC,OAAO;EAAEC;AAAqB,CAAC,KAAK;EACvE,MAAMC,UAAU,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EACpC,MAAMC,gBAAgB,GAAG,IAAAC,aAAM,EAAgB,IAAI,CAAC;EACpD,MAAMC,eAAe,GAAG,IAAAD,aAAM,EAAC,KAAK,CAAC;EACrC,MAAM,CAACE,oBAAoB,EAAEC,uBAAuB,CAAC,GAAG,IAAAC,eAAQ,EAAC,KAAK,CAAC;EAEvE,MAAMC,aAAa,GAAG,IAAAC,kBAAW,EAC9BC,KAAwB,IAAK;IAC5B,IAAI,CAACZ,OAAO,EAAE;MACZ;IACF;IAEA,MAAMa,SAAS,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAACE,IAAI,CAACJ,KAAK,CAACK,WAAW,CAACC,MAAM,CAACC,KAAK,CAAC,CAAC;IAExE,IAAIf,gBAAgB,CAACgB,OAAO,KAAKP,SAAS,EAAE;MAC1C;IACF;IAEAT,gBAAgB,CAACgB,OAAO,GAAGP,SAAS;;IAEpC;IACA,IAAI,CAACP,eAAe,CAACc,OAAO,EAAE;MAC5Bd,eAAe,CAACc,OAAO,GAAG,IAAI;MAC9BlB,UAAU,CAACmB,KAAK,GAAGR,SAAS;MAC5BL,uBAAuB,CAAC,IAAI,CAAC;MAC7B;IACF;IAEAN,UAAU,CAACmB,KAAK,GAAGpB,YAAY,CAACY,SAAS,CAAC;EAC5C,CAAC,EACD,CAACZ,YAAY,EAAED,OAAO,EAAEE,UAAU,CACpC,CAAC;EAED,MAAMoB,kBAAkB,GAAG,IAAAC,uCAAgB,EACzC,MACEvB,OAAO,IAAIO,oBAAoB,GAC3B;IACEY,KAAK,EAAEjB,UAAU,CAACmB;EACpB,CAAC,GACD,CAAC,CAAC,EACR,CAACrB,OAAO,EAAEO,oBAAoB,CAChC,CAAC;EAED,OAAO;IACLG,aAAa;IACbY;EACF,CAAC;AACH,CAAC;AAACE,OAAA,CAAAzB,kBAAA,GAAAA,kBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_reactNativeReanimated","WIDTH_CACHE_LIMIT","useInlineAutoWidth","enabled","driveToWidth","measurementKey","widthValue","useSharedValue","measuredWidthRef","useRef","bootstrappedRef","widthCacheRef","Map","hasBootstrappedWidth","setHasBootstrappedWidth","useState","applyWidth","useCallback","nextWidth","current","value","captureLayout","event","Math","max","ceil","nativeEvent","layout","width","delete","size","oldestKey","keys","next","undefined","set","cachedWidth","get","useEffect","animatedWidthStyle","useAnimatedStyle","shouldMeasure","exports"],"sourceRoot":"../../../src","sources":["hooks/use-inline-auto-width.ts"],"mappings":"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","ignoreList":[]}
@@ -6,13 +6,14 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useMorphMotion = void 0;
7
7
  var _react = require("react");
8
8
  var _presetMap = require("../motion/preset-map");
9
+ // resolve one motion recipe and one shared stagger unit for a render tree
9
10
  const useMorphMotion = ({
10
11
  variant,
11
12
  animationPreset,
12
13
  animationDuration,
13
14
  stagger
14
15
  }) => {
15
- // numbers feel better with snappy unless you pick something else
16
+ // numeric variants need a quicker default because their lanes update often
16
17
  const resolvedPreset = animationPreset ?? (variant === "text" ? "default" : "snappy");
17
18
  const motionRecipe = (0, _react.useMemo)(() => (0, _presetMap.resolveMotionRecipe)(resolvedPreset, animationDuration), [animationDuration, resolvedPreset]);
18
19
  return {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_presetMap","useMorphMotion","variant","animationPreset","animationDuration","stagger","resolvedPreset","motionRecipe","useMemo","resolveMotionRecipe","staggerMs","Math","round","exports"],"sourceRoot":"../../../src","sources":["hooks/use-morph-motion.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAmBO,MAAME,cAAc,GAAGA,CAAC;EAC7BC,OAAO;EACPC,eAAe;EACfC,iBAAiB;EACjBC;AACM,CAAC,KAAkB;EACzB;EACA,MAAMC,cAAc,GAClBH,eAAe,KAAKD,OAAO,KAAK,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;EAEhE,MAAMK,YAAY,GAAG,IAAAC,cAAO,EAC1B,MAAM,IAAAC,8BAAmB,EAACH,cAAc,EAAEF,iBAAiB,CAAC,EAC5D,CAACA,iBAAiB,EAAEE,cAAc,CACpC,CAAC;EAED,OAAO;IACLC,YAAY;IACZG,SAAS,EAAEC,IAAI,CAACC,KAAK,CAACP,OAAO,GAAG,IAAI;EACtC,CAAC;AACH,CAAC;AAACQ,OAAA,CAAAZ,cAAA,GAAAA,cAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_presetMap","useMorphMotion","variant","animationPreset","animationDuration","stagger","resolvedPreset","motionRecipe","useMemo","resolveMotionRecipe","staggerMs","Math","round","exports"],"sourceRoot":"../../../src","sources":["hooks/use-morph-motion.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAmBA;AACO,MAAME,cAAc,GAAGA,CAAC;EAC7BC,OAAO;EACPC,eAAe;EACfC,iBAAiB;EACjBC;AACM,CAAC,KAAkB;EACzB;EACA,MAAMC,cAAc,GAClBH,eAAe,KAAKD,OAAO,KAAK,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;EAEhE,MAAMK,YAAY,GAAG,IAAAC,cAAO,EAC1B,MAAM,IAAAC,8BAAmB,EAACH,cAAc,EAAEF,iBAAiB,CAAC,EAC5D,CAACA,iBAAiB,EAAEE,cAAc,CACpC,CAAC;EAED,OAAO;IACLC,YAAY;IACZG,SAAS,EAAEC,IAAI,CAACC,KAAK,CAACP,OAAO,GAAG,IAAI;EACtC,CAAC;AACH,CAAC;AAACQ,OAAA,CAAAZ,cAAA,GAAAA,cAAA","ignoreList":[]}
@@ -5,12 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useMorphTextStyle = void 0;
7
7
  var _react = require("react");
8
+ // compose the public style layers into the style passed to every glyph
8
9
  const useMorphTextStyle = ({
9
10
  fontSize,
10
11
  color,
11
12
  fontStyle,
12
13
  style
13
14
  }) => {
15
+ // keep the base layer small so caller styles can override it predictably
14
16
  const baseTextStyle = (0, _react.useMemo)(() => {
15
17
  const nextStyle = {
16
18
  includeFontPadding: false
@@ -23,6 +25,8 @@ const useMorphTextStyle = ({
23
25
  }
24
26
  return nextStyle;
25
27
  }, [color, fontSize]);
28
+
29
+ // preserve the merge order used by the public style contract
26
30
  const textStyle = (0, _react.useMemo)(() => [baseTextStyle, fontStyle, style], [baseTextStyle, fontStyle, style]);
27
31
  return {
28
32
  textStyle
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","useMorphTextStyle","fontSize","color","fontStyle","style","baseTextStyle","useMemo","nextStyle","includeFontPadding","undefined","textStyle","exports"],"sourceRoot":"../../../src","sources":["hooks/use-morph-text-style.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAcO,MAAMC,iBAAiB,GAAGA,CAAC;EAChCC,QAAQ;EACRC,KAAK;EACLC,SAAS;EACTC;AACM,CAAC,KAAqB;EAC5B,MAAMC,aAAa,GAAG,IAAAC,cAAO,EAAC,MAAM;IAClC,MAAMC,SAAoB,GAAG;MAC3BC,kBAAkB,EAAE;IACtB,CAAC;IAED,IAAIP,QAAQ,KAAKQ,SAAS,EAAE;MAC1BF,SAAS,CAACN,QAAQ,GAAGA,QAAQ;IAC/B;IAEA,IAAIC,KAAK,KAAKO,SAAS,EAAE;MACvBF,SAAS,CAACL,KAAK,GAAGA,KAAK;IACzB;IAEA,OAAOK,SAAS;EAClB,CAAC,EAAE,CAACL,KAAK,EAAED,QAAQ,CAAC,CAAC;EAErB,MAAMS,SAAS,GAAG,IAAAJ,cAAO,EACvB,MAAM,CAACD,aAAa,EAAEF,SAAS,EAAEC,KAAK,CAAC,EACvC,CAACC,aAAa,EAAEF,SAAS,EAAEC,KAAK,CAClC,CAAC;EAED,OAAO;IACLM;EACF,CAAC;AACH,CAAC;AAACC,OAAA,CAAAX,iBAAA,GAAAA,iBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","useMorphTextStyle","fontSize","color","fontStyle","style","baseTextStyle","useMemo","nextStyle","includeFontPadding","undefined","textStyle","exports"],"sourceRoot":"../../../src","sources":["hooks/use-morph-text-style.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAcA;AACO,MAAMC,iBAAiB,GAAGA,CAAC;EAChCC,QAAQ;EACRC,KAAK;EACLC,SAAS;EACTC;AACM,CAAC,KAAqB;EAC5B;EACA,MAAMC,aAAa,GAAG,IAAAC,cAAO,EAAC,MAAM;IAClC,MAAMC,SAAoB,GAAG;MAC3BC,kBAAkB,EAAE;IACtB,CAAC;IAED,IAAIP,QAAQ,KAAKQ,SAAS,EAAE;MAC1BF,SAAS,CAACN,QAAQ,GAAGA,QAAQ;IAC/B;IAEA,IAAIC,KAAK,KAAKO,SAAS,EAAE;MACvBF,SAAS,CAACL,KAAK,GAAGA,KAAK;IACzB;IAEA,OAAOK,SAAS;EAClB,CAAC,EAAE,CAACL,KAAK,EAAED,QAAQ,CAAC,CAAC;;EAErB;EACA,MAAMS,SAAS,GAAG,IAAAJ,cAAO,EACvB,MAAM,CAACD,aAAa,EAAEF,SAAS,EAAEC,KAAK,CAAC,EACvC,CAACC,aAAa,EAAEF,SAAS,EAAEC,KAAK,CAClC,CAAC;EAED,OAAO;IACLM;EACF,CAAC;AACH,CAAC;AAACC,OAAA,CAAAX,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -7,6 +7,7 @@ exports.useNumericLanes = void 0;
7
7
  var _react = require("react");
8
8
  var _displayUnits = require("../model/display-units");
9
9
  var _numericLanes = require("../model/numeric-lanes");
10
+ // retain numeric lane identity across value changes without storing it in state
10
11
  const useNumericLanes = value => {
11
12
  const units = (0, _react.useMemo)(() => (0, _displayUnits.splitDisplayUnits)(value), [value]);
12
13
  const ledgerRef = (0, _react.useRef)({
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_displayUnits","_numericLanes","useNumericLanes","value","units","useMemo","splitDisplayUnits","ledgerRef","useRef","previousValue","laneKeys","map","_","index","nextSeed","length","direction","current","nextLedger","reconcileNumericLanes","leadLength","findNumericLeadLength","exports"],"sourceRoot":"../../../src","sources":["hooks/use-numeric-lanes.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,aAAA,GAAAD,OAAA;AAIA,IAAAE,aAAA,GAAAF,OAAA;AAgBO,MAAMG,eAAe,GAAIC,KAAa,IAA0B;EACrE,MAAMC,KAAK,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAAC,+BAAiB,EAACH,KAAK,CAAC,EAAE,CAACA,KAAK,CAAC,CAAC;EAC9D,MAAMI,SAAS,GAAG,IAAAC,aAAM,EAAgB;IACtCC,aAAa,EAAEN,KAAK;IACpBO,QAAQ,EAAEN,KAAK,CAACO,GAAG,CAAC,CAACC,CAAC,EAAEC,KAAK,KAAKA,KAAK,CAAC;IACxCC,QAAQ,EAAEV,KAAK,CAACW,MAAM;IACtBC,SAAS,EAAE;EACb,CAAC,CAAC;;EAEF;EACA,IAAIb,KAAK,KAAKI,SAAS,CAACU,OAAO,CAACR,aAAa,EAAE;IAC7C,MAAMS,UAAU,GAAG,IAAAC,mCAAqB,EACtCZ,SAAS,CAACU,OAAO,CAACR,aAAa,EAC/BN,KAAK,EACLI,SAAS,CAACU,OAAO,CAACP,QAAQ,EAC1BH,SAAS,CAACU,OAAO,CAACH,QACpB,CAAC;IAEDP,SAAS,CAACU,OAAO,GAAG;MAClBR,aAAa,EAAEN,KAAK;MACpBO,QAAQ,EAAEQ,UAAU,CAACR,QAAQ;MAC7BI,QAAQ,EAAEI,UAAU,CAACJ,QAAQ;MAC7BE,SAAS,EAAEE,UAAU,CAACF;IACxB,CAAC;EACH;EAEA,OAAO;IACLZ,KAAK;IACLM,QAAQ,EAAEH,SAAS,CAACU,OAAO,CAACP,QAAQ;IACpCM,SAAS,EAAET,SAAS,CAACU,OAAO,CAACD,SAAS;IACtCI,UAAU,EAAE,IAAAC,mCAAqB,EAACjB,KAAK;EACzC,CAAC;AACH,CAAC;AAACkB,OAAA,CAAApB,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_displayUnits","_numericLanes","useNumericLanes","value","units","useMemo","splitDisplayUnits","ledgerRef","useRef","previousValue","laneKeys","map","_","index","nextSeed","length","direction","current","nextLedger","reconcileNumericLanes","leadLength","findNumericLeadLength","exports"],"sourceRoot":"../../../src","sources":["hooks/use-numeric-lanes.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,aAAA,GAAAD,OAAA;AAIA,IAAAE,aAAA,GAAAF,OAAA;AAgBA;AACO,MAAMG,eAAe,GAAIC,KAAa,IAA0B;EACrE,MAAMC,KAAK,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAAC,+BAAiB,EAACH,KAAK,CAAC,EAAE,CAACA,KAAK,CAAC,CAAC;EAC9D,MAAMI,SAAS,GAAG,IAAAC,aAAM,EAAgB;IACtCC,aAAa,EAAEN,KAAK;IACpBO,QAAQ,EAAEN,KAAK,CAACO,GAAG,CAAC,CAACC,CAAC,EAAEC,KAAK,KAAKA,KAAK,CAAC;IACxCC,QAAQ,EAAEV,KAAK,CAACW,MAAM;IACtBC,SAAS,EAAE;EACb,CAAC,CAAC;;EAEF;EACA,IAAIb,KAAK,KAAKI,SAAS,CAACU,OAAO,CAACR,aAAa,EAAE;IAC7C,MAAMS,UAAU,GAAG,IAAAC,mCAAqB,EACtCZ,SAAS,CAACU,OAAO,CAACR,aAAa,EAC/BN,KAAK,EACLI,SAAS,CAACU,OAAO,CAACP,QAAQ,EAC1BH,SAAS,CAACU,OAAO,CAACH,QACpB,CAAC;IAEDP,SAAS,CAACU,OAAO,GAAG;MAClBR,aAAa,EAAEN,KAAK;MACpBO,QAAQ,EAAEQ,UAAU,CAACR,QAAQ;MAC7BI,QAAQ,EAAEI,UAAU,CAACJ,QAAQ;MAC7BE,SAAS,EAAEE,UAAU,CAACF;IACxB,CAAC;EACH;EAEA,OAAO;IACLZ,KAAK;IACLM,QAAQ,EAAEH,SAAS,CAACU,OAAO,CAACP,QAAQ;IACpCM,SAAS,EAAET,SAAS,CAACU,OAAO,CAACD,SAAS;IACtCI,UAAU,EAAE,IAAAC,mCAAqB,EAACjB,KAAK;EACzC,CAAC;AACH,CAAC;AAACkB,OAAA,CAAApB,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -7,28 +7,49 @@ exports.useTextGlyphs = void 0;
7
7
  var _react = require("react");
8
8
  var _displayUnits = require("../model/display-units");
9
9
  var _textKeys = require("../model/text-keys");
10
- const useTextGlyphs = (value, namespace) => {
11
- const units = (0, _react.useMemo)(() => (0, _displayUnits.splitDisplayUnits)(value), [value]);
10
+ // build the inline token stream that lets text and leading content share one ledger
11
+ const useTextGlyphs = (value, namespace, leading, leadingKey) => {
12
+ const units = (0, _react.useMemo)(() => [
13
+ // the map key becomes the identity when leading content is state keyed
14
+ ...(leading ? [{
15
+ kind: "element",
16
+ signature: `leading:${String(leadingKey ?? "default")}`,
17
+ element: leading
18
+ }] : []), ...(0, _displayUnits.splitDisplayUnits)(value).map(unit => ({
19
+ kind: "text",
20
+ signature: `text:${unit}`,
21
+ value: unit
22
+ }))], [leading, leadingKey, value]);
23
+ const signatures = units.map(unit => unit.signature);
12
24
  const ledgerRef = (0, _react.useRef)({
13
25
  previousValue: value,
14
- previousUnits: units,
26
+ previousSignatures: signatures,
15
27
  glyphKeys: units.map((_, index) => `${namespace}:c${index}`),
16
28
  nextSeed: units.length
17
29
  });
18
- if (value !== ledgerRef.current.previousValue) {
30
+
31
+ // reconcile only when a token signature changes so stable glyphs keep their views
32
+ if (value !== ledgerRef.current.previousValue || signatures.length !== ledgerRef.current.previousSignatures.length || signatures.some((signature, index) => signature !== ledgerRef.current.previousSignatures[index])) {
19
33
  // keep ids stable so unchanged glyphs stay mounted between updates
20
- const nextLedger = (0, _textKeys.reconcileTextGlyphKeys)(ledgerRef.current.previousUnits, units, ledgerRef.current.glyphKeys, ledgerRef.current.nextSeed, namespace);
34
+ const nextLedger = (0, _textKeys.reconcileTextGlyphKeys)(ledgerRef.current.previousSignatures, signatures, ledgerRef.current.glyphKeys, ledgerRef.current.nextSeed, namespace);
21
35
  ledgerRef.current = {
22
36
  previousValue: value,
23
- previousUnits: units,
37
+ previousSignatures: signatures,
24
38
  glyphKeys: nextLedger.glyphKeys,
25
39
  nextSeed: nextLedger.nextSeed
26
40
  };
27
41
  }
28
42
  const glyphKeys = ledgerRef.current.glyphKeys;
43
+
44
+ // normalize spaces at the edge where tokens become renderable glyphs
29
45
  return (0, _react.useMemo)(() => units.map((unit, index) => ({
30
46
  id: glyphKeys[index],
31
- value: (0, _displayUnits.normalizeDisplayUnit)(unit)
47
+ kind: unit.kind,
48
+ ...(unit.kind === "text" ? {
49
+ value: (0, _displayUnits.normalizeDisplayUnit)(unit.value)
50
+ } : {
51
+ element: unit.element
52
+ })
32
53
  })), [glyphKeys, units]);
33
54
  };
34
55
  exports.useTextGlyphs = useTextGlyphs;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_displayUnits","_textKeys","useTextGlyphs","value","namespace","units","useMemo","splitDisplayUnits","ledgerRef","useRef","previousValue","previousUnits","glyphKeys","map","_","index","nextSeed","length","current","nextLedger","reconcileTextGlyphKeys","unit","id","normalizeDisplayUnit","exports"],"sourceRoot":"../../../src","sources":["hooks/use-text-glyphs.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAIA,IAAAE,SAAA,GAAAF,OAAA;AAUO,MAAMG,aAAa,GAAGA,CAC3BC,KAAa,EACbC,SAAiB,KACS;EAC1B,MAAMC,KAAK,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAAC,+BAAiB,EAACJ,KAAK,CAAC,EAAE,CAACA,KAAK,CAAC,CAAC;EAC9D,MAAMK,SAAS,GAAG,IAAAC,aAAM,EAAkB;IACxCC,aAAa,EAAEP,KAAK;IACpBQ,aAAa,EAAEN,KAAK;IACpBO,SAAS,EAAEP,KAAK,CAACQ,GAAG,CAAC,CAACC,CAAC,EAAEC,KAAK,KAAK,GAAGX,SAAS,KAAKW,KAAK,EAAE,CAAC;IAC5DC,QAAQ,EAAEX,KAAK,CAACY;EAClB,CAAC,CAAC;EAEF,IAAId,KAAK,KAAKK,SAAS,CAACU,OAAO,CAACR,aAAa,EAAE;IAC7C;IACA,MAAMS,UAAU,GAAG,IAAAC,gCAAsB,EACvCZ,SAAS,CAACU,OAAO,CAACP,aAAa,EAC/BN,KAAK,EACLG,SAAS,CAACU,OAAO,CAACN,SAAS,EAC3BJ,SAAS,CAACU,OAAO,CAACF,QAAQ,EAC1BZ,SACF,CAAC;IAEDI,SAAS,CAACU,OAAO,GAAG;MAClBR,aAAa,EAAEP,KAAK;MACpBQ,aAAa,EAAEN,KAAK;MACpBO,SAAS,EAAEO,UAAU,CAACP,SAAS;MAC/BI,QAAQ,EAAEG,UAAU,CAACH;IACvB,CAAC;EACH;EAEA,MAAMJ,SAAS,GAAGJ,SAAS,CAACU,OAAO,CAACN,SAAS;EAE7C,OAAO,IAAAN,cAAO,EACZ,MACED,KAAK,CAACQ,GAAG,CAAC,CAACQ,IAAI,EAAEN,KAAK,MAAM;IAC1BO,EAAE,EAAEV,SAAS,CAACG,KAAK,CAAC;IACpBZ,KAAK,EAAE,IAAAoB,kCAAoB,EAACF,IAAI;EAClC,CAAC,CAAC,CAAC,EACL,CAACT,SAAS,EAAEP,KAAK,CACnB,CAAC;AACH,CAAC;AAACmB,OAAA,CAAAtB,aAAA,GAAAA,aAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_displayUnits","_textKeys","useTextGlyphs","value","namespace","leading","leadingKey","units","useMemo","kind","signature","String","element","splitDisplayUnits","map","unit","signatures","ledgerRef","useRef","previousValue","previousSignatures","glyphKeys","_","index","nextSeed","length","current","some","nextLedger","reconcileTextGlyphKeys","id","normalizeDisplayUnit","exports"],"sourceRoot":"../../../src","sources":["hooks/use-text-glyphs.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAIA,IAAAE,SAAA,GAAAF,OAAA;AAcA;AACO,MAAMG,aAAa,GAAGA,CAC3BC,KAAa,EACbC,SAAiB,EACjBC,OAAmB,EACnBC,UAA4B,KACF;EAC1B,MAAMC,KAAK,GAAG,IAAAC,cAAO,EACnB,MAAM;EACJ;EACA,IAAIH,OAAO,GACP,CACE;IACEI,IAAI,EAAE,SAAS;IACfC,SAAS,EAAE,WAAWC,MAAM,CAACL,UAAU,IAAI,SAAS,CAAC,EAAE;IACvDM,OAAO,EAAEP;EACX,CAAC,CACF,GACD,EAAE,CAAC,EACP,GAAG,IAAAQ,+BAAiB,EAACV,KAAK,CAAC,CAACW,GAAG,CAAEC,IAAI,KAAM;IACzCN,IAAI,EAAE,MAAe;IACrBC,SAAS,EAAE,QAAQK,IAAI,EAAE;IACzBZ,KAAK,EAAEY;EACT,CAAC,CAAC,CAAC,CACJ,EACD,CAACV,OAAO,EAAEC,UAAU,EAAEH,KAAK,CAC7B,CAAC;EACD,MAAMa,UAAU,GAAGT,KAAK,CAACO,GAAG,CAAEC,IAAI,IAAKA,IAAI,CAACL,SAAS,CAAC;EACtD,MAAMO,SAAS,GAAG,IAAAC,aAAM,EAAkB;IACxCC,aAAa,EAAEhB,KAAK;IACpBiB,kBAAkB,EAAEJ,UAAU;IAC9BK,SAAS,EAAEd,KAAK,CAACO,GAAG,CAAC,CAACQ,CAAC,EAAEC,KAAK,KAAK,GAAGnB,SAAS,KAAKmB,KAAK,EAAE,CAAC;IAC5DC,QAAQ,EAAEjB,KAAK,CAACkB;EAClB,CAAC,CAAC;;EAEF;EACA,IACEtB,KAAK,KAAKc,SAAS,CAACS,OAAO,CAACP,aAAa,IACzCH,UAAU,CAACS,MAAM,KAAKR,SAAS,CAACS,OAAO,CAACN,kBAAkB,CAACK,MAAM,IACjET,UAAU,CAACW,IAAI,CACb,CAACjB,SAAS,EAAEa,KAAK,KAAKb,SAAS,KAAKO,SAAS,CAACS,OAAO,CAACN,kBAAkB,CAACG,KAAK,CAChF,CAAC,EACD;IACA;IACA,MAAMK,UAAU,GAAG,IAAAC,gCAAsB,EACvCZ,SAAS,CAACS,OAAO,CAACN,kBAAkB,EACpCJ,UAAU,EACVC,SAAS,CAACS,OAAO,CAACL,SAAS,EAC3BJ,SAAS,CAACS,OAAO,CAACF,QAAQ,EAC1BpB,SACF,CAAC;IAEDa,SAAS,CAACS,OAAO,GAAG;MAClBP,aAAa,EAAEhB,KAAK;MACpBiB,kBAAkB,EAAEJ,UAAU;MAC9BK,SAAS,EAAEO,UAAU,CAACP,SAAS;MAC/BG,QAAQ,EAAEI,UAAU,CAACJ;IACvB,CAAC;EACH;EAEA,MAAMH,SAAS,GAAGJ,SAAS,CAACS,OAAO,CAACL,SAAS;;EAE7C;EACA,OAAO,IAAAb,cAAO,EACZ,MACED,KAAK,CAACO,GAAG,CAAC,CAACC,IAAI,EAAEQ,KAAK,MAAM;IAC1BO,EAAE,EAAET,SAAS,CAACE,KAAK,CAAC;IACpBd,IAAI,EAAEM,IAAI,CAACN,IAAI;IACf,IAAIM,IAAI,CAACN,IAAI,KAAK,MAAM,GACpB;MAAEN,KAAK,EAAE,IAAA4B,kCAAoB,EAAChB,IAAI,CAACZ,KAAK;IAAE,CAAC,GAC3C;MAAES,OAAO,EAAEG,IAAI,CAACH;IAAQ,CAAC;EAC/B,CAAC,CAAC,CAAC,EACL,CAACS,SAAS,EAAEd,KAAK,CACnB,CAAC;AACH,CAAC;AAACyB,OAAA,CAAA9B,aAAA,GAAAA,aAAA","ignoreList":[]}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.MorphingText = exports.Laminar = void 0;
6
+ exports.Laminar = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _useInlineAutoWidth = require("./hooks/use-inline-auto-width");
@@ -12,9 +12,11 @@ var _useMorphTextStyle = require("./hooks/use-morph-text-style");
12
12
  var _displayUnits = require("./model/display-units");
13
13
  var _morphViewport = require("./view/morph-viewport");
14
14
  var _numberRun = require("./view/number-run");
15
+ var _slotsRun = require("./view/slots-run");
15
16
  var _textRun = require("./view/text-run");
16
17
  var _jsxRuntime = require("react/jsx-runtime");
17
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
+ // choose the content variant and connect it to the shared viewport and measurement flow
18
20
  const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Laminar({
19
21
  text,
20
22
  variant = "text",
@@ -22,6 +24,9 @@ const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Lami
22
24
  color,
23
25
  align = "left",
24
26
  className,
27
+ leading,
28
+ leadingKey,
29
+ leadingGap = 0,
25
30
  style,
26
31
  containerStyle,
27
32
  fontStyle,
@@ -32,6 +37,10 @@ const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Lami
32
37
  clipToBounds = false
33
38
  }) {
34
39
  const resolvedValue = String(text ?? "");
40
+ // resolve state keyed leading content before measurement and token reconciliation
41
+ const leadingMap = isLeadingMap(leading) ? leading : undefined;
42
+ const resolvedLeading = leadingMap ? leadingMap[resolvedValue] : leading;
43
+ const resolvedLeadingKey = leadingMap ? resolvedValue : leadingKey;
35
44
  const {
36
45
  motionRecipe,
37
46
  staggerMs
@@ -49,13 +58,22 @@ const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Lami
49
58
  fontStyle,
50
59
  style
51
60
  });
61
+
62
+ // invalidate the probe when text style, leading content, or leading spacing changes
63
+ const measurementKey = _react.default.useMemo(() => {
64
+ const flattenedStyle = _reactNative.StyleSheet.flatten(textStyle);
65
+ return JSON.stringify([resolvedValue, flattenedStyle?.fontFamily, flattenedStyle?.fontSize, flattenedStyle?.fontStyle, flattenedStyle?.fontWeight, flattenedStyle?.fontVariant, flattenedStyle?.letterSpacing, flattenedStyle?.lineHeight, flattenedStyle?.textTransform, variant === "text" && Boolean(resolvedLeading), variant === "text" ? resolvedLeadingKey : undefined, variant === "text" ? leadingGap : 0]);
66
+ }, [leadingGap, resolvedLeading, resolvedLeadingKey, resolvedValue, textStyle, variant]);
52
67
  const {
53
68
  captureLayout,
54
- animatedWidthStyle
69
+ animatedWidthStyle,
70
+ shouldMeasure
55
71
  } = (0, _useInlineAutoWidth.useInlineAutoWidth)({
56
72
  enabled: autoSize,
57
- driveToWidth: motionRecipe.driveNumber
73
+ driveToWidth: motionRecipe.driveNumber,
74
+ measurementKey
58
75
  });
76
+ // measurement uses the same normalized units as the visible text row
59
77
  const measuredValue = _react.default.useMemo(() => {
60
78
  if (!autoSize) {
61
79
  return "";
@@ -68,13 +86,33 @@ const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Lami
68
86
  align: align,
69
87
  containerStyle: containerStyle,
70
88
  animatedWidthStyle: animatedWidthStyle,
71
- measurement: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
72
- numberOfLines: 1,
89
+ measurement: shouldMeasure ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
73
90
  onLayout: captureLayout,
74
- style: textStyle,
75
- children: measuredValue
76
- }),
77
- children: variant === "number" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_numberRun.NumberRun, {
91
+ style: {
92
+ flexDirection: "row",
93
+ alignSelf: "flex-start"
94
+ },
95
+ children: [variant === "text" && resolvedLeading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
96
+ style: {
97
+ alignItems: "center",
98
+ justifyContent: "center",
99
+ marginRight: leadingGap
100
+ },
101
+ children: resolvedLeading
102
+ }) : null, (0, _displayUnits.splitDisplayUnits)(measuredValue).map((unit, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
103
+ style: textStyle,
104
+ children: (0, _displayUnits.normalizeDisplayUnit)(unit)
105
+ }, `${unit}-${index}`))]
106
+ }) : undefined,
107
+ children: variant === "slots" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_slotsRun.SlotsRun, {
108
+ value: resolvedValue,
109
+ motionRecipe: motionRecipe,
110
+ align: align,
111
+ fontSize: fontSize,
112
+ textStyle: textStyle,
113
+ staggerMs: staggerMs,
114
+ className: className
115
+ }) : variant === "number" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_numberRun.NumberRun, {
78
116
  value: resolvedValue,
79
117
  motionRecipe: motionRecipe,
80
118
  align: align,
@@ -86,11 +124,16 @@ const Laminar = exports.Laminar = /*#__PURE__*/_react.default.memo(function Lami
86
124
  value: resolvedValue,
87
125
  motionRecipe: motionRecipe,
88
126
  align: align,
127
+ leading: resolvedLeading,
128
+ leadingKey: resolvedLeadingKey,
129
+ leadingGap: leadingGap,
89
130
  textStyle: textStyle,
90
131
  className: className
91
132
  })
92
133
  });
93
134
  });
94
- const MorphingText = exports.MorphingText = Laminar;
95
- var _default = exports.default = Laminar;
135
+ function isLeadingMap(value) {
136
+ // react elements are objects too, so exclude them before treating a value as a map
137
+ return typeof value === "object" && value !== null && ! /*#__PURE__*/_react.default.isValidElement(value) && !Array.isArray(value);
138
+ }
96
139
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_useInlineAutoWidth","_useMorphMotion","_useMorphTextStyle","_displayUnits","_morphViewport","_numberRun","_textRun","_jsxRuntime","e","__esModule","default","Laminar","exports","React","memo","text","variant","fontSize","color","align","className","style","containerStyle","fontStyle","animationDuration","animationPreset","stagger","autoSize","clipToBounds","resolvedValue","String","motionRecipe","staggerMs","useMorphMotion","textStyle","useMorphTextStyle","captureLayout","animatedWidthStyle","useInlineAutoWidth","enabled","driveToWidth","driveNumber","measuredValue","useMemo","splitDisplayUnits","map","normalizeDisplayUnit","join","jsx","MorphViewport","measurement","Text","numberOfLines","onLayout","children","NumberRun","value","TextRun","MorphingText","_default"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_useInlineAutoWidth","_useMorphMotion","_useMorphTextStyle","_displayUnits","_morphViewport","_numberRun","_slotsRun","_textRun","_jsxRuntime","e","__esModule","default","Laminar","exports","React","memo","text","variant","fontSize","color","align","className","leading","leadingKey","leadingGap","style","containerStyle","fontStyle","animationDuration","animationPreset","stagger","autoSize","clipToBounds","resolvedValue","String","leadingMap","isLeadingMap","undefined","resolvedLeading","resolvedLeadingKey","motionRecipe","staggerMs","useMorphMotion","textStyle","useMorphTextStyle","measurementKey","useMemo","flattenedStyle","StyleSheet","flatten","JSON","stringify","fontFamily","fontWeight","fontVariant","letterSpacing","lineHeight","textTransform","Boolean","captureLayout","animatedWidthStyle","shouldMeasure","useInlineAutoWidth","enabled","driveToWidth","driveNumber","measuredValue","splitDisplayUnits","map","normalizeDisplayUnit","join","jsx","MorphViewport","measurement","jsxs","View","onLayout","flexDirection","alignSelf","children","alignItems","justifyContent","marginRight","unit","index","Text","SlotsRun","value","NumberRun","TextRun","isValidElement","Array","isArray"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -8,6 +8,8 @@ const NBSP = "\u00A0";
8
8
  const graphemeSegmenter = typeof Intl !== "undefined" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(undefined, {
9
9
  granularity: "grapheme"
10
10
  }) : null;
11
+
12
+ // segment graphemes when the runtime supports them so emoji and combining marks stay whole
11
13
  const splitDisplayUnits = input => {
12
14
  if (graphemeSegmenter) {
13
15
  return Array.from(graphemeSegmenter.segment(input), part => part.segment);
@@ -15,11 +17,15 @@ const splitDisplayUnits = input => {
15
17
  return Array.from(input);
16
18
  };
17
19
 
18
- // swap plain spaces so measured text keeps its width
20
+ // replace plain spaces because native text measurement can collapse them
19
21
  exports.splitDisplayUnits = splitDisplayUnits;
20
22
  const normalizeDisplayUnit = unit => unit === " " ? NBSP : unit;
23
+
24
+ // numeric lanes only treat ascii digits as place-value columns
21
25
  exports.normalizeDisplayUnit = normalizeDisplayUnit;
22
26
  const isAsciiDigit = unit => unit >= "0" && unit <= "9";
27
+
28
+ // leading symbols and punctuation stay attached to the left side of a number
23
29
  exports.isAsciiDigit = isAsciiDigit;
24
30
  const findNumericLeadLength = units => {
25
31
  const firstDigitIndex = units.findIndex(isAsciiDigit);
@@ -1 +1 @@
1
- {"version":3,"names":["NBSP","graphemeSegmenter","Intl","Segmenter","undefined","granularity","splitDisplayUnits","input","Array","from","segment","part","exports","normalizeDisplayUnit","unit","isAsciiDigit","findNumericLeadLength","units","firstDigitIndex","findIndex","length"],"sourceRoot":"../../../src","sources":["model/display-units.ts"],"mappings":";;;;;;AAAA,MAAMA,IAAI,GAAG,QAAQ;AACrB,MAAMC,iBAAiB,GACrB,OAAOC,IAAI,KAAK,WAAW,IAAI,OAAOA,IAAI,CAACC,SAAS,KAAK,UAAU,GAC/D,IAAID,IAAI,CAACC,SAAS,CAACC,SAAS,EAAE;EAAEC,WAAW,EAAE;AAAW,CAAC,CAAC,GAC1D,IAAI;AAEH,MAAMC,iBAAiB,GAAIC,KAAa,IAAe;EAC5D,IAAIN,iBAAiB,EAAE;IACrB,OAAOO,KAAK,CAACC,IAAI,CACfR,iBAAiB,CAACS,OAAO,CAACH,KAAK,CAAC,EAC/BI,IAAI,IAAKA,IAAI,CAACD,OACjB,CAAC;EACH;EAEA,OAAOF,KAAK,CAACC,IAAI,CAACF,KAAK,CAAC;AAC1B,CAAC;;AAED;AAAAK,OAAA,CAAAN,iBAAA,GAAAA,iBAAA;AACO,MAAMO,oBAAoB,GAAIC,IAAY,IAC/CA,IAAI,KAAK,GAAG,GAAGd,IAAI,GAAGc,IAAI;AAACF,OAAA,CAAAC,oBAAA,GAAAA,oBAAA;AAEtB,MAAME,YAAY,GAAID,IAAY,IAAKA,IAAI,IAAI,GAAG,IAAIA,IAAI,IAAI,GAAG;AAACF,OAAA,CAAAG,YAAA,GAAAA,YAAA;AAElE,MAAMC,qBAAqB,GAAIC,KAAwB,IAAK;EACjE,MAAMC,eAAe,GAAGD,KAAK,CAACE,SAAS,CAACJ,YAAY,CAAC;EAErD,OAAOG,eAAe,KAAK,CAAC,CAAC,GAAGD,KAAK,CAACG,MAAM,GAAGF,eAAe;AAChE,CAAC;AAACN,OAAA,CAAAI,qBAAA,GAAAA,qBAAA","ignoreList":[]}
1
+ {"version":3,"names":["NBSP","graphemeSegmenter","Intl","Segmenter","undefined","granularity","splitDisplayUnits","input","Array","from","segment","part","exports","normalizeDisplayUnit","unit","isAsciiDigit","findNumericLeadLength","units","firstDigitIndex","findIndex","length"],"sourceRoot":"../../../src","sources":["model/display-units.ts"],"mappings":";;;;;;AAAA,MAAMA,IAAI,GAAG,QAAQ;AACrB,MAAMC,iBAAiB,GACrB,OAAOC,IAAI,KAAK,WAAW,IAAI,OAAOA,IAAI,CAACC,SAAS,KAAK,UAAU,GAC/D,IAAID,IAAI,CAACC,SAAS,CAACC,SAAS,EAAE;EAAEC,WAAW,EAAE;AAAW,CAAC,CAAC,GAC1D,IAAI;;AAEV;AACO,MAAMC,iBAAiB,GAAIC,KAAa,IAAe;EAC5D,IAAIN,iBAAiB,EAAE;IACrB,OAAOO,KAAK,CAACC,IAAI,CACfR,iBAAiB,CAACS,OAAO,CAACH,KAAK,CAAC,EAC/BI,IAAI,IAAKA,IAAI,CAACD,OACjB,CAAC;EACH;EAEA,OAAOF,KAAK,CAACC,IAAI,CAACF,KAAK,CAAC;AAC1B,CAAC;;AAED;AAAAK,OAAA,CAAAN,iBAAA,GAAAA,iBAAA;AACO,MAAMO,oBAAoB,GAAIC,IAAY,IAC/CA,IAAI,KAAK,GAAG,GAAGd,IAAI,GAAGc,IAAI;;AAE5B;AAAAF,OAAA,CAAAC,oBAAA,GAAAA,oBAAA;AACO,MAAME,YAAY,GAAID,IAAY,IAAKA,IAAI,IAAI,GAAG,IAAIA,IAAI,IAAI,GAAG;;AAExE;AAAAF,OAAA,CAAAG,YAAA,GAAAA,YAAA;AACO,MAAMC,qBAAqB,GAAIC,KAAwB,IAAK;EACjE,MAAMC,eAAe,GAAGD,KAAK,CAACE,SAAS,CAACJ,YAAY,CAAC;EAErD,OAAOG,eAAe,KAAK,CAAC,CAAC,GAAGD,KAAK,CAACG,MAAM,GAAGF,eAAe;AAChE,CAAC;AAACN,OAAA,CAAAI,qBAAA,GAAAA,qBAAA","ignoreList":[]}
@@ -5,8 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.reconcileNumericLanes = void 0;
7
7
  var _displayUnits = require("./display-units");
8
+ // strip formatting before comparing values so direction follows the displayed number
8
9
  const readNumericMagnitude = input => parseFloat(input.replace(/[^0-9.-]/g, "")) || 0;
10
+
11
+ // the sign controls which side of each digit lane enters and exits
9
12
  const deriveFlowDirection = (previousValue, nextValue) => Math.sign(readNumericMagnitude(nextValue) - readNumericMagnitude(previousValue));
13
+ // preserve right-aligned place values while allowing prefixes to grow or shrink
10
14
  const reconcileNumericLanes = (previousValue, nextValue, previousKeys, seed) => {
11
15
  const previousUnits = (0, _displayUnits.splitDisplayUnits)(previousValue);
12
16
  const nextUnits = (0, _displayUnits.splitDisplayUnits)(nextValue);
@@ -1 +1 @@
1
- {"version":3,"names":["_displayUnits","require","readNumericMagnitude","input","parseFloat","replace","deriveFlowDirection","previousValue","nextValue","Math","sign","reconcileNumericLanes","previousKeys","seed","previousUnits","splitDisplayUnits","nextUnits","nextLaneKeys","Array","length","nextSeed","nextLeadLength","findNumericLeadLength","previousLeadLength","sharedLeadLength","min","index","previousTailUnits","slice","nextTailUnits","previousTailKeys","laneCount","max","leftPaddedPreviousUnits","fill","leftPaddedNextUnits","leftPaddedPreviousKeys","nextTailOffset","paddedIndex","nextUnit","previousUnit","previousKey","laneKeys","direction","exports"],"sourceRoot":"../../../src","sources":["model/numeric-lanes.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_displayUnits","require","readNumericMagnitude","input","parseFloat","replace","deriveFlowDirection","previousValue","nextValue","Math","sign","reconcileNumericLanes","previousKeys","seed","previousUnits","splitDisplayUnits","nextUnits","nextLaneKeys","Array","length","nextSeed","nextLeadLength","findNumericLeadLength","previousLeadLength","sharedLeadLength","min","index","previousTailUnits","slice","nextTailUnits","previousTailKeys","laneCount","max","leftPaddedPreviousUnits","fill","leftPaddedNextUnits","leftPaddedPreviousKeys","nextTailOffset","paddedIndex","nextUnit","previousUnit","previousKey","laneKeys","direction","exports"],"sourceRoot":"../../../src","sources":["model/numeric-lanes.ts"],"mappings":"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","ignoreList":[]}
@@ -4,12 +4,15 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.reconcileTextGlyphKeys = void 0;
7
+ // find the longest ordered set of shared units so edits keep nearby glyph identity
7
8
  const computeLcsPairs = (previousUnits, nextUnits) => {
8
9
  const previousLength = previousUnits.length;
9
10
  const nextLength = nextUnits.length;
10
11
  if (previousLength === 0 || nextLength === 0) {
11
12
  return [];
12
13
  }
14
+
15
+ // dynamic programming makes the middle edit deterministic when prefix and suffix match
13
16
  const dp = Array.from({
14
17
  length: previousLength + 1
15
18
  }, () => new Array(nextLength + 1).fill(0));
@@ -37,6 +40,7 @@ const computeLcsPairs = (previousUnits, nextUnits) => {
37
40
  pairs.reverse();
38
41
  return pairs;
39
42
  };
43
+ // reuse prefix, suffix, and lcs matches before allocating keys for new glyphs
40
44
  const reconcileTextGlyphKeys = (previousUnits, nextUnits, previousKeys, seed, namespace) => {
41
45
  const previousLength = previousUnits.length;
42
46
  const nextLength = nextUnits.length;
@@ -1 +1 @@
1
- {"version":3,"names":["computeLcsPairs","previousUnits","nextUnits","previousLength","length","nextLength","dp","Array","from","fill","previousIndex","nextIndex","Math","max","pairs","push","reverse","reconcileTextGlyphKeys","previousKeys","seed","namespace","nextGlyphKeys","nextSeed","sharedPrefixLength","sharedSuffixLength","previousMiddleEnd","nextMiddleEnd","previousMiddleUnits","slice","nextMiddleUnits","matches","absolutePreviousIndex","absoluteNextIndex","glyphKeys","exports"],"sourceRoot":"../../../src","sources":["model/text-keys.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["computeLcsPairs","previousUnits","nextUnits","previousLength","length","nextLength","dp","Array","from","fill","previousIndex","nextIndex","Math","max","pairs","push","reverse","reconcileTextGlyphKeys","previousKeys","seed","namespace","nextGlyphKeys","nextSeed","sharedPrefixLength","sharedSuffixLength","previousMiddleEnd","nextMiddleEnd","previousMiddleUnits","slice","nextMiddleUnits","matches","absolutePreviousIndex","absoluteNextIndex","glyphKeys","exports"],"sourceRoot":"../../../src","sources":["model/text-keys.ts"],"mappings":"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","ignoreList":[]}