@number-flow/react 0.5.2 → 0.5.3

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.
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
+
4
+ declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
5
+ type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
6
+ declare class NumberFlowElement extends NumberFlowLite {
7
+ static observedAttributes: readonly ["data", "digits"] | never[];
8
+ attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
9
+ }
10
+ type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
11
+ isolate?: boolean;
12
+ willChange?: boolean;
13
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
14
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
15
+ };
16
+ type NumberFlowProps = BaseProps & {
17
+ value: Value;
18
+ locales?: Intl.LocalesArgument;
19
+ format?: Format;
20
+ prefix?: string;
21
+ suffix?: string;
22
+ };
23
+ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
24
+ isolate?: boolean;
25
+ willChange?: boolean;
26
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
27
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
28
+ } & {
29
+ value: Value;
30
+ locales?: Intl.LocalesArgument;
31
+ format?: Format;
32
+ prefix?: string;
33
+ suffix?: string;
34
+ } & React.RefAttributes<NumberFlowElement>>;
35
+
36
+ declare function NumberFlowGroup({ children }: {
37
+ children: React.ReactNode;
38
+ }): React.JSX.Element;
39
+
40
+ export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default };
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
+
4
+ declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
5
+ type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
6
+ declare class NumberFlowElement extends NumberFlowLite {
7
+ static observedAttributes: readonly ["data", "digits"] | never[];
8
+ attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
9
+ }
10
+ type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
11
+ isolate?: boolean;
12
+ willChange?: boolean;
13
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
14
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
15
+ };
16
+ type NumberFlowProps = BaseProps & {
17
+ value: Value;
18
+ locales?: Intl.LocalesArgument;
19
+ format?: Format;
20
+ prefix?: string;
21
+ suffix?: string;
22
+ };
23
+ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
24
+ isolate?: boolean;
25
+ willChange?: boolean;
26
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
27
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
28
+ } & {
29
+ value: Value;
30
+ locales?: Intl.LocalesArgument;
31
+ format?: Format;
32
+ prefix?: string;
33
+ suffix?: string;
34
+ } & React.RefAttributes<NumberFlowElement>>;
35
+
36
+ declare function NumberFlowGroup({ children }: {
37
+ children: React.ReactNode;
38
+ }): React.JSX.Element;
39
+
40
+ export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default };
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/NumberFlow.tsx
32
+ var NumberFlow_exports = {};
33
+ __export(NumberFlow_exports, {
34
+ NumberFlowElement: () => NumberFlowElement,
35
+ NumberFlowGroup: () => NumberFlowGroup,
36
+ default: () => NumberFlow_default
37
+ });
38
+ module.exports = __toCommonJS(NumberFlow_exports);
39
+ var React = __toESM(require("react"));
40
+ var import_number_flow = require("number-flow");
41
+ var import_esm_env = require("esm-env");
42
+ var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
43
+ var isReact19 = REACT_MAJOR >= 19;
44
+ var OBSERVED_ATTRIBUTES = ["data", "digits"];
45
+ var NumberFlowElement = class extends import_number_flow.NumberFlowLite {
46
+ attributeChangedCallback(attr, _oldValue, newValue) {
47
+ this[attr] = JSON.parse(newValue);
48
+ }
49
+ };
50
+ NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
51
+ (0, import_number_flow.define)("number-flow-react", NumberFlowElement);
52
+ var formatters = {};
53
+ var serialize = isReact19 ? (p) => p : JSON.stringify;
54
+ function splitProps(props) {
55
+ const {
56
+ transformTiming,
57
+ spinTiming,
58
+ opacityTiming,
59
+ animated,
60
+ respectMotionPreference,
61
+ trend,
62
+ plugins,
63
+ ...rest
64
+ } = props;
65
+ return [
66
+ {
67
+ transformTiming,
68
+ spinTiming,
69
+ opacityTiming,
70
+ animated,
71
+ respectMotionPreference,
72
+ trend,
73
+ plugins
74
+ },
75
+ rest
76
+ ];
77
+ }
78
+ var NumberFlowImpl = class extends React.Component {
79
+ constructor(props) {
80
+ super(props);
81
+ this.handleRef = this.handleRef.bind(this);
82
+ }
83
+ // Update the non-`data` props to avoid JSON serialization
84
+ // Data needs to be set in render still:
85
+ updateProperties(prevProps) {
86
+ if (!this.el) return;
87
+ this.el.manual = !this.props.isolate;
88
+ const [nonData] = splitProps(this.props);
89
+ Object.entries(nonData).forEach(([k, v]) => {
90
+ this.el[k] = v ?? NumberFlowElement.defaultProps[k];
91
+ });
92
+ if (prevProps?.onAnimationsStart)
93
+ this.el.removeEventListener("animationsstart", prevProps.onAnimationsStart);
94
+ if (this.props.onAnimationsStart)
95
+ this.el.addEventListener("animationsstart", this.props.onAnimationsStart);
96
+ if (prevProps?.onAnimationsFinish)
97
+ this.el.removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
98
+ if (this.props.onAnimationsFinish)
99
+ this.el.addEventListener("animationsfinish", this.props.onAnimationsFinish);
100
+ }
101
+ componentDidMount() {
102
+ this.updateProperties();
103
+ if (isReact19 && this.el) {
104
+ this.el.digits = this.props.digits;
105
+ this.el.data = this.props.data;
106
+ }
107
+ }
108
+ getSnapshotBeforeUpdate(prevProps) {
109
+ this.updateProperties(prevProps);
110
+ if (prevProps.data !== this.props.data) {
111
+ if (this.props.group) {
112
+ this.props.group.willUpdate();
113
+ return () => this.props.group?.didUpdate();
114
+ }
115
+ if (!this.props.isolate) {
116
+ this.el?.willUpdate();
117
+ return () => this.el?.didUpdate();
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ componentDidUpdate(_, __, didUpdate) {
123
+ didUpdate?.();
124
+ }
125
+ handleRef(el) {
126
+ if (this.props.innerRef) this.props.innerRef.current = el;
127
+ this.el = el;
128
+ }
129
+ render() {
130
+ const [
131
+ _,
132
+ {
133
+ innerRef,
134
+ className,
135
+ data,
136
+ willChange,
137
+ isolate,
138
+ group,
139
+ digits,
140
+ onAnimationsStart,
141
+ onAnimationsFinish,
142
+ ...rest
143
+ }
144
+ ] = splitProps(this.props);
145
+ return (
146
+ // @ts-expect-error missing types
147
+ /* @__PURE__ */ React.createElement(
148
+ "number-flow-react",
149
+ {
150
+ ref: this.handleRef,
151
+ "data-will-change": willChange ? "" : void 0,
152
+ class: className,
153
+ "aria-label": data.valueAsString,
154
+ ...rest,
155
+ role: "img",
156
+ dangerouslySetInnerHTML: { __html: import_esm_env.BROWSER ? "" : (0, import_number_flow.renderInnerHTML)(data) },
157
+ suppressHydrationWarning: true,
158
+ digits: serialize(digits),
159
+ data: serialize(data)
160
+ }
161
+ )
162
+ );
163
+ }
164
+ };
165
+ var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format, prefix, suffix, ...props }, _ref) {
166
+ React.useImperativeHandle(_ref, () => ref.current, []);
167
+ const ref = React.useRef();
168
+ const group = React.useContext(NumberFlowGroupContext);
169
+ group?.useRegister(ref);
170
+ const localesString = React.useMemo(() => locales ? JSON.stringify(locales) : "", [locales]);
171
+ const formatString = React.useMemo(() => format ? JSON.stringify(format) : "", [format]);
172
+ const data = React.useMemo(() => {
173
+ const formatter = formatters[`${localesString}:${formatString}`] ??= new Intl.NumberFormat(
174
+ locales,
175
+ format
176
+ );
177
+ return (0, import_number_flow.formatToData)(value, formatter, prefix, suffix);
178
+ }, [value, localesString, formatString, prefix, suffix]);
179
+ return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
180
+ });
181
+ var NumberFlow_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
+ }
221
+ // Annotate the CommonJS export names for ESM import in node:
222
+ 0 && (module.exports = {
223
+ NumberFlowElement,
224
+ NumberFlowGroup
225
+ });
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import {
3
+ NumberFlowElement,
4
+ NumberFlowGroup,
5
+ NumberFlow_default
6
+ } from "./chunk-44AMDIF5.mjs";
7
+ export {
8
+ NumberFlowElement,
9
+ NumberFlowGroup,
10
+ NumberFlow_default as default
11
+ };
@@ -0,0 +1,194 @@
1
+ // src/NumberFlow.tsx
2
+ import * as React from "react";
3
+ import {
4
+ renderInnerHTML,
5
+ formatToData,
6
+ NumberFlowLite,
7
+ define
8
+ } from "number-flow";
9
+ import { BROWSER } from "esm-env";
10
+ var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
11
+ var isReact19 = REACT_MAJOR >= 19;
12
+ var OBSERVED_ATTRIBUTES = ["data", "digits"];
13
+ var NumberFlowElement = class extends NumberFlowLite {
14
+ attributeChangedCallback(attr, _oldValue, newValue) {
15
+ this[attr] = JSON.parse(newValue);
16
+ }
17
+ };
18
+ NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
19
+ define("number-flow-react", NumberFlowElement);
20
+ var formatters = {};
21
+ var serialize = isReact19 ? (p) => p : JSON.stringify;
22
+ function splitProps(props) {
23
+ const {
24
+ transformTiming,
25
+ spinTiming,
26
+ opacityTiming,
27
+ animated,
28
+ respectMotionPreference,
29
+ trend,
30
+ plugins,
31
+ ...rest
32
+ } = props;
33
+ return [
34
+ {
35
+ transformTiming,
36
+ spinTiming,
37
+ opacityTiming,
38
+ animated,
39
+ respectMotionPreference,
40
+ trend,
41
+ plugins
42
+ },
43
+ rest
44
+ ];
45
+ }
46
+ var NumberFlowImpl = class extends React.Component {
47
+ constructor(props) {
48
+ super(props);
49
+ this.handleRef = this.handleRef.bind(this);
50
+ }
51
+ // Update the non-`data` props to avoid JSON serialization
52
+ // Data needs to be set in render still:
53
+ updateProperties(prevProps) {
54
+ if (!this.el) return;
55
+ this.el.manual = !this.props.isolate;
56
+ const [nonData] = splitProps(this.props);
57
+ Object.entries(nonData).forEach(([k, v]) => {
58
+ this.el[k] = v ?? NumberFlowElement.defaultProps[k];
59
+ });
60
+ if (prevProps?.onAnimationsStart)
61
+ this.el.removeEventListener("animationsstart", prevProps.onAnimationsStart);
62
+ if (this.props.onAnimationsStart)
63
+ this.el.addEventListener("animationsstart", this.props.onAnimationsStart);
64
+ if (prevProps?.onAnimationsFinish)
65
+ this.el.removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
66
+ if (this.props.onAnimationsFinish)
67
+ this.el.addEventListener("animationsfinish", this.props.onAnimationsFinish);
68
+ }
69
+ componentDidMount() {
70
+ this.updateProperties();
71
+ if (isReact19 && this.el) {
72
+ this.el.digits = this.props.digits;
73
+ this.el.data = this.props.data;
74
+ }
75
+ }
76
+ getSnapshotBeforeUpdate(prevProps) {
77
+ this.updateProperties(prevProps);
78
+ if (prevProps.data !== this.props.data) {
79
+ if (this.props.group) {
80
+ this.props.group.willUpdate();
81
+ return () => this.props.group?.didUpdate();
82
+ }
83
+ if (!this.props.isolate) {
84
+ this.el?.willUpdate();
85
+ return () => this.el?.didUpdate();
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ componentDidUpdate(_, __, didUpdate) {
91
+ didUpdate?.();
92
+ }
93
+ handleRef(el) {
94
+ if (this.props.innerRef) this.props.innerRef.current = el;
95
+ this.el = el;
96
+ }
97
+ render() {
98
+ const [
99
+ _,
100
+ {
101
+ innerRef,
102
+ className,
103
+ data,
104
+ willChange,
105
+ isolate,
106
+ group,
107
+ digits,
108
+ onAnimationsStart,
109
+ onAnimationsFinish,
110
+ ...rest
111
+ }
112
+ ] = splitProps(this.props);
113
+ return (
114
+ // @ts-expect-error missing types
115
+ /* @__PURE__ */ React.createElement(
116
+ "number-flow-react",
117
+ {
118
+ ref: this.handleRef,
119
+ "data-will-change": willChange ? "" : void 0,
120
+ class: className,
121
+ "aria-label": data.valueAsString,
122
+ ...rest,
123
+ role: "img",
124
+ dangerouslySetInnerHTML: { __html: BROWSER ? "" : renderInnerHTML(data) },
125
+ suppressHydrationWarning: true,
126
+ digits: serialize(digits),
127
+ data: serialize(data)
128
+ }
129
+ )
130
+ );
131
+ }
132
+ };
133
+ var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format, prefix, suffix, ...props }, _ref) {
134
+ React.useImperativeHandle(_ref, () => ref.current, []);
135
+ const ref = React.useRef();
136
+ const group = React.useContext(NumberFlowGroupContext);
137
+ group?.useRegister(ref);
138
+ const localesString = React.useMemo(() => locales ? JSON.stringify(locales) : "", [locales]);
139
+ const formatString = React.useMemo(() => format ? JSON.stringify(format) : "", [format]);
140
+ const data = React.useMemo(() => {
141
+ const formatter = formatters[`${localesString}:${formatString}`] ??= new Intl.NumberFormat(
142
+ locales,
143
+ format
144
+ );
145
+ return formatToData(value, formatter, prefix, suffix);
146
+ }, [value, localesString, formatString, prefix, suffix]);
147
+ return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
148
+ });
149
+ var NumberFlow_default = NumberFlow;
150
+ var NumberFlowGroupContext = React.createContext(void 0);
151
+ function NumberFlowGroup({ children }) {
152
+ const flows = React.useRef(/* @__PURE__ */ new Set());
153
+ const updating = React.useRef(false);
154
+ const pending = React.useRef(/* @__PURE__ */ new WeakMap());
155
+ const value = React.useMemo(
156
+ () => ({
157
+ useRegister(ref) {
158
+ React.useEffect(() => {
159
+ flows.current.add(ref);
160
+ return () => {
161
+ flows.current.delete(ref);
162
+ };
163
+ }, []);
164
+ },
165
+ willUpdate() {
166
+ if (updating.current) return;
167
+ updating.current = true;
168
+ flows.current.forEach((ref) => {
169
+ const f = ref.current;
170
+ if (!f || !f.created) return;
171
+ f.willUpdate();
172
+ pending.current.set(f, true);
173
+ });
174
+ },
175
+ didUpdate() {
176
+ flows.current.forEach((ref) => {
177
+ const f = ref.current;
178
+ if (!f || !pending.current.get(f)) return;
179
+ f.didUpdate();
180
+ pending.current.delete(f);
181
+ });
182
+ updating.current = false;
183
+ }
184
+ }),
185
+ []
186
+ );
187
+ return /* @__PURE__ */ React.createElement(NumberFlowGroupContext.Provider, { value }, children);
188
+ }
189
+
190
+ export {
191
+ NumberFlowElement,
192
+ NumberFlow_default,
193
+ NumberFlowGroup
194
+ };
package/dist/index.d.mts CHANGED
@@ -1,47 +1,12 @@
1
- import * as React from 'react';
2
- import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
- export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
1
  export * from 'number-flow/plugins';
