Skip to content

Commit

Permalink
Add v-confirm-directive
Browse files Browse the repository at this point in the history
  • Loading branch information
kieuminhcanh committed May 8, 2024
1 parent 767ecdc commit b7cb5b4
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 0 deletions.
28 changes: 28 additions & 0 deletions packages/vuetify/src/directives/confirm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Components
import { VConfirm } from '@/labs/VConfirm'

// Composables
import { useDirectiveComponent } from '@/composables/directiveComponent'

// Types
import type { DirectiveBinding } from 'vue'
import type { Anchor } from '@/util'

export interface ConfirmDirectiveBinding
extends Omit<DirectiveBinding<string>, 'arg' | 'value'> {
arg?: {
[T in Anchor]: T extends `${infer A} ${infer B}` ? `${A}-${B}` : T;
}[Anchor]
value: boolean | string | Record<string, any>
}

export const Confirm = useDirectiveComponent<ConfirmDirectiveBinding>(
VConfirm,
binding => {
return {
activator: 'parent',
}
},
)

export default Confirm
1 change: 1 addition & 0 deletions packages/vuetify/src/directives/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { Ripple } from './ripple'
export { Scroll } from './scroll'
export { Touch } from './touch'
export { Tooltip } from './tooltip'
export { Confirm } from './confirm'
134 changes: 134 additions & 0 deletions packages/vuetify/src/labs/VConfirm/VConfirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Composables
import { useBackgroundColor } from '@/composables/color'
import { makeLocationProps, useLocation } from '@/composables/location'
import { makeThemeProps, provideTheme } from '@/composables/theme'
import { makeVariantProps } from '@/composables/variant'

// Utilities
import { computed, ref, toRef, watch } from 'vue'
import {
VBtn,
VList,
VListItem,
VListItemAction,
VListItemTitle,
VMenu,
VTextField,
} from '../allComponents'
import { genericComponent, propsFactory, useRender } from '@/util'

export const makeVConfirmProps = propsFactory(
{
title: String,
text: String,
input: [String, Boolean],
onSubmit: Function,
onCancel: Function,
inputProps: Object,
...makeLocationProps({ location: 'bottom' } as const),
...makeVariantProps(),
...makeThemeProps(),
},
'VConfirm',
)

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

props: makeVConfirmProps(),

setup (props, { slots }) {
const input = ref('')
const isActive = ref(false)

const { themeClasses } = provideTheme(props)
const { backgroundColorClasses, backgroundColorStyles } =
useBackgroundColor(toRef(props, 'color'))
const { locationStyles } = useLocation(props)
watch(isActive, value =>
value
? (input.value = typeof props.input === 'string' ? props.input : '')
: '',
)

const showInput = computed(() => props.input || props.input !== false)

function onSubmit () {
isActive.value = false
if (props.onSubmit) {
props.onSubmit(props.input ? input.value : undefined)
}
}
function onCancel () {
isActive.value = false
if (props.onCancel) {
props.onCancel()
}
}

useRender(() => (
<VMenu
v-model={ isActive.value }
close-on-content-click={ !showInput.value }
style={[locationStyles.value]}
>
<VList
class={[themeClasses.value, backgroundColorClasses.value]}
style={[backgroundColorStyles.value]}
>
<VListItem
lines="one"
v-slots={{
title: () => (
<VListItemTitle>
{ !showInput.value ? (
props.text
) : (
<VTextField
v-model={ input.value }
variant="solo-filled"
clearable
hide-details
minWidth="200"
label={ props.text }
{ ...props.inputProps }
onKeydown={ (e: KeyboardEvent) =>
e.key === 'Enter' && onSubmit()
}
/>
)}
</VListItemTitle>
),
append: () => (
<VListItemAction>
{ props.onCancel && (
<VBtn
key="btnCancel"
prependIcon="$close"
text="Cancel"
variant="text"
onClick={ onCancel }
/>
)}
{ props.onSubmit && (
<VBtn
key="btnSubmit"
prependIcon="$success"
text="OK"
variant="text"
onClick={ onSubmit }
/>
)}
</VListItemAction>
),
}}
></VListItem>
</VList>
</VMenu>
))

return {}
},
})

export type VConfirm = InstanceType<typeof VConfirm>;
1 change: 1 addition & 0 deletions packages/vuetify/src/labs/VConfirm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { VConfirm } from './VConfirm'

0 comments on commit b7cb5b4

Please sign in to comment.