@webamoki/web-svelte 0.1.1 → 0.3.1

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.
Files changed (40) hide show
  1. package/README.md +4 -55
  2. package/dist/components/form/FieldWrapper.svelte +6 -0
  3. package/dist/components/form/FieldWrapper.svelte.d.ts +5 -0
  4. package/dist/components/form/fields/ChoiceField.svelte +44 -0
  5. package/dist/components/form/fields/ChoiceField.svelte.d.ts +27 -0
  6. package/dist/components/form/fields/ChoiceMultiField.svelte +46 -0
  7. package/dist/components/form/fields/ChoiceMultiField.svelte.d.ts +27 -0
  8. package/dist/components/form/fields/WeekdayChoiceField.svelte +41 -0
  9. package/dist/components/form/fields/WeekdayChoiceField.svelte.d.ts +27 -0
  10. package/dist/components/form/fields/WeekdayChoiceMultiField.svelte +41 -0
  11. package/dist/components/form/fields/WeekdayChoiceMultiField.svelte.d.ts +27 -0
  12. package/dist/components/index.d.ts +7 -1
  13. package/dist/components/index.js +7 -1
  14. package/dist/components/showcase/CodeBlock.svelte +52 -0
  15. package/dist/components/showcase/CodeBlock.svelte.d.ts +30 -0
  16. package/dist/components/showcase/Container.svelte +13 -0
  17. package/dist/components/showcase/Container.svelte.d.ts +24 -0
  18. package/dist/components/showcase/Preview.svelte +6 -0
  19. package/dist/components/showcase/Preview.svelte.d.ts +26 -0
  20. package/dist/components/showcase/Sidebar.svelte +6 -0
  21. package/dist/components/showcase/Sidebar.svelte.d.ts +26 -0
  22. package/dist/components/showcase/SidebarLink.svelte +7 -0
  23. package/dist/components/showcase/SidebarLink.svelte.d.ts +20 -0
  24. package/dist/components/ui/choice/Choice.svelte +27 -0
  25. package/dist/components/ui/choice/Choice.svelte.d.ts +29 -0
  26. package/dist/components/ui/choice/ChoiceInternal.svelte +57 -0
  27. package/dist/components/ui/choice/ChoiceInternal.svelte.d.ts +34 -0
  28. package/dist/components/ui/choice/ChoiceMulti.svelte +55 -0
  29. package/dist/components/ui/choice/ChoiceMulti.svelte.d.ts +30 -0
  30. package/dist/components/ui/choice/WeekdayChoice.svelte +28 -0
  31. package/dist/components/ui/choice/WeekdayChoice.svelte.d.ts +13 -0
  32. package/dist/components/ui/choice/WeekdayChoiceMulti.svelte +29 -0
  33. package/dist/components/ui/choice/WeekdayChoiceMulti.svelte.d.ts +14 -0
  34. package/dist/highlight.d.ts +1 -0
  35. package/dist/highlight.js +9 -0
  36. package/dist/utils/datetime/index.d.ts +168 -0
  37. package/dist/utils/datetime/index.js +322 -0
  38. package/dist/utils/index.d.ts +1 -1
  39. package/dist/utils/index.js +1 -2
  40. package/package.json +7 -3