2
+ export { NumberFlowElement, NumberFlowGroup, NumberFlowProps, default } from './NumberFlow.mjs';
3
+ export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
+ import 'react';
5
5
 
6
- declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
7
- type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
8
- declare class NumberFlowElement extends NumberFlowLite {
9
- static observedAttributes: readonly ["data", "digits"] | never[];
10
- attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
11
- }
12
- type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
13
- isolate?: boolean;
14
- willChange?: boolean;
15
- onAnimationsStart?: (e: CustomEvent<undefined>) => void;
16
- onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
17
- };
18
- type NumberFlowProps = BaseProps & {
19
- value: Value;
20
- locales?: Intl.LocalesArgument;
21
- format?: Format;
22
- prefix?: string;
23
- suffix?: string;
24
- };
25
- declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
26
- isolate?: boolean;
27
- willChange?: boolean;
28
- onAnimationsStart?: (e: CustomEvent<undefined>) => void;
29
- onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
30
- } & {
31
- value: Value;
32
- locales?: Intl.LocalesArgument;
33
- format?: Format;
34
- prefix?: string;
35
- suffix?: string;
36
- } & React.RefAttributes<NumberFlowElement>>;
37
-
38
- declare function NumberFlowGroup({ children }: {
39
- children: React.ReactNode;
40
- }): React.JSX.Element;
41
6
  declare const useIsSupported: () => boolean;
