@number-flow/react 0.3.5 → 0.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.
package/dist/index.d.mts CHANGED
@@ -2,10 +2,10 @@ import * as React from 'react';
2
2
  import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
3
  export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
4
 
5
- declare const OBSERVED_ATTRIBUTES: readonly ["data"];
5
+ declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
6
6
  type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
7
7
  declare class NumberFlowElement extends NumberFlowLite {
8
- static observedAttributes: readonly ["data"] | never[];
8
+ static observedAttributes: readonly ["data", "digits"] | never[];
9
9
  attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
10
10
  }
11
11
  type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
@@ -34,8 +34,11 @@ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<N
34
34
  suffix?: string;
35
35
  } & React.RefAttributes<NumberFlowElement>>;
36
36
 
37
+ declare function NumberFlowGroup({ children }: {
38
+ children: React.ReactNode;
39
+ }): React.JSX.Element;
37
40
  declare function useCanAnimate({ respectMotionPreference }?: {
38
41
  respectMotionPreference?: boolean | undefined;
39
42
  }): boolean;
40
43
 
41
- export { NumberFlowElement, type NumberFlowProps, NumberFlow as default, useCanAnimate };
44
+ export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default, useCanAnimate };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,10 @@ import * as React from 'react';
2
2
  import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
3
  export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
4
 
5
- declare const OBSERVED_ATTRIBUTES: readonly ["data"];
5
+ declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
6
6
  type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
7
7
  declare class NumberFlowElement extends NumberFlowLite {
8
- static observedAttributes: readonly ["data"] | never[];
8
+ static observedAttributes: readonly ["data", "digits"] | never[];
9
9
  attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
10
10
  }
11
11
  type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
@@ -34,8 +34,11 @@ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<N
34
34
  suffix?: string;
35
35
  } & React.RefAttributes<NumberFlowElement>>;
36
36
 
37
+ declare function NumberFlowGroup({ children }: {
38
+ children: React.ReactNode;
39
+ }): React.JSX.Element;
37
40
  declare function useCanAnimate({ respectMotionPreference }?: {
38
41
  respectMotionPreference?: boolean | undefined;
39
42
  }): boolean;
40
43
 
41
- export { NumberFlowElement, type NumberFlowProps, NumberFlow as default, useCanAnimate };
44
+ export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default, useCanAnimate };
package/dist/index.js CHANGED
@@ -6,9 +6,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __typeError = (msg) => {
10
- throw TypeError(msg);
11
- };
12
9
  var __export = (target, all) => {
13
10
  for (var name in all)
14
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,15 +27,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
27
  mod
31
28
  ));
32
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
34
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
35
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
36
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
37
30
 
38
31
  // src/index.tsx
39
32
  var src_exports = {};
40
33
  __export(src_exports, {
41
34
  NumberFlowElement: () => NumberFlowElement,
35
+ NumberFlowGroup: () => NumberFlowGroup,
42
36
  default: () => src_default,
43
37
  useCanAnimate: () => useCanAnimate
44
38
  });
@@ -48,7 +42,7 @@ var import_number_flow = require("number-flow");
48
42
  var import_esm_env = require("esm-env");
49
43
  var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
50
44
  var isReact19 = REACT_MAJOR >= 19;
