@w3ux/react-odometer 2.3.12 → 2.3.13

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/index.cjs CHANGED
@@ -64,7 +64,7 @@ var Odometer = ({
64
64
  );
65
65
  setAllDigitRefs(all);
66
66
  }, []);
67
- (0, import_react.useEffect)(() => {
67
+ (0, import_react.useLayoutEffect)(() => {
68
68
  if (Object.keys(allDigitRefs)) {
69
69
  value = String(value) === "0" ? Number(value).toFixed(zeroDecimals) : value;
70
70
  const newDigits = value.toString().split("").map((v) => v === "." ? "dot" : v).map((v) => v === "," ? "comma" : v);
@@ -80,7 +80,7 @@ var Odometer = ({
80
80
  );
81
81
  }
82
82
  }, [value]);
83
- (0, import_react.useEffect)(() => {
83
+ (0, import_react.useLayoutEffect)(() => {
84
84
  if (status === "new" && !digitRefs.find((d) => d.current === null)) {
85
85
  setStatus("transition");
86
86
  activeTransitionCounter.current++;
@@ -96,7 +96,7 @@ var Odometer = ({
96
96
  let lineHeight = odometerCurrent ? window.getComputedStyle(odometerCurrent).lineHeight : "inherit";
97
97
  lineHeight = lineHeight === "normal" ? "1.1rem" : lineHeight;
98
98
  let foundDecimal = false;
99
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "odometer", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "odometer-inner", ref: odometerRef, children: [
99
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
100
100
  allDigits.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
101
101
  "span",
102
102
  {
@@ -104,6 +104,7 @@ var Odometer = ({
104
104
  style: {
105
105
  opacity: 0,
106
106
  position: "fixed",
107
+ display: "inline-block",
107
108
  top: "-999%",
108
109
  left: "-999%",
109
110
  userSelect: "none"
@@ -112,100 +113,102 @@ var Odometer = ({
112
113
  },
113
114
  `odometer_template_digit_${i}`
114
115
  )),
115
- spaceBefore ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { paddingLeft: spaceBefore } }) : null,
116
- digits.map((d, i) => {
117
- if (d === "dot") {
118
- foundDecimal = true;
119
- }
120
- let childDigits = null;
121
- if (status === "transition") {
122
- const digitsToAnimate = [];
123
- const digitIndex = allDigits.indexOf(digits[i]);
124
- const prevDigitIndex = allDigits.indexOf(prevDigits[i]);
125
- const difference = Math.abs(digitIndex - prevDigitIndex);
126
- const delay = `${0.01 * (digits.length - i - 1)}s`;
127
- const direction = digitIndex === prevDigitIndex ? "none" : "down";
128
- const animClass = `slide-${direction}-${difference} `;
129
- digitsToAnimate.push(prevDigits[i]);
130
- if (digitIndex < prevDigitIndex) {
131
- digitsToAnimate.push(
132
- ...Array.from(
133
- { length: difference },
134
- (_, k) => allDigits[prevDigitIndex - k - 1]
135
- )
136
- );
137
- } else {
138
- digitsToAnimate.push(
139
- ...Array.from(
140
- { length: difference },
141
- (_, k) => allDigits[k + prevDigitIndex + 1]
142
- )
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "odometer", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "odometer-inner", ref: odometerRef, children: [
117
+ spaceBefore ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { paddingLeft: spaceBefore } }) : null,
118
+ digits.map((d, i) => {
119
+ if (d === "dot") {
120
+ foundDecimal = true;
121
+ }
122
+ let childDigits = null;
123
+ if (status === "transition") {
124
+ const digitsToAnimate = [];
125
+ const digitIndex = allDigits.indexOf(digits[i]);
126
+ const prevDigitIndex = allDigits.indexOf(prevDigits[i]);
127
+ const difference = Math.abs(digitIndex - prevDigitIndex);
128
+ const delay = `${0.01 * (digits.length - i - 1)}s`;
129
+ const direction = digitIndex === prevDigitIndex ? "none" : "down";
130
+ const animClass = `slide-${direction}-${difference} `;
131
+ digitsToAnimate.push(prevDigits[i]);
132
+ if (digitIndex < prevDigitIndex) {
133
+ digitsToAnimate.push(
134
+ ...Array.from(
135
+ { length: difference },
136
+ (_, k) => allDigits[prevDigitIndex - k - 1]
137
+ )
138
+ );
139
+ } else {
140
+ digitsToAnimate.push(
141
+ ...Array.from(
142
+ { length: difference },
143
+ (_, k) => allDigits[k + prevDigitIndex + 1]
144
+ )
145
+ );
146
+ }
147
+ childDigits = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
148
+ "span",
149
+ {
150
+ style: {
151
+ position: "absolute",
152
+ top: 0,
153
+ left: 0,
154
+ animationName: direction === "none" ? void 0 : animClass,
155
+ animationDuration: direction === "none" ? void 0 : DURATION_SECS,
156
+ animationFillMode: "forwards",
157
+ animationTimingFunction: "cubic-bezier(0.1, 1, 0.2, 1)",
158
+ animationDelay: delay,
159
+ color: foundDecimal ? decimalColor : wholeColor,
160
+ userSelect: "none"
161
+ },
162
+ children: digitsToAnimate.map((c, j) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
163
+ "span",
164
+ {
165
+ className: "odometer-digit odometer-child",
166
+ style: {
167
+ top: j === 0 ? 0 : `${100 * j}%`,
168
+ height: lineHeight,
169
+ lineHeight
170
+ },
171
+ children: c === "dot" ? "." : c === "comma" ? "," : c
172
+ },
173
+ `child_digit_${j}`
174
+ ))
175
+ }
143
176
  );
144
177
  }
145
- childDigits = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
178
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
146
179
  "span",
147
180
  {
181
+ ref: digitRefs[i],
182
+ className: "odometer-digit",
148
183
  style: {
149
- position: "absolute",
150
- top: 0,
151
- left: 0,
152
- animationName: direction === "none" ? void 0 : animClass,
153
- animationDuration: direction === "none" ? void 0 : DURATION_SECS,
154
- animationFillMode: "forwards",
155
- animationTimingFunction: "cubic-bezier(0.1, 1, 0.2, 1)",
156
- animationDelay: delay,
157
184
  color: foundDecimal ? decimalColor : wholeColor,
158
- userSelect: "none"
185
+ height: lineHeight,
186
+ lineHeight,
187
+ paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
159
188
  },
160
- children: digitsToAnimate.map((c, j) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
- "span",
162
- {
163
- className: "odometer-digit odometer-child",
164
- style: {
165
- top: j === 0 ? 0 : `${100 * j}%`,
166
- height: lineHeight,
167
- lineHeight
168
- },
169
- children: c === "dot" ? "." : c === "comma" ? "," : c
170
- },
171
- `child_digit_${j}`
172
- ))
173
- }
174
- );
175
- }
176
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
177
- "span",
178
- {
179
- ref: digitRefs[i],
180
- className: "odometer-digit",
181
- style: {
182
- color: foundDecimal ? decimalColor : wholeColor,
183
- height: lineHeight,
184
- lineHeight,
185
- paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
189
+ children: [
190
+ status === "inactive" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
191
+ "span",
192
+ {
193
+ className: "odometer-digit odometer-child",
194
+ style: {
195
+ top: 0,
196
+ height: lineHeight,
197
+ lineHeight,
198
+ width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
199
+ },
200
+ children: d === "dot" ? "." : d === "comma" ? "," : d
201
+ }
202
+ ),
203
+ status === "transition" && childDigits
204
+ ]
186
205
  },
187
- children: [
188
- status === "inactive" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
189
- "span",
190
- {
191
- className: "odometer-digit odometer-child",
192
- style: {
193
- top: 0,
194
- height: lineHeight,
195
- lineHeight,
196
- width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
197
- },
198
- children: d === "dot" ? "." : d === "comma" ? "," : d
199
- }
200
- ),
201
- status === "transition" && childDigits
202
- ]
203
- },
204
- `digit_${i}`
205
- );
206
- }),
207
- spaceAfter ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { paddingRight: spaceAfter } }) : null
208
- ] }) });
206
+ `digit_${i}`
207
+ );
208
+ }),
209
+ spaceAfter ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { paddingRight: spaceAfter } }) : null
210
+ ] }) })
211
+ ] });
209
212
  };
