Skip to content

Commit 223c918

Browse files
authored
refactor: Replace date-fns usage with new @layerstack/utils date utils (based on d3-time) to reduce bundle size (#602)
* refactor: Replace `date-fns` usage with new `@layerstack/utils` date utils (based on d3-time) to reduce bundle size * Replace `date-fns` `parse` / `format` with @layerstack/utils `parseDate` / `formatDate`. Remove `date-fns
1 parent c7a4b08 commit 223c918

File tree

20 files changed

+249
-202
lines changed

20 files changed

+249
-202
lines changed

.changeset/funny-days-crash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte-ux': patch
3+
---
4+
5+
refactor: Replace `date-fns` usage with new `@layerstack/utils` date utils (based on d3-time) to reduce bundle size

packages/svelte-ux/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,15 @@
5353
"dependencies": {
5454
"@floating-ui/dom": "^1.7.0",
5555
"@fortawesome/fontawesome-common-types": "^6.7.2",
56-
"@layerstack/svelte-actions": "1.0.1-next.6",
57-
"@layerstack/svelte-stores": "1.0.2-next.6",
58-
"@layerstack/svelte-table": "1.0.1-next.6",
59-
"@layerstack/tailwind": "2.0.0-next.8",
60-
"@layerstack/utils": "2.0.0-next.6",
56+
"@layerstack/svelte-actions": "1.0.1-next.11",
57+
"@layerstack/svelte-stores": "1.0.2-next.11",
58+
"@layerstack/svelte-table": "1.0.1-next.11",
59+
"@layerstack/tailwind": "2.0.0-next.13",
60+
"@layerstack/utils": "2.0.0-next.11",
6161
"@mdi/js": "^7.4.47",
6262
"culori": "^4.0.1",
6363
"d3-array": "^3.2.4",
6464
"d3-scale": "^4.0.2",
65-
"date-fns": "^4.1.0",
6665
"esm-env": "^1.2.2",
6766
"immer": "^10.1.1",
6867
"lodash-es": "^4.17.21",

packages/svelte-ux/src/lib/components/DateButton.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createEventDispatcher } from 'svelte';
3-
import { isWithinInterval } from 'date-fns';
43
54
import { cls } from '@layerstack/tailwind';
65
import {
@@ -9,6 +8,7 @@
98
type CustomIntlDateTimeFormatOptions,
109
type SelectedDate,
1110
getDateFuncsByPeriodType,
11+
isDateWithin,
1212
} from '@layerstack/utils';
1313
1414
import Button from './Button.svelte';
@@ -50,7 +50,7 @@
5050
? selected.some((d) => isSame(date, d))
5151
: selected instanceof Object
5252
? selected.from
53-
? isWithinInterval(date, {
53+
? isDateWithin(date, {
5454
start: start(selected.from),
5555
end: end(selected.to ?? selected.from),
5656
})

packages/svelte-ux/src/lib/components/DateField.svelte

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
22
import { createEventDispatcher, type ComponentProps } from 'svelte';
3-
import { parse as parseDate, format as formatDate } from 'date-fns';
4-
import { type DisabledDate } from '@layerstack/utils';
3+
import { formatDate, parseDate, type DisabledDate } from '@layerstack/utils';
54
import { cls } from '@layerstack/tailwind';
65
76
import { getComponentSettings, getSettings } from './settings.js';
@@ -54,7 +53,7 @@
5453
function onInputChange(e: any) {
5554
inputValue = e.detail.value;
5655
const lastValue = value;
57-
const parsedValue = parseDate(inputValue ?? '', actualFormat, new Date());
56+
const parsedValue = parseDate(inputValue ?? '', actualFormat);
5857
value = isNaN(parsedValue.valueOf()) ? null : parsedValue;
5958
if (value != lastValue) {
6059
dispatch('change', { value });

packages/svelte-ux/src/lib/components/DateRange.svelte

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<script lang="ts">
2-
import { isAfter, isBefore, isSameDay } from 'date-fns';
32
import { cls } from '@layerstack/tailwind';
43
import { omit } from '@layerstack/utils/object';
54
import { mdScreen } from '@layerstack/svelte-stores';
@@ -8,6 +7,9 @@
87
DayOfWeek,
98
getDateFuncsByPeriodType,
109
type DisabledDate,
10+
isDateAfter,
11+
isDateBefore,
12+
isSameInterval,
1113
} from '@layerstack/utils';
1214
import { getDateRangePresets, type DateRange } from '@layerstack/utils/dateRange';
1315
import { hasDayOfWeek, replaceDayOfWeek, missingDayOfWeek } from '@layerstack/utils/date';
@@ -72,7 +74,7 @@
7274
}
7375
7476
function onDateChange(date: Date) {
75-
// Apply date-fns function based on type and from/to.
77+
// Apply date function based on type and from/to.
7678
let newSelected = { ...selected, periodType: selectedPeriodType };
7779
7880
const { start, end } = getDateFuncsByPeriodType($localeSettings, selectedPeriodType);
@@ -81,12 +83,12 @@
8183
8284
if (activeDate === 'from') {
8385
newSelected.from = start(date);
84-
if (selected!.to != null && isAfter(date, selected!.to)) {
86+
if (selected!.to != null && isDateAfter(date, selected!.to)) {
8587
newSelected.to = end(date);
8688
}
8789
} else {
8890
newSelected.to = end(date);
89-
if (selected!.from != null && isBefore(date, selected!.from)) {
91+
if (selected!.from != null && isDateBefore(date, selected!.from)) {
9092
newSelected.from = start(date);
9193
newActiveDate = 'to';
9294
}
@@ -134,9 +136,9 @@
134136
].find(
135137
(x) =>
136138
x.value.from &&
137-
isSameDay(x.value.from, selected!.from!) &&
139+
isSameInterval('day', x.value.from, selected!.from!) &&
138140
x.value.to &&
139-
isSameDay(x.value.to, selected!.to!)
141+
isSameInterval('day', x.value.to, selected!.to!)
140142
);
141143
142144
if (prevPeriodTypePreset && newPeriodType) {

packages/svelte-ux/src/lib/components/DateSelect.svelte

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
TODO:
44
- [ ] Set max-height / overflow on MonthListByYear, YearList
55
*/
6-
import { startOfMonth as startOfMonthFunc } from 'date-fns';
7-
import { PeriodType, type DisabledDate, type SelectedDate } from '@layerstack/utils';
6+
import {
7+
PeriodType,
8+
type DisabledDate,
9+
type SelectedDate,
10+
startOfInterval,
11+
} from '@layerstack/utils';
812
913
import Month from './Month.svelte';
1014
import MonthListByYear from './MonthListByYear.svelte';
@@ -20,7 +24,10 @@
2024
export let disabledDates: DisabledDate | undefined = undefined;
2125
2226
// @ts-expect-error
23-
$: startOfMonth = selected?.[activeDate] ? startOfMonthFunc(selected[activeDate]) : undefined;
27+
$: startOfMonth = selected?.[activeDate]
28+
? // @ts-expect-error
29+
startOfInterval('month', selected[activeDate])
30+
: undefined;
2431
</script>
2532

2633
{#if periodType === PeriodType.Month || periodType === PeriodType.Quarter}

packages/svelte-ux/src/lib/components/Month.svelte

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
<script lang="ts">
22
import {
3-
startOfDay as startOfDayFunc,
4-
endOfDay as endOfDayFunc,
5-
startOfMonth as startOfMonthFunc,
6-
endOfMonth as endOfMonthFunc,
7-
addMonths,
8-
isSameDay,
9-
isWithinInterval,
10-
} from 'date-fns';
11-
import { type SelectedDate, PeriodType, hasKeyOf } from '@layerstack/utils';
12-
import { getMonthDaysByWeek } from '@layerstack/utils/date';
3+
type SelectedDate,
4+
PeriodType,
5+
hasKeyOf,
6+
startOfInterval,
7+
endOfInterval,
8+
intervalOffset,
9+
} from '@layerstack/utils';
10+
import { getMonthDaysByWeek, isDateWithin, isSameInterval } from '@layerstack/utils/date';
1311
1412
import { mdiChevronLeft, mdiChevronRight } from '@mdi/js';
1513
@@ -21,18 +19,18 @@
2119
export let selected: SelectedDate = undefined;
2220
2321
export let startOfMonth =
24-
(selected instanceof Date && startOfMonthFunc(selected)) ||
25-
(selected instanceof Array && selected.length && startOfMonthFunc(selected[0])) ||
22+
(selected instanceof Date && startOfInterval('month', selected)) ||
23+
(selected instanceof Array && selected.length && startOfInterval('month', selected[0])) ||
2624
(selected &&
2725
hasKeyOf<{ from: Date }>(selected, 'from') &&
2826
selected.from &&
29-
startOfMonthFunc(selected.from)) ||
30-
startOfMonthFunc(new Date());
27+
startOfInterval('month', selected.from)) ||
28+
startOfInterval('month', new Date());
3129
3230
const { format } = getSettings();
3331
$: dateFormat = $format.settings.formats.dates;
3432
35-
$: endOfMonth = endOfMonthFunc(startOfMonth);
33+
$: endOfMonth = endOfInterval('month', startOfMonth);
3634
$: monthDaysByWeek = getMonthDaysByWeek(startOfMonth, dateFormat.weekStartsOn);
3735
3836
/**
@@ -56,27 +54,27 @@
5654
return disabledDates instanceof Function
5755
? disabledDates(date)
5856
: disabledDates instanceof Date
59-
? isSameDay(date, disabledDates)
57+
? isSameInterval('day', date, disabledDates)
6058
: disabledDates instanceof Array
61-
? disabledDates.some((d) => isSameDay(date, d))
59+
? disabledDates.some((d) => isSameInterval('day', date, d))
6260
: disabledDates instanceof Object
63-
? isWithinInterval(date, {
64-
start: startOfDayFunc(disabledDates.from),
65-
end: endOfDayFunc(disabledDates.to || disabledDates.from),
61+
? isDateWithin(date, {
62+
start: startOfInterval('day', disabledDates.from),
63+
end: endOfInterval('day', disabledDates.to || disabledDates.from),
6664
})
6765
: false;
6866
};
6967
7068
$: isDayHidden = (day: Date) => {
71-
const isCurrentMonth = isWithinInterval(day, {
69+
const isCurrentMonth = isDateWithin(day, {
7270
start: startOfMonth,
7371
end: endOfMonth,
7472
});
7573
return !isCurrentMonth && !showOutsideDays;
7674
};
7775
7876
$: isDayFaded = (day: Date) => {
79-
const isCurrentMonth = isWithinInterval(day, {
77+
const isCurrentMonth = isDateWithin(day, {
8078
start: startOfMonth,
8179
end: endOfMonth,
8280
});
@@ -102,7 +100,7 @@
102100
<Button
103101
icon={mdiChevronLeft}
104102
class="p-2"
105-
on:click={() => (startOfMonth = addMonths(startOfMonth, -1))}
103+
on:click={() => (startOfMonth = intervalOffset('month', startOfMonth, -1))}
106104
/>
107105

108106
<div class="flex flex-1 items-center justify-center">
@@ -114,7 +112,7 @@
114112
<Button
115113
icon={mdiChevronRight}
116114
class="p-2"
117-
on:click={() => (startOfMonth = addMonths(startOfMonth, 1))}
115+
on:click={() => (startOfMonth = intervalOffset('month', startOfMonth, 1))}
118116
/>
119117
</div>
120118
{/if}

packages/svelte-ux/src/lib/components/MonthList.svelte

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
<script lang="ts">
22
import type { ComponentProps } from 'svelte';
3-
import { isSameMonth, isWithinInterval, startOfMonth, endOfMonth } from 'date-fns';
4-
import { type DisabledDate, type SelectedDate, PeriodType } from '@layerstack/utils';
3+
import {
4+
type DisabledDate,
5+
type SelectedDate,
6+
PeriodType,
7+
isSameInterval,
8+
startOfInterval,
9+
endOfInterval,
10+
isDateWithin,
11+
} from '@layerstack/utils';
512
import { getMonths } from '@layerstack/utils/date';
613
714
import DateButton from './DateButton.svelte';
@@ -18,13 +25,13 @@
1825
return disabledDates instanceof Function
1926
? disabledDates(date)
2027
: disabledDates instanceof Date
21-
? isSameMonth(date, disabledDates)
28+
? isSameInterval('month', date, disabledDates)
2229
: disabledDates instanceof Array
23-
? disabledDates.some((d) => isSameMonth(date, d))
30+
? disabledDates.some((d) => isSameInterval('month', date, d))
2431
: disabledDates instanceof Object
25-
? isWithinInterval(date, {
26-
start: startOfMonth(disabledDates.from),
27-
end: endOfMonth(disabledDates.to || disabledDates.from),
32+
? isDateWithin(date, {
33+
start: startOfInterval('month', disabledDates.from),
34+
end: endOfInterval('month', disabledDates.to || disabledDates.from),
2835
})
2936
: false;
3037
};

packages/svelte-ux/src/lib/components/MonthListByYear.svelte

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
2-
import { addYears, subYears } from 'date-fns';
32
import { getMinSelectedDate, getMaxSelectedDate } from '@layerstack/utils/date';
4-
import type { SelectedDate } from '@layerstack/utils';
3+
import { intervalOffset, type SelectedDate } from '@layerstack/utils';
54
65
import Button from './Button.svelte';
76
import MonthList from './MonthList.svelte';
@@ -15,14 +14,14 @@
1514
minYear ??
1615
(minDate
1716
? minDate.getFullYear()
18-
: subYears(getMinSelectedDate(selected) || new Date(), 2).getFullYear());
17+
: intervalOffset('year', getMinSelectedDate(selected) || new Date(), -2).getFullYear());
1918
2019
let maxYear: number;
2120
$: maxYear =
2221
maxYear ??
2322
(maxDate
2423
? maxDate.getFullYear()
25-
: addYears(getMaxSelectedDate(selected) || new Date(), 2).getFullYear());
24+
: intervalOffset('year', getMaxSelectedDate(selected) || new Date(), 2).getFullYear());
2625
2726
$: years = Array.from({ length: maxYear - minYear + 1 }, (_, i) => minYear + i);
2827

packages/svelte-ux/src/lib/components/YearList.svelte

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<script lang="ts">
22
import type { ComponentProps } from 'svelte';
33
import {
4-
addYears,
5-
subYears,
6-
isSameYear,
7-
isWithinInterval,
8-
startOfYear,
9-
endOfYear,
10-
} from 'date-fns';
11-
import { type DisabledDate, type SelectedDate, PeriodType } from '@layerstack/utils';
4+
type DisabledDate,
5+
type SelectedDate,
6+
PeriodType,
7+
intervalOffset,
8+
isSameInterval,
9+
startOfInterval,
10+
endOfInterval,
11+
isDateWithin,
12+
} from '@layerstack/utils';
1213
import { getMinSelectedDate, getMaxSelectedDate } from '@layerstack/utils/date';
1314
1415
import Button from './Button.svelte';
@@ -29,14 +30,14 @@
2930
minYear ??
3031
(minDate
3132
? minDate.getFullYear()
32-
: subYears(getMinSelectedDate(selected) || new Date(), 2).getFullYear());
33+
: intervalOffset('year', getMinSelectedDate(selected) || new Date(), -2).getFullYear());
3334
3435
let maxYear: number;
3536
$: maxYear =
3637
maxYear ??
3738
(maxDate
3839
? maxDate.getFullYear()
39-
: addYears(getMaxSelectedDate(selected) || new Date(), 2).getFullYear());
40+
: intervalOffset('year', getMaxSelectedDate(selected) || new Date(), 2).getFullYear());
4041
4142
$: years = Array.from({ length: maxYear - minYear + 1 }, (_, i) => minYear + i) ?? [];
4243
@@ -47,13 +48,13 @@
4748
return disabledDates instanceof Function
4849
? disabledDates(date)
4950
: disabledDates instanceof Date
50-
? isSameYear(date, disabledDates)
51+
? isSameInterval('year', date, disabledDates)
5152
: disabledDates instanceof Array
52-
? disabledDates.some((d) => isSameYear(date, d))
53+
? disabledDates.some((d) => isSameInterval('year', date, d))
5354
: disabledDates instanceof Object
54-
? isWithinInterval(date, {
55-
start: startOfYear(disabledDates.from),
56-
end: endOfYear(disabledDates.to || disabledDates.from),
55+
? isDateWithin(date, {
56+
start: startOfInterval('year', disabledDates.from),
57+
end: endOfInterval('year', disabledDates.to || disabledDates.from),
5758
})
5859
: false;
5960
};

packages/svelte-ux/src/routes/docs/components/DateField/+page.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script lang="ts">
2-
import { addDays } from 'date-fns';
2+
import { Button, DateField, getSettings } from 'svelte-ux';
33
import { mdiCalendarStart, mdiCalendarEnd } from '@mdi/js';
4+
import { intervalOffset } from '@layerstack/utils';
45
5-
import { Button, DateField, getSettings } from 'svelte-ux';
66
import Preview from '$lib/components/Preview.svelte';
77
88
const { localeSettings } = getSettings();
@@ -32,13 +32,13 @@
3232
<Button on:click={() => (value = new Date())}>
3333
{$localeSettings.dictionary.Date.PeriodDay.Current}
3434
</Button>
35-
<Button on:click={() => (value = addDays(new Date(), -1))}>
35+
<Button on:click={() => (value = intervalOffset('day', new Date(), -1))}>
3636
{$localeSettings.dictionary.Date.PeriodDay.Last}
3737
</Button>
38-
<Button on:click={() => (value = addDays(new Date(), -7))}>
38+
<Button on:click={() => (value = intervalOffset('day', new Date(), -7))}>
3939
{$localeSettings.dictionary.Date.PeriodWeek.Last}
4040
</Button>
41-
<Button on:click={() => (value = addDays(new Date(), 7))}>
41+
<Button on:click={() => (value = intervalOffset('day', new Date(), 7))}>
4242
<!-- TODO: Add to dictionary -->
4343
Next week
4444
</Button>

0 commit comments

Comments
 (0)