diff --git a/packages/example-nextjs/src/app/Form.tsx b/packages/example-nextjs/src/app/Form.tsx index b21f046..9428125 100644 --- a/packages/example-nextjs/src/app/Form.tsx +++ b/packages/example-nextjs/src/app/Form.tsx @@ -104,7 +104,7 @@ export const Form = ({ className }: { className?: string }) => { }; const tags = [ - { id: '1', value: { text: '1' } }, - { id: '2', value: { text: '2' } }, - { id: '3', value: { text: '3' } } + { id: '1', value: { text: '1', time: new Date() } }, + { id: '2', value: { text: '2', time: new Date() } }, + { id: '3', value: { text: '3', time: new Date() } } ] diff --git a/packages/example-nextjs/src/app/form.ts b/packages/example-nextjs/src/app/form.ts index 8068e14..d32db4b 100644 --- a/packages/example-nextjs/src/app/form.ts +++ b/packages/example-nextjs/src/app/form.ts @@ -9,5 +9,5 @@ type Form = { name: string; age: number | string; 'agree to terms': boolean; - tags: { id: string, value: { text: string }}[] + tags: { id: string, value: { text: string, time: Date }}[] }; diff --git a/packages/url-state/constants.ts b/packages/url-state/constants.ts index b2294d3..09163c8 100644 --- a/packages/url-state/constants.ts +++ b/packages/url-state/constants.ts @@ -3,6 +3,7 @@ export const SYMBOLS = { null: '∙null', undefined: '∙undefined', number: '∓', + date: '⏲', arrayL: '⦋', arrayR: '⦌', objectL: '❴', diff --git a/packages/url-state/encoder.test.ts b/packages/url-state/encoder.test.ts index b2f40fd..9ad9c56 100644 --- a/packages/url-state/encoder.test.ts +++ b/packages/url-state/encoder.test.ts @@ -23,6 +23,13 @@ describe('encoder', () => { }); }); + + it('date', () => { + const d = new Date('2024-06-28T09:10:38.763Z') + expect(encode(d)).toStrictEqual('⏲2024-06-28T09:10:38.763Z'); + }); + + it('boolean', () => { expect(encode(true)).toStrictEqual('🗵true'); expect(encode(false)).toStrictEqual('🗵false'); @@ -96,6 +103,12 @@ describe('decoder', () => { expect(decode('∙undefined')).toStrictEqual(undefined); }); + it('date', () => { + const dateString = '⏲2024-06-28T09:10:38.763Z' + const date = new Date(dateString.slice(1)) + expect(decode(dateString)).toStrictEqual(date); + }); + it('complex', () => { expect( decode( diff --git a/packages/url-state/encoder.ts b/packages/url-state/encoder.ts index 4a2261f..b74dc30 100644 --- a/packages/url-state/encoder.ts +++ b/packages/url-state/encoder.ts @@ -8,6 +8,8 @@ export function encode(payload: unknown): string{ case 'function': case 'symbol': return ''; + case 'date': + return SYMBOLS.date + (payload as Date).toISOString() case 'string': return encodeURIComponent(payload as string); case 'number': @@ -43,6 +45,7 @@ const replacer = (key: string, value: unknown) => { const decodeStr = (str: string) => { if (str.match(/^∓/)) return Number.parseFloat(str.replaceAll('∓', '')); if (str.match(/^🗵/)) return str.includes('true') ? true : false; + if (str.match(/^⏲/)) return new Date(str.slice(1)); if (str === SYMBOLS.null) return null; if (str === SYMBOLS.undefined) return undefined; return decodeURIComponent(str); diff --git a/packages/url-state/utils.test.ts b/packages/url-state/utils.test.ts index bd54a13..59705a7 100644 --- a/packages/url-state/utils.test.ts +++ b/packages/url-state/utils.test.ts @@ -7,6 +7,11 @@ describe('typeOf', () => { expect(typeOf('5')).toEqual('string'); }); + it('date', () => { + const d = new Date() + expect(typeOf(d)).toEqual('date'); + }); + it('number', () => { expect(typeOf(5)).toEqual('number'); expect(typeOf(3.14567)).toEqual('number'); diff --git a/packages/url-state/utils.ts b/packages/url-state/utils.ts index 68d7230..259c2e1 100644 --- a/packages/url-state/utils.ts +++ b/packages/url-state/utils.ts @@ -1,5 +1,6 @@ export type Type = | 'string' + | 'date' | 'boolean' | 'number' | 'bigint' @@ -13,10 +14,12 @@ export type Type = export const typeOf = (val: unknown): Type => { const isNull = val === null; const isArray = Array.isArray(val); - const isObject = !isNull && !isArray && typeof val === 'object'; + const isDate = val instanceof Date + const isObject = !isNull && !isDate && !isArray && typeof val === 'object'; return ( (isNull && 'null') || + (isDate && 'date') || (isArray && 'array') || (isObject && 'object') || typeof val