@@ -0,0 +1,322 @@
1
+ import { CalendarDate, DateFormatter, getDayOfWeek, getLocalTimeZone, startOfMonth, Time, toCalendarDate, today, toTime, ZonedDateTime } from '@internationalized/date';
2
+ import { type } from 'arktype';
3
+ import { map, range } from 'ramda';
4
+ const DEFAULT_TIME_ZONE = 'Europe/London';
5
+ const DEFAULT_LOCALE = 'en-GB';
6
+ // Day of the week
7
+ export const Days = [
8
+ 'Monday',
9
+ 'Tuesday',
10
+ 'Wednesday',
11
+ 'Thursday',
12
+ 'Friday',
13
+ 'Saturday',
14
+ 'Sunday'
15
+ ];
16
+ export const Day = type.enumerated(...Days);
17
+ const DayIndex = Object.fromEntries(Days.map((day, index) => [day, index]));
18
+ /** Gets the day index of the date */
19
+ function getDayIndex(date) {
20
+ // Always start 0 on Monday
21
+ return getDayOfWeek(date, DEFAULT_LOCALE, 'mon');
22
+ }
23
+ /**
24
+ * Gets the day of the week for a given date.
25
+ * @param date - The date to get the day of the week for.
26
+ * @returns The day of the week
27
+ */
28
+ export function getDayOfDate(date) {
29
+ return Days[getDayIndex(date)];
30
+ }
31
+ /**
32
+ * Checks if a given date is a specific day of the week.
33
+ * @param date - The date to check.
34
+ * @param dayOfWeek - The day of the week to check against.
35
+ * @returns True if the date is the specified day, false otherwise.
36
+ */
37
+ export function isDateDay(date, dayOfWeek) {
38
+ const dateDay = getDayOfDate(date);
39
+ return dateDay === dayOfWeek;
40
+ }
41
+ /**
42
+ * Checks if a given date is today.
43
+ * @param date - The date to check.
44
+ * @returns True if the date is today, false otherwise.
45
+ */
46
+ export function isDateToday(date, timezone) {
47
+ return today(timezone).compare(date) === 0;
48
+ }
49
+ /**
50
+ * Calculates the age from a date of birth.
51
+ * @param dob - The date of birth.
52
+ * @returns The age in years.
53
+ * @throws Error if the date of birth is in the future.
54
+ */
55
+ export function ageFromDob(dob, timezone) {
56
+ const todayDate = today(timezone);
57
+ if (todayDate.compare(dob) < 0) {
58
+ throw new Error('Date of birth is in the future');
59
+ }
60
+ let years = todayDate.year - dob.year;
61
+ const monthDiff = todayDate.month - dob.month;
62
+ const dayDiff = todayDate.day - dob.day;
63
+ // Adjust years down if birthday hasn't occurred this year
64
+ if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
65
+ years--;
66
+ }
67
+ return years;
68
+ }
69
+ /**
70
+ * Gets the date of the next occurrence of a day of the week.
71
+ * @param dayOfWeek - The day of the week to get the next occurrence for.
72
+ * @param startDate - The date to check from. Inclusive.
73
+ * @returns The date of the next occurrence of the specified day.
74
+ */
75
+ export function getNextDateOfDay(dayOfWeek, startDate) {
76
+ const dayIndex = DayIndex[dayOfWeek];
77
+ const startIndex = getDayIndex(startDate);
78
+ // Already on the day
79
+ if (startIndex === dayIndex)
80
+ return startDate;
81
+ // Calculate how many days to add to get to the next occurrence
82
+ const addition = (dayIndex - startIndex + 7) % 7;
83
+ return startDate.add({ days: addition });
84
+ }
85
+ /**
86
+ * Gets the most recent occurrence of a day of the week.
87
+ * @param dayOfWeek - The day of the week
88
+ * @param startDate - The date to check from. Inclusive.
89
+ * @returns The most recent date for the specified day.
90
+ * @throws An error if the day of the week is invalid.
91
+ */
92
+ export function getLastDateOfDay(dayOfWeek, startDate) {
93
+ const dayIndex = DayIndex[dayOfWeek];
94
+ const startIndex = getDayIndex(startDate);
95
+ // Already on the day
96
+ if (startIndex === dayIndex)
97
+ return startDate;
98
+ // Calculate how many days to subtract to get to the previous occurrence
99
+ const subtraction = (startIndex + 7 - dayIndex) % 7;
100
+ return startDate.subtract({ days: subtraction });
101
+ }
102
+ /**
103
+ * Gets an array of the last dates of the day of the week.
104
+ * @param dayOfWeek - The day of the week.
105
+ * @param count - The number of dates to get.
106
+ * @param startDate - The date to check from. Inclusive.
107
+ * @returns The array of dates from oldest to most recent.
108
+ * @throws An error if the day of the week is invalid.
109
+ */
110
+ export function getLastDatesOfDay(dayOfWeek, count, startDate) {
111
+ // Set up the array of dates
112
+ if (count < 1)
113
+ return [];
114
+ // Get the most recent date
115
+ const latestDate = getLastDateOfDay(dayOfWeek, startDate);
116
+ // Calculate all dates subtracted, oldest -> most recent
117
+ return map((i) => latestDate.subtract({ weeks: count - 1 - i }), range(0, count));
118
+ }
119
+ /**
120
+ * Gets an array of dates of the last few months (first day) from a date.
121
+ * @param count - The number of months to get.
122
+ * @param startDate - The date to start from (defaults to today).
123
+ * @returns The array of dates from oldest to most recent.
124
+ */
125
+ export function getLastMonths(count, startDate) {
126
+ if (count < 1)
127
+ return [];
128
+ // Get the most recent date
129
+ const latestDate = startOfMonth(startDate);
130
+ // Calculate the previous dates
131
+ return map((i) => latestDate.subtract({ months: count - 1 - i }), range(0, count));
132
+ }
133
+ /* Intervals */
134
+ /**
135
+ * Checks if two time ranges overlap, boundaries are not considered overlapping.
136
+ * @param start1 - The start time of the first range.
137
+ * @param end1 - The end time of the first range.
138
+ * @param start2 - The start time of the second range.
139
+ * @param end2 - The end time of the second range.
140
+ * @returns True if the ranges overlap, false otherwise.
141
+ */
142
+ export function checkOverlap(start1, end1, start2, end2) {
143
+ return start1.compare(end2) < 0 && start2.compare(end1) < 0;
144
+ }
145
+ /**
146
+ * Determines if the given dates are within the given duration of each other.
147
+ * @param date1 - The first date in order.
148
+ * @param date2 - The second date in order.
149
+ * @param duration - The duration to check against. Inclusive of boundaries.
150
+ * @returns True if the dates are within duration, false otherwise.
151
+ */
152
+ export function datesWithin(date1, date2, duration) {
153
+ // reject invalid order
154
+ if (date1.compare(date2) > 0)
155
+ return false;
156
+ return date1.add(duration).compare(date2) >= 0;
157
+ }
158
+ const msPerWeek = 7 * 24 * 60 * 60 * 1000;
159
+ /**
160
+ * Calculates the difference in weeks between two dates.
161
+ * @param date1 - The first date in order.
162
+ * @param date2 - The second date in order.
163
+ */
164
+ export function dateDiffWeeks(date1, date2) {
165
+ const date1Abs = date1.toDate(DEFAULT_TIME_ZONE).getTime();
166
+ const date2Abs = date2.toDate(DEFAULT_TIME_ZONE).getTime();
167
+ return Math.floor((date2Abs - date1Abs) / msPerWeek);
168
+ }
169
+ /* Formatting */
170
+ /* Day of the week*/
171
+ /**
172
+ * Formats a day of the week.
173
+ * @param day - The day of the week to format.
174
+ * @example "Monday" -> "Mon"
175
+ * @returns Formatted string of the day of the week.
176
+ */
177
+ export function formatDayShort(day) {
178
+ // Use the first three letters of the day
179
+ return day.slice(0, 3);
180
+ }
181
+ /**
182
+ * Formats a day of the week.
183
+ * @param day - The day of the week to format.
184
+ * @example "Monday" -> "M"
185
+ * @returns Formatted letter of the day of the week.
186
+ */
187
+ export function formatDayLetter(day) {
188
+ // Use the first letters of the day
189
+ return day.slice(0, 1);
190
+ }
191
+ /* Calendar Dates */
192
+ const FullDateFormatter = new DateFormatter(DEFAULT_LOCALE, {
193
+ day: 'numeric',
194
+ month: 'short',
195
+ year: 'numeric'
196
+ });
197
+ const ShortDateFormatter = new DateFormatter(DEFAULT_LOCALE, {
198
+ month: 'short',
199
+ day: 'numeric'
200
+ });
201
+ const MonthFormatter = new DateFormatter(DEFAULT_LOCALE, {
202
+ month: 'short',
203
+ year: '2-digit'
204
+ });
205
+ const NumFormatter = new DateFormatter(DEFAULT_LOCALE, {
206
+ day: '2-digit',
207
+ month: '2-digit',
208
+ year: 'numeric'
209
+ });
210
+ function formatDate(date, formatter) {
211
+ const nativeDate = date.toDate(getLocalTimeZone());
212
+ return formatter.format(nativeDate);
213
+ }
214
+ /**
215
+ * @param date The CalendarDate object to format.
216
+ * @returns string of date in shortened format
217
+ * @example "Oct 5"
218
+ */
219
+ export function formatDateShort(date) {
220
+ return formatDate(date, ShortDateFormatter);
221
+ }
222
+ /**
223
+ * @param date The CalendarDate object to format.
224
+ * @returns The formatted date string.
225
+ * @example "5 Oct 2023"
226
+ */
227
+ export function formatDateFull(date) {
228
+ return formatDate(date, FullDateFormatter);
229
+ }
230
+ /**
231
+ * ISO format
232
+ * @param date The CalendarDate object to format.
233
+ * @returns The formatted date string in YYYY-MM-DD format.
234
+ * @example "2023-10-05"
235
+ */
236
+ export function formatDateISO(date) {
237
+ return date.toString();
238
+ }
239
+ /**
240
+ * @param date The CalendarDate object to format.
241
+ * @returns The formatted date string in dd/mm/yyyy format.
242
+ * @example "05/10/2023"
243
+ */
244
+ export function formatDateNum(date) {
245
+ return formatDate(date, NumFormatter);
246
+ }
247
+ /**
248
+ * Formats the month only.
249
+ * @param date - The date to format.
250
+ * @returns The formatted month string.
251
+ * @example "Oct"
252
+ */
253
+ export function formatMonth(date) {
254
+ return formatDate(date, MonthFormatter);
255
+ }
256
+ /* Times */
257
+ // Pad number with zeroes to the left
258
+ function padNum(num, len) {
259
+ if (isNaN(num)) {
260
+ return '0'.repeat(len);
261
+ }
262
+ return num.toString().padStart(len, '0');
263
+ }
264
+ /**
265
+ * Gives time in HH:MM format
266
+ * @param time
267
+ * @returns string of time in that format
268
+ */
269
+ export function formatTimeShort(time) {
270
+ const hours = padNum(time.hour, 2);
271
+ const minutes = padNum(time.minute, 2);
272
+ return `${hours}:${minutes}`;
273
+ }
274
+ /**
275
+ * Gives time in HH:MM:SS format
276
+ * @param time
277
+ * @returns string of time in that format
278
+ */
279
+ export function formatTimeFull(time) {
280
+ const hours = padNum(time.hour, 2);
281
+ const minutes = padNum(time.minute, 2);
282
+ const seconds = padNum(time.second, 2);
283
+ return `${hours}:${minutes}:${seconds}`;
284
+ }
285
+ /**
286
+ * Calculates the end time given a starting time and duration.
287
+ * @param timeStart starting time
288
+ * @param durationMinutes duration in minutes
289
+ * @returns end time in HH:MM format
290
+ */
291
+ export function formatTimeEnd(timeStart, durationMinutes) {
292
+ const timeEnd = timeStart.add({ minutes: durationMinutes });
293
+ return formatTimeShort(timeEnd);
294
+ }
295
+ /**
296
+ * Formats a full date and time.
297
+ * @param datetime The ZonedDateTime object to format.
298
+ * @returns The formatted date and time string.
299
+ * @example "05/10/2023 14:30:00"
300
+ */
301
+ export function formatAbsolute(datetime) {
302
+ const date = toCalendarDate(datetime);
303
+ const time = toTime(datetime);
304
+ return `${formatDateNum(date)} ${formatTimeFull(time)}`;
305
+ }
306
+ /* State handling */
307
+ /**
308
+ * Unfreezes a CalendarDate object from a snapshot.
309
+ * @param raw - The snapshot of the CalendarDate object.
310
+ * @returns The unfrozen CalendarDate object.
311
+ */
312
+ export function unfreezeDate(raw) {
313
+ return new CalendarDate(raw.year, raw.month, raw.day);
314
+ }
315
+ /**
316
+ * Unfreezes a Time object from a snapshot.
317
+ * @param raw - The snapshot of the Time object.
318
+ * @returns The unfrozen Time object.
319
+ */
320
+ export function unfreezeTime(raw) {
321
+ return new Time(raw.hour, raw.minute, raw.second, raw.millisecond);
322
+ }
@@ -1 +1 @@
1
- export {};
1
+ export * from './datetime/index.js';
@@ -1,2 +1 @@
1
- "use strict";
2
- // Reexport your entry utils here
1
+ export * from './datetime/index.js';
package/package.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.1",
6
+ "version": "0.3.1",
7
+ "license": "MIT",
7
8
  "files": [
8
9
  "dist",
9
10
  "!dist/**/*.test.*",
@@ -49,6 +50,7 @@
49
50
  "@tailwindcss/vite": "^4.0.0",
50
51
  "@types/node": "^22",
51
52
  "@types/ramda": "^0.31.1",
53
+ "@types/sorted-array-functions": "^1.3.3",
52
54
  "arktype": "^2.1.22",
53
55
  "clsx": "^2.1.1",
54
56
  "eslint": "^9.22.0",
@@ -59,7 +61,7 @@
59
61
  "prettier-plugin-svelte": "^3.3.3",
60
62
  "prettier-plugin-tailwindcss": "^0.6.11",
61
63
  "publint": "^0.3.2",
62
- "ramda": "^0.31.3",
64
+ "shiki": "^3.13.0",
63
65
  "svelte": "^5.0.0",
64
66
  "svelte-check": "^4.0.0",
65
67
  "sveltekit-superforms": "^2.27.1",
@@ -76,7 +78,9 @@
76
78
  "svelte"
77
79
  ],
78
80
  "dependencies": {
79
- "formsnap": "^2.0.1"
81
+ "formsnap": "^2.0.1",
82
+ "ramda": "^0.31.3",
83
+ "sorted-array-functions": "^1.3.0"
80
84
  },
81
85
  "scripts": {
82
86
  "dev": "vite dev",