42
7
  declare const usePrefersReducedMotion: () => boolean;
43
8
  declare function useCanAnimate({ respectMotionPreference }?: {
44
9
  respectMotionPreference?: boolean | undefined;
45
10
  }): boolean;
46
11
 
47
- export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default, useCanAnimate, useIsSupported, usePrefersReducedMotion };
12
+ export { useCanAnimate, useIsSupported, usePrefersReducedMotion };
package/dist/index.d.ts CHANGED
@@ -1,47 +1,12 @@
1
- import * as React from 'react';
2
- import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
- export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
1
  export * from 'number-flow/plugins';
2
+ export { NumberFlowElement, NumberFlowGroup, NumberFlowProps, default } from './NumberFlow.js';
3
+ export { Format, NumberPartType, Trend, Value } from 'number-flow';
4
+ import 'react';
5
5
 
6
- declare const OBSERVED_ATTRIBUTES: readonly ["data", "digits"];
7
- type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
8
- declare class NumberFlowElement extends NumberFlowLite {
9
- static observedAttributes: readonly ["data", "digits"] | never[];
10
- attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
11
- }
12
- type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
13
- isolate?: boolean;
14
- willChange?: boolean;
15
- onAnimationsStart?: (e: CustomEvent<undefined>) => void;
16
- onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
17
- };
18
- type NumberFlowProps = BaseProps & {
19
- value: Value;
20
- locales?: Intl.LocalesArgument;
21
- format?: Format;
22
- prefix?: string;
23
- suffix?: string;
24
- };
25
- declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
26
- isolate?: boolean;
27
- willChange?: boolean;
28
- onAnimationsStart?: (e: CustomEvent<undefined>) => void;
29
- onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
30
- } & {
31
- value: Value;
32
- locales?: Intl.LocalesArgument;
33
- format?: Format;
34
- prefix?: string;
35
- suffix?: string;
36
- } & React.RefAttributes<NumberFlowElement>>;
37
-
38
- declare function NumberFlowGroup({ children }: {
39
- children: React.ReactNode;
40
- }): React.JSX.Element;
41
6
  declare const useIsSupported: () => boolean;