51
- var OBSERVED_ATTRIBUTES = ["data"];
45
+ var OBSERVED_ATTRIBUTES = ["data", "digits"];
52
46
  var NumberFlowElement = class extends import_number_flow.NumberFlowLite {
53
47
  attributeChangedCallback(attr, _oldValue, newValue) {
54
48
  this[attr] = JSON.parse(newValue);
@@ -57,7 +51,7 @@ var NumberFlowElement = class extends import_number_flow.NumberFlowLite {
57
51
  NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
58
52
  (0, import_number_flow.define)("number-flow-react", NumberFlowElement);
59
53
  var formatters = {};
60
- var serializeData = isReact19 ? (p) => p : JSON.stringify;
54
+ var serialize = isReact19 ? (p) => p : JSON.stringify;
61
55
  function splitProps(props) {
62
56
  const {
63
57
  transformTiming,
@@ -82,54 +76,56 @@ function splitProps(props) {
82
76
  rest
83
77
  ];
84
78
  }
85
- var _el;
86
79
  var NumberFlowImpl = class extends React.Component {
87
80
  constructor(props) {
88
81
  super(props);
89
- __privateAdd(this, _el);
90
82
  this.handleRef = this.handleRef.bind(this);
91
83
  }
92
84
  // Update the non-`data` props to avoid JSON serialization
93
85
  // Data needs to be set in render still:
94
- updateNonDataProps(prevProps) {
95
- if (!__privateGet(this, _el)) return;
96
- __privateGet(this, _el).manual = !this.props.isolate;
86
+ updateProperties(prevProps) {
87
+ if (!this.el) return;
88
+ this.el.manual = !this.props.isolate;
97
89
  const [nonData] = splitProps(this.props);
98
- Object.assign(
99
- __privateGet(this, _el),
100
- Object.fromEntries(Object.entries(nonData).filter(([_, v]) => v != null))
101
- );
90
+ Object.entries(nonData).forEach(([k, v]) => {
91
+ this.el[k] = v ?? NumberFlowElement.defaultProps[k];
92
+ });
102
93
  if (prevProps?.onAnimationsStart)
103
- __privateGet(this, _el).removeEventListener("animationsstart", prevProps.onAnimationsStart);
94
+ this.el.removeEventListener("animationsstart", prevProps.onAnimationsStart);
104
95
  if (this.props.onAnimationsStart)
105
- __privateGet(this, _el).addEventListener("animationsstart", this.props.onAnimationsStart);
96
+ this.el.addEventListener("animationsstart", this.props.onAnimationsStart);
106
97
  if (prevProps?.onAnimationsFinish)
107
- __privateGet(this, _el).removeEventListener(
108
- "animationsfinish",
109
- prevProps.onAnimationsFinish
110
- );
98
+ this.el.removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
111
99
  if (this.props.onAnimationsFinish)
112
- __privateGet(this, _el).addEventListener("animationsfinish", this.props.onAnimationsFinish);
100
+ this.el.addEventListener("animationsfinish", this.props.onAnimationsFinish);
113
101
  }
114
102
  componentDidMount() {
115
- this.updateNonDataProps();
116
- if (isReact19 && __privateGet(this, _el)) {
117
- __privateGet(this, _el).data = this.props.data;
103
+ this.updateProperties();
104
+ if (isReact19 && this.el) {
105
+ this.el.digits = this.props.digits;
106
+ this.el.data = this.props.data;
118
107
  }
119
108
  }
120
109
  getSnapshotBeforeUpdate(prevProps) {
121
- this.updateNonDataProps(prevProps);
122
- if (this.props.isolate || this.props.animated === false || prevProps.data === this.props.data)
123
- return false;
124
- __privateGet(this, _el)?.willUpdate();
125
- return true;
110
+ this.updateProperties(prevProps);
111
+ if (prevProps.data !== this.props.data) {
112
+ if (this.props.group) {
113
+ this.props.group.willUpdate();
114
+ return () => this.props.group?.didUpdate();
115
+ }
116
+ if (!this.props.isolate) {
117
+ this.el?.willUpdate();
118
+ return () => this.el?.didUpdate();
119
+ }
120
+ }
121
+ return null;
126
122
  }
127
- componentDidUpdate(_, __, snapshot) {
128
- if (snapshot) __privateGet(this, _el)?.didUpdate();
123
+ componentDidUpdate(_, __, didUpdate) {
124
+ didUpdate?.();
129
125
  }
130
126
  handleRef(el) {
131
127
  if (this.props.innerRef) this.props.innerRef.current = el;
132
- __privateSet(this, _el, el);
128
+ this.el = el;
133
129
  }
134
130
  render() {
135
131
  const [
@@ -140,6 +136,7 @@ var NumberFlowImpl = class extends React.Component {
140
136
  data,
141
137
  willChange,
142
138
  isolate,
139
+ digits,
143
140
  onAnimationsStart,
144
141
  onAnimationsFinish,
145
142
  ...rest
@@ -158,16 +155,18 @@ var NumberFlowImpl = class extends React.Component {
158
155
  role: "img",
159
156
  dangerouslySetInnerHTML: { __html: import_esm_env.BROWSER ? "" : (0, import_number_flow.renderInnerHTML)(data) },
160
157
  suppressHydrationWarning: true,
161
- data: serializeData(data)
158
+ digits: serialize(digits),
159
+ data: serialize(data)
162
160
  }
163
161
  )
164
162
  );
165
163
  }
166
164
  };
167
- _el = new WeakMap();
168
165
  var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format, prefix, suffix, ...props }, _ref) {
169
166
  React.useImperativeHandle(_ref, () => ref.current, []);
170
167
  const ref = React.useRef();
168
+ const group = React.useContext(NumberFlowGroupContext);
169
+ group?.useRegister(ref);
171
170
  const localesString = React.useMemo(() => locales ? JSON.stringify(locales) : "", [locales]);
172
171
  const formatString = React.useMemo(() => format ? JSON.stringify(format) : "", [format]);
173
172
  const data = React.useMemo(() => {
@@ -177,11 +176,50 @@ var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format,
177
176
  );
178
177
  return (0, import_number_flow.formatToData)(value, formatter, prefix, suffix);
179
178
  }, [value, localesString, formatString, prefix, suffix]);
180
- return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, data, innerRef: ref });
179
+ return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
181
180
  });
182
181
  var src_default = NumberFlow;
182
+ var NumberFlowGroupContext = React.createContext(void 0);
183
+ function NumberFlowGroup({ children }) {
184
+ const flows = React.useRef(/* @__PURE__ */ new Set());
185
+ const updating = React.useRef(false);
186
+ const pending = React.useRef(/* @__PURE__ */ new WeakMap());
187
+ const value = React.useMemo(
188
+ () => ({
189
+ useRegister(ref) {
190
+ React.useEffect(() => {
191
+ flows.current.add(ref);
192
+ return () => {
193
+ flows.current.delete(ref);
194
+ };
195
+ }, []);
196
+ },
197
+ willUpdate() {
198
+ if (updating.current) return;
199
+ updating.current = true;
200
+ flows.current.forEach((ref) => {
201
+ const f = ref.current;
202
+ if (!f || !f.created) return;
203
+ f.willUpdate();
204
+ pending.current.set(f, true);
205
+ });
206
+ },
207
+ didUpdate() {
208
+ flows.current.forEach((ref) => {
209
+ const f = ref.current;
210
+ if (!f || !pending.current.get(f)) return;
211
+ f.didUpdate();
212
+ pending.current.delete(f);
213
+ });
214
+ updating.current = false;
215
+ }
216
+ }),
217
+ []
218
+ );
219
+ return /* @__PURE__ */ React.createElement(NumberFlowGroupContext.Provider, { value }, children);
220
+ }
183
221
  function useCanAnimate({ respectMotionPreference = true } = {}) {
184
- const [canAnimate, setCanAnimate] = React.useState(import_number_flow.canAnimate);
222
+ const [canAnimate, setCanAnimate] = React.useState(false);
185
223
  const [reducedMotion, setReducedMotion] = React.useState(false);
186
224
  React.useEffect(() => {
187
225
  setCanAnimate(import_number_flow.canAnimate);
@@ -202,5 +240,6 @@ function useCanAnimate({ respectMotionPreference = true } = {}) {
202
240
  // Annotate the CommonJS export names for ESM import in node:
203
241
  0 && (module.exports = {
204
242
  NumberFlowElement,
243
+ NumberFlowGroup,
205
244
  useCanAnimate
206
245
  });
package/dist/index.mjs CHANGED
@@ -1,11 +1,4 @@
1
1
  "use client";
2
- var __typeError = (msg) => {
3
- throw TypeError(msg);
4
- };
5
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
8
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
9
2
 
10
3
  // src/index.tsx
11
4
  import * as React from "react";
@@ -20,7 +13,7 @@ import {
20
13
  import { BROWSER } from "esm-env";
21
14
  var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
22
15
  var isReact19 = REACT_MAJOR >= 19;
23
- var OBSERVED_ATTRIBUTES = ["data"];
16
+ var OBSERVED_ATTRIBUTES = ["data", "digits"];
24
17
  var NumberFlowElement = class extends NumberFlowLite {
25
18
  attributeChangedCallback(attr, _oldValue, newValue) {
26
19
  this[attr] = JSON.parse(newValue);
@@ -29,7 +22,7 @@ var NumberFlowElement = class extends NumberFlowLite {
29
22
  NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
30
23
  define("number-flow-react", NumberFlowElement);
31
24
  var formatters = {};
32
- var serializeData = isReact19 ? (p) => p : JSON.stringify;
25
+ var serialize = isReact19 ? (p) => p : JSON.stringify;
33
26
  function splitProps(props) {
34
27
  const {
35
28
  transformTiming,
@@ -54,54 +47,56 @@ function splitProps(props) {
54
47
  rest
55
48
  ];
56
49
  }
57
- var _el;
58
50
  var NumberFlowImpl = class extends React.Component {
59
51
  constructor(props) {
60
52
  super(props);
61
- __privateAdd(this, _el);
62
53
  this.handleRef = this.handleRef.bind(this);
63
54
  }
64
55
  // Update the non-`data` props to avoid JSON serialization
65
56
  // Data needs to be set in render still:
66
- updateNonDataProps(prevProps) {
67
- if (!__privateGet(this, _el)) return;
68
- __privateGet(this, _el).manual = !this.props.isolate;
57
+ updateProperties(prevProps) {
58
+ if (!this.el) return;
59
+ this.el.manual = !this.props.isolate;
69
60
  const [nonData] = splitProps(this.props);
70
- Object.assign(
71
- __privateGet(this, _el),
72
- Object.fromEntries(Object.entries(nonData).filter(([_, v]) => v != null))
73
- );
61
+ Object.entries(nonData).forEach(([k, v]) => {
62
+ this.el[k] = v ?? NumberFlowElement.defaultProps[k];
63
+ });
74
64
  if (prevProps?.onAnimationsStart)
75
- __privateGet(this, _el).removeEventListener("animationsstart", prevProps.onAnimationsStart);
65
+ this.el.removeEventListener("animationsstart", prevProps.onAnimationsStart);
76
66
  if (this.props.onAnimationsStart)
77
- __privateGet(this, _el).addEventListener("animationsstart", this.props.onAnimationsStart);
67
+ this.el.addEventListener("animationsstart", this.props.onAnimationsStart);
78
68
  if (prevProps?.onAnimationsFinish)
79
- __privateGet(this, _el).removeEventListener(
80
- "animationsfinish",
81
- prevProps.onAnimationsFinish
82
- );
69
+ this.el.removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
83
70
  if (this.props.onAnimationsFinish)
84
- __privateGet(this, _el).addEventListener("animationsfinish", this.props.onAnimationsFinish);
71
+ this.el.addEventListener("animationsfinish", this.props.onAnimationsFinish);
85
72
  }
86
73
  componentDidMount() {
87
- this.updateNonDataProps();
88
- if (isReact19 && __privateGet(this, _el)) {
89
- __privateGet(this, _el).data = this.props.data;
74
+ this.updateProperties();
75
+ if (isReact19 && this.el) {
76
+ this.el.digits = this.props.digits;
77
+ this.el.data = this.props.data;
90
78
  }
91
79
  }
92
80
  getSnapshotBeforeUpdate(prevProps) {
93
- this.updateNonDataProps(prevProps);
94
- if (this.props.isolate || this.props.animated === false || prevProps.data === this.props.data)
95
- return false;
96
- __privateGet(this, _el)?.willUpdate();
97
- return true;
81
+ this.updateProperties(prevProps);
82
+ if (prevProps.data !== this.props.data) {
83
+ if (this.props.group) {
84
+ this.props.group.willUpdate();
85
+ return () => this.props.group?.didUpdate();
86
+ }
87
+ if (!this.props.isolate) {
88
+ this.el?.willUpdate();
89
+ return () => this.el?.didUpdate();
90
+ }
91
+ }
92
+ return null;
98
93
  }
99
- componentDidUpdate(_, __, snapshot) {
100
- if (snapshot) __privateGet(this, _el)?.didUpdate();
94
+ componentDidUpdate(_, __, didUpdate) {
95
+ didUpdate?.();
101
96
  }
102
97
  handleRef(el) {
103
98
  if (this.props.innerRef) this.props.innerRef.current = el;
104
- __privateSet(this, _el, el);
99
+ this.el = el;
105
100
  }
106
101
  render() {
107
102
  const [
@@ -112,6 +107,7 @@ var NumberFlowImpl = class extends React.Component {
112
107
  data,
113
108
  willChange,
114
109
  isolate,
110
+ digits,
115
111
  onAnimationsStart,
116
112
  onAnimationsFinish,
117
113
  ...rest
@@ -130,16 +126,18 @@ var NumberFlowImpl = class extends React.Component {
130
126
  role: "img",
131
127
  dangerouslySetInnerHTML: { __html: BROWSER ? "" : renderInnerHTML(data) },
132
128
  suppressHydrationWarning: true,
133
- data: serializeData(data)
129
+ digits: serialize(digits),
130
+ data: serialize(data)
134
131
  }
135
132
  )
136
133
  );
137
134
  }
138
135
  };
139
- _el = new WeakMap();
140
136
  var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format, prefix, suffix, ...props }, _ref) {
141
137
  React.useImperativeHandle(_ref, () => ref.current, []);
142
138
  const ref = React.useRef();
139
+ const group = React.useContext(NumberFlowGroupContext);
140
+ group?.useRegister(ref);
143
141
  const localesString = React.useMemo(() => locales ? JSON.stringify(locales) : "", [locales]);
144
142
  const formatString = React.useMemo(() => format ? JSON.stringify(format) : "", [format]);
145
143
  const data = React.useMemo(() => {
@@ -149,11 +147,50 @@ var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format,
149
147
  );
150
148
  return formatToData(value, formatter, prefix, suffix);
151
149
  }, [value, localesString, formatString, prefix, suffix]);
152
- return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, data, innerRef: ref });
150
+ return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
153
151
  });
154
152
  var src_default = NumberFlow;
153
+ var NumberFlowGroupContext = React.createContext(void 0);
154
+ function NumberFlowGroup({ children }) {
155
+ const flows = React.useRef(/* @__PURE__ */ new Set());
156
+ const updating = React.useRef(false);
157
+ const pending = React.useRef(/* @__PURE__ */ new WeakMap());
158
+ const value = React.useMemo(
159
+ () => ({
160
+ useRegister(ref) {
161
+ React.useEffect(() => {
162
+ flows.current.add(ref);
163
+ return () => {
164
+ flows.current.delete(ref);
165
+ };
166
+ }, []);
167
+ },
168
+ willUpdate() {
169
+ if (updating.current) return;
170
+ updating.current = true;
171
+ flows.current.forEach((ref) => {
172
+ const f = ref.current;
173
+ if (!f || !f.created) return;
174
+ f.willUpdate();
175
+ pending.current.set(f, true);
176
+ });
177
+ },
178
+ didUpdate() {
179
+ flows.current.forEach((ref) => {
180
+ const f = ref.current;
181
+ if (!f || !pending.current.get(f)) return;
182
+ f.didUpdate();
183
+ pending.current.delete(f);
184
+ });
185
+ updating.current = false;
186
+ }
187
+ }),
188
+ []
189
+ );
190
+ return /* @__PURE__ */ React.createElement(NumberFlowGroupContext.Provider, { value }, children);
191
+ }
155
192
  function useCanAnimate({ respectMotionPreference = true } = {}) {
156
- const [canAnimate, setCanAnimate] = React.useState(_canAnimate);
193
+ const [canAnimate, setCanAnimate] = React.useState(false);
157
194
  const [reducedMotion, setReducedMotion] = React.useState(false);
158
195
  React.useEffect(() => {
159
196
  setCanAnimate(_canAnimate);
@@ -173,6 +210,7 @@ function useCanAnimate({ respectMotionPreference = true } = {}) {
173
210
  }
174
211
  export {
175
212
  NumberFlowElement,
213
+ NumberFlowGroup,
176
214
  src_default as default,
177
215
  useCanAnimate
178
216
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.3.5",
6
+ "version": "0.4.1",
7
7
  "author": {
8
8
  "name": "Maxwell Barvian",
9
9
  "email": "max@barvian.me",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "esm-env": "^1.1.4",
52
- "number-flow": "0.3.10"
52
+ "number-flow": "0.4.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@playwright/test": "^1.48.0",