Skip to content

Commit

Permalink
[format()] Allow only passing value and determine type based on value…
Browse files Browse the repository at this point in the history
… (integer, decimal, or Date) for quick/basic formatting
  • Loading branch information
techniq committed Jul 10, 2024
1 parent 5efdbc3 commit 9fbdd6e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-pumas-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-ux': patch
---

[format()] Allow only passing value and determine type based on value (integer, decimal, or Date) for quick/basic formatting
23 changes: 23 additions & 0 deletions packages/svelte-ux/src/lib/utils/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, it, expect } from 'vitest';
import { format } from './format.js';
import { PeriodType } from './date_types.js';
import { testDate } from './date.test.js';
import { parseISO } from 'date-fns';

describe('format()', () => {
it('returns empty string for null', () => {
Expand Down Expand Up @@ -36,4 +37,26 @@ describe('format()', () => {
const actual = format(1234.5678, (value) => Math.round(value).toString());
expect(actual).equal('1235');
});

// Default format based on value type
it('format based on value type (integer)', () => {
const actual = format(1234);
expect(actual).equal('1,234');
});
it('format based on value type (decimal)', () => {
const actual = format(1234.5678);
expect(actual).equal('1,234.57');
});
it('format based on value type (date string)', () => {
const actual = format(testDate);
expect(actual).equal('11/21/2023');
});
it('format based on value type (date)', () => {
const actual = format(parseISO(testDate));
expect(actual).equal('11/21/2023');
});
it('format based on value type (string)', () => {
const actual = format('hello');
expect(actual).equal('hello');
});
});
50 changes: 27 additions & 23 deletions packages/svelte-ux/src/lib/utils/format.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { formatDateWithLocale, getPeriodTypeNameWithLocale, getDayOfWeekName } from './date.js';
import {
formatDateWithLocale,
getPeriodTypeNameWithLocale,
getDayOfWeekName,
isStringDate,
} from './date.js';
import { formatNumberWithLocale } from './number.js';
import type { FormatNumberOptions, FormatNumberStyle } from './number.js';
import { defaultLocale, type LocaleSettings } from './locale.js';
Expand Down Expand Up @@ -37,29 +42,28 @@ export function formatWithLocale(
format?: FormatType,
options?: FormatNumberOptions | FormatDateOptions
) {
let formattedValue: string | undefined;

if (format) {
if (typeof format === 'function') {
formattedValue = format(value);
} else if (format in PeriodType) {
formattedValue = formatDateWithLocale(
settings,
value,
format as PeriodType,
options as FormatDateOptions
);
} else if (typeof value === 'number') {
formattedValue = formatNumberWithLocale(
settings,
value,
format as FormatNumberStyle,
options as FormatNumberOptions
);
}
if (typeof format === 'function') {
return format(value);
} else if (value instanceof Date || isStringDate(value) || (format && format in PeriodType)) {
return formatDateWithLocale(
settings,
value,
(format ?? PeriodType.Day) as PeriodType,
options as FormatDateOptions
);
} else if (typeof value === 'number') {
return formatNumberWithLocale(
settings,
value,
format as FormatNumberStyle,
options as FormatNumberOptions
);
} else if (typeof value === 'string') {
// Keep original value if already string
return value;
} else if (value == null) {
return '';
}

return formattedValue ?? ''; // return empty string so Svelte doesn't render `null` string;
}

export type FormatFunction = ((
Expand Down
5 changes: 5 additions & 0 deletions packages/svelte-ux/src/lib/utils/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ export function formatNumberWithLocale(
return `${number}`;
}

// Determine default style if not provided (undefined or null)
if (style == null) {
style = Number.isInteger(number) ? 'integer' : 'decimal';
}

const defaults = getFormatNumber(settings, style);

const formatter = Intl.NumberFormat(settings.locale, {
Expand Down

0 comments on commit 9fbdd6e

Please sign in to comment.