diff --git a/packages/api-generator/src/locale/en/VDatePickerMonth.json b/packages/api-generator/src/locale/en/VDatePickerMonth.json
new file mode 100644
index 00000000000..e7697b78d2b
--- /dev/null
+++ b/packages/api-generator/src/locale/en/VDatePickerMonth.json
@@ -0,0 +1,7 @@
+{
+ "props": {
+ "hideWeekdays": "Hide the days of the week letters.",
+ "transition": "The transition used when changing months into the future",
+ "reverseTransition": "The transition used when changing months into the past"
+ }
+}
diff --git a/packages/api-generator/src/locale/en/VPicker.json b/packages/api-generator/src/locale/en/VPicker.json
new file mode 100644
index 00000000000..0e720d6074f
--- /dev/null
+++ b/packages/api-generator/src/locale/en/VPicker.json
@@ -0,0 +1,6 @@
+{
+ "props": {
+ "landscape": "Puts the picker into landscape mode.",
+ "hideHeader": "Hide the picker header."
+ }
+}
diff --git a/packages/api-generator/src/locale/en/calendar.json b/packages/api-generator/src/locale/en/calendar.json
new file mode 100644
index 00000000000..e96908554f0
--- /dev/null
+++ b/packages/api-generator/src/locale/en/calendar.json
@@ -0,0 +1,9 @@
+{
+ "props": {
+ "displayValue": "The value that determines the month to show. This is different from modelValue, which determines the selected value.",
+ "month": "The current month number to show",
+ "weekdays": "An array of weekdays to display.",
+ "weeksInMonth": "A dynamic number of weeks in a month will grow and shrink depending on how many days are in the month. A static number always shows 7 weeks.",
+ "year": "The current year number to show"
+ }
+}
diff --git a/packages/docs/src/data/nav.json b/packages/docs/src/data/nav.json
index 097e219856a..9666b28d020 100644
--- a/packages/docs/src/data/nav.json
+++ b/packages/docs/src/data/nav.json
@@ -231,6 +231,10 @@
"title": "confirm-edit",
"subfolder": "components"
},
+ {
+ "title": "date-inputs",
+ "subfolder": "components"
+ },
{
"title": "empty-states",
"subfolder": "components"
diff --git a/packages/docs/src/data/page-to-api.json b/packages/docs/src/data/page-to-api.json
index be62a3cf190..49014d5d39a 100644
--- a/packages/docs/src/data/page-to-api.json
+++ b/packages/docs/src/data/page-to-api.json
@@ -69,8 +69,9 @@
"VDataTableServer",
"VDataTableVirtual"
],
+ "components/date-inputs": ["VDateInput", "VDatePicker"],
"components/date-pickers-month": ["VDatePicker"],
- "components/date-pickers": ["VDatePicker"],
+ "components/date-pickers": ["VDatePicker", "VDateInput"],
"components/defaults-providers": ["VDefaultsProvider"],
"components/dialogs": ["VDialog", "VOverlay"],
"components/dividers": ["VDivider"],
diff --git a/packages/docs/src/examples/v-date-input/misc-passenger.vue b/packages/docs/src/examples/v-date-input/misc-passenger.vue
new file mode 100644
index 00000000000..546a5207657
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/misc-passenger.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prev
+
+
+
+ Next
+
+
+
diff --git a/packages/docs/src/examples/v-date-input/prop-model.vue b/packages/docs/src/examples/v-date-input/prop-model.vue
new file mode 100644
index 00000000000..5123cc86bf6
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/prop-model.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/src/examples/v-date-input/prop-multiple-range.vue b/packages/docs/src/examples/v-date-input/prop-multiple-range.vue
new file mode 100644
index 00000000000..db613aabd24
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/prop-multiple-range.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/src/examples/v-date-input/prop-multiple.vue b/packages/docs/src/examples/v-date-input/prop-multiple.vue
new file mode 100644
index 00000000000..15202ef1eeb
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/prop-multiple.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/src/examples/v-date-input/prop-prepend-icon.vue b/packages/docs/src/examples/v-date-input/prop-prepend-icon.vue
new file mode 100644
index 00000000000..427c4be6487
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/prop-prepend-icon.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/src/examples/v-date-input/usage.vue b/packages/docs/src/examples/v-date-input/usage.vue
new file mode 100644
index 00000000000..93e6dfdd1a5
--- /dev/null
+++ b/packages/docs/src/examples/v-date-input/usage.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/src/pages/en/components/date-inputs.md b/packages/docs/src/pages/en/components/date-inputs.md
new file mode 100644
index 00000000000..0bf278bad86
--- /dev/null
+++ b/packages/docs/src/pages/en/components/date-inputs.md
@@ -0,0 +1,102 @@
+---
+emphasized: true
+meta:
+ nav: Date inputs
+ title: Date input component
+ description: The date input is a specialized input that provides a clean interface for selecting dates, showing detailed selection information.
+ keywords: date input, date picker, date field
+related:
+ - /components/date-pickers/
+ - /components/text-fields/
+ - /components/menus/
+features:
+ label: 'C: VDateInput'
+ report: true
+ github: /labs/VDateInput/
+---
+
+# Date inputs
+
+The `v-date-input` component combines a text field with a date picker. It is meant to be a direct replacement for a standard date input.
+
+
+
+::: warning
+
+This feature requires [v3.6.0](/getting-started/release-notes/?version=v3.6.0)
+
+:::
+
+## Installation
+
+Labs components require a manual import and installation of the component.
+
+```js { resource="src/plugins/vuetify.js" }
+import { VDateInput } from 'vuetify/labs/VDateInput'
+
+export default createVuetify({
+ components: {
+ VDateInput,
+ },
+})
+```
+
+## Usage
+
+At its core, the `v-date-input` component is a basic container that extends [v-text-field](/components/text-fields).
+
+
+
+
+
+## API
+
+| Component | Description |
+| - | - |
+| [v-date-input](/api/v-date-input/) | Primary component |
+| [v-date-picker](/api/v-date-picker/) | Date picker component |
+| [v-text-field](/api/v-text-field/) | Text field component |
+
+
+
+## Guide
+
+The `v-date-input` component is a replacement for the standard date input. It provides a clean interface for selecting dates and shows detailed selection information.
+
+### Props
+
+The `v-date-input` component extends the [v-text-field](/components/text-fields/) and [v-date-picker](/components/date-pickers/) component; and supports all of their props.
+
+#### Model
+
+The default model value is a Date object, but is displayed as formatted text in the input..
+
+
+
+#### Multiple
+
+Using the **multiple** prop, the default model value is an empty array.
+
+
+
+#### Range
+
+Using the multiple prop with a value of **range**, select 2 dates to select them and all the dates between them.
+
+
+
+#### Calendar icon
+
+You can move the calendar icon within the input or entirely by utilizing the **prepend-icon** and **prepend-inner-icon** properties.
+
+
+
+## Examples
+
+The following are a collection of examples that demonstrate more advanced and real world use of the `v-date-input` component.
+
+### Passenger
+
+In this example, the `v-date-input` component is used to select a date of birth.
+
+
diff --git a/packages/docs/src/pages/en/labs/introduction.md b/packages/docs/src/pages/en/labs/introduction.md
index 532e8cac8eb..9588cd6a8fb 100644
--- a/packages/docs/src/pages/en/labs/introduction.md
+++ b/packages/docs/src/pages/en/labs/introduction.md
@@ -78,6 +78,7 @@ The following is a list of available and up-and-coming components for use with L
| - | - | - |
| [v-calendar](/components/calendars/) | A calendar component | [v3.4.9](/getting-started/release-notes/?version=v3.4.9) |
| [v-confirm-edit](/components/confirm-edit/) | A component for confirming model changes | [v3.4.0](/getting-started/release-notes/?version=v3.4.0) |
+| [v-date-input](/components/date-inputs/) | A date input component | [v3.6.0](/getting-started/release-notes/?version=v3.6.0) |
| [v-empty-state](/components/empty-states/) | A component for displaying empty states | [v3.5.7](/getting-started/release-notes/?version=v3.5.7) |
| [v-fab](/components/floating-action-buttons/) | A layout aware [v-btn](/components/buttons/) | [v3.5.7](/getting-started/release-notes/?version=v3.5.7) |
| [v-number-input](/components/number-input/) | A component for numerical data | [v3.5.10](/getting-started/release-notes/?version=v3.5.10) |
diff --git a/packages/vuetify/src/labs/VDateInput/VDateInput.tsx b/packages/vuetify/src/labs/VDateInput/VDateInput.tsx
new file mode 100644
index 00000000000..678a7937285
--- /dev/null
+++ b/packages/vuetify/src/labs/VDateInput/VDateInput.tsx
@@ -0,0 +1,161 @@
+// Components
+import { makeVDatePickerProps, VDatePicker } from '@/components/VDatePicker/VDatePicker'
+import { VMenu } from '@/components/VMenu/VMenu'
+import { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'
+import { makeVConfirmEditProps, VConfirmEdit } from '@/labs/VConfirmEdit/VConfirmEdit'
+
+// Composables
+import { useDate } from '@/composables/date'
+import { makeFocusProps, useFocus } from '@/composables/focus'
+import { useLocale } from '@/composables/locale'
+import { useProxiedModel } from '@/composables/proxiedModel'
+
+// Utilities
+import { computed, shallowRef } from 'vue'
+import { genericComponent, omit, propsFactory, useRender, wrapInArray } from '@/util'
+
+// Types
+export interface VDateInputSlots {
+ default: never
+}
+
+export const makeVDateInputProps = propsFactory({
+ hideActions: Boolean,
+
+ ...makeFocusProps(),
+ ...makeVConfirmEditProps(),
+ ...makeVTextFieldProps({
+ placeholder: 'mm/dd/yyyy',
+ prependIcon: '$calendar',
+ }),
+ ...omit(makeVDatePickerProps({
+ weeksInMonth: 'dynamic' as const,
+ hideHeader: true,
+ }), ['active']),
+}, 'VDateInput')
+
+export const VDateInput = genericComponent()({
+ name: 'VDateInput',
+
+ props: makeVDateInputProps(),
+
+ emits: {
+ 'update:modelValue': (val: string) => true,
+ },
+
+ setup (props, { slots }) {
+ const { t } = useLocale()
+ const adapter = useDate()
+ const { isFocused, focus, blur } = useFocus(props)
+ const model = useProxiedModel(props, 'modelValue', props.multiple ? [] : null)
+ const menu = shallowRef(false)
+
+ const display = computed(() => {
+ const value = wrapInArray(model.value)
+
+ if (!value.length) return null
+
+ if (props.multiple === true) {
+ return t('$vuetify.datePicker.itemsSelected', value.length)
+ }
+
+ if (props.multiple === 'range') {
+ const start = value[0]
+ const end = value[value.length - 1]
+
+ return adapter.isValid(start) && adapter.isValid(end)
+ ? `${adapter.format(start, 'keyboardDate')} - ${adapter.format(end, 'keyboardDate')}`
+ : ''
+ }
+
+ return adapter.isValid(model.value) ? adapter.format(model.value, 'keyboardDate') : ''
+ })
+
+ function onKeydown (e: KeyboardEvent) {
+ if (e.key !== 'Enter') return
+
+ if (!menu.value || !isFocused.value) {
+ menu.value = true
+
+ return
+ }
+
+ const target = e.target as HTMLInputElement
+
+ model.value = adapter.date(target.value)
+ }
+
+ function onClick (e: MouseEvent) {
+ e.preventDefault()
+ e.stopPropagation()
+
+ menu.value = true
+ }
+
+ function onSave () {
+ menu.value = false
+ }
+
+ useRender(() => {
+ const confirmEditProps = VConfirmEdit.filterProps(props)
+ const datePickerProps = VDatePicker.filterProps(omit(props, ['active']))
+ const textFieldProps = VTextField.filterProps(props)
+
+ return (
+
+
+
+ {{
+ default: ({ actions, model: proxyModel }) => {
+ return (
+ {
+ if (!props.hideActions) {
+ proxyModel.value = val
+ } else {
+ model.value = val
+
+ if (!props.multiple) menu.value = false
+ }
+ }}
+ onMousedown={ (e: MouseEvent) => e.preventDefault() }
+ >
+ {{
+ actions: !props.hideActions ? () => actions : undefined,
+ }}
+
+ )
+ },
+ }}
+
+
+
+ { slots.default?.() }
+
+ )
+ })
+ },
+})
+
+export type VDateInput = InstanceType
diff --git a/packages/vuetify/src/labs/VDateInput/index.ts b/packages/vuetify/src/labs/VDateInput/index.ts
new file mode 100644
index 00000000000..73ccf785b24
--- /dev/null
+++ b/packages/vuetify/src/labs/VDateInput/index.ts
@@ -0,0 +1 @@
+export { VDateInput } from './VDateInput'
diff --git a/packages/vuetify/src/labs/components.ts b/packages/vuetify/src/labs/components.ts
index 037336bc275..41c5a37956e 100644
--- a/packages/vuetify/src/labs/components.ts
+++ b/packages/vuetify/src/labs/components.ts
@@ -1,5 +1,6 @@
export * from './VCalendar'
export * from './VConfirmEdit'
+export * from './VDateInput'
export * from './VEmptyState'
export * from './VFab'
export * from './VNumberInput'