42
7
  declare const usePrefersReducedMotion: () => boolean;
43
8
  declare function useCanAnimate({ respectMotionPreference }?: {
44
9
  respectMotionPreference?: boolean | undefined;
45
10
  }): boolean;
46
11
 
47
- export { NumberFlowElement, NumberFlowGroup, type NumberFlowProps, NumberFlow as default, useCanAnimate, useIsSupported, usePrefersReducedMotion };
12
+ export { useCanAnimate, useIsSupported, usePrefersReducedMotion };
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- "use client";
3
2
  var __create = Object.create;
4
3
  var __defProp = Object.defineProperty;
5
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -30,20 +29,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
30
 
32
31
  // src/index.tsx
33
- var src_exports = {};
34
- __export(src_exports, {
32
+ var index_exports = {};
33
+ __export(index_exports, {
35
34
  NumberFlowElement: () => NumberFlowElement,
36
35
  NumberFlowGroup: () => NumberFlowGroup,
37
- default: () => src_default,
36
+ default: () => NumberFlow_default,
38
37
  useCanAnimate: () => useCanAnimate,
39
38
  useIsSupported: () => useIsSupported,
40
39
  usePrefersReducedMotion: () => usePrefersReducedMotion
41
40
  });
42
- module.exports = __toCommonJS(src_exports);
41
+ module.exports = __toCommonJS(index_exports);
42
+ var React2 = __toESM(require("react"));
43
+ var import_number_flow2 = require("number-flow");
44
+ __reExport(index_exports, require("number-flow/plugins"), module.exports);
45
+
46
+ // src/NumberFlow.tsx
43
47
  var React = __toESM(require("react"));
44
48
  var import_number_flow = require("number-flow");
45
49
  var import_esm_env = require("esm-env");
46
- __reExport(src_exports, require("number-flow/plugins"), module.exports);
47
50
  var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
48
51
  var isReact19 = REACT_MAJOR >= 19;
49
52
  var OBSERVED_ATTRIBUTES = ["data", "digits"];
@@ -183,7 +186,7 @@ var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format,
183
186
  }, [value, localesString, formatString, prefix, suffix]);
