@number-flow/react 0.2.5 → 0.3.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/dist/index.d.mts CHANGED
@@ -1,44 +1,33 @@
1
1
  import * as React from 'react';
2
- import { NumberFlowLite, Value, Format } from 'number-flow';
2
+ import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
3
  export { Format, Trend, Value } from 'number-flow';
4
4
 
5
5
  declare const OBSERVED_ATTRIBUTES: readonly ["parts"];
6
6
  type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
7
7
  declare class NumberFlowElement extends NumberFlowLite {
8
- static observedAttributes: readonly ["parts"];
8
+ static observedAttributes: readonly ["parts"] | never[];
9
9
  attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
10
10
  }
11
- type NumberFlowProps = React.HTMLAttributes<NumberFlowElement> & {
12
- value: Value;
13
- locales?: Intl.LocalesArgument;
14
- format?: Format;
11
+ type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
15
12
  isolate?: boolean;
16
- animated?: boolean;
17
- respectMotionPreference?: boolean;
18
13
  willChange?: boolean;
19
- onAnimationsStart?: () => void;
20
- onAnimationsFinish?: () => void;
21
- trend?: (typeof NumberFlowElement)['prototype']['trend'];
22
- continuous?: (typeof NumberFlowElement)['prototype']['continuous'];
23
- opacityTiming?: (typeof NumberFlowElement)['prototype']['opacityTiming'];
24
- transformTiming?: (typeof NumberFlowElement)['prototype']['transformTiming'];
25
- spinTiming?: (typeof NumberFlowElement)['prototype']['spinTiming'];
14
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
15
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
26
16
  };
27
- declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & {
17
+ type NumberFlowProps = BaseProps & {
28
18
  value: Value;
29
19
  locales?: Intl.LocalesArgument;
30
20
  format?: Format;
21
+ };
22
+ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
31
23
  isolate?: boolean;
32
- animated?: boolean;
33
- respectMotionPreference?: boolean;
34
24
  willChange?: boolean;
35
- onAnimationsStart?: () => void;
36
- onAnimationsFinish?: () => void;
37
- trend?: (typeof NumberFlowElement)["prototype"]["trend"];
38
- continuous?: (typeof NumberFlowElement)["prototype"]["continuous"];
39
- opacityTiming?: (typeof NumberFlowElement)["prototype"]["opacityTiming"];
40
- transformTiming?: (typeof NumberFlowElement)["prototype"]["transformTiming"];
41
- spinTiming?: (typeof NumberFlowElement)["prototype"]["spinTiming"];
25
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
26
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
27
+ } & {
28
+ value: Value;
29
+ locales?: Intl.LocalesArgument;
30
+ format?: Format;
42
31
  } & React.RefAttributes<NumberFlowElement>>;
43
32
 