210
213
  var index_default = Odometer;
211
214
  // Annotate the CommonJS export names for ESM import in node:
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport type { RefObject } from 'react'\nimport { createRef, useEffect, useRef, useState } from 'react'\nimport './index.css'\nimport type { Digit, DigitRef, Direction, Props, Status } from './types'\n\nexport const Odometer = ({\n\tvalue,\n\tspaceBefore = 0,\n\tspaceAfter = '0.25rem',\n\twholeColor = 'var(--text-color-primary)',\n\tdecimalColor = 'var(--text-color-secondary)',\n\tzeroDecimals = 0,\n}: Props) => {\n\t// Store all possible digits.\n\tconst [allDigits] = useState<Digit[]>([\n\t\t'comma',\n\t\t'dot',\n\t\t'0',\n\t\t'1',\n\t\t'2',\n\t\t'3',\n\t\t'4',\n\t\t'5',\n\t\t'6',\n\t\t'7',\n\t\t'8',\n\t\t'9',\n\t])\n\n\t// Store the digits of the current value.\n\tconst [digits, setDigits] = useState<Digit[]>([])\n\n\t// Store digits of the previous value.\n\tconst [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n\t// Store the status of the odometer (transitioning or stable).\n\tconst [status, setStatus] = useState<Status>('inactive')\n\n\t// Store whether component has iniiialized.\n\tconst [initialized, setInitialized] = useState<boolean>(false)\n\n\t// Store ref of the odometer.\n\tconst [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n\t// Store refs of each digit.\n\tconst [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n\t// Store refs of each `all` digit.\n\tconst [allDigitRefs, setAllDigitRefs] = useState<\n\t\tRecord<string, RefObject<HTMLSpanElement | null>>\n\t>({})\n\n\t// Keep track of active transitions.\n\tconst activeTransitionCounter = useRef<number>(0)\n\n\t// Transition duration.\n\tconst DURATION_MS = 750\n\tconst DURATION_SECS = `${DURATION_MS / 1000}s`\n\n\t// Phase 0: populate `allDigitRefs`.\n\tuseEffect(() => {\n\t\tconst all: Record<\n\t\t\tstring,\n\t\t\tRefObject<HTMLSpanElement | null>\n\t\t> = Object.fromEntries(\n\t\t\tObject.values(allDigits).map((v) => [`d_${v}`, createRef()]),\n\t\t)\n\n\t\tsetAllDigitRefs(all)\n\t}, [])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs)) {\n\t\t\tvalue =\n\t\t\t\tString(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n\t\t\tconst newDigits = value\n\t\t\t\t.toString()\n\t\t\t\t.split('')\n\t\t\t\t.map((v) => (v === '.' ? 'dot' : v))\n\t\t\t\t.map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n\t\t\tsetDigits(newDigits)\n\n\t\t\tif (!initialized) {\n\t\t\t\tsetInitialized(true)\n\t\t\t} else {\n\t\t\t\tsetStatus('new')\n\t\t\t\tsetPrevDigits(digits)\n\t\t\t}\n\t\t\tsetDigitRefs(\n\t\t\t\tArray.from({ length: newDigits.length }, () => createRef() as DigitRef),\n\t\t\t)\n\t\t}\n\t}, [value])\n\n\t// Phase 2: set up digit transition.\n\tuseEffect(() => {\n\t\tif (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n\t\t\tsetStatus('transition')\n\t\t\tactiveTransitionCounter.current++\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tactiveTransitionCounter.current--\n\t\t\t\tif (activeTransitionCounter.current === 0) {\n\t\t\t\t\tsetStatus('inactive')\n\t\t\t\t}\n\t\t\t}, DURATION_MS)\n\t\t}\n\t}, [status, digitRefs])\n\n\tconst odometerCurrent: HTMLSpanElement | null = odometerRef.current\n\tlet lineHeight = odometerCurrent\n\t\t? window.getComputedStyle(odometerCurrent).lineHeight\n\t\t: 'inherit'\n\n\t// Fallback line height to `1.1rem` if `normal`.\n\tlineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n\t// Track whether decimal point has been found.\n\tlet foundDecimal = false\n\n\treturn (\n\t\t<span className=\"odometer\">\n\t\t\t<span className=\"odometer-inner\" ref={odometerRef}>\n\t\t\t\t{allDigits.map((d, i) => (\n\t\t\t\t\t<span\n\t\t\t\t\t\tkey={`odometer_template_digit_${i}`}\n\t\t\t\t\t\tref={allDigitRefs[`d_${d}`]}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\t\ttop: '-999%',\n\t\t\t\t\t\t\tleft: '-999%',\n\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t</span>\n\t\t\t\t))}\n\n\t\t\t\t{spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n\t\t\t\t{digits.map((d, i) => {\n\t\t\t\t\tif (d === 'dot') {\n\t\t\t\t\t\tfoundDecimal = true\n\t\t\t\t\t}\n\n\t\t\t\t\t// If transitioning, get digits needed to animate.\n\t\t\t\t\tlet childDigits = null\n\t\t\t\t\tif (status === 'transition') {\n\t\t\t\t\t\tconst digitsToAnimate = []\n\t\t\t\t\t\tconst digitIndex = allDigits.indexOf(digits[i])\n\t\t\t\t\t\tconst prevDigitIndex = allDigits.indexOf(prevDigits[i])\n\t\t\t\t\t\tconst difference = Math.abs(digitIndex - prevDigitIndex)\n\t\t\t\t\t\tconst delay = `${0.01 * (digits.length - i - 1)}s`\n\t\t\t\t\t\tconst direction: Direction =\n\t\t\t\t\t\t\tdigitIndex === prevDigitIndex ? 'none' : 'down'\n\t\t\t\t\t\tconst animClass = `slide-${direction}-${difference} `\n\n\t\t\t\t\t\t// Push current prev digit to stop of stack.\n\t\t\t\t\t\tdigitsToAnimate.push(prevDigits[i])\n\n\t\t\t\t\t\t// If transitioning between two digits, animate all digits in between.\n\t\t\t\t\t\tif (digitIndex < prevDigitIndex) {\n\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t(_, k) => allDigits[prevDigitIndex - k - 1],\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t(_, k) => allDigits[k + prevDigitIndex + 1],\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tchildDigits = (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\t\tanimationName: direction === 'none' ? undefined : animClass,\n\t\t\t\t\t\t\t\t\tanimationDuration:\n\t\t\t\t\t\t\t\t\t\tdirection === 'none' ? undefined : DURATION_SECS,\n\t\t\t\t\t\t\t\t\tanimationFillMode: 'forwards',\n\t\t\t\t\t\t\t\t\tanimationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n\t\t\t\t\t\t\t\t\tanimationDelay: delay,\n\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{digitsToAnimate.map((c, j) => (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tkey={`child_digit_${j}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\ttop: j === 0 ? 0 : `${100 * j}%`,\n\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tkey={`digit_${i}`}\n\t\t\t\t\t\t\tref={digitRefs[i]}\n\t\t\t\t\t\t\tclassName=\"odometer-digit\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\tpaddingRight:\n\t\t\t\t\t\t\t\t\tstatus === 'transition'\n\t\t\t\t\t\t\t\t\t\t? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n\t\t\t\t\t\t\t\t\t\t: '0',\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{status === 'inactive' && (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\twidth: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{status === 'transition' && childDigits}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t\t{spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n\t\t\t</span>\n\t\t</span>\n\t)\n}\n\nexport default Odometer\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport type { RefObject } from 'react'\nimport { createRef, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport './index.css'\nimport type { Digit, DigitRef, Direction, Props, Status } from './types'\n\nexport const Odometer = ({\n\tvalue,\n\tspaceBefore = 0,\n\tspaceAfter = '0.25rem',\n\twholeColor = 'var(--text-color-primary)',\n\tdecimalColor = 'var(--text-color-secondary)',\n\tzeroDecimals = 0,\n}: Props) => {\n\t// Store all possible digits.\n\tconst [allDigits] = useState<Digit[]>([\n\t\t'comma',\n\t\t'dot',\n\t\t'0',\n\t\t'1',\n\t\t'2',\n\t\t'3',\n\t\t'4',\n\t\t'5',\n\t\t'6',\n\t\t'7',\n\t\t'8',\n\t\t'9',\n\t])\n\n\t// Store the digits of the current value.\n\tconst [digits, setDigits] = useState<Digit[]>([])\n\n\t// Store digits of the previous value.\n\tconst [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n\t// Store the status of the odometer (transitioning or stable).\n\tconst [status, setStatus] = useState<Status>('inactive')\n\n\t// Store whether component has iniiialized.\n\tconst [initialized, setInitialized] = useState<boolean>(false)\n\n\t// Store ref of the odometer.\n\tconst [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n\t// Store refs of each digit.\n\tconst [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n\t// Store refs of each `all` digit.\n\tconst [allDigitRefs, setAllDigitRefs] = useState<\n\t\tRecord<string, RefObject<HTMLSpanElement | null>>\n\t>({})\n\n\t// Keep track of active transitions.\n\tconst activeTransitionCounter = useRef<number>(0)\n\n\t// Transition duration.\n\tconst DURATION_MS = 750\n\tconst DURATION_SECS = `${DURATION_MS / 1000}s`\n\n\t// Phase 0: populate `allDigitRefs`.\n\tuseEffect(() => {\n\t\tconst all: Record<\n\t\t\tstring,\n\t\t\tRefObject<HTMLSpanElement | null>\n\t\t> = Object.fromEntries(\n\t\t\tObject.values(allDigits).map((v) => [`d_${v}`, createRef()]),\n\t\t)\n\n\t\tsetAllDigitRefs(all)\n\t}, [])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseLayoutEffect(() => {\n\t\tif (Object.keys(allDigitRefs)) {\n\t\t\tvalue =\n\t\t\t\tString(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n\t\t\tconst newDigits = value\n\t\t\t\t.toString()\n\t\t\t\t.split('')\n\t\t\t\t.map((v) => (v === '.' ? 'dot' : v))\n\t\t\t\t.map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n\t\t\tsetDigits(newDigits)\n\n\t\t\tif (!initialized) {\n\t\t\t\tsetInitialized(true)\n\t\t\t} else {\n\t\t\t\tsetStatus('new')\n\t\t\t\tsetPrevDigits(digits)\n\t\t\t}\n\t\t\tsetDigitRefs(\n\t\t\t\tArray.from({ length: newDigits.length }, () => createRef() as DigitRef),\n\t\t\t)\n\t\t}\n\t}, [value])\n\n\t// Phase 2: set up digit transition.\n\tuseLayoutEffect(() => {\n\t\tif (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n\t\t\tsetStatus('transition')\n\t\t\tactiveTransitionCounter.current++\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tactiveTransitionCounter.current--\n\t\t\t\tif (activeTransitionCounter.current === 0) {\n\t\t\t\t\tsetStatus('inactive')\n\t\t\t\t}\n\t\t\t}, DURATION_MS)\n\t\t}\n\t}, [status, digitRefs])\n\n\tconst odometerCurrent: HTMLSpanElement | null = odometerRef.current\n\tlet lineHeight = odometerCurrent\n\t\t? window.getComputedStyle(odometerCurrent).lineHeight\n\t\t: 'inherit'\n\n\t// Fallback line height to `1.1rem` if `normal`.\n\tlineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n\t// Track whether decimal point has been found.\n\tlet foundDecimal = false\n\n\treturn (\n\t\t<>\n\t\t\t{allDigits.map((d, i) => (\n\t\t\t\t<span\n\t\t\t\t\tkey={`odometer_template_digit_${i}`}\n\t\t\t\t\tref={allDigitRefs[`d_${d}`]}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\tdisplay: 'inline-block',\n\t\t\t\t\t\ttop: '-999%',\n\t\t\t\t\t\tleft: '-999%',\n\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t<span className=\"odometer\">\n\t\t\t\t<span className=\"odometer-inner\" ref={odometerRef}>\n\t\t\t\t\t{spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n\t\t\t\t\t{digits.map((d, i) => {\n\t\t\t\t\t\tif (d === 'dot') {\n\t\t\t\t\t\t\tfoundDecimal = true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If transitioning, get digits needed to animate.\n\t\t\t\t\t\tlet childDigits = null\n\t\t\t\t\t\tif (status === 'transition') {\n\t\t\t\t\t\t\tconst digitsToAnimate = []\n\t\t\t\t\t\t\tconst digitIndex = allDigits.indexOf(digits[i])\n\t\t\t\t\t\t\tconst prevDigitIndex = allDigits.indexOf(prevDigits[i])\n\t\t\t\t\t\t\tconst difference = Math.abs(digitIndex - prevDigitIndex)\n\t\t\t\t\t\t\tconst delay = `${0.01 * (digits.length - i - 1)}s`\n\t\t\t\t\t\t\tconst direction: Direction =\n\t\t\t\t\t\t\t\tdigitIndex === prevDigitIndex ? 'none' : 'down'\n\t\t\t\t\t\t\tconst animClass = `slide-${direction}-${difference} `\n\n\t\t\t\t\t\t\t// Push current prev digit to stop of stack.\n\t\t\t\t\t\t\tdigitsToAnimate.push(prevDigits[i])\n\n\t\t\t\t\t\t\t// If transitioning between two digits, animate all digits in between.\n\t\t\t\t\t\t\tif (digitIndex < prevDigitIndex) {\n\t\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t\t(_, k) => allDigits[prevDigitIndex - k - 1],\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t\t(_, k) => allDigits[k + prevDigitIndex + 1],\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tchildDigits = (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\t\t\tanimationName: direction === 'none' ? undefined : animClass,\n\t\t\t\t\t\t\t\t\t\tanimationDuration:\n\t\t\t\t\t\t\t\t\t\t\tdirection === 'none' ? undefined : DURATION_SECS,\n\t\t\t\t\t\t\t\t\t\tanimationFillMode: 'forwards',\n\t\t\t\t\t\t\t\t\t\tanimationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n\t\t\t\t\t\t\t\t\t\tanimationDelay: delay,\n\t\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{digitsToAnimate.map((c, j) => (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tkey={`child_digit_${j}`}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\ttop: j === 0 ? 0 : `${100 * j}%`,\n\t\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={`digit_${i}`}\n\t\t\t\t\t\t\t\tref={digitRefs[i]}\n\t\t\t\t\t\t\t\tclassName=\"odometer-digit\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\tpaddingRight:\n\t\t\t\t\t\t\t\t\t\tstatus === 'transition'\n\t\t\t\t\t\t\t\t\t\t\t? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n\t\t\t\t\t\t\t\t\t\t\t: '0',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{status === 'inactive' && (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t\twidth: `${\n\t\t\t\t\t\t\t\t\t\t\t\tallDigitRefs[`d_${d}`]?.current?.offsetWidth\n\t\t\t\t\t\t\t\t\t\t\t}px`,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{status === 'transition' && childDigits}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t\t{spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n\t\t\t\t</span>\n\t\t\t</span>\n\t\t</>\n\t)\n}\n\nexport default Odometer\n"],"mappings":"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","names":[]}
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.tsx
2
- import { createRef, useEffect, useRef, useState } from "react";
3
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { createRef, useEffect, useLayoutEffect, useRef, useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  var Odometer = ({
5
5
  value,
6
6
  spaceBefore = 0,
@@ -39,7 +39,7 @@ var Odometer = ({
39
39
  );
40
40
  setAllDigitRefs(all);
41
41
  }, []);
42
- useEffect(() => {
42
+ useLayoutEffect(() => {
43
43
  if (Object.keys(allDigitRefs)) {
44
44
  value = String(value) === "0" ? Number(value).toFixed(zeroDecimals) : value;
45
45
  const newDigits = value.toString().split("").map((v) => v === "." ? "dot" : v).map((v) => v === "," ? "comma" : v);
@@ -55,7 +55,7 @@ var Odometer = ({
55
55
  );
56
56
  }
57
57
  }, [value]);
58
- useEffect(() => {
58
+ useLayoutEffect(() => {
59
59
  if (status === "new" && !digitRefs.find((d) => d.current === null)) {
60
60
  setStatus("transition");
61
61
  activeTransitionCounter.current++;
@@ -71,7 +71,7 @@ var Odometer = ({
71
71
  let lineHeight = odometerCurrent ? window.getComputedStyle(odometerCurrent).lineHeight : "inherit";
72
72
  lineHeight = lineHeight === "normal" ? "1.1rem" : lineHeight;
73
73
  let foundDecimal = false;
74
- return /* @__PURE__ */ jsx("span", { className: "odometer", children: /* @__PURE__ */ jsxs("span", { className: "odometer-inner", ref: odometerRef, children: [
74
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
75
75
  allDigits.map((d, i) => /* @__PURE__ */ jsx(
76
76
  "span",
77
77
  {
@@ -79,6 +79,7 @@ var Odometer = ({
79
79
  style: {
80
80
  opacity: 0,
81
81
  position: "fixed",
82
+ display: "inline-block",
82
83
  top: "-999%",
83
84
  left: "-999%",
84
85
  userSelect: "none"
@@ -87,100 +88,102 @@ var Odometer = ({
87
88
  },
88
89
  `odometer_template_digit_${i}`
89
90
  )),
90
- spaceBefore ? /* @__PURE__ */ jsx("span", { style: { paddingLeft: spaceBefore } }) : null,
91
- digits.map((d, i) => {
92
- if (d === "dot") {
93
- foundDecimal = true;
94
- }
95
- let childDigits = null;
96
- if (status === "transition") {
97
- const digitsToAnimate = [];
98
- const digitIndex = allDigits.indexOf(digits[i]);
99
- const prevDigitIndex = allDigits.indexOf(prevDigits[i]);
100
- const difference = Math.abs(digitIndex - prevDigitIndex);
101
- const delay = `${0.01 * (digits.length - i - 1)}s`;
102
- const direction = digitIndex === prevDigitIndex ? "none" : "down";
103
- const animClass = `slide-${direction}-${difference} `;
104
- digitsToAnimate.push(prevDigits[i]);
105
- if (digitIndex < prevDigitIndex) {
106
- digitsToAnimate.push(
107
- ...Array.from(
108
- { length: difference },
109
- (_, k) => allDigits[prevDigitIndex - k - 1]
110
- )
111
- );
112
- } else {
113
- digitsToAnimate.push(
114
- ...Array.from(
115
- { length: difference },
116
- (_, k) => allDigits[k + prevDigitIndex + 1]
117
- )
91
+ /* @__PURE__ */ jsx("span", { className: "odometer", children: /* @__PURE__ */ jsxs("span", { className: "odometer-inner", ref: odometerRef, children: [
92
+ spaceBefore ? /* @__PURE__ */ jsx("span", { style: { paddingLeft: spaceBefore } }) : null,
93
+ digits.map((d, i) => {
94
+ if (d === "dot") {
95
+ foundDecimal = true;
96
+ }
97
+ let childDigits = null;
98
+ if (status === "transition") {
99
+ const digitsToAnimate = [];
100
+ const digitIndex = allDigits.indexOf(digits[i]);
101
+ const prevDigitIndex = allDigits.indexOf(prevDigits[i]);
102
+ const difference = Math.abs(digitIndex - prevDigitIndex);
103
+ const delay = `${0.01 * (digits.length - i - 1)}s`;
104
+ const direction = digitIndex === prevDigitIndex ? "none" : "down";
105
+ const animClass = `slide-${direction}-${difference} `;
106
+ digitsToAnimate.push(prevDigits[i]);
107
+ if (digitIndex < prevDigitIndex) {
108
+ digitsToAnimate.push(
109
+ ...Array.from(
110
+ { length: difference },
111
+ (_, k) => allDigits[prevDigitIndex - k - 1]
112
+ )
113
+ );
114
+ } else {
115
+ digitsToAnimate.push(
116
+ ...Array.from(
117
+ { length: difference },
118
+ (_, k) => allDigits[k + prevDigitIndex + 1]
119
+ )
120
+ );
121
+ }
122
+ childDigits = /* @__PURE__ */ jsx(
123
+ "span",
124
+ {
125
+ style: {
126
+ position: "absolute",
127
+ top: 0,
128
+ left: 0,
129
+ animationName: direction === "none" ? void 0 : animClass,
130
+ animationDuration: direction === "none" ? void 0 : DURATION_SECS,
131
+ animationFillMode: "forwards",
132
+ animationTimingFunction: "cubic-bezier(0.1, 1, 0.2, 1)",
133
+ animationDelay: delay,
134
+ color: foundDecimal ? decimalColor : wholeColor,
135
+ userSelect: "none"
136
+ },
137
+ children: digitsToAnimate.map((c, j) => /* @__PURE__ */ jsx(
138
+ "span",
139
+ {
140
+ className: "odometer-digit odometer-child",
141
+ style: {
142
+ top: j === 0 ? 0 : `${100 * j}%`,
143
+ height: lineHeight,
144
+ lineHeight
145
+ },
146
+ children: c === "dot" ? "." : c === "comma" ? "," : c
147
+ },
148
+ `child_digit_${j}`
149
+ ))
150
+ }
118
151
  );
119
152
  }
120
- childDigits = /* @__PURE__ */ jsx(
153
+ return /* @__PURE__ */ jsxs(
121
154
  "span",
122
155
  {
156
+ ref: digitRefs[i],
157
+ className: "odometer-digit",
123
158
  style: {
124
- position: "absolute",
125
- top: 0,
126
- left: 0,
127
- animationName: direction === "none" ? void 0 : animClass,
128
- animationDuration: direction === "none" ? void 0 : DURATION_SECS,
129
- animationFillMode: "forwards",
130
- animationTimingFunction: "cubic-bezier(0.1, 1, 0.2, 1)",
131
- animationDelay: delay,
132
159
  color: foundDecimal ? decimalColor : wholeColor,
133
- userSelect: "none"
160
+ height: lineHeight,
161
+ lineHeight,
162
+ paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
134
163
  },
135
- children: digitsToAnimate.map((c, j) => /* @__PURE__ */ jsx(
136
- "span",
137
- {
138
- className: "odometer-digit odometer-child",
139
- style: {
140
- top: j === 0 ? 0 : `${100 * j}%`,
141
- height: lineHeight,
142
- lineHeight
143
- },
144
- children: c === "dot" ? "." : c === "comma" ? "," : c
145
- },
146
- `child_digit_${j}`
147
- ))
148
- }
149
- );
150
- }
151
- return /* @__PURE__ */ jsxs(
152
- "span",
153
- {
154
- ref: digitRefs[i],
155
- className: "odometer-digit",
156
- style: {
157
- color: foundDecimal ? decimalColor : wholeColor,
158
- height: lineHeight,
159
- lineHeight,
160
- paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
164
+ children: [
165
+ status === "inactive" && /* @__PURE__ */ jsx(
166
+ "span",
167
+ {
168
+ className: "odometer-digit odometer-child",
169
+ style: {
170
+ top: 0,
171
+ height: lineHeight,
172
+ lineHeight,
173
+ width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
174
+ },
175
+ children: d === "dot" ? "." : d === "comma" ? "," : d
176
+ }
177
+ ),
178
+ status === "transition" && childDigits
179
+ ]
161
180
  },
162
- children: [
163
- status === "inactive" && /* @__PURE__ */ jsx(
164
- "span",
165
- {
166
- className: "odometer-digit odometer-child",
167
- style: {
168
- top: 0,
169
- height: lineHeight,
170
- lineHeight,
171
- width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
172
- },
173
- children: d === "dot" ? "." : d === "comma" ? "," : d
174
- }
175
- ),
176
- status === "transition" && childDigits
177
- ]
178
- },
179
- `digit_${i}`
180
- );
181
- }),
182
- spaceAfter ? /* @__PURE__ */ jsx("span", { style: { paddingRight: spaceAfter } }) : null
183
- ] }) });
181
+ `digit_${i}`
182
+ );
183
+ }),
184
+ spaceAfter ? /* @__PURE__ */ jsx("span", { style: { paddingRight: spaceAfter } }) : null
185
+ ] }) })
186
+ ] });
184
187
  };
185
188
  var index_default = Odometer;
186
189
  export {
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport type { RefObject } from 'react'\nimport { createRef, useEffect, useRef, useState } from 'react'\nimport './index.css'\nimport type { Digit, DigitRef, Direction, Props, Status } from './types'\n\nexport const Odometer = ({\n\tvalue,\n\tspaceBefore = 0,\n\tspaceAfter = '0.25rem',\n\twholeColor = 'var(--text-color-primary)',\n\tdecimalColor = 'var(--text-color-secondary)',\n\tzeroDecimals = 0,\n}: Props) => {\n\t// Store all possible digits.\n\tconst [allDigits] = useState<Digit[]>([\n\t\t'comma',\n\t\t'dot',\n\t\t'0',\n\t\t'1',\n\t\t'2',\n\t\t'3',\n\t\t'4',\n\t\t'5',\n\t\t'6',\n\t\t'7',\n\t\t'8',\n\t\t'9',\n\t])\n\n\t// Store the digits of the current value.\n\tconst [digits, setDigits] = useState<Digit[]>([])\n\n\t// Store digits of the previous value.\n\tconst [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n\t// Store the status of the odometer (transitioning or stable).\n\tconst [status, setStatus] = useState<Status>('inactive')\n\n\t// Store whether component has iniiialized.\n\tconst [initialized, setInitialized] = useState<boolean>(false)\n\n\t// Store ref of the odometer.\n\tconst [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n\t// Store refs of each digit.\n\tconst [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n\t// Store refs of each `all` digit.\n\tconst [allDigitRefs, setAllDigitRefs] = useState<\n\t\tRecord<string, RefObject<HTMLSpanElement | null>>\n\t>({})\n\n\t// Keep track of active transitions.\n\tconst activeTransitionCounter = useRef<number>(0)\n\n\t// Transition duration.\n\tconst DURATION_MS = 750\n\tconst DURATION_SECS = `${DURATION_MS / 1000}s`\n\n\t// Phase 0: populate `allDigitRefs`.\n\tuseEffect(() => {\n\t\tconst all: Record<\n\t\t\tstring,\n\t\t\tRefObject<HTMLSpanElement | null>\n\t\t> = Object.fromEntries(\n\t\t\tObject.values(allDigits).map((v) => [`d_${v}`, createRef()]),\n\t\t)\n\n\t\tsetAllDigitRefs(all)\n\t}, [])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs)) {\n\t\t\tvalue =\n\t\t\t\tString(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n\t\t\tconst newDigits = value\n\t\t\t\t.toString()\n\t\t\t\t.split('')\n\t\t\t\t.map((v) => (v === '.' ? 'dot' : v))\n\t\t\t\t.map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n\t\t\tsetDigits(newDigits)\n\n\t\t\tif (!initialized) {\n\t\t\t\tsetInitialized(true)\n\t\t\t} else {\n\t\t\t\tsetStatus('new')\n\t\t\t\tsetPrevDigits(digits)\n\t\t\t}\n\t\t\tsetDigitRefs(\n\t\t\t\tArray.from({ length: newDigits.length }, () => createRef() as DigitRef),\n\t\t\t)\n\t\t}\n\t}, [value])\n\n\t// Phase 2: set up digit transition.\n\tuseEffect(() => {\n\t\tif (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n\t\t\tsetStatus('transition')\n\t\t\tactiveTransitionCounter.current++\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tactiveTransitionCounter.current--\n\t\t\t\tif (activeTransitionCounter.current === 0) {\n\t\t\t\t\tsetStatus('inactive')\n\t\t\t\t}\n\t\t\t}, DURATION_MS)\n\t\t}\n\t}, [status, digitRefs])\n\n\tconst odometerCurrent: HTMLSpanElement | null = odometerRef.current\n\tlet lineHeight = odometerCurrent\n\t\t? window.getComputedStyle(odometerCurrent).lineHeight\n\t\t: 'inherit'\n\n\t// Fallback line height to `1.1rem` if `normal`.\n\tlineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n\t// Track whether decimal point has been found.\n\tlet foundDecimal = false\n\n\treturn (\n\t\t<span className=\"odometer\">\n\t\t\t<span className=\"odometer-inner\" ref={odometerRef}>\n\t\t\t\t{allDigits.map((d, i) => (\n\t\t\t\t\t<span\n\t\t\t\t\t\tkey={`odometer_template_digit_${i}`}\n\t\t\t\t\t\tref={allDigitRefs[`d_${d}`]}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\t\ttop: '-999%',\n\t\t\t\t\t\t\tleft: '-999%',\n\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t</span>\n\t\t\t\t))}\n\n\t\t\t\t{spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n\t\t\t\t{digits.map((d, i) => {\n\t\t\t\t\tif (d === 'dot') {\n\t\t\t\t\t\tfoundDecimal = true\n\t\t\t\t\t}\n\n\t\t\t\t\t// If transitioning, get digits needed to animate.\n\t\t\t\t\tlet childDigits = null\n\t\t\t\t\tif (status === 'transition') {\n\t\t\t\t\t\tconst digitsToAnimate = []\n\t\t\t\t\t\tconst digitIndex = allDigits.indexOf(digits[i])\n\t\t\t\t\t\tconst prevDigitIndex = allDigits.indexOf(prevDigits[i])\n\t\t\t\t\t\tconst difference = Math.abs(digitIndex - prevDigitIndex)\n\t\t\t\t\t\tconst delay = `${0.01 * (digits.length - i - 1)}s`\n\t\t\t\t\t\tconst direction: Direction =\n\t\t\t\t\t\t\tdigitIndex === prevDigitIndex ? 'none' : 'down'\n\t\t\t\t\t\tconst animClass = `slide-${direction}-${difference} `\n\n\t\t\t\t\t\t// Push current prev digit to stop of stack.\n\t\t\t\t\t\tdigitsToAnimate.push(prevDigits[i])\n\n\t\t\t\t\t\t// If transitioning between two digits, animate all digits in between.\n\t\t\t\t\t\tif (digitIndex < prevDigitIndex) {\n\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t(_, k) => allDigits[prevDigitIndex - k - 1],\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t(_, k) => allDigits[k + prevDigitIndex + 1],\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tchildDigits = (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\t\tanimationName: direction === 'none' ? undefined : animClass,\n\t\t\t\t\t\t\t\t\tanimationDuration:\n\t\t\t\t\t\t\t\t\t\tdirection === 'none' ? undefined : DURATION_SECS,\n\t\t\t\t\t\t\t\t\tanimationFillMode: 'forwards',\n\t\t\t\t\t\t\t\t\tanimationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n\t\t\t\t\t\t\t\t\tanimationDelay: delay,\n\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{digitsToAnimate.map((c, j) => (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tkey={`child_digit_${j}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\ttop: j === 0 ? 0 : `${100 * j}%`,\n\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tkey={`digit_${i}`}\n\t\t\t\t\t\t\tref={digitRefs[i]}\n\t\t\t\t\t\t\tclassName=\"odometer-digit\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\tpaddingRight:\n\t\t\t\t\t\t\t\t\tstatus === 'transition'\n\t\t\t\t\t\t\t\t\t\t? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n\t\t\t\t\t\t\t\t\t\t: '0',\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{status === 'inactive' && (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\twidth: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{status === 'transition' && childDigits}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t\t{spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n\t\t\t</span>\n\t\t</span>\n\t)\n}\n\nexport default Odometer\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport type { RefObject } from 'react'\nimport { createRef, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport './index.css'\nimport type { Digit, DigitRef, Direction, Props, Status } from './types'\n\nexport const Odometer = ({\n\tvalue,\n\tspaceBefore = 0,\n\tspaceAfter = '0.25rem',\n\twholeColor = 'var(--text-color-primary)',\n\tdecimalColor = 'var(--text-color-secondary)',\n\tzeroDecimals = 0,\n}: Props) => {\n\t// Store all possible digits.\n\tconst [allDigits] = useState<Digit[]>([\n\t\t'comma',\n\t\t'dot',\n\t\t'0',\n\t\t'1',\n\t\t'2',\n\t\t'3',\n\t\t'4',\n\t\t'5',\n\t\t'6',\n\t\t'7',\n\t\t'8',\n\t\t'9',\n\t])\n\n\t// Store the digits of the current value.\n\tconst [digits, setDigits] = useState<Digit[]>([])\n\n\t// Store digits of the previous value.\n\tconst [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n\t// Store the status of the odometer (transitioning or stable).\n\tconst [status, setStatus] = useState<Status>('inactive')\n\n\t// Store whether component has iniiialized.\n\tconst [initialized, setInitialized] = useState<boolean>(false)\n\n\t// Store ref of the odometer.\n\tconst [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n\t// Store refs of each digit.\n\tconst [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n\t// Store refs of each `all` digit.\n\tconst [allDigitRefs, setAllDigitRefs] = useState<\n\t\tRecord<string, RefObject<HTMLSpanElement | null>>\n\t>({})\n\n\t// Keep track of active transitions.\n\tconst activeTransitionCounter = useRef<number>(0)\n\n\t// Transition duration.\n\tconst DURATION_MS = 750\n\tconst DURATION_SECS = `${DURATION_MS / 1000}s`\n\n\t// Phase 0: populate `allDigitRefs`.\n\tuseEffect(() => {\n\t\tconst all: Record<\n\t\t\tstring,\n\t\t\tRefObject<HTMLSpanElement | null>\n\t\t> = Object.fromEntries(\n\t\t\tObject.values(allDigits).map((v) => [`d_${v}`, createRef()]),\n\t\t)\n\n\t\tsetAllDigitRefs(all)\n\t}, [])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseLayoutEffect(() => {\n\t\tif (Object.keys(allDigitRefs)) {\n\t\t\tvalue =\n\t\t\t\tString(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n\t\t\tconst newDigits = value\n\t\t\t\t.toString()\n\t\t\t\t.split('')\n\t\t\t\t.map((v) => (v === '.' ? 'dot' : v))\n\t\t\t\t.map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n\t\t\tsetDigits(newDigits)\n\n\t\t\tif (!initialized) {\n\t\t\t\tsetInitialized(true)\n\t\t\t} else {\n\t\t\t\tsetStatus('new')\n\t\t\t\tsetPrevDigits(digits)\n\t\t\t}\n\t\t\tsetDigitRefs(\n\t\t\t\tArray.from({ length: newDigits.length }, () => createRef() as DigitRef),\n\t\t\t)\n\t\t}\n\t}, [value])\n\n\t// Phase 2: set up digit transition.\n\tuseLayoutEffect(() => {\n\t\tif (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n\t\t\tsetStatus('transition')\n\t\t\tactiveTransitionCounter.current++\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tactiveTransitionCounter.current--\n\t\t\t\tif (activeTransitionCounter.current === 0) {\n\t\t\t\t\tsetStatus('inactive')\n\t\t\t\t}\n\t\t\t}, DURATION_MS)\n\t\t}\n\t}, [status, digitRefs])\n\n\tconst odometerCurrent: HTMLSpanElement | null = odometerRef.current\n\tlet lineHeight = odometerCurrent\n\t\t? window.getComputedStyle(odometerCurrent).lineHeight\n\t\t: 'inherit'\n\n\t// Fallback line height to `1.1rem` if `normal`.\n\tlineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n\t// Track whether decimal point has been found.\n\tlet foundDecimal = false\n\n\treturn (\n\t\t<>\n\t\t\t{allDigits.map((d, i) => (\n\t\t\t\t<span\n\t\t\t\t\tkey={`odometer_template_digit_${i}`}\n\t\t\t\t\tref={allDigitRefs[`d_${d}`]}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\tdisplay: 'inline-block',\n\t\t\t\t\t\ttop: '-999%',\n\t\t\t\t\t\tleft: '-999%',\n\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t<span className=\"odometer\">\n\t\t\t\t<span className=\"odometer-inner\" ref={odometerRef}>\n\t\t\t\t\t{spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n\t\t\t\t\t{digits.map((d, i) => {\n\t\t\t\t\t\tif (d === 'dot') {\n\t\t\t\t\t\t\tfoundDecimal = true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If transitioning, get digits needed to animate.\n\t\t\t\t\t\tlet childDigits = null\n\t\t\t\t\t\tif (status === 'transition') {\n\t\t\t\t\t\t\tconst digitsToAnimate = []\n\t\t\t\t\t\t\tconst digitIndex = allDigits.indexOf(digits[i])\n\t\t\t\t\t\t\tconst prevDigitIndex = allDigits.indexOf(prevDigits[i])\n\t\t\t\t\t\t\tconst difference = Math.abs(digitIndex - prevDigitIndex)\n\t\t\t\t\t\t\tconst delay = `${0.01 * (digits.length - i - 1)}s`\n\t\t\t\t\t\t\tconst direction: Direction =\n\t\t\t\t\t\t\t\tdigitIndex === prevDigitIndex ? 'none' : 'down'\n\t\t\t\t\t\t\tconst animClass = `slide-${direction}-${difference} `\n\n\t\t\t\t\t\t\t// Push current prev digit to stop of stack.\n\t\t\t\t\t\t\tdigitsToAnimate.push(prevDigits[i])\n\n\t\t\t\t\t\t\t// If transitioning between two digits, animate all digits in between.\n\t\t\t\t\t\t\tif (digitIndex < prevDigitIndex) {\n\t\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t\t(_, k) => allDigits[prevDigitIndex - k - 1],\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdigitsToAnimate.push(\n\t\t\t\t\t\t\t\t\t...Array.from(\n\t\t\t\t\t\t\t\t\t\t{ length: difference },\n\t\t\t\t\t\t\t\t\t\t(_, k) => allDigits[k + prevDigitIndex + 1],\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tchildDigits = (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\t\t\tanimationName: direction === 'none' ? undefined : animClass,\n\t\t\t\t\t\t\t\t\t\tanimationDuration:\n\t\t\t\t\t\t\t\t\t\t\tdirection === 'none' ? undefined : DURATION_SECS,\n\t\t\t\t\t\t\t\t\t\tanimationFillMode: 'forwards',\n\t\t\t\t\t\t\t\t\t\tanimationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n\t\t\t\t\t\t\t\t\t\tanimationDelay: delay,\n\t\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\t\tuserSelect: 'none',\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{digitsToAnimate.map((c, j) => (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tkey={`child_digit_${j}`}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\ttop: j === 0 ? 0 : `${100 * j}%`,\n\t\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={`digit_${i}`}\n\t\t\t\t\t\t\t\tref={digitRefs[i]}\n\t\t\t\t\t\t\t\tclassName=\"odometer-digit\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor: foundDecimal ? decimalColor : wholeColor,\n\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\tpaddingRight:\n\t\t\t\t\t\t\t\t\t\tstatus === 'transition'\n\t\t\t\t\t\t\t\t\t\t\t? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n\t\t\t\t\t\t\t\t\t\t\t: '0',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{status === 'inactive' && (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclassName=\"odometer-digit odometer-child\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight,\n\t\t\t\t\t\t\t\t\t\t\twidth: `${\n\t\t\t\t\t\t\t\t\t\t\t\tallDigitRefs[`d_${d}`]?.current?.offsetWidth\n\t\t\t\t\t\t\t\t\t\t\t}px`,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{status === 'transition' && childDigits}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t\t{spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n\t\t\t\t</span>\n\t\t\t</span>\n\t\t</>\n\t)\n}\n\nexport default Odometer\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w3ux/react-odometer",
3
- "version": "2.3.12",
3
+ "version": "2.3.13",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "description": "An odometer effect used for number and balance transitions",