@ibobbyts/svelte-ui-utils 0.2.7 → 0.2.8

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/README.md CHANGED
@@ -409,7 +409,9 @@ selected first, the year select fills with the most recent matching year. For
409
409
  example, in July 2026, July resolves to 2026 and August resolves to 2025. Pass
410
410
  `defaultPreset` to apply a preset on mount when the current value is empty.
411
411
  Clicking the currently active preset clears both date inputs and emits an empty
412
- range. The `last24Hours` preset also emits `startDateTime` and `endDateTime` so
412
+ range. `thisWeek`, `thisMonth`, and `thisYear` cover the complete calendar
413
+ period, including days after today. The `last24Hours` preset also emits
414
+ `startDateTime` and `endDateTime` so
413
415
  a consuming app can run an exact timestamp query while still showing the covered
414
416
  dates in the inputs.
415
417
 
@@ -4,6 +4,7 @@
4
4
  import { onMount } from 'svelte';
5
5
  import Dropdown from '../dropdown/Dropdown.svelte';
6
6
  import { getUiMessages, type UiLanguage } from '../i18n.js';
7
+ import { endOfMonth, formatDate, resolveDateRangePreset, startOfDay } from './date-range.js';
7
8
  import type { DateRangeFilterValue, DateRangePreset } from './types.js';
8
9
 
9
10
  export let value: DateRangeFilterValue = {
@@ -49,39 +50,6 @@
49
50
  ...quickYearOptions.map((year) => ({ label: String(year), value: String(year) }))
50
51
  ];
51
52
 
