Skip to content

Commit 16215ce

Browse files
Merge pull request #83 from formkit/release/1.1.0
Release 1.1.0 PR rollup
2 parents 46db3eb + bd47809 commit 16215ce

35 files changed

Lines changed: 1070 additions & 63 deletions

‎docs/components/content/Data.vue‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const fns: Record<
1717
ap: {
1818
name: "ap",
1919
description: "Returns either am or pm but in any given locale.",
20-
return: "Date",
20+
return: "string",
2121
arguments: [
2222
{
2323
name: "amOrPm",
@@ -80,7 +80,7 @@ const fns: Record<
8080
type: "Date",
8181
},
8282
],
83-
return: "string",
83+
return: "boolean",
8484
},
8585
monthDays: {
8686
name: "month-days",

‎docs/components/content/Helpers.vue‎

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
<script lang="ts" setup>
22
import sizes from "../../assets/func-sizes.json"
3-
import type { FunctionRef } from "../../src/types"
3+
import type { FunctionRef, ObjectRef } from "../../src/types"
4+
5+
const durationProperties: ObjectRef["properties"] = [
6+
{ name: "years?", type: "number", jsdoc: ["Years in the duration."] },
7+
{ name: "months?", type: "number", jsdoc: ["Months in the duration."] },
8+
{ name: "weeks?", type: "number", jsdoc: ["Weeks in the duration."] },
9+
{ name: "days?", type: "number", jsdoc: ["Days in the duration."] },
10+
{ name: "hours?", type: "number", jsdoc: ["Hours in the duration."] },
11+
{ name: "minutes?", type: "number", jsdoc: ["Minutes in the duration."] },
12+
{ name: "seconds?", type: "number", jsdoc: ["Seconds in the duration."] },
13+
{ name: "milliseconds?", type: "number", jsdoc: ["Milliseconds in the duration."] },
14+
]
15+
16+
const diffOptionsProperties: ObjectRef["properties"] = [
17+
{
18+
name: "abs?",
19+
type: "boolean",
20+
jsdoc: ["Return absolute values instead of signed values."],
21+
},
22+
{
23+
name: "skip?",
24+
type: "Array<keyof Duration> | Set<keyof Duration>",
25+
jsdoc: ["Units to omit while calculating the duration."],
26+
},
27+
]
428
529
const fns: Record<
630
string,
@@ -12,6 +36,27 @@ const fns: Record<
1236
tip?: string
1337
}
1438
> = {
39+
diff: {
40+
description:
41+
"Returns the difference between two dates as a duration object. The result can be passed to <code>add</code> or formatted with <code>Intl.DurationFormat</code>.",
42+
return: "Duration",
43+
arguments: [
44+
{
45+
name: "dateA",
46+
type: "string | Date | null",
47+
},
48+
{
49+
name: "dateB",
50+
type: "string | Date",
51+
},
52+
{
53+
name: "options",
54+
type: "DiffOptions",
55+
comment: "abs, skip",
56+
},
57+
],
58+
example: "diff",
59+
},
1560
diffMilliseconds: {
1661
description:
1762
"Returns the number of milliseconds difference between two date objects.",
@@ -326,6 +371,10 @@ const fns: Record<
326371
:arguments="def.arguments"
327372
:return="def.return"
328373
/>
374+
<template v-if="fn === 'diff'">
375+
<ObjectReference type="Duration" :properties="durationProperties" />
376+
<ObjectReference type="DiffOptions" :properties="diffOptionsProperties" />
377+
</template>
329378
<p v-html="def.description" />
330379
<CodeExample v-if="def.example" :file="def.example" />
331380
<CalloutInfo v-if="def.tip">

‎docs/components/content/Modify.vue‎

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
<script lang="ts" setup>
22
import sizes from "../../assets/func-sizes.json"
3-
import type { FunctionRef } from "../../src/types"
3+
import type { FunctionRef, ObjectRef } from "../../src/types"
4+
5+
const durationProperties: ObjectRef["properties"] = [
6+
{ name: "years?", type: "number", jsdoc: ["Years to add."] },
7+
{ name: "months?", type: "number", jsdoc: ["Months to add."] },
8+
{ name: "weeks?", type: "number", jsdoc: ["Weeks to add."] },
9+
{ name: "days?", type: "number", jsdoc: ["Days to add."] },
10+
{ name: "hours?", type: "number", jsdoc: ["Hours to add."] },
11+
{ name: "minutes?", type: "number", jsdoc: ["Minutes to add."] },
12+
{ name: "seconds?", type: "number", jsdoc: ["Seconds to add."] },
13+
{ name: "milliseconds?", type: "number", jsdoc: ["Milliseconds to add."] },
14+
]
415
516
const fns: Record<
617
string,
@@ -13,6 +24,28 @@ const fns: Record<
1324
tip?: string
1425
}
1526
> = {
27+
add: {
28+
name: "add",
29+
description:
30+
"Returns a new Date object with a duration object applied. To subtract time, use negative values. Month and year overflow behavior matches <code>addMonth</code> and <code>addYear</code>.",
31+
return: "Date",
32+
arguments: [
33+
{
34+
name: "date",
35+
type: "string | Date | null",
36+
},
37+
{
38+
name: "duration",
39+
type: "Duration",
40+
},
41+
{
42+
name: "dateOverflow",
43+
type: "boolean",
44+
comment: "default: false",
45+
},
46+
],
47+
example: "add",
48+
},
1649
addDay: {
1750
name: "add-day",
1851
description:
@@ -282,6 +315,138 @@ const fns: Record<
282315
},
283316
],
284317
},
318+
setDayOfMonth: {
319+
name: "set-day-of-month",
320+
description:
321+
"Returns a new Date object with the day of the month set. By default, days beyond the end of the month clamp to the last day; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
322+
return: "Date",
323+
arguments: [
324+
{
325+
name: "date",
326+
type: "string | Date | null",
327+
},
328+
{
329+
name: "day",
330+
type: "number",
331+
},
332+
{
333+
name: "dateOverflow",
334+
type: "boolean",
335+
comment: "default: false",
336+
},
337+
],
338+
},
339+
setHour: {
340+
name: "set-hour",
341+
description:
342+
"Returns a new Date object with the hour set. Values outside 0-23 use the native Date overflow behavior.",
343+
return: "Date",
344+
arguments: [
345+
{
346+
name: "date",
347+
type: "string | Date | null",
348+
},
349+
{
350+
name: "hour",
351+
type: "number",
352+
comment: "0-23",
353+
},
354+
],
355+
},
356+
setMilliseconds: {
357+
name: "set-milliseconds",
358+
description:
359+
"Returns a new Date object with the millisecond value set. Values outside 0-999 use the native Date overflow behavior.",
360+
return: "Date",
361+
arguments: [
362+
{
363+
name: "date",
364+
type: "string | Date | null",
365+
},
366+
{
367+
name: "milliseconds",
368+
type: "number",
369+
comment: "0-999",
370+
},
371+
],
372+
},
373+
setMinutes: {
374+
name: "set-minutes",
375+
description:
376+
"Returns a new Date object with the minute set. Values outside 0-59 use the native Date overflow behavior.",
377+
return: "Date",
378+
arguments: [
379+
{
380+
name: "date",
381+
type: "string | Date | null",
382+
},
383+
{
384+
name: "minute",
385+
type: "number",
386+
comment: "0-59",
387+
},
388+
],
389+
},
390+
setMonth: {
391+
name: "set-month",
392+
description:
393+
"Returns a new Date object with the zero-based month set. By default, invalid days clamp to the last day of the target month; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
394+
return: "Date",
395+
arguments: [
396+
{
397+
name: "date",
398+
type: "string | Date | null",
399+
},
400+
{
401+
name: "month",
402+
type: "number",
403+
comment: "0-11, 0 is January",
404+
},
405+
{
406+
name: "dateOverflow",
407+
type: "boolean",
408+
comment: "default: false",
409+
},
410+
],
411+
},
412+
setSeconds: {
413+
name: "set-seconds",
414+
description:
415+
"Returns a new Date object with the second set. Values outside 0-59 use the native Date overflow behavior.",
416+
return: "Date",
417+
arguments: [
418+
{
419+
name: "date",
420+
type: "string | Date | null",
421+
},
422+
{
423+
name: "second",
424+
type: "number",
425+
comment: "0-59",
426+
},
427+
],
428+
},
429+
setYear: {
430+
name: "set-year",
431+
description:
432+
"Returns a new Date object with the year set. By default, invalid leap days clamp to the last day of the target month; set <code>dateOverflow</code> to <code>true</code> to allow overflow.",
433+
return: "Date",
434+
arguments: [
435+
{
436+
name: "date",
437+
type: "string | Date | null",
438+
},
439+
{
440+
name: "year",
441+
type: "number",
442+
},
443+
{
444+
name: "dateOverflow",
445+
type: "boolean",
446+
comment: "default: false",
447+
},
448+
],
449+
},
285450
tzDate: {
286451
name: "tz-date",
287452
description: `Converts an ISO 8601 like string into a Date object with a timezone applied. For example, <code>tzDate('2021-01-01T00:00', 'America/Los_Angeles')</code> will return a Date object representing 2021-01-01 00:00 in L.A.`,
@@ -383,6 +548,11 @@ const fns: Record<
383548
:arguments="def.arguments"
384549
:return="def.return"
385550
/>
551+
<ObjectReference
552+
v-if="fn === 'add'"
553+
type="Duration"
554+
:properties="durationProperties"
555+
/>
386556
<p v-html="def.description" />
387557
<CodeExample v-if="def.example" :file="def.example" />
388558
<CalloutInfo v-if="def.tip">

‎docs/examples/add.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { add } from "@formkit/tempo"
2+
3+
// Add multiple units at once
4+
add("2024-01-01 12:00:00", {
5+
years: 1,
6+
months: 3,
7+
days: 15,
8+
hours: 2,
9+
minutes: 8,
10+
seconds: 40,
11+
})
12+
13+
// Subtract 5 weeks
14+
add("2024-02-05", { weeks: -5 })
15+
16+
// Allow month overflow
17+
add("2024-01-30", { months: 1 }, true)

‎docs/examples/diff.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { add, diff } from "@formkit/tempo"
2+
3+
// Get a duration object
4+
diff("2025-04-01 12:00:50", "2024-01-01 12:00:00")
5+
6+
// Skip units you do not want in the result
7+
diff("2025-07-01 12:01:00", "2024-01-01 12:00:00", {
8+
skip: ["years", "minutes"],
9+
})
10+
11+
// Apply a duration to another date
12+
add("2024-01-30", diff("2024-03-01", "2024-01-30"))

‎src/__tests__/add.spec.ts‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { describe, expect, it } from "vitest"
2+
import { add, date, diff } from "../index"
3+
4+
describe("add", () => {
5+
it("adds multiple duration units", () => {
6+
expect(
7+
add("2024-01-01 12:00:00", {
8+
years: 1,
9+
months: 3,
10+
days: 15,
11+
hours: 2,
12+
minutes: 8,
13+
seconds: 40,
14+
})
15+
).toEqual(date("2025-04-16 14:08:40"))
16+
})
17+
18+
it("allows month overflow when requested", () => {
19+
expect(add("2024-01-30", { months: 1 }, true)).toEqual(date("2024-03-01"))
20+
})
21+
22+
it("adds weeks and milliseconds", () => {
23+
expect(add("2024-02-05 10:00:00.250", { weeks: -5, milliseconds: 100 })).toEqual(
24+
date("2024-01-01 10:00:00.350")
25+
)
26+
})
27+
28+
it("round-trips a positive duration returned by diff", () => {
29+
const start = "2024-01-30"
30+
const end = "2024-03-01"
31+
32+
expect(add(start, diff(end, start))).toEqual(date(end))
33+
})
34+
35+
it("round-trips a negative duration returned by diff", () => {
36+
const start = "2024-01-30"
37+
const end = "2024-03-01"
38+
39+
expect(add(end, diff(start, end))).toEqual(date(start))
40+
})
41+
})

0 commit comments

Comments
 (0)