Skip to content

Commit

Permalink
feat(VTimeInput): add new component
Browse files Browse the repository at this point in the history
  • Loading branch information
johnleider committed Apr 27, 2024
1 parent bc32a67 commit be276cd
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/vuetify/src/iconsets/mdi.ts
Expand Up @@ -23,6 +23,7 @@ const aliases: IconAliases = {
checkboxOn: 'mdi-checkbox-marked',
checkboxOff: 'mdi-checkbox-blank-outline',
checkboxIndeterminate: 'mdi-minus-box',
clock: 'mdi-clock',
delimiter: 'mdi-circle', // for carousel
sortAsc: 'mdi-arrow-up',
sortDesc: 'mdi-arrow-down',
Expand Down
146 changes: 146 additions & 0 deletions packages/vuetify/src/labs/VTimeInput/VTimeInput.tsx
@@ -0,0 +1,146 @@
// Components
import { VMenu } from '@/components/VMenu/VMenu'
import { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'
import { makeVConfirmEditProps, VConfirmEdit } from '@/labs/VConfirmEdit/VConfirmEdit'
import { makeVTimePickerProps, VTimePicker } from '@/labs/VTimePicker/VTimePicker'

// 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 VTimeInputSlots {
default: never
}

export const makeVTimeInputProps = propsFactory({
hideActions: Boolean,

...makeFocusProps(),
...makeVConfirmEditProps(),
...makeVTextFieldProps({
placeholder: 'hh:mm',
prependIcon: '$clock',
}),
...omit(makeVTimePickerProps({
weeksInMonth: 'dynamic' as const,
hideHeader: true,
}), ['active']),
}, 'VTimeInput')

export const VTimeInput = genericComponent()({
name: 'VTimeInput',

props: makeVTimeInputProps(),

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

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 timePickerProps = VTimePicker.filterProps(omit(props, ['active']))
const textFieldProps = VTextField.filterProps(props)

return (
<VTextField
{ ...textFieldProps }
modelValue={ display.value }
onKeydown={ onKeydown }
focused={ menu.value || isFocused.value }
onFocus={ focus }
onBlur={ blur }
onClick:control={ onClick }
onClick:prepend={ onClick }
>
<VMenu
v-model={ menu.value }
activator="parent"
min-width="0"
closeOnContentClick={ false }
openOnClick={ false }
>
<VConfirmEdit
{ ...confirmEditProps }
v-model={ model.value }
onSave={ onSave }
>
{{
default: ({ actions, model: proxyModel }) => {
return (
<VTimePicker
{ ...timePickerProps }
modelValue={ props.hideActions ? model.value : proxyModel.value }
onUpdate:modelValue={ val => {
if (!props.hideActions) {
proxyModel.value = val
} else {
model.value = val
}
}}
onMousedown={ (e: MouseEvent) => e.preventDefault() }
>
{{
actions: !props.hideActions ? () => actions : undefined,
}}
</VTimePicker>
)
},
}}
</VConfirmEdit>
</VMenu>

{ slots.default?.() }
</VTextField>
)
})
},
})

export type VTimeInput = InstanceType<typeof VTimeInput>
1 change: 1 addition & 0 deletions packages/vuetify/src/labs/VTimeInput/index.ts
@@ -0,0 +1 @@
export { VTimeInput } from './VTimeInput'

0 comments on commit be276cd

Please sign in to comment.