52
- function pad(value: number) {
53
- return String(value).padStart(2, '0');
54
- }
55
-
56
- function formatDate(date: Date) {
57
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
58
- }
59
-
60
- function formatDateTime(date: Date) {
61
- return `${formatDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
62
- }
63
-
64
- function startOfDay(date: Date) {
65
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
66
- }
67
-
68
- function addDays(date: Date, days: number) {
69
- const next = new Date(date);
70
- next.setDate(next.getDate() + days);
71
- return next;
72
- }
73
-
74
- function startOfWeek(date: Date) {
75
- const start = startOfDay(date);
76
- const day = start.getDay();
77
- const offset = weekStartsOn === 1 ? (day + 6) % 7 : day;
78
- return addDays(start, -offset);
79
- }
80
-
81
- function endOfMonth(year: number, month: number) {
82
- return new Date(year, month, 0);
83
- }
84
-
85
53
  function resolveYearForMonth(month: number) {
86
54
  const today = startOfDay(now());
87
55
  return month <= today.getMonth() + 1 ? today.getFullYear() : today.getFullYear() - 1;
@@ -104,65 +72,7 @@
104
72
  }
105
73
 
106
74
  function resolvePreset(preset: DateRangePreset): DateRangeFilterValue {
107
- const current = now();
108
- const today = startOfDay(current);
109
-
110
- if (preset === 'last24Hours') {
111
- const start = new Date(current.getTime() - 24 * 60 * 60 * 1000);
112
- return {
113
- startDate: formatDate(start),
114
- endDate: formatDate(current),
115
- preset,
116
- startDateTime: formatDateTime(start),
117
- endDateTime: formatDateTime(current)
118
- };
119
- }
120
-
121
- if (preset === 'last7Days') {
122
- return {
123
- startDate: formatDate(addDays(today, -6)),
124
- endDate: formatDate(today),
125
- preset
126
- };
127
- }
128
-
129
- if (preset === 'last30Days') {
130
- return {
131
- startDate: formatDate(addDays(today, -29)),
132
- endDate: formatDate(today),
133
- preset
134
- };
135
- }
136
-
137
- if (preset === 'thisWeek') {
138
- return {
139
- startDate: formatDate(startOfWeek(today)),
140
- endDate: formatDate(today),
141
- preset
142
- };
143
- }
144
-
145
- if (preset === 'thisMonth') {
146
- return {
147
- startDate: formatDate(new Date(today.getFullYear(), today.getMonth(), 1)),
148
- endDate: formatDate(today),
149
- preset
150
- };
151
- }
152
-
153
- if (preset === 'thisYear') {
154
- return {
155
- startDate: formatDate(new Date(today.getFullYear(), 0, 1)),
156
- endDate: formatDate(today),
157
- preset
158
- };
159
- }
160
-
161
- return {
162
- startDate: formatDate(today),
163
- endDate: formatDate(today),
164
- preset
165
- };
75
+ return resolveDateRangePreset(preset, now(), weekStartsOn);
166
76
  }
167
77
 
168
78
  function emit(next: DateRangeFilterValue) {
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeFilter.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/DateRangeFilter.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0RxE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;YAV2O,oBAAoB;eAAa,UAAU;iBAAe,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;mBAAiB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;oBAAkB,eAAe,GAAG,SAAS;iBAAe,MAAM,EAAE,GAAG,SAAS;UAAQ,MAAM,IAAI;mBAAiB,CAAC,GAAG,CAAC;eAAa,CAAC,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS;;;kBAUxf,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"DateRangeFilter.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/DateRangeFilter.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgMxE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;YAV2O,oBAAoB;eAAa,UAAU;iBAAe,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;mBAAiB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;oBAAkB,eAAe,GAAG,SAAS;iBAAe,MAAM,EAAE,GAAG,SAAS;UAAQ,MAAM,IAAI;mBAAiB,CAAC,GAAG,CAAC;eAAa,CAAC,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS;;;kBAUxf,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { DateRangeFilterValue, DateRangePreset } from './types.js';
2
+ export declare function formatDate(date: Date): string;
3
+ export declare function startOfDay(date: Date): Date;
4
+ export declare function endOfMonth(year: number, month: number): Date;
5
+ export declare function resolveDateRangePreset(preset: DateRangePreset, current: Date, weekStartsOn?: 0 | 1): DateRangeFilterValue;
6
+ //# sourceMappingURL=date-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/date-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMxE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,UAEpC;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,QAEpC;AAeD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAErD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,IAAI,EACb,YAAY,GAAE,CAAC,GAAG,CAAK,GACtB,oBAAoB,CA4DtB"}
@@ -0,0 +1,80 @@
1
+ function pad(value) {
2
+ return String(value).padStart(2, '0');
3
+ }
4
+ export function formatDate(date) {
5
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
6
+ }
7
+ function formatDateTime(date) {
8
+ return `${formatDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
9
+ }
10
+ export function startOfDay(date) {
11
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
12
+ }
13
+ function addDays(date, days) {
14
+ const next = new Date(date);
15
+ next.setDate(next.getDate() + days);
16
+ return next;
17
+ }
18
+ function startOfWeek(date, weekStartsOn) {
19
+ const start = startOfDay(date);
20
+ const day = start.getDay();
21
+ const offset = weekStartsOn === 1 ? (day + 6) % 7 : day;
22
+ return addDays(start, -offset);
23
+ }
24
+ export function endOfMonth(year, month) {
25
+ return new Date(year, month, 0);
26
+ }
27
+ export function resolveDateRangePreset(preset, current, weekStartsOn = 1) {
28
+ const today = startOfDay(current);
29
+ if (preset === 'last24Hours') {
30
+ const start = new Date(current.getTime() - 24 * 60 * 60 * 1000);
31
+ return {
32
+ startDate: formatDate(start),
33
+ endDate: formatDate(current),
34
+ preset,
35
+ startDateTime: formatDateTime(start),
36
+ endDateTime: formatDateTime(current)
37
+ };
38
+ }
39
+ if (preset === 'last7Days') {
40
+ return {
41
+ startDate: formatDate(addDays(today, -6)),
42
+ endDate: formatDate(today),
43
+ preset
44
+ };
45
+ }
46
+ if (preset === 'last30Days') {
47
+ return {
48
+ startDate: formatDate(addDays(today, -29)),
49
+ endDate: formatDate(today),
50
+ preset
51
+ };
52
+ }
53
+ if (preset === 'thisWeek') {
54
+ const start = startOfWeek(today, weekStartsOn);
55
+ return {
56
+ startDate: formatDate(start),
57
+ endDate: formatDate(addDays(start, 6)),
58
+ preset
59
+ };
60
+ }
61
+ if (preset === 'thisMonth') {
62
+ return {
63
+ startDate: formatDate(new Date(today.getFullYear(), today.getMonth(), 1)),
64
+ endDate: formatDate(endOfMonth(today.getFullYear(), today.getMonth() + 1)),
65
+ preset
66
+ };
67
+ }
68
+ if (preset === 'thisYear') {
69
+ return {
70
+ startDate: formatDate(new Date(today.getFullYear(), 0, 1)),
71
+ endDate: formatDate(new Date(today.getFullYear(), 11, 31)),
72
+ preset
73
+ };
74
+ }
75
+ return {
76
+ startDate: formatDate(today),
77
+ endDate: formatDate(today),
78
+ preset
79
+ };
80
+ }
@@ -4,6 +4,7 @@ export { default as FilterTable } from './FilterTable.svelte';
4
4
  export { default as NumberRangeFilter } from './NumberRangeFilter.svelte';
5
5
  export { default as Pagination } from '../pagination/Pagination.svelte';
6
6
  export { filter } from './filter.js';
7
+ export { resolveDateRangePreset } from './date-range.js';
7
8
  export { getUiMessages, resolveUiLanguage, uiLanguages } from '../i18n.js';
8
9
  export { getAriaSort, getCellValue, getPageCount, normalizePagination, setDataTableFilters, setDataTablePageSize, setDataTablePagination, setDataTableSort, toggleSort } from './state.js';
9
10
  export type { UiLanguage, UiMessages } from '../i18n.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC"}
@@ -4,5 +4,6 @@ export { default as FilterTable } from './FilterTable.svelte';
4
4
  export { default as NumberRangeFilter } from './NumberRangeFilter.svelte';
5
5
  export { default as Pagination } from '../pagination/Pagination.svelte';
6
6
  export { filter } from './filter.js';
7
+ export { resolveDateRangePreset } from './date-range.js';
7
8
  export { getUiMessages, resolveUiLanguage, uiLanguages } from '../i18n.js';
8
9
  export { getAriaSort, getCellValue, getPageCount, normalizePagination, setDataTableFilters, setDataTablePageSize, setDataTablePagination, setDataTableSort, toggleSort } from './state.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibobbyts/svelte-ui-utils",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Reusable Svelte 5 UI utilities for dialogs, toast notifications, dropdown search, and data tables.",
5
5
  "type": "module",
6
6
  "license": "MIT",