184
187
  return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
185
188
  });
186
- var src_default = NumberFlow;
189
+ var NumberFlow_default = NumberFlow;
187
190
  var NumberFlowGroupContext = React.createContext(void 0);
188
191
  function NumberFlowGroup({ children }) {
189
192
  const flows = React.useRef(/* @__PURE__ */ new Set());
@@ -223,19 +226,21 @@ function NumberFlowGroup({ children }) {
223
226
  );
224
227
  return /* @__PURE__ */ React.createElement(NumberFlowGroupContext.Provider, { value }, children);
225
228
  }
226
- var useIsSupported = () => React.useSyncExternalStore(
229
+
230
+ // src/index.tsx
231
+ var useIsSupported = () => React2.useSyncExternalStore(
227
232
  () => () => {
228
233
  },
229
234
  // this value doesn't change, but it's useful to specify a different SSR value:
230
- () => import_number_flow.canAnimate,
235
+ () => import_number_flow2.canAnimate,
231
236
  () => false
232
237
  );
233
- var usePrefersReducedMotion = () => React.useSyncExternalStore(
238
+ var usePrefersReducedMotion = () => React2.useSyncExternalStore(
234
239
  (cb) => {
235
- import_number_flow.prefersReducedMotion?.addEventListener("change", cb);
236
- return () => import_number_flow.prefersReducedMotion?.removeEventListener("change", cb);
240
+ import_number_flow2.prefersReducedMotion?.addEventListener("change", cb);
241
+ return () => import_number_flow2.prefersReducedMotion?.removeEventListener("change", cb);
237
242
  },
238
- () => import_number_flow.prefersReducedMotion.matches,
243
+ () => import_number_flow2.prefersReducedMotion.matches,
239
244
  () => false
240
245
  );
241
246
  function useCanAnimate({ respectMotionPreference = true } = {}) {
package/dist/index.mjs CHANGED
@@ -1,196 +1,16 @@
1
- "use client";
1
+ import {
2
+ NumberFlowElement,
3
+ NumberFlowGroup,
4
+ NumberFlow_default
5
+ } from "./chunk-44AMDIF5.mjs";
2
6
 
3
7
  // src/index.tsx
4
8
  import * as React from "react";
5
9
  import {
6
- renderInnerHTML,
7
- formatToData,
8
- NumberFlowLite,
9
10
  prefersReducedMotion as _prefersReducedMotion,
10
- canAnimate as _canAnimate,
11
- define
11
+ canAnimate as _canAnimate
12
12
  } from "number-flow";
13
- import { BROWSER } from "esm-env";
14
13
  export * from "number-flow/plugins";
15
- var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
16
- var isReact19 = REACT_MAJOR >= 19;
17
- var OBSERVED_ATTRIBUTES = ["data", "digits"];
18
- var NumberFlowElement = class extends NumberFlowLite {
19
- attributeChangedCallback(attr, _oldValue, newValue) {
20
- this[attr] = JSON.parse(newValue);
21
- }
22
- };
23
- NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
24
- define("number-flow-react", NumberFlowElement);
25
- var formatters = {};
26
- var serialize = isReact19 ? (p) => p : JSON.stringify;
27
- function splitProps(props) {
28
- const {
29
- transformTiming,
30
- spinTiming,
31
- opacityTiming,
32
- animated,
33
- respectMotionPreference,
34
- trend,
35
- plugins,
36
- ...rest
37
- } = props;
38
- return [
39
- {
40
- transformTiming,
41
- spinTiming,
42
- opacityTiming,
43
- animated,
44
- respectMotionPreference,
45
- trend,
46
- plugins
47
- },
48
- rest
49
- ];
50
- }
51
- var NumberFlowImpl = class extends React.Component {
52
- constructor(props) {
53
- super(props);
54
- this.handleRef = this.handleRef.bind(this);
55
- }
56
- // Update the non-`data` props to avoid JSON serialization
57
- // Data needs to be set in render still:
58
- updateProperties(prevProps) {
59
- if (!this.el) return;
60
- this.el.manual = !this.props.isolate;
61
- const [nonData] = splitProps(this.props);
62
- Object.entries(nonData).forEach(([k, v]) => {
63
- this.el[k] = v ?? NumberFlowElement.defaultProps[k];
64
- });
65
- if (prevProps?.onAnimationsStart)
66
- this.el.removeEventListener("animationsstart", prevProps.onAnimationsStart);
67
- if (this.props.onAnimationsStart)
68
- this.el.addEventListener("animationsstart", this.props.onAnimationsStart);
69
- if (prevProps?.onAnimationsFinish)
70
- this.el.removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
71
- if (this.props.onAnimationsFinish)
72
- this.el.addEventListener("animationsfinish", this.props.onAnimationsFinish);
73
- }
74
- componentDidMount() {
75
- this.updateProperties();
76
- if (isReact19 && this.el) {
77
- this.el.digits = this.props.digits;
78
- this.el.data = this.props.data;
79
- }
80
- }
81
- getSnapshotBeforeUpdate(prevProps) {
82
- this.updateProperties(prevProps);
83
- if (prevProps.data !== this.props.data) {
84
- if (this.props.group) {
85
- this.props.group.willUpdate();
86
- return () => this.props.group?.didUpdate();
87
- }
88
- if (!this.props.isolate) {
89
- this.el?.willUpdate();
90
- return () => this.el?.didUpdate();
91
- }
92
- }
93
- return null;
94
- }
95
- componentDidUpdate(_, __, didUpdate) {
96
- didUpdate?.();
97
- }
98
- handleRef(el) {
99
- if (this.props.innerRef) this.props.innerRef.current = el;
100
- this.el = el;
101
- }
102
- render() {
103
- const [
104
- _,
105
- {
106
- innerRef,
107
- className,
108
- data,
109
- willChange,
110
- isolate,
111
- group,
112
- digits,
113
- onAnimationsStart,
114
- onAnimationsFinish,
115
- ...rest
116
- }
117
- ] = splitProps(this.props);
118
- return (
119
- // @ts-expect-error missing types
120
- /* @__PURE__ */ React.createElement(
121
- "number-flow-react",
122
- {
123
- ref: this.handleRef,
124
- "data-will-change": willChange ? "" : void 0,
125
- class: className,
126
- "aria-label": data.valueAsString,
127
- ...rest,
128
- role: "img",
129
- dangerouslySetInnerHTML: { __html: BROWSER ? "" : renderInnerHTML(data) },
130
- suppressHydrationWarning: true,
131
- digits: serialize(digits),
132
- data: serialize(data)
133
- }
134
- )
135
- );
136
- }
137
- };
138
- var NumberFlow = React.forwardRef(function NumberFlow2({ value, locales, format, prefix, suffix, ...props }, _ref) {
139
- React.useImperativeHandle(_ref, () => ref.current, []);
140
- const ref = React.useRef();
141
- const group = React.useContext(NumberFlowGroupContext);
142
- group?.useRegister(ref);
143
- const localesString = React.useMemo(() => locales ? JSON.stringify(locales) : "", [locales]);
144
- const formatString = React.useMemo(() => format ? JSON.stringify(format) : "", [format]);
145
- const data = React.useMemo(() => {
146
- const formatter = formatters[`${localesString}:${formatString}`] ??= new Intl.NumberFormat(
147
- locales,
148
- format
149
- );
150
- return formatToData(value, formatter, prefix, suffix);
151
- }, [value, localesString, formatString, prefix, suffix]);
152
- return /* @__PURE__ */ React.createElement(NumberFlowImpl, { ...props, group, data, innerRef: ref });
153
- });
154
- var src_default = NumberFlow;
155
- var NumberFlowGroupContext = React.createContext(void 0);
156
- function NumberFlowGroup({ children }) {
157
- const flows = React.useRef(/* @__PURE__ */ new Set());
158
- const updating = React.useRef(false);
159
- const pending = React.useRef(/* @__PURE__ */ new WeakMap());
160
- const value = React.useMemo(
161
- () => ({
162
- useRegister(ref) {
163
- React.useEffect(() => {
164
- flows.current.add(ref);
165
- return () => {
166
- flows.current.delete(ref);
167
- };
168
- }, []);
169
- },
170
- willUpdate() {
171
- if (updating.current) return;
172
- updating.current = true;
173
- flows.current.forEach((ref) => {
174
- const f = ref.current;
175
- if (!f || !f.created) return;
176
- f.willUpdate();
177
- pending.current.set(f, true);
178
- });
179
- },
180
- didUpdate() {
181
- flows.current.forEach((ref) => {
182
- const f = ref.current;
183
- if (!f || !pending.current.get(f)) return;
184
- f.didUpdate();
185
- pending.current.delete(f);
186
- });
187
- updating.current = false;
188
- }
189
- }),
190
- []
191
- );
192
- return /* @__PURE__ */ React.createElement(NumberFlowGroupContext.Provider, { value }, children);
193
- }
194
14
  var useIsSupported = () => React.useSyncExternalStore(
195
15
  () => () => {
196
16
  },
@@ -214,7 +34,7 @@ function useCanAnimate({ respectMotionPreference = true } = {}) {
214
34
  export {
215
35
  NumberFlowElement,
216
36
  NumberFlowGroup,
217
- src_default as default,
37
+ NumberFlow_default as default,
218
38
  useCanAnimate,
219
39
  useIsSupported,
220
40
  usePrefersReducedMotion
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.5.2",
6
+ "version": "0.5.3",
7
7
  "author": {
8
8
  "name": "Maxwell Barvian",
9
9
  "email": "max@barvian.me",
@@ -58,7 +58,7 @@
58
58
  "@types/react-dom": "^18.3.0",
59
59
  "react": "^18.3.1",
60
60
  "react-dom": "^18.3.1",
61
- "tsup": "^8.2.4"
61
+ "tsup": "^8.3.5"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "react": "^18 || ^19",