Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(date): add new composable #16691

Merged
merged 15 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions packages/api-generator/src/locale/en/use-date.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"exposed": {
"date": "Takes any value and returns a date object.",
"format": "Takes a date object and returns it in a specified format.",
"startOfMonth": "Returns first day of the month.",
"endOfMonth": "Returns the last day of the month.",
"startOfWeek": "Returns the first day of the week.",
"endOfWeek": "Returns the last day of the week.",
"startOfDay": "Returns the first second of the day.",
"endOfDay": "Returns the last second of the day.",
"startOfYear": "Returns the first day of the year.",
"endOfYear": "Returns the last day of the year.",
"isAfter": "Returns true if the first date is after the second date.",
"isEqual": "Returns true if the two dates are equal.",
"isSameDay": "Returns true if the two dates are the same day.",
"isSameMonth": "Returns true if the two dates are the same month.",
"isValid": "Returns true if the date is valid.",
"isWithinRange": "Returns true if the first date is within the range of the second and third dates.",
"addDays": "Adds the specified number of days to the date.",
"addMonths": "Adds the specified number of months to the date.",
"getYear": "Returns the year of the date.",
"setYear": "Sets the year of the date.",
"getDiff": "Returns the difference between two dates in the specified unit.",
"getWeek": "Returns the week of the year of the date.",
"getWeekArray": "Returns an array of the days of the week of the date.",
"getWeekdays": "Returns an array of the names of the days of the week.",
"getMonth": "Returns the month of the date."
}
}
1 change: 1 addition & 0 deletions packages/docs/src/data/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"aliasing",
"application-layout",
"blueprints",
"dates",
"display-and-platform",
"global-configuration",
"icon-fonts",
Expand Down
143 changes: 143 additions & 0 deletions packages/docs/src/pages/en/features/dates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
emphasized: true
meta:
title: Dates
description: Vuetify has first party date support that can easily be swapped for another date library
keywords: date, datepicker, datetime, time, calendar, picker, date library
related:
- /features/blueprints/
- /features/global-configuration/
- /features/treeshaking/
---

# Dates

Easily hook up date libraries that are used for components that require date functionality.

<entry />

## Usage

The date composable provides a shared architecture that is used by components such as date picker and calendar. The default implementation is built using the native Date object, but can be swapped out for another date library. If no other date adapter is given, the default Vuetify one is used.

The following example demonstrates explicitly importing the Vuetify date adapter and passing it to the date options.

```js { resource="src/plugins/vuetify.js" }
import { createVuetify } from 'vuetify'
import VuetifyDateAdapter from 'vuetify/adapters'

export default createVuetify({
date: {
adapter: VuetifyDateAdapter,
},
})
```

Within your application, import the **useDate** function and use it to access the date composable.

```html { resource="src/views/Date.vue" }
<script>
import { useDate } from 'vuetify'

export default {
setup () {
const date = useDate()

console.log(date.getMonth(new Date('March 1, 2021'))) // 3
},
}
</script>
```

<alert type="info">

For a list of all supported date adapters, visit the [date-io](https://github.com/dmtrKovalenko/date-io#projects) project repository.

</alert>

### Format options

The date composable supports the following date formatting options:

* fullDateWithWeekday
* normalDateWithWeekday
* keyboardDate
* monthAndDate
* monthAndYear

The following example shows how to use the date composable to format a date string:

```html { resource="src/views/Date.vue" }
<script>
import { useDate } from 'vuetify'

export default {
setup () {
const date = useDate()

const formatted = date.format('2010-04-13 00:00:00', 'fullDateWithWeekday')

console.log(formatted) // Tuesday, April 13, 2010
},
}
</script>
```

## API

| Feature | Description |
| - | - |
| [useDate](/api/use-date/) | The date composable is used by components that require date functionality |

<api-inline hide-links />

### Adapter

The built in date adapter implements a subset of functionality from the [DateIOFormats](https://github.com/dmtrKovalenko/date-io/blob/master/packages/core/IUtils.d.ts) interface. Because of this, it's easy to swap in any date library supported by [date-io](https://github.com/dmtrKovalenko/date-io).

```js { resource="src/plugins/vuetify.js" }
import { createVuetify } from 'vuetify'
import LuxonAdapter from "@date-io/luxon"

const luxon = new LuxonAdapter({ locale: "sv" });

export default createVuetify({
date: {
adapter: luxon,
},
})
```

#### Create you own

To create your own date adapter, implement the **DateAdapter** interface:

```ts
export interface DateAdapter<Date> {
date (value?: any): Date | null
format (date: Date, formatString: string): string

startOfMonth (date: Date): Date
endOfMonth (date: Date): Date
startOfYear (date: Date): Date
endOfYear (date: Date): Date

isAfter (date: Date, comparing: Date): boolean
isEqual (date: Date, comparing: Date): boolean
isSameDay (date: Date, comparing: Date): boolean
isSameMonth (date: Date, comparing: Date): boolean
isValid (date: any): boolean
isWithinRange (date: Date, range: [Date, Date]): boolean

addDays (date: Date, amount: number): Date
addMonths (date: Date, amount: number): Date

getYear (date: Date): number
setYear (date: Date, year: number): Date
getDiff (date: Date, comparing: Date | string, unit?: string): number
getWeek (date: Date): number
getWeekArray (date: Date): (Date | null)[][]
getWeekdays (): string[]
getMonth (date: Date): number
}
```
24 changes: 24 additions & 0 deletions packages/vuetify/src/adapters/__tests__/vuetify.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from '@jest/globals'
import VuetifyDateAdapter from '../vuetify'

describe('vuetify date adapter', () => {
it('should return weekdays based on locale', () => {
let instance = new VuetifyDateAdapter('en-us')

expect(instance.getWeekdays()).toStrictEqual(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'])

instance = new VuetifyDateAdapter('sv-se')

expect(instance.getWeekdays()).toStrictEqual(['måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag', 'söndag'])
})

it('should format dates', () => {
let instance = new VuetifyDateAdapter('en-us')

expect(instance.format(new Date(2000, 0, 1), 'fullDateWithWeekday')).toBe('Saturday, January 1, 2000')

instance = new VuetifyDateAdapter('sv-SE')

expect(instance.format(new Date(2000, 0, 1), 'fullDateWithWeekday')).toBe('lördag 1 januari 2000')
})
})
27 changes: 27 additions & 0 deletions packages/vuetify/src/adapters/date-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export interface DateAdapter<Date> {
date (value?: any): Date | null
format (date: Date, formatString: string): string

startOfMonth (date: Date): Date
endOfMonth (date: Date): Date
startOfYear (date: Date): Date
endOfYear (date: Date): Date

isAfter (date: Date, comparing: Date): boolean
isEqual (date: Date, comparing: Date): boolean
isSameDay (date: Date, comparing: Date): boolean
isSameMonth (date: Date, comparing: Date): boolean
isValid (date: any): boolean
isWithinRange (date: Date, range: [Date, Date]): boolean

addDays (date: Date, amount: number): Date
addMonths (date: Date, amount: number): Date

getYear (date: Date): number
setYear (date: Date, year: number): Date
getDiff (date: Date, comparing: Date | string, unit?: string): number
getWeek (date: Date): number
getWeekArray (date: Date): (Date | null)[][]
getWeekdays (): string[]
getMonth (date: Date): number
}
Loading