@coinbase/cds-web 8.32.3 → 8.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 8.33.0 (12/18/2025 PST)
12
+
13
+ #### 🚀 Updates
14
+
15
+ - New digitTransitionVariant for RollingNumber. [[#237](https://github.com/coinbase/cds/pull/237)]
16
+
11
17
  ## 8.32.3 (12/18/2025 PST)
12
18
 
13
19
  #### 🐞 Fixes
@@ -1,8 +1,17 @@
1
1
  import { type RollingNumberDigitComponent } from './RollingNumber';
2
2
  /**
3
- * Note that the DefaultRollingNumberDigit component implementation is different in web
4
- * and mobile due to different animation libraries and the performance issue in mobile.
5
- * This has nearly unnoticeable difference in animation effect.
6
- * */
3
+ * Default digit component for RollingNumber on web.
4
+ *
5
+ * The web implementation differs from mobile due to platform-specific animation libraries:
6
+ * - Web uses framer-motion with imperative `animate` calls
7
+ * - Mobile uses react-native-reanimated with shared values and worklets
8
+ *
9
+ * For the "every" variant, web renders only the necessary digits above/below the current
10
+ * value using CSS positioning. Mobile renders all 10 digits (0-9) stacked with absolute
11
+ * positioning.
12
+ *
13
+ * For the "single" variant, web uses imperative opacity crossfades on DOM sections.
14
+ * Mobile uses reanimated's `entering`/`exiting` props with custom animation worklets.
15
+ */
7
16
  export declare const DefaultRollingNumberDigit: RollingNumberDigitComponent;
8
17
  //# sourceMappingURL=DefaultRollingNumberDigit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultRollingNumberDigit.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/DefaultRollingNumberDigit.tsx"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,2BAA2B,EAEjC,MAAM,iBAAiB,CAAC;AAqCzB;;;;MAIM;AACN,eAAO,MAAM,yBAAyB,EAAE,2BAgFvC,CAAC"}
1
+ {"version":3,"file":"DefaultRollingNumberDigit.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/DefaultRollingNumberDigit.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,2BAA2B,EAEjC,MAAM,iBAAiB,CAAC;AAqCzB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,EAAE,2BAsIvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultRollingNumberValueSection.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/DefaultRollingNumberValueSection.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,kCAAkC,EAEnC,MAAM,iBAAiB,CAAC;AAWzB,eAAO,MAAM,gCAAgC,EAAE,kCA+G9C,CAAC"}
1
+ {"version":3,"file":"DefaultRollingNumberValueSection.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/DefaultRollingNumberValueSection.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,kCAAkC,EAEnC,MAAM,iBAAiB,CAAC;AAWzB,eAAO,MAAM,gCAAgC,EAAE,kCAyH9C,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { ThemeVars } from '@coinbase/cds-common/core/theme';
2
2
  import { type KeyedNumberPart } from '@coinbase/cds-common/numbers/IntlNumberFormat';
3
+ import { type SingleDirection } from '@coinbase/cds-common/numbers/useValueChangeDirection';
3
4
  import type { SharedProps } from '@coinbase/cds-common/types/SharedProps';
4
5
  import { type Transition } from 'framer-motion';
5
6
  import type { Polymorphic } from '../../core/polymorphism';
@@ -9,16 +10,33 @@ import { type TextBaseProps, type TextDefaultElement, type TextProps } from '../
9
10
  */
10
11
  type RollingNumberTransitionConfig = {
11
12
  /**
12
- * Transition override applied to the vertical translation animation.
13
+ * Transition applied to the vertical translation animation (digit roll).
13
14
  */
14
15
  y?: Transition;
15
16
  /**
16
- * Transition override applied to the color interpolation animation.
17
+ * Transition applied to the opacity animation during digit transitions.
18
+ * Controls how digits fade in/out during the single variant animation.
19
+ */
20
+ opacity?: Transition;
21
+ /**
22
+ * Transition applied to the color interpolation animation (color pulse).
17
23
  */
18
24
  color?: Transition;
19
25
  };
26
+ /**
27
+ * Defines the style of digit transition animation.
28
+ * - `'every'`: Rolls through every intermediate digit (e.g., 1→2→3→...→9). Default behavior.
29
+ * - `'single'`: Rolls directly to the new digit without showing intermediates (e.g., 1→9).
30
+ */
31
+ export type DigitTransitionVariant = 'every' | 'single';
20
32
  export declare const defaultTransitionConfig: {
21
33
  readonly y: {
34
+ readonly type: 'spring';
35
+ readonly stiffness: 280;
36
+ readonly damping: 18;
37
+ readonly mass: 0.3;
38
+ };
39
+ readonly opacity: {
22
40
  readonly duration: number;
23
41
  readonly ease: import('@coinbase/cds-common/motion/tokens').EasingArray;
24
42
  };
@@ -98,6 +116,15 @@ export type RollingNumberValueSectionProps = TextProps<TextDefaultElement> & {
98
116
  * Transition overrides applied to digit and symbol animations.
99
117
  */
100
118
  transitionConfig?: RollingNumberTransitionConfig;
119
+ /**
120
+ * Style of digit transition animation.
121
+ * @default 'every'
122
+ */
123
+ digitTransitionVariant?: DigitTransitionVariant;
124
+ /**
125
+ * Direction of the roll animation. Only used when {@link digitTransitionVariant} is `'single'`.
126
+ */
127
+ direction?: SingleDirection;
101
128
  /**
102
129
  * Inline style overrides applied to the value section.
103
130
  */
@@ -146,6 +173,15 @@ export type RollingNumberDigitProps = TextProps<TextDefaultElement> & {
146
173
  * Component used to mask the digit column.
147
174
  */
148
175
  RollingNumberMaskComponent?: RollingNumberMaskComponent;
176
+ /**
177
+ * Style of digit transition animation.
178
+ * @default 'every'
179
+ */
180
+ digitTransitionVariant?: DigitTransitionVariant;
181
+ /**
182
+ * Direction of the roll animation. Only used when {@link digitTransitionVariant} is `'single'`.
183
+ */
184
+ direction?: SingleDirection;
149
185
  /**
150
186
  * Inline style overrides applied to the digit component.
151
187
  */
@@ -267,19 +303,22 @@ export type RollingNumberBaseProps = SharedProps &
267
303
  */
268
304
  locale?: Intl.LocalesArgument;
269
305
  /**
270
- * Base text color token. When {@link colorPulseOnUpdate} is true, the color briefly pulses to a positive or negative mid color before returning to this base color. Defaults to {@code 'fg'}.
306
+ * Base text color token. When {@link colorPulseOnUpdate} is true, the color briefly pulses to a positive or negative mid color before returning to this base color.
307
+ * @default 'fg'
271
308
  */
272
309
  color?: ThemeVars.Color;
273
310
  /**
274
- * Enables color pulsing on positive or negative changes. Defaults to {@code false}.
311
+ * Enables color pulsing on positive or negative changes.
275
312
  */
276
313
  colorPulseOnUpdate?: boolean;
277
314
  /**
278
- * Color token used for positive numeric changes. Defaults to {@code 'fgPositive'}.
315
+ * Color token used for positive numeric changes.
316
+ * @default 'fgPositive'
279
317
  */
280
318
  positivePulseColor?: ThemeVars.Color;
281
319
  /**
282
- * Color token used for negative numeric changes. Defaults to {@code 'fgNegative'}.
320
+ * Color token used for negative numeric changes.
321
+ * @default 'fgNegative'
283
322
  */
284
323
  negativePulseColor?: ThemeVars.Color;
285
324
  /**
@@ -290,6 +329,13 @@ export type RollingNumberBaseProps = SharedProps &
290
329
  * Framer Motion transition overrides. Supports per-property overrides for {@code y} and {@code color} only.
291
330
  */
292
331
  transition?: RollingNumberTransitionConfig;
332
+ /**
333
+ * Style of digit transition animation.
334
+ * - `'every'`: Rolls through every intermediate digit (e.g., 1→2→3→...→9).
335
+ * - `'single'`: Rolls directly to the new digit without showing intermediates (e.g., 1→9).
336
+ * @default 'every'
337
+ */
338
+ digitTransitionVariant?: DigitTransitionVariant;
293
339
  /**
294
340
  * Accessibility label prefix announced before the value.
295
341
  */
@@ -299,11 +345,13 @@ export type RollingNumberBaseProps = SharedProps &
299
345
  */
300
346
  accessibilityLabelSuffix?: string;
301
347
  /**
302
- * aria-live politeness level. Defaults to {@code 'polite'}.
348
+ * aria-live politeness level.
349
+ * @default 'polite'
303
350
  */
304
351
  ariaLive?: React.AriaAttributes['aria-live'];
305
352
  /**
306
- * Enables tabular figures on the underlying {@link Text}. Defaults to {@code true}.
353
+ * Enables tabular figures on the underlying {@link Text}.
354
+ * @default true
307
355
  */
308
356
  tabularNumbers?: boolean;
309
357
  };
@@ -1 +1 @@
1
- {"version":3,"file":"RollingNumber.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/RollingNumber.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RollingNumber.d.ts","sourceRoot":"","sources":["../../../src/numbers/RollingNumber/RollingNumber.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,sDAAsD,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAE1E,OAAO,EAAK,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACf,MAAM,uBAAuB,CAAC;AAkC/B;;GAEG;AACH,KAAK,6BAA6B,GAAG;IACnC;;OAEG;IACH,CAAC,CAAC,EAAE,UAAU,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;CAIc,CAAC;AAGnD,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG;IACnE;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG;IAC3E;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG;IAC3E;;OAEG;IACH,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC;;OAEG;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D;;OAEG;IACH,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;IAC5D;;OAEG;IACH,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;IACjD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;OAEG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG;IACpE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;IACjD;;OAEG;IACH,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;OAEG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAAC,kBAAkB,CAAC,GAAG;IACrE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC;AAE1E,MAAM,MAAM,kCAAkC,GAAG,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC;AAE1F,MAAM,MAAM,2BAA2B,GAAG,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC;AAE5E,MAAM,MAAM,4BAA4B,GAAG,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC;AAE9E,MAAM,MAAM,kCAAkC,GAAG,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC;AAE1F,MAAM,MAAM,sBAAsB,GAAG,WAAW,GAC9C,aAAa,GAAG;IACd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG;QACpD,QAAQ,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC;KAClF,CAAC;IACF;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD;;OAEG;IACH,kCAAkC,CAAC,EAAE,kCAAkC,CAAC;IACxE;;OAEG;IACH,kCAAkC,CAAC,EAAE,kCAAkC,CAAC;IACxE;;OAEG;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D;;OAEG;IACH,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;IAC5D;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;IACxB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;IACrC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;IACrC;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEJ,MAAM,MAAM,kBAAkB,CAAC,WAAW,SAAS,KAAK,CAAC,WAAW,IAAI,WAAW,CAAC,KAAK,CACvF,WAAW,EACX,sBAAsB,GAAG;IACvB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB;;WAEG;QACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B;;WAEG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;WAEG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;WAEG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;WAEG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B;;WAEG;QACH,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QACrC;;WAEG;QACH,qBAAqB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC5C;;WAEG;QACH,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC7B;;WAEG;QACH,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC7B;;WAEG;QACH,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QACjC;;WAEG;QACH,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QACjC;;WAEG;QACH,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC9B;;WAEG;QACH,QAAQ,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC/B;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;CACH,CACF,CAAC;AAEF,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAClD,MAAM,MAAM,2BAA2B,GAAG,OAAO,2BAA2B,CAAC;AAE7E,KAAK,sBAAsB,GAAG,CAAC,CAC7B,WAAW,SAAS,KAAK,CAAC,WAAW,GAAG,2BAA2B,EAEnE,KAAK,EAAE,kBAAkB,CAAC,WAAW,CAAC,KACnC,WAAW,CAAC,WAAW,CAAC,GAC3B,WAAW,CAAC,UAAU,CAAC;AAEzB,eAAO,MAAM,aAAa,EAAE,sBA0T3B,CAAC"}
@@ -1,4 +1,4 @@
1
- const _excluded = ["value", "initialValue", "transitionConfig", "RollingNumberMaskComponent", "color", "className", "styles", "style", "classNames"];
1
+ const _excluded = ["value", "initialValue", "transitionConfig", "digitTransitionVariant", "direction", "RollingNumberMaskComponent", "color", "className", "styles", "style", "classNames"];
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -6,7 +6,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
6
6
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
7
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
8
8
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
9
- import { forwardRef, memo, useCallback, useImperativeHandle, useLayoutEffect, useRef } from 'react';
9
+ import { forwardRef, memo, useCallback, useImperativeHandle, useLayoutEffect, useMemo, useRef } from 'react';
10
10
  import { getWidthInEm } from '@coinbase/cds-common';
11
11
  import { animate, m } from 'framer-motion';
12
12
  import { cx } from '../../cx';
@@ -22,15 +22,26 @@ const bottomNonActiveCss = "bottomNonActiveCss-b1n8654t";
22
22
  const digitSpanCss = "digitSpanCss-d1240w0v";
23
23
 
24
24
  /**
25
- * Note that the DefaultRollingNumberDigit component implementation is different in web
26
- * and mobile due to different animation libraries and the performance issue in mobile.
27
- * This has nearly unnoticeable difference in animation effect.
28
- * */
25
+ * Default digit component for RollingNumber on web.
26
+ *
27
+ * The web implementation differs from mobile due to platform-specific animation libraries:
28
+ * - Web uses framer-motion with imperative `animate` calls
29
+ * - Mobile uses react-native-reanimated with shared values and worklets
30
+ *
31
+ * For the "every" variant, web renders only the necessary digits above/below the current
32
+ * value using CSS positioning. Mobile renders all 10 digits (0-9) stacked with absolute
33
+ * positioning.
34
+ *
35
+ * For the "single" variant, web uses imperative opacity crossfades on DOM sections.
36
+ * Mobile uses reanimated's `entering`/`exiting` props with custom animation worklets.
37
+ */
29
38
  export const DefaultRollingNumberDigit = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
30
39
  let {
31
40
  value,
32
41
  initialValue,
33
42
  transitionConfig,
43
+ digitTransitionVariant = 'every',
44
+ direction,
34
45
  RollingNumberMaskComponent = DefaultRollingNumberMask,
35
46
  color = 'inherit',
36
47
  className,
@@ -42,27 +53,60 @@ export const DefaultRollingNumberDigit = /*#__PURE__*/memo(/*#__PURE__*/forwardR
42
53
  const internalRef = useRef(null);
43
54
  useImperativeHandle(ref, () => internalRef.current);
44
55
  const numberRefs = useRef(new Array(10));
56
+ const singleVariantPrevDigitRef = useRef(null);
57
+ const singleVariantCurrentDigitRef = useRef(null);
45
58
  const prevValue = useRef(initialValue !== null && initialValue !== void 0 ? initialValue : value);
59
+ const isSingleVariant = useMemo(() => digitTransitionVariant === 'single', [digitTransitionVariant]);
46
60
  useLayoutEffect(() => {
47
61
  var _transitionConfig$y;
48
62
  const prevDigit = numberRefs.current[prevValue.current];
49
63
  const currDigit = numberRefs.current[value];
50
64
  if (!internalRef.current || !prevDigit || !currDigit || value === prevValue.current) return;
51
65
  const box = internalRef.current.getBoundingClientRect();
52
- const initialY = box.height * (value - prevValue.current);
66
+ // Every: distance based on numeric difference (rolls through every intermediate digit)
67
+ // Single: distance is always 1 height (rolls directly to the new digit)
68
+ const directionSign = direction === 'up' ? 1 : -1;
69
+ const initialY = isSingleVariant ? box.height * directionSign : box.height * (value - prevValue.current);
53
70
  const prevWidth = getWidthInEm(prevDigit);
54
71
  const currentWidth = getWidthInEm(currDigit);
55
72
  animate(internalRef.current, {
56
73
  y: [initialY, 0],
57
74
  width: [prevWidth, currentWidth]
58
75
  }, (_transitionConfig$y = transitionConfig === null || transitionConfig === void 0 ? void 0 : transitionConfig.y) !== null && _transitionConfig$y !== void 0 ? _transitionConfig$y : defaultTransitionConfig.y);
76
+
77
+ // Single variant: add opacity crossfade (prev fades out, current fades in)
78
+ if (isSingleVariant) {
79
+ var _transitionConfig$opa;
80
+ const opacityTransition = (_transitionConfig$opa = transitionConfig === null || transitionConfig === void 0 ? void 0 : transitionConfig.opacity) !== null && _transitionConfig$opa !== void 0 ? _transitionConfig$opa : defaultTransitionConfig.opacity;
81
+ if (singleVariantPrevDigitRef.current) {
82
+ animate(singleVariantPrevDigitRef.current, {
83
+ opacity: [1, 0]
84
+ }, opacityTransition);
85
+ }
86
+ if (singleVariantCurrentDigitRef.current) {
87
+ animate(singleVariantCurrentDigitRef.current, {
88
+ opacity: [0, 1]
89
+ }, opacityTransition);
90
+ }
91
+ }
59
92
  prevValue.current = value;
60
- }, [transitionConfig, value]);
93
+ }, [isSingleVariant, transitionConfig, value, direction]);
61
94
  const renderDigit = useCallback(digit => /*#__PURE__*/_jsx("span", {
62
95
  ref: r => void (numberRefs.current[digit] = r),
63
96
  className: digitSpanCss,
64
97
  children: digit
65
98
  }, digit), []);
99
+
100
+ // Use direction prop for single variant positioning
101
+ const isGoingUp = direction === 'up';
102
+ const isGoingDown = direction === 'down';
103
+
104
+ // Every: render all digits above/below current (shows every intermediate digit during animation)
105
+ // Single: render only the previous digit in the appropriate section (direct transition)
106
+ const showTopSection = isSingleVariant ? isGoingUp : value !== 0;
107
+ const showBottomSection = isSingleVariant ? isGoingDown : value !== 9;
108
+ const topDigits = isSingleVariant ? renderDigit(prevValue.current) : new Array(value).fill(null).map((_, i) => renderDigit(i));
109
+ const bottomDigits = isSingleVariant ? renderDigit(prevValue.current) : new Array(9 - value).fill(null).map((_, i) => renderDigit(value + i + 1));
66
110
  return /*#__PURE__*/_jsx(RollingNumberMaskComponent, {
67
111
  children: /*#__PURE__*/_jsxs(MotionText, _objectSpread(_objectSpread({
68
112
  ref: internalRef,
@@ -70,12 +114,17 @@ export const DefaultRollingNumberDigit = /*#__PURE__*/memo(/*#__PURE__*/forwardR
70
114
  color: color,
71
115
  style: _objectSpread(_objectSpread(_objectSpread({}, style), styles === null || styles === void 0 ? void 0 : styles.root), styles === null || styles === void 0 ? void 0 : styles.text)
72
116
  }, props), {}, {
73
- children: [value !== 0 && /*#__PURE__*/_jsx("span", {
117
+ children: [showTopSection && /*#__PURE__*/_jsx("span", {
118
+ ref: isSingleVariant ? singleVariantPrevDigitRef : undefined,
74
119
  className: cx(digitNonActiveCss, topNonActiveCss),
75
- children: new Array(value).fill(null).map((_, i) => renderDigit(i))
76
- }), renderDigit(value), value !== 9 && /*#__PURE__*/_jsx("span", {
120
+ children: topDigits
121
+ }), /*#__PURE__*/_jsx("span", {
122
+ ref: isSingleVariant ? singleVariantCurrentDigitRef : undefined,
123
+ children: renderDigit(value)
124
+ }), showBottomSection && /*#__PURE__*/_jsx("span", {
125
+ ref: isSingleVariant ? singleVariantPrevDigitRef : undefined,
77
126
  className: cx(digitNonActiveCss, bottomNonActiveCss),
78
- children: new Array(9 - value).fill(null).map((_, i) => renderDigit(value + i + 1))
127
+ children: bottomDigits
79
128
  })]
80
129
  }))
81
130
  });
@@ -1,4 +1,4 @@
1
- const _excluded = ["intlNumberParts", "color", "justifyContent", "className", "RollingNumberDigitComponent", "RollingNumberSymbolComponent", "RollingNumberMaskComponent", "formattedValue", "transitionConfig", "styles", "classNames", "style"];
1
+ const _excluded = ["intlNumberParts", "color", "justifyContent", "className", "RollingNumberDigitComponent", "RollingNumberSymbolComponent", "RollingNumberMaskComponent", "formattedValue", "transitionConfig", "digitTransitionVariant", "direction", "styles", "classNames", "style"];
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -29,6 +29,8 @@ export const DefaultRollingNumberValueSection = /*#__PURE__*/memo(/*#__PURE__*/f
29
29
  RollingNumberMaskComponent = DefaultRollingNumberMask,
30
30
  formattedValue,
31
31
  transitionConfig,
32
+ digitTransitionVariant,
33
+ direction,
32
34
  styles,
33
35
  classNames,
34
36
  style
@@ -49,18 +51,22 @@ export const DefaultRollingNumberValueSection = /*#__PURE__*/memo(/*#__PURE__*/f
49
51
  classNames: {
50
52
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
51
53
  },
54
+ digitTransitionVariant: digitTransitionVariant,
55
+ direction: direction,
52
56
  initialValue: hasMounted ? 0 : undefined,
53
57
  styles: {
54
58
  text: styles === null || styles === void 0 ? void 0 : styles.text
55
59
  },
56
60
  transitionConfig: transitionConfig,
57
61
  value: part.value
58
- }, part.key)), [intlNumberParts, RollingNumberSymbolComponent, justifyContent, RollingNumberDigitComponent, hasMounted, transitionConfig, RollingNumberMaskComponent, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
62
+ }, part.key)), [intlNumberParts, RollingNumberSymbolComponent, justifyContent, RollingNumberDigitComponent, hasMounted, transitionConfig, digitTransitionVariant, direction, RollingNumberMaskComponent, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
59
63
  const formattedValueDigits = useMemo(() => formattedValue === null || formattedValue === void 0 ? void 0 : formattedValue.split('').map((char, index) => isDigit(char) ? /*#__PURE__*/_jsx(RollingNumberDigitComponent, {
60
64
  RollingNumberMaskComponent: RollingNumberMaskComponent,
61
65
  classNames: {
62
66
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
63
67
  },
68
+ digitTransitionVariant: digitTransitionVariant,
69
+ direction: direction,
64
70
  initialValue: hasMounted ? 0 : undefined,
65
71
  styles: {
66
72
  text: styles === null || styles === void 0 ? void 0 : styles.text
@@ -76,7 +82,7 @@ export const DefaultRollingNumberValueSection = /*#__PURE__*/memo(/*#__PURE__*/f
76
82
  text: styles === null || styles === void 0 ? void 0 : styles.text
77
83
  },
78
84
  value: char
79
- }, index)), [RollingNumberDigitComponent, RollingNumberSymbolComponent, formattedValue, hasMounted, justifyContent, RollingNumberMaskComponent, transitionConfig, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
85
+ }, index)), [RollingNumberDigitComponent, RollingNumberSymbolComponent, formattedValue, hasMounted, justifyContent, RollingNumberMaskComponent, transitionConfig, digitTransitionVariant, direction, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
80
86
  return /*#__PURE__*/_jsx(MotionText, _objectSpread(_objectSpread({
81
87
  ref: ref,
82
88
  className: cx(containerCss, className, classNames === null || classNames === void 0 ? void 0 : classNames.root, classNames === null || classNames === void 0 ? void 0 : classNames.text),
@@ -1,4 +1,4 @@
1
- const _excluded = ["as", "value", "transition", "color", "colorPulseOnUpdate", "positivePulseColor", "negativePulseColor", "font", "fontFamily", "fontSize", "fontWeight", "lineHeight", "locale", "format", "formattedValue", "style", "ariaLive", "prefix", "suffix", "classNames", "styles", "enableSubscriptNotation", "RollingNumberMaskComponent", "RollingNumberAffixSectionComponent", "RollingNumberValueSectionComponent", "RollingNumberDigitComponent", "RollingNumberSymbolComponent", "accessibilityLabel", "tabularNumbers", "accessibilityLabelPrefix", "accessibilityLabelSuffix"];
1
+ const _excluded = ["as", "value", "transition", "color", "colorPulseOnUpdate", "positivePulseColor", "negativePulseColor", "font", "fontFamily", "fontSize", "fontWeight", "lineHeight", "locale", "format", "formattedValue", "style", "ariaLive", "prefix", "suffix", "classNames", "styles", "enableSubscriptNotation", "digitTransitionVariant", "RollingNumberMaskComponent", "RollingNumberAffixSectionComponent", "RollingNumberValueSectionComponent", "RollingNumberDigitComponent", "RollingNumberSymbolComponent", "accessibilityLabel", "tabularNumbers", "accessibilityLabelPrefix", "accessibilityLabelSuffix"];
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -9,6 +9,7 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
9
9
  import { forwardRef, memo, useMemo } from 'react';
10
10
  import { curves, durations } from '@coinbase/cds-common/motion/tokens';
11
11
  import { IntlNumberFormat } from '@coinbase/cds-common/numbers/IntlNumberFormat';
12
+ import { useValueChangeDirection } from '@coinbase/cds-common/numbers/useValueChangeDirection';
12
13
  import { useLocale } from '@coinbase/cds-common/system/LocaleProvider';
13
14
  import { m } from 'framer-motion';
14
15
  import { cx } from '../../cx';
@@ -29,9 +30,21 @@ const screenReaderOnlyCss = "screenReaderOnlyCss-sa1j2r";
29
30
  * Defines transition overrides for RollingNumber animations.
30
31
  */
31
32
 
33
+ /**
34
+ * Defines the style of digit transition animation.
35
+ * - `'every'`: Rolls through every intermediate digit (e.g., 1→2→3→...→9). Default behavior.
36
+ * - `'single'`: Rolls directly to the new digit without showing intermediates (e.g., 1→9).
37
+ */
38
+
32
39
  export const defaultTransitionConfig = {
33
40
  y: {
34
- duration: durations.moderate3 / 1000,
41
+ type: 'spring',
42
+ stiffness: 280,
43
+ damping: 18,
44
+ mass: 0.3
45
+ },
46
+ opacity: {
47
+ duration: durations.fast2 / 1000,
35
48
  ease: curves.global
36
49
  },
37
50
  color: {
@@ -68,6 +81,7 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
68
81
  classNames,
69
82
  styles,
70
83
  enableSubscriptNotation,
84
+ digitTransitionVariant = 'every',
71
85
  RollingNumberMaskComponent = DefaultRollingNumberMask,
72
86
  RollingNumberAffixSectionComponent = DefaultRollingNumberAffixSection,
73
87
  RollingNumberValueSectionComponent = DefaultRollingNumberValueSection,
@@ -91,6 +105,7 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
91
105
  locale
92
106
  }), [value, format, locale]);
93
107
  const formatted = useMemo(() => formattedValue !== null && formattedValue !== void 0 ? formattedValue : intlNumberFormatter.format(), [formattedValue, intlNumberFormatter]);
108
+ const direction = useValueChangeDirection(value);
94
109
  const colorControls = useColorPulse({
95
110
  value,
96
111
  defaultColor: color,
@@ -151,6 +166,8 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
151
166
  classNames: {
152
167
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
153
168
  },
169
+ digitTransitionVariant: digitTransitionVariant,
170
+ direction: direction,
154
171
  intlNumberParts: pre,
155
172
  justifyContent: "flex-end",
156
173
  style: styles === null || styles === void 0 ? void 0 : styles.i18nPrefix,
@@ -166,6 +183,8 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
166
183
  classNames: {
167
184
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
168
185
  },
186
+ digitTransitionVariant: digitTransitionVariant,
187
+ direction: direction,
169
188
  intlNumberParts: integer,
170
189
  justifyContent: "flex-end",
171
190
  style: styles === null || styles === void 0 ? void 0 : styles.integer,
@@ -181,6 +200,8 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
181
200
  classNames: {
182
201
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
183
202
  },
203
+ digitTransitionVariant: digitTransitionVariant,
204
+ direction: direction,
184
205
  intlNumberParts: fraction,
185
206
  justifyContent: "flex-start",
186
207
  style: styles === null || styles === void 0 ? void 0 : styles.fraction,
@@ -196,6 +217,8 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
196
217
  classNames: {
197
218
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
198
219
  },
220
+ digitTransitionVariant: digitTransitionVariant,
221
+ direction: direction,
199
222
  intlNumberParts: post,
200
223
  justifyContent: "flex-start",
201
224
  style: styles === null || styles === void 0 ? void 0 : styles.i18nSuffix,
@@ -205,7 +228,7 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
205
228
  transitionConfig: transitionConfig
206
229
  })]
207
230
  });
208
- }, [intlNumberFormatter, enableSubscriptNotation, classNames === null || classNames === void 0 ? void 0 : classNames.formattedValueSection, classNames === null || classNames === void 0 ? void 0 : classNames.i18nPrefix, classNames === null || classNames === void 0 ? void 0 : classNames.integer, classNames === null || classNames === void 0 ? void 0 : classNames.fraction, classNames === null || classNames === void 0 ? void 0 : classNames.i18nSuffix, styles === null || styles === void 0 ? void 0 : styles.formattedValueSection, styles === null || styles === void 0 ? void 0 : styles.i18nPrefix, styles === null || styles === void 0 ? void 0 : styles.integer, styles === null || styles === void 0 ? void 0 : styles.fraction, styles === null || styles === void 0 ? void 0 : styles.i18nSuffix, RollingNumberValueSectionComponent, RollingNumberMaskComponent, RollingNumberDigitComponent, RollingNumberSymbolComponent, transitionConfig, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
231
+ }, [intlNumberFormatter, enableSubscriptNotation, classNames === null || classNames === void 0 ? void 0 : classNames.formattedValueSection, classNames === null || classNames === void 0 ? void 0 : classNames.i18nPrefix, classNames === null || classNames === void 0 ? void 0 : classNames.integer, classNames === null || classNames === void 0 ? void 0 : classNames.fraction, classNames === null || classNames === void 0 ? void 0 : classNames.i18nSuffix, styles === null || styles === void 0 ? void 0 : styles.formattedValueSection, styles === null || styles === void 0 ? void 0 : styles.i18nPrefix, styles === null || styles === void 0 ? void 0 : styles.integer, styles === null || styles === void 0 ? void 0 : styles.fraction, styles === null || styles === void 0 ? void 0 : styles.i18nSuffix, RollingNumberValueSectionComponent, RollingNumberMaskComponent, RollingNumberDigitComponent, RollingNumberSymbolComponent, transitionConfig, digitTransitionVariant, direction, styles === null || styles === void 0 ? void 0 : styles.text, classNames === null || classNames === void 0 ? void 0 : classNames.text]);
209
232
  const formattedValueValueSection = useMemo(() => /*#__PURE__*/_jsx(RollingNumberValueSectionComponent, {
210
233
  RollingNumberDigitComponent: RollingNumberDigitComponent,
211
234
  RollingNumberMaskComponent: RollingNumberMaskComponent,
@@ -214,6 +237,8 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
214
237
  classNames: {
215
238
  text: classNames === null || classNames === void 0 ? void 0 : classNames.text
216
239
  },
240
+ digitTransitionVariant: digitTransitionVariant,
241
+ direction: direction,
217
242
  formattedValue: formattedValue,
218
243
  intlNumberParts: [],
219
244
  justifyContent: "flex-start",
@@ -222,7 +247,7 @@ export const RollingNumber = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, re
222
247
  text: styles === null || styles === void 0 ? void 0 : styles.text
223
248
  },
224
249
  transitionConfig: transitionConfig
225
- }), [classNames === null || classNames === void 0 ? void 0 : classNames.formattedValueSection, styles === null || styles === void 0 ? void 0 : styles.formattedValueSection, classNames === null || classNames === void 0 ? void 0 : classNames.text, styles === null || styles === void 0 ? void 0 : styles.text, RollingNumberValueSectionComponent, RollingNumberDigitComponent, RollingNumberSymbolComponent, formattedValue, RollingNumberMaskComponent, transitionConfig]);
250
+ }), [classNames === null || classNames === void 0 ? void 0 : classNames.formattedValueSection, styles === null || styles === void 0 ? void 0 : styles.formattedValueSection, classNames === null || classNames === void 0 ? void 0 : classNames.text, styles === null || styles === void 0 ? void 0 : styles.text, RollingNumberValueSectionComponent, RollingNumberDigitComponent, RollingNumberSymbolComponent, formattedValue, RollingNumberMaskComponent, transitionConfig, digitTransitionVariant, direction]);
226
251
  const screenReaderOnlySection = useMemo(() => {
227
252
  const prefixString = typeof prefix === 'string' ? prefix : '';
228
253
  const suffixString = typeof suffix === 'string' ? suffix : '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-web",
3
- "version": "8.32.3",
3
+ "version": "8.33.0",
4
4
  "description": "Coinbase Design System - Web",
5
5
  "repository": {
6
6
  "type": "git",
@@ -203,7 +203,7 @@
203
203
  "react-dom": "^18.3.1"
204
204
  },
205
205
  "dependencies": {
206
- "@coinbase/cds-common": "^8.32.3",
206
+ "@coinbase/cds-common": "^8.33.0",
207
207
  "@coinbase/cds-icons": "^5.8.0",
208
208
  "@coinbase/cds-illustrations": "^4.29.0",
209
209
  "@coinbase/cds-lottie-files": "^3.3.4",