@w3ux/react-odometer 2.2.6 → 2.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/index.cjs CHANGED
@@ -55,6 +55,8 @@ var Odometer = ({
55
55
  const [odometerRef] = (0, import_react.useState)((0, import_react.createRef)());
56
56
  const [digitRefs, setDigitRefs] = (0, import_react.useState)([]);
57
57
  const [allDigitRefs, setAllDigitRefs] = (0, import_react.useState)({});
58
+ const [digitWidths, setDigitWidths] = (0, import_react.useState)({});
59
+ const [widthsMeasured, setWidthsMeasured] = (0, import_react.useState)(false);
58
60
  const activeTransitionCounter = (0, import_react.useRef)(0);
59
61
  const DURATION_MS = 750;
60
62
  const DURATION_SECS = `${DURATION_MS / 1e3}s`;
@@ -65,7 +67,26 @@ var Odometer = ({
65
67
  setAllDigitRefs(all);
66
68
  }, []);
67
69
  (0, import_react.useEffect)(() => {
68
- if (Object.keys(allDigitRefs)) {
70
+ if (Object.keys(allDigitRefs).length > 0 && !widthsMeasured) {
71
+ requestAnimationFrame(() => {
72
+ const widths = {};
73
+ let allMeasured = true;
74
+ for (const [key, ref] of Object.entries(allDigitRefs)) {
75
+ if (ref.current) {
76
+ widths[key] = ref.current.offsetWidth;
77
+ } else {
78
+ allMeasured = false;
79
+ }
80
+ }
81
+ if (allMeasured) {
82
+ setDigitWidths(widths);
83
+ setWidthsMeasured(true);
84
+ }
85
+ });
86
+ }
87
+ }, [allDigitRefs, widthsMeasured]);
88
+ (0, import_react.useEffect)(() => {
89
+ if (Object.keys(allDigitRefs).length > 0 && widthsMeasured) {
69
90
  value = String(value) === "0" ? Number(value).toFixed(zeroDecimals) : value;
70
91
  const newDigits = value.toString().split("").map((v) => v === "." ? "dot" : v).map((v) => v === "," ? "comma" : v);
71
92
  setDigits(newDigits);
@@ -96,6 +117,23 @@ var Odometer = ({
96
117
  let lineHeight = odometerCurrent ? window.getComputedStyle(odometerCurrent).lineHeight : "inherit";
97
118
  lineHeight = lineHeight === "normal" ? "1.1rem" : lineHeight;
98
119
  let foundDecimal = false;
120
+ if (!widthsMeasured) {
121
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: allDigits.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
122
+ "span",
123
+ {
124
+ ref: allDigitRefs[`d_${d}`],
125
+ style: {
126
+ opacity: 0,
127
+ position: "fixed",
128
+ top: "-999%",
129
+ left: "-999%",
130
+ userSelect: "none"
131
+ },
132
+ children: d === "dot" ? "." : d === "comma" ? "," : d
133
+ },
134
+ `odometer_template_digit_${i}`
135
+ )) });
136
+ }
99
137
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
100
138
  allDigits.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
101
139
  "span",
@@ -183,7 +221,7 @@ var Odometer = ({
183
221
  color: foundDecimal ? decimalColor : wholeColor,
184
222
  height: lineHeight,
185
223
  lineHeight,
186
- paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
224
+ paddingRight: status === "transition" ? `${digitWidths[`d_${d}`]}px` : "0"
187
225
  },
188
226
  children: [
189
227
  status === "inactive" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -194,7 +232,7 @@ var Odometer = ({
194
232
  top: 0,
195
233
  height: lineHeight,
196
234
  lineHeight,
197
- width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
235
+ width: `${digitWidths[`d_${d}`]}px`
198
236
  },
199
237
  children: d === "dot" ? "." : d === "comma" ? "," : d
200
238
  }
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 value,\n spaceBefore = 0,\n spaceAfter = '0.25rem',\n wholeColor = 'var(--text-color-primary)',\n decimalColor = 'var(--text-color-secondary)',\n zeroDecimals = 0,\n}: Props) => {\n // Store all possible digits.\n const [allDigits] = useState<Digit[]>([\n 'comma',\n 'dot',\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n ])\n\n // Store the digits of the current value.\n const [digits, setDigits] = useState<Digit[]>([])\n\n // Store digits of the previous value.\n const [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n // Store the status of the odometer (transitioning or stable).\n const [status, setStatus] = useState<Status>('inactive')\n\n // Store whether component has iniiialized.\n const [initialized, setInitialized] = useState<boolean>(false)\n\n // Store ref of the odometer.\n const [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n // Store refs of each digit.\n const [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n // Store refs of each `all` digit.\n const [allDigitRefs, setAllDigitRefs] = useState<\n Record<string, RefObject<HTMLSpanElement | null>>\n >({})\n\n // Keep track of active transitions.\n const activeTransitionCounter = useRef<number>(0)\n\n // Transition duration.\n const DURATION_MS = 750\n const DURATION_SECS = `${DURATION_MS / 1000}s`\n\n // Phase 0: populate `allDigitRefs`.\n useEffect(() => {\n const all: Record<\n string,\n RefObject<HTMLSpanElement | null>\n > = Object.fromEntries(\n Object.values(allDigits).map((v) => [`d_${v}`, createRef()])\n )\n\n setAllDigitRefs(all)\n }, [])\n\n // Phase 1: new digits and refs are added to the odometer.\n useEffect(() => {\n if (Object.keys(allDigitRefs)) {\n value =\n String(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n const newDigits = value\n .toString()\n .split('')\n .map((v) => (v === '.' ? 'dot' : v))\n .map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n setDigits(newDigits)\n\n if (!initialized) {\n setInitialized(true)\n } else {\n setStatus('new')\n setPrevDigits(digits)\n }\n setDigitRefs(\n Array.from({ length: newDigits.length }, () => createRef() as DigitRef)\n )\n }\n }, [value])\n\n // Phase 2: set up digit transition.\n useEffect(() => {\n if (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n setStatus('transition')\n activeTransitionCounter.current++\n\n setTimeout(() => {\n activeTransitionCounter.current--\n if (activeTransitionCounter.current === 0) {\n setStatus('inactive')\n }\n }, DURATION_MS)\n }\n }, [status, digitRefs])\n\n const odometerCurrent: HTMLSpanElement | null = odometerRef.current\n let lineHeight = odometerCurrent\n ? window.getComputedStyle(odometerCurrent).lineHeight\n : 'inherit'\n\n // Fallback line height to `1.1rem` if `normal`.\n lineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n // Track whether decimal point has been found.\n let foundDecimal = false\n\n return (\n <>\n {allDigits.map((d, i) => (\n <span\n key={`odometer_template_digit_${i}`}\n ref={allDigitRefs[`d_${d}`]}\n style={{\n opacity: 0,\n position: 'fixed',\n top: '-999%',\n left: '-999%',\n userSelect: 'none',\n }}\n >\n {d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n </span>\n ))}\n <span className=\"odometer\">\n <span className=\"odometer-inner\" ref={odometerRef}>\n {spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n {digits.map((d, i) => {\n if (d === 'dot') {\n foundDecimal = true\n }\n\n // If transitioning, get digits needed to animate.\n let childDigits = null\n if (status === 'transition') {\n const digitsToAnimate = []\n const digitIndex = allDigits.indexOf(digits[i])\n const prevDigitIndex = allDigits.indexOf(prevDigits[i])\n const difference = Math.abs(digitIndex - prevDigitIndex)\n const delay = `${0.01 * (digits.length - i - 1)}s`\n const direction: Direction =\n digitIndex === prevDigitIndex ? 'none' : 'down'\n const animClass = `slide-${direction}-${difference} `\n\n // Push current prev digit to stop of stack.\n digitsToAnimate.push(prevDigits[i])\n\n // If transitioning between two digits, animate all digits in between.\n if (digitIndex < prevDigitIndex) {\n digitsToAnimate.push(\n ...Array.from(\n { length: difference },\n (_, k) => allDigits[prevDigitIndex - k - 1]\n )\n )\n } else {\n digitsToAnimate.push(\n ...Array.from(\n { length: difference },\n (_, k) => allDigits[k + prevDigitIndex + 1]\n )\n )\n }\n\n childDigits = (\n <span\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n animationName: direction === 'none' ? undefined : animClass,\n animationDuration:\n direction === 'none' ? undefined : DURATION_SECS,\n animationFillMode: 'forwards',\n animationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n animationDelay: delay,\n color: foundDecimal ? decimalColor : wholeColor,\n userSelect: 'none',\n }}\n >\n {digitsToAnimate.map((c, j) => (\n <span\n key={`child_digit_${j}`}\n className=\"odometer-digit odometer-child\"\n style={{\n top: j === 0 ? 0 : `${100 * j}%`,\n height: lineHeight,\n lineHeight,\n }}\n >\n {c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n </span>\n ))}\n </span>\n )\n }\n\n return (\n <span\n key={`digit_${i}`}\n ref={digitRefs[i]}\n className=\"odometer-digit\"\n style={{\n color: foundDecimal ? decimalColor : wholeColor,\n height: lineHeight,\n lineHeight,\n paddingRight:\n status === 'transition'\n ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n : '0',\n }}\n >\n {status === 'inactive' && (\n <span\n className=\"odometer-digit odometer-child\"\n style={{\n top: 0,\n height: lineHeight,\n lineHeight,\n width: `${\n allDigitRefs[`d_${d}`]?.current?.offsetWidth\n }px`,\n }}\n >\n {d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n </span>\n )}\n {status === 'transition' && childDigits}\n </span>\n )\n })}\n {spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n </span>\n </span>\n </>\n )\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, 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// Store calculated widths for each digit.\n\tconst [digitWidths, setDigitWidths] = useState<Record<string, number>>({})\n\n\t// Track if widths have been measured.\n\tconst [widthsMeasured, setWidthsMeasured] = useState<boolean>(false)\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 0.5: measure digit widths after refs are populated.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs).length > 0 && !widthsMeasured) {\n\t\t\t// Wait for next frame to ensure refs are attached\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tconst widths: Record<string, number> = {}\n\t\t\t\tlet allMeasured = true\n\n\t\t\t\tfor (const [key, ref] of Object.entries(allDigitRefs)) {\n\t\t\t\t\tif (ref.current) {\n\t\t\t\t\t\twidths[key] = ref.current.offsetWidth\n\t\t\t\t\t} else {\n\t\t\t\t\t\tallMeasured = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (allMeasured) {\n\t\t\t\t\tsetDigitWidths(widths)\n\t\t\t\t\tsetWidthsMeasured(true)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}, [allDigitRefs, widthsMeasured])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs).length > 0 && widthsMeasured) {\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\t// Don't render odometer until widths are measured\n\tif (!widthsMeasured) {\n\t\treturn (\n\t\t\t<>\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\t\t\t</>\n\t\t)\n\t}\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\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? `${digitWidths[`d_${d}`]}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: `${digitWidths[`d_${d}`]}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.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../src/index.css"],"names":[],"mappings":"AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;AAEA;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE","file":"index.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../src/index.css"],"names":[],"mappings":"AAAA;AAAA;AAGA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAGD;AAEA;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC;;;AAIF;EACC;IACC;;EAGD;IACC","file":"index.css"}
package/index.js CHANGED
@@ -30,6 +30,8 @@ var Odometer = ({
30
30
  const [odometerRef] = useState(createRef());
31
31
  const [digitRefs, setDigitRefs] = useState([]);
32
32
  const [allDigitRefs, setAllDigitRefs] = useState({});
33
+ const [digitWidths, setDigitWidths] = useState({});
34
+ const [widthsMeasured, setWidthsMeasured] = useState(false);
33
35
  const activeTransitionCounter = useRef(0);
34
36
  const DURATION_MS = 750;
35
37
  const DURATION_SECS = `${DURATION_MS / 1e3}s`;
@@ -40,7 +42,26 @@ var Odometer = ({
40
42
  setAllDigitRefs(all);
41
43
  }, []);
42
44
  useEffect(() => {
43
- if (Object.keys(allDigitRefs)) {
45
+ if (Object.keys(allDigitRefs).length > 0 && !widthsMeasured) {
46
+ requestAnimationFrame(() => {
47
+ const widths = {};
48
+ let allMeasured = true;
49
+ for (const [key, ref] of Object.entries(allDigitRefs)) {
50
+ if (ref.current) {
51
+ widths[key] = ref.current.offsetWidth;
52
+ } else {
53
+ allMeasured = false;
54
+ }
55
+ }
56
+ if (allMeasured) {
57
+ setDigitWidths(widths);
58
+ setWidthsMeasured(true);
59
+ }
60
+ });
61
+ }
62
+ }, [allDigitRefs, widthsMeasured]);
63
+ useEffect(() => {
64
+ if (Object.keys(allDigitRefs).length > 0 && widthsMeasured) {
44
65
  value = String(value) === "0" ? Number(value).toFixed(zeroDecimals) : value;
45
66
  const newDigits = value.toString().split("").map((v) => v === "." ? "dot" : v).map((v) => v === "," ? "comma" : v);
46
67
  setDigits(newDigits);
@@ -71,6 +92,23 @@ var Odometer = ({
71
92
  let lineHeight = odometerCurrent ? window.getComputedStyle(odometerCurrent).lineHeight : "inherit";
72
93
  lineHeight = lineHeight === "normal" ? "1.1rem" : lineHeight;
73
94
  let foundDecimal = false;
95
+ if (!widthsMeasured) {
96
+ return /* @__PURE__ */ jsx(Fragment, { children: allDigits.map((d, i) => /* @__PURE__ */ jsx(
97
+ "span",
98
+ {
99
+ ref: allDigitRefs[`d_${d}`],
100
+ style: {
101
+ opacity: 0,
102
+ position: "fixed",
103
+ top: "-999%",
104
+ left: "-999%",
105
+ userSelect: "none"
106
+ },
107
+ children: d === "dot" ? "." : d === "comma" ? "," : d
108
+ },
109
+ `odometer_template_digit_${i}`
110
+ )) });
111
+ }
74
112
  return /* @__PURE__ */ jsxs(Fragment, { children: [
75
113
  allDigits.map((d, i) => /* @__PURE__ */ jsx(
76
114
  "span",
@@ -158,7 +196,7 @@ var Odometer = ({
158
196
  color: foundDecimal ? decimalColor : wholeColor,
159
197
  height: lineHeight,
160
198
  lineHeight,
161
- paddingRight: status === "transition" ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px` : "0"
199
+ paddingRight: status === "transition" ? `${digitWidths[`d_${d}`]}px` : "0"
162
200
  },
163
201
  children: [
164
202
  status === "inactive" && /* @__PURE__ */ jsx(
@@ -169,7 +207,7 @@ var Odometer = ({
169
207
  top: 0,
170
208
  height: lineHeight,
171
209
  lineHeight,
172
- width: `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`
210
+ width: `${digitWidths[`d_${d}`]}px`
173
211
  },
174
212
  children: d === "dot" ? "." : d === "comma" ? "," : d
175
213
  }
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 value,\n spaceBefore = 0,\n spaceAfter = '0.25rem',\n wholeColor = 'var(--text-color-primary)',\n decimalColor = 'var(--text-color-secondary)',\n zeroDecimals = 0,\n}: Props) => {\n // Store all possible digits.\n const [allDigits] = useState<Digit[]>([\n 'comma',\n 'dot',\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n ])\n\n // Store the digits of the current value.\n const [digits, setDigits] = useState<Digit[]>([])\n\n // Store digits of the previous value.\n const [prevDigits, setPrevDigits] = useState<Digit[]>([])\n\n // Store the status of the odometer (transitioning or stable).\n const [status, setStatus] = useState<Status>('inactive')\n\n // Store whether component has iniiialized.\n const [initialized, setInitialized] = useState<boolean>(false)\n\n // Store ref of the odometer.\n const [odometerRef] = useState(createRef<HTMLSpanElement>())\n\n // Store refs of each digit.\n const [digitRefs, setDigitRefs] = useState<DigitRef[]>([])\n\n // Store refs of each `all` digit.\n const [allDigitRefs, setAllDigitRefs] = useState<\n Record<string, RefObject<HTMLSpanElement | null>>\n >({})\n\n // Keep track of active transitions.\n const activeTransitionCounter = useRef<number>(0)\n\n // Transition duration.\n const DURATION_MS = 750\n const DURATION_SECS = `${DURATION_MS / 1000}s`\n\n // Phase 0: populate `allDigitRefs`.\n useEffect(() => {\n const all: Record<\n string,\n RefObject<HTMLSpanElement | null>\n > = Object.fromEntries(\n Object.values(allDigits).map((v) => [`d_${v}`, createRef()])\n )\n\n setAllDigitRefs(all)\n }, [])\n\n // Phase 1: new digits and refs are added to the odometer.\n useEffect(() => {\n if (Object.keys(allDigitRefs)) {\n value =\n String(value) === '0' ? Number(value).toFixed(zeroDecimals) : value\n\n const newDigits = value\n .toString()\n .split('')\n .map((v) => (v === '.' ? 'dot' : v))\n .map((v) => (v === ',' ? 'comma' : v)) as Digit[]\n\n setDigits(newDigits)\n\n if (!initialized) {\n setInitialized(true)\n } else {\n setStatus('new')\n setPrevDigits(digits)\n }\n setDigitRefs(\n Array.from({ length: newDigits.length }, () => createRef() as DigitRef)\n )\n }\n }, [value])\n\n // Phase 2: set up digit transition.\n useEffect(() => {\n if (status === 'new' && !digitRefs.find((d) => d.current === null)) {\n setStatus('transition')\n activeTransitionCounter.current++\n\n setTimeout(() => {\n activeTransitionCounter.current--\n if (activeTransitionCounter.current === 0) {\n setStatus('inactive')\n }\n }, DURATION_MS)\n }\n }, [status, digitRefs])\n\n const odometerCurrent: HTMLSpanElement | null = odometerRef.current\n let lineHeight = odometerCurrent\n ? window.getComputedStyle(odometerCurrent).lineHeight\n : 'inherit'\n\n // Fallback line height to `1.1rem` if `normal`.\n lineHeight = lineHeight === 'normal' ? '1.1rem' : lineHeight\n\n // Track whether decimal point has been found.\n let foundDecimal = false\n\n return (\n <>\n {allDigits.map((d, i) => (\n <span\n key={`odometer_template_digit_${i}`}\n ref={allDigitRefs[`d_${d}`]}\n style={{\n opacity: 0,\n position: 'fixed',\n top: '-999%',\n left: '-999%',\n userSelect: 'none',\n }}\n >\n {d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n </span>\n ))}\n <span className=\"odometer\">\n <span className=\"odometer-inner\" ref={odometerRef}>\n {spaceBefore ? <span style={{ paddingLeft: spaceBefore }} /> : null}\n {digits.map((d, i) => {\n if (d === 'dot') {\n foundDecimal = true\n }\n\n // If transitioning, get digits needed to animate.\n let childDigits = null\n if (status === 'transition') {\n const digitsToAnimate = []\n const digitIndex = allDigits.indexOf(digits[i])\n const prevDigitIndex = allDigits.indexOf(prevDigits[i])\n const difference = Math.abs(digitIndex - prevDigitIndex)\n const delay = `${0.01 * (digits.length - i - 1)}s`\n const direction: Direction =\n digitIndex === prevDigitIndex ? 'none' : 'down'\n const animClass = `slide-${direction}-${difference} `\n\n // Push current prev digit to stop of stack.\n digitsToAnimate.push(prevDigits[i])\n\n // If transitioning between two digits, animate all digits in between.\n if (digitIndex < prevDigitIndex) {\n digitsToAnimate.push(\n ...Array.from(\n { length: difference },\n (_, k) => allDigits[prevDigitIndex - k - 1]\n )\n )\n } else {\n digitsToAnimate.push(\n ...Array.from(\n { length: difference },\n (_, k) => allDigits[k + prevDigitIndex + 1]\n )\n )\n }\n\n childDigits = (\n <span\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n animationName: direction === 'none' ? undefined : animClass,\n animationDuration:\n direction === 'none' ? undefined : DURATION_SECS,\n animationFillMode: 'forwards',\n animationTimingFunction: 'cubic-bezier(0.1, 1, 0.2, 1)',\n animationDelay: delay,\n color: foundDecimal ? decimalColor : wholeColor,\n userSelect: 'none',\n }}\n >\n {digitsToAnimate.map((c, j) => (\n <span\n key={`child_digit_${j}`}\n className=\"odometer-digit odometer-child\"\n style={{\n top: j === 0 ? 0 : `${100 * j}%`,\n height: lineHeight,\n lineHeight,\n }}\n >\n {c === 'dot' ? '.' : c === 'comma' ? ',' : c}\n </span>\n ))}\n </span>\n )\n }\n\n return (\n <span\n key={`digit_${i}`}\n ref={digitRefs[i]}\n className=\"odometer-digit\"\n style={{\n color: foundDecimal ? decimalColor : wholeColor,\n height: lineHeight,\n lineHeight,\n paddingRight:\n status === 'transition'\n ? `${allDigitRefs[`d_${d}`]?.current?.offsetWidth}px`\n : '0',\n }}\n >\n {status === 'inactive' && (\n <span\n className=\"odometer-digit odometer-child\"\n style={{\n top: 0,\n height: lineHeight,\n lineHeight,\n width: `${\n allDigitRefs[`d_${d}`]?.current?.offsetWidth\n }px`,\n }}\n >\n {d === 'dot' ? '.' : d === 'comma' ? ',' : d}\n </span>\n )}\n {status === 'transition' && childDigits}\n </span>\n )\n })}\n {spaceAfter ? <span style={{ paddingRight: spaceAfter }} /> : null}\n </span>\n </span>\n </>\n )\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, 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// Store calculated widths for each digit.\n\tconst [digitWidths, setDigitWidths] = useState<Record<string, number>>({})\n\n\t// Track if widths have been measured.\n\tconst [widthsMeasured, setWidthsMeasured] = useState<boolean>(false)\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 0.5: measure digit widths after refs are populated.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs).length > 0 && !widthsMeasured) {\n\t\t\t// Wait for next frame to ensure refs are attached\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tconst widths: Record<string, number> = {}\n\t\t\t\tlet allMeasured = true\n\n\t\t\t\tfor (const [key, ref] of Object.entries(allDigitRefs)) {\n\t\t\t\t\tif (ref.current) {\n\t\t\t\t\t\twidths[key] = ref.current.offsetWidth\n\t\t\t\t\t} else {\n\t\t\t\t\t\tallMeasured = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (allMeasured) {\n\t\t\t\t\tsetDigitWidths(widths)\n\t\t\t\t\tsetWidthsMeasured(true)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}, [allDigitRefs, widthsMeasured])\n\n\t// Phase 1: new digits and refs are added to the odometer.\n\tuseEffect(() => {\n\t\tif (Object.keys(allDigitRefs).length > 0 && widthsMeasured) {\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\t// Don't render odometer until widths are measured\n\tif (!widthsMeasured) {\n\t\treturn (\n\t\t\t<>\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\t\t\t</>\n\t\t)\n\t}\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\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? `${digitWidths[`d_${d}`]}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: `${digitWidths[`d_${d}`]}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.2.6",
3
+ "version": "2.3.0",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "description": "An odometer effect used for number and balance transitions",