diff --git a/.changeset/countup-negative-zero.md b/.changeset/countup-negative-zero.md new file mode 100644 index 000000000..e44b21922 --- /dev/null +++ b/.changeset/countup-negative-zero.md @@ -0,0 +1,5 @@ +--- +"@tabler/core": patch +--- + +Fixed CountUp printing `-0` when a value crosses or rounds to zero. diff --git a/core/js/src/countup.ts b/core/js/src/countup.ts index a980b350c..5f22ddc56 100644 --- a/core/js/src/countup.ts +++ b/core/js/src/countup.ts @@ -331,14 +331,18 @@ class CountUp extends BaseComponent { } if (format === 'time') { - const minutes = Math.round(Math.abs(value)) - return `${value < 0 ? '-' : ''}${prefix}${Math.floor(minutes / 60)}:${String(minutes % 60).padStart(2, '0')}${suffix}` + // Rounded away from zero on both sides, so -90.5 and 90.5 give the same + // minutes; a value that rounds to 0 stays unsigned (-0 < 0 is false). + const rounded = Math.sign(value) * Math.round(Math.abs(value)) + const minutes = Math.abs(rounded) + return `${rounded < 0 ? '-' : ''}${prefix}${Math.floor(minutes / 60)}:${String(minutes % 60).padStart(2, '0')}${suffix}` } - const [integer, fraction] = Math.abs(value).toFixed(decimalPlaces).split('.') as [string, string | undefined] + const fixed = value.toFixed(decimalPlaces) + const [integer, fraction] = fixed.replace('-', '').split('.') as [string, string | undefined] const grouped = useGrouping ? integer.replace(/\B(?=(\d{3})+(?!\d))/g, separator) : integer - return `${value < 0 ? '-' : ''}${prefix}${grouped}${fraction ? decimal + fraction : ''}${suffix}` + return `${Number(fixed) < 0 ? '-' : ''}${prefix}${grouped}${fraction ? decimal + fraction : ''}${suffix}` } } diff --git a/core/js/tests/unit/countup.spec.ts b/core/js/tests/unit/countup.spec.ts index 16aa5b5de..f5fea6271 100644 --- a/core/js/tests/unit/countup.spec.ts +++ b/core/js/tests/unit/countup.spec.ts @@ -239,6 +239,15 @@ describe('CountUp', () => { instance.reset() expect(element().textContent).toBe('50,000') }) + + it('should not print a negative zero when a value rounds to zero', async () => { + fixtureEl.innerHTML = '