44
33
  declare function useCanAnimate({ respectMotionPreference }?: {
package/dist/index.d.ts CHANGED
@@ -1,44 +1,33 @@
1
1
  import * as React from 'react';
2
- import { NumberFlowLite, Value, Format } from 'number-flow';
2
+ import { NumberFlowLite, Value, Format, Props } from 'number-flow';
3
3
  export { Format, Trend, Value } from 'number-flow';
4
4
 
5
5
  declare const OBSERVED_ATTRIBUTES: readonly ["parts"];
6
6
  type ObservedAttribute = (typeof OBSERVED_ATTRIBUTES)[number];
7
7
  declare class NumberFlowElement extends NumberFlowLite {
8
- static observedAttributes: readonly ["parts"];
8
+ static observedAttributes: readonly ["parts"] | never[];
9
9
  attributeChangedCallback(attr: ObservedAttribute, _oldValue: string, newValue: string): void;
10
10
  }
11
- type NumberFlowProps = React.HTMLAttributes<NumberFlowElement> & {
12
- value: Value;
13
- locales?: Intl.LocalesArgument;
14
- format?: Format;
11
+ type BaseProps = React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
15
12
  isolate?: boolean;
16
- animated?: boolean;
17
- respectMotionPreference?: boolean;
18
13
  willChange?: boolean;
19
- onAnimationsStart?: () => void;
20
- onAnimationsFinish?: () => void;
21
- trend?: (typeof NumberFlowElement)['prototype']['trend'];
22
- continuous?: (typeof NumberFlowElement)['prototype']['continuous'];
23
- opacityTiming?: (typeof NumberFlowElement)['prototype']['opacityTiming'];
24
- transformTiming?: (typeof NumberFlowElement)['prototype']['transformTiming'];
25
- spinTiming?: (typeof NumberFlowElement)['prototype']['spinTiming'];
14
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
15
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
26
16
  };
27
- declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & {
17
+ type NumberFlowProps = BaseProps & {
28
18
  value: Value;
29
19
  locales?: Intl.LocalesArgument;
30
20
  format?: Format;
21
+ };
22
+ declare const NumberFlow: React.ForwardRefExoticComponent<React.HTMLAttributes<NumberFlowElement> & Partial<Props> & {
31
23
  isolate?: boolean;
32
- animated?: boolean;
33
- respectMotionPreference?: boolean;
34
24
  willChange?: boolean;
35
- onAnimationsStart?: () => void;
36
- onAnimationsFinish?: () => void;
37
- trend?: (typeof NumberFlowElement)["prototype"]["trend"];
38
- continuous?: (typeof NumberFlowElement)["prototype"]["continuous"];
39
- opacityTiming?: (typeof NumberFlowElement)["prototype"]["opacityTiming"];
40
- transformTiming?: (typeof NumberFlowElement)["prototype"]["transformTiming"];
41
- spinTiming?: (typeof NumberFlowElement)["prototype"]["spinTiming"];
25
+ onAnimationsStart?: (e: CustomEvent<undefined>) => void;
26
+ onAnimationsFinish?: (e: CustomEvent<undefined>) => void;
27
+ } & {
28
+ value: Value;
29
+ locales?: Intl.LocalesArgument;
30
+ format?: Format;
42
31
  } & React.RefAttributes<NumberFlowElement>>;
43
32
 
44
33
  declare function useCanAnimate({ respectMotionPreference }?: {
package/dist/index.js CHANGED
@@ -45,17 +45,42 @@ __export(src_exports, {
45
45
  module.exports = __toCommonJS(src_exports);
46
46
  var React = __toESM(require("react"));
47
47
  var import_number_flow = require("number-flow");
48
- var isReact19 = React.version.startsWith("19.");
48
+ var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
49
+ var isReact19 = REACT_MAJOR >= 19;
49
50
  var OBSERVED_ATTRIBUTES = ["parts"];
50
51
  var NumberFlowElement = class extends import_number_flow.NumberFlowLite {
51
52
  attributeChangedCallback(attr, _oldValue, newValue) {
52
53
  this[attr] = JSON.parse(newValue);
53
54
  }
54
55
  };
55
- NumberFlowElement.observedAttributes = OBSERVED_ATTRIBUTES;
56
- NumberFlowElement.define();
56
+ NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
57
+ (0, import_number_flow.define)("number-flow-react", NumberFlowElement);
57
58
  var formatters = {};
58
59
  var serializeParts = isReact19 ? (p) => p : JSON.stringify;
60
+ function splitProps(props) {
61
+ const {
62
+ transformTiming,
63
+ spinTiming,
64
+ opacityTiming,
65
+ animated,
66
+ respectMotionPreference,
67
+ trend,
68
+ continuous,
69
+ ...rest
70
+ } = props;
71
+ return [
72
+ {
73
+ transformTiming,
74
+ spinTiming,
75
+ opacityTiming,
76
+ animated,
77
+ respectMotionPreference,
78
+ trend,
79
+ continuous
80
+ },
81
+ rest
82
+ ];
83
+ }
59
84
  var _el;
60
85
  var NumberFlowImpl = class extends React.Component {
61
86
  constructor(props) {
@@ -63,25 +88,25 @@ var NumberFlowImpl = class extends React.Component {
63
88
  __privateAdd(this, _el);
64
89
  this.handleRef = this.handleRef.bind(this);
65
90
  }
66
- // Update the non-parts props to avoid JSON serialization
91
+ // Update the non-`parts` props to avoid JSON serialization
67
92
  // Parts needs to be set in render still:
68
93
  updateNonPartsProps(prevProps) {
69
94
  if (!__privateGet(this, _el)) return;
70
95
  __privateGet(this, _el).manual = !this.props.isolate;
71
- if (this.props.animated != null) __privateGet(this, _el).animated = this.props.animated;
72
- if (this.props.respectMotionPreference != null)
73
- __privateGet(this, _el).respectMotionPreference = this.props.respectMotionPreference;
74
- if (this.props.trend != null) __privateGet(this, _el).trend = this.props.trend;
75
- if (this.props.continuous != null) __privateGet(this, _el).continuous = this.props.continuous;
76
- if (this.props.opacityTiming) __privateGet(this, _el).opacityTiming = this.props.opacityTiming;
77
- if (this.props.transformTiming) __privateGet(this, _el).transformTiming = this.props.transformTiming;
78
- if (this.props.spinTiming) __privateGet(this, _el).spinTiming = this.props.spinTiming;
96
+ const [nonParts] = splitProps(this.props);
97
+ Object.assign(
98
+ __privateGet(this, _el),
99
+ Object.fromEntries(Object.entries(nonParts).filter(([_, v]) => v != null))
100
+ );
79
101
  if (prevProps?.onAnimationsStart)
80
102
  __privateGet(this, _el).removeEventListener("animationsstart", prevProps.onAnimationsStart);
81
103
  if (this.props.onAnimationsStart)
82
104
  __privateGet(this, _el).addEventListener("animationsstart", this.props.onAnimationsStart);
83
105
  if (prevProps?.onAnimationsFinish)
84
- __privateGet(this, _el).removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
106
+ __privateGet(this, _el).removeEventListener(
107
+ "animationsfinish",
108
+ prevProps.onAnimationsFinish
109
+ );
85
110
  if (this.props.onAnimationsFinish)
86
111
  __privateGet(this, _el).addEventListener("animationsfinish", this.props.onAnimationsFinish);
87
112
  }
@@ -93,8 +118,8 @@ var NumberFlowImpl = class extends React.Component {
93
118
  }
94
119
  getSnapshotBeforeUpdate(prevProps) {
95
120
  this.updateNonPartsProps(prevProps);
96
- if (this.props.isolate) return false;
97
- if (prevProps.parts === this.props.parts) return false;
121
+ if (this.props.isolate || this.props.animated === false || prevProps.parts === this.props.parts)
122
+ return false;
98
123
  __privateGet(this, _el)?.willUpdate();
99
124
  return true;
100
125
  }
@@ -106,34 +131,19 @@ var NumberFlowImpl = class extends React.Component {
106
131
  __privateSet(this, _el, el);
107
132
  }
108
133
  render() {
109
- const {
110
- innerRef,
111
- className,
112
- parts,
113
- willChange,
114
- // These are set in updateNonPartsProps, so ignore them here:
115
- animated,
116
- respectMotionPreference,
117
- isolate,
118
- trend,
119
- continuous,
120
- opacityTiming,
121
- transformTiming,
122
- spinTiming,
123
- ...rest
124
- } = this.props;
134
+ const [_, { innerRef, className, parts, willChange, isolate, ...rest }] = splitProps(this.props);
125
135
  return (
126
136
  // @ts-expect-error missing types
127
137
  /* @__PURE__ */ React.createElement(
128
- "number-flow",
138
+ "number-flow-react",
129
139
  {
130
140
  ref: this.handleRef,
131
141
  "data-will-change": willChange ? "" : void 0,
132
142
  class: className,
133
143
  ...rest,
144
+ dangerouslySetInnerHTML: { __html: (0, import_number_flow.render)({ formatted: parts.formatted, willChange }) },
134
145
  parts: serializeParts(parts)
135
- },
136
- /* @__PURE__ */ React.createElement(import_number_flow.SlottedTag, { style: (0, import_number_flow.slottedStyles)({ willChange }) }, parts.formatted)
146
+ }
137
147
  )
138
148
  );
139
149
  }
package/dist/index.mjs CHANGED
@@ -10,24 +10,49 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
10
10
  // src/index.tsx
11
11
  import * as React from "react";
12
12
  import {
13
- SlottedTag,
14
- slottedStyles,
13
+ render,
15
14
  partitionParts,
16
15
  NumberFlowLite,
17
16
  prefersReducedMotion,
18
- canAnimate as _canAnimate
17
+ canAnimate as _canAnimate,
18
+ define
19
19
  } from "number-flow";
20
- var isReact19 = React.version.startsWith("19.");
20
+ var REACT_MAJOR = parseInt(React.version.match(/^(\d+)\./)?.[1]);
21
+ var isReact19 = REACT_MAJOR >= 19;
21
22
  var OBSERVED_ATTRIBUTES = ["parts"];
22
23
  var NumberFlowElement = class extends NumberFlowLite {
23
24
  attributeChangedCallback(attr, _oldValue, newValue) {
24
25
  this[attr] = JSON.parse(newValue);
25
26
  }
26
27
  };
27
- NumberFlowElement.observedAttributes = OBSERVED_ATTRIBUTES;
28
- NumberFlowElement.define();
28
+ NumberFlowElement.observedAttributes = isReact19 ? [] : OBSERVED_ATTRIBUTES;
29
+ define("number-flow-react", NumberFlowElement);
29
30
  var formatters = {};
30
31
  var serializeParts = isReact19 ? (p) => p : JSON.stringify;
32
+ function splitProps(props) {
33
+ const {
34
+ transformTiming,
35
+ spinTiming,
36
+ opacityTiming,
37
+ animated,
38
+ respectMotionPreference,
39
+ trend,
40
+ continuous,
41
+ ...rest
42
+ } = props;
43
+ return [
44
+ {
45
+ transformTiming,
46
+ spinTiming,
47
+ opacityTiming,
48
+ animated,
49
+ respectMotionPreference,
50
+ trend,
51
+ continuous
52
+ },
53
+ rest
54
+ ];
55
+ }
31
56
  var _el;
32
57
  var NumberFlowImpl = class extends React.Component {
33
58
  constructor(props) {
@@ -35,25 +60,25 @@ var NumberFlowImpl = class extends React.Component {
35
60
  __privateAdd(this, _el);
36
61
  this.handleRef = this.handleRef.bind(this);
37
62
  }
38
- // Update the non-parts props to avoid JSON serialization
63
+ // Update the non-`parts` props to avoid JSON serialization
39
64
  // Parts needs to be set in render still:
40
65
  updateNonPartsProps(prevProps) {
41
66
  if (!__privateGet(this, _el)) return;
42
67
  __privateGet(this, _el).manual = !this.props.isolate;
43
- if (this.props.animated != null) __privateGet(this, _el).animated = this.props.animated;
44
- if (this.props.respectMotionPreference != null)
45
- __privateGet(this, _el).respectMotionPreference = this.props.respectMotionPreference;
46
- if (this.props.trend != null) __privateGet(this, _el).trend = this.props.trend;
47
- if (this.props.continuous != null) __privateGet(this, _el).continuous = this.props.continuous;
48
- if (this.props.opacityTiming) __privateGet(this, _el).opacityTiming = this.props.opacityTiming;
49
- if (this.props.transformTiming) __privateGet(this, _el).transformTiming = this.props.transformTiming;
50
- if (this.props.spinTiming) __privateGet(this, _el).spinTiming = this.props.spinTiming;
68
+ const [nonParts] = splitProps(this.props);
69
+ Object.assign(
70
+ __privateGet(this, _el),
71
+ Object.fromEntries(Object.entries(nonParts).filter(([_, v]) => v != null))
72
+ );
51
73
  if (prevProps?.onAnimationsStart)
52
74
  __privateGet(this, _el).removeEventListener("animationsstart", prevProps.onAnimationsStart);
53
75
  if (this.props.onAnimationsStart)
54
76
  __privateGet(this, _el).addEventListener("animationsstart", this.props.onAnimationsStart);
55
77
  if (prevProps?.onAnimationsFinish)
56
- __privateGet(this, _el).removeEventListener("animationsfinish", prevProps.onAnimationsFinish);
78
+ __privateGet(this, _el).removeEventListener(
79
+ "animationsfinish",
80
+ prevProps.onAnimationsFinish
81
+ );
57
82
  if (this.props.onAnimationsFinish)
58
83
  __privateGet(this, _el).addEventListener("animationsfinish", this.props.onAnimationsFinish);
59
84
  }
@@ -65,8 +90,8 @@ var NumberFlowImpl = class extends React.Component {
65
90
  }
66
91
  getSnapshotBeforeUpdate(prevProps) {
67
92
  this.updateNonPartsProps(prevProps);
68
- if (this.props.isolate) return false;
69
- if (prevProps.parts === this.props.parts) return false;
93
+ if (this.props.isolate || this.props.animated === false || prevProps.parts === this.props.parts)
94
+ return false;
70
95
  __privateGet(this, _el)?.willUpdate();
71
96
  return true;
72
97
  }
@@ -78,34 +103,19 @@ var NumberFlowImpl = class extends React.Component {
78
103
  __privateSet(this, _el, el);
79
104
  }
80
105
  render() {
81
- const {
82
- innerRef,
83
- className,
84
- parts,
85
- willChange,
86
- // These are set in updateNonPartsProps, so ignore them here:
87
- animated,
88
- respectMotionPreference,
89
- isolate,
90
- trend,
91
- continuous,
92
- opacityTiming,
93
- transformTiming,
94
- spinTiming,
95
- ...rest
96
- } = this.props;
106
+ const [_, { innerRef, className, parts, willChange, isolate, ...rest }] = splitProps(this.props);
97
107
  return (
98
108
  // @ts-expect-error missing types
99
109
  /* @__PURE__ */ React.createElement(
100
- "number-flow",
110
+ "number-flow-react",
101
111
  {
102
112
  ref: this.handleRef,
103
113
  "data-will-change": willChange ? "" : void 0,
104
114
  class: className,
105
115
  ...rest,
116
+ dangerouslySetInnerHTML: { __html: render({ formatted: parts.formatted, willChange }) },
106
117
  parts: serializeParts(parts)
107
- },
108
- /* @__PURE__ */ React.createElement(SlottedTag, { style: slottedStyles({ willChange }) }, parts.formatted)
118
+ }
109
119
  )
110
120
  );
111
121
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.2.5",
6
+ "version": "0.3.0",
7
7
  "author": {
8
8
  "name": "Maxwell Barvian",
9
9
  "email": "max@barvian.me",
@@ -48,9 +48,11 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "number-flow": "0.3.3"
51
+ "number-flow": "0.3.5"
52
52
  },
53
53
  "devDependencies": {
54
+ "@playwright/test": "^1.48.0",
55
+ "@types/node": "^22.7.9",
54
56
  "@types/react": "^18.3.3",
55
57
  "@types/react-dom": "^18.3.0",
56
58
  "react": "^18.3.1",