Skip to content

Commit

Permalink
refactor: update rest of components
Browse files Browse the repository at this point in the history
  • Loading branch information
MellKam committed Oct 15, 2023
1 parent 809e1c7 commit c432cfa
Show file tree
Hide file tree
Showing 32 changed files with 303 additions and 322 deletions.
11 changes: 5 additions & 6 deletions packages/radix-vue/src/Combobox/ComboboxArrow.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<script setup lang="ts">
import { inject } from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import { COMBOBOX_CONTENT_INJECTION_KEY } from './ComboboxContentImpl.vue'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
import { injectComboboxContentContext } from './ComboboxContentImpl.vue'
import { PopperArrow, type PopperArrowProps } from '@/Popper'
const props = defineProps<ComboboxArrowProps>()
const context = inject(COMBOBOX_INJECT_KEY)
const contentContext = inject(COMBOBOX_CONTENT_INJECTION_KEY)
const rootContext = injectComboboxRootContext()
const contentContext = injectComboboxContentContext()
export interface ComboboxArrowProps extends PopperArrowProps {}
</script>

<template>
<PopperArrow
v-if="context?.open.value && contentContext?.position.value === 'popper'"
v-if="rootContext.open.value && contentContext.position.value === 'popper'"
v-bind="props"
>
<slot />
Expand Down
9 changes: 4 additions & 5 deletions packages/radix-vue/src/Combobox/ComboboxCancel.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<script setup lang="ts">
import { Primitive, type PrimitiveProps } from '@/Primitive'
import { inject } from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
export interface ComboboxCancelProps extends PrimitiveProps {}
const props = withDefaults(defineProps<ComboboxCancelProps>(), {
as: 'button',
})
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
function handleClick() {
context!.searchTerm.value = ''
context?.inputElement.value?.focus()
rootContext.searchTerm.value = ''
rootContext.inputElement.value?.focus()
}
</script>

Expand Down
7 changes: 3 additions & 4 deletions packages/radix-vue/src/Combobox/ComboboxContent.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { inject } from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
import ComboboxContentImpl, { type ComboboxContentImplEmits, type ComboboxContentImplProps } from './ComboboxContentImpl.vue'
import { Presence } from '@/Presence'
import { useForwardPropsEmits } from '@/shared'
Expand All @@ -12,11 +11,11 @@ const props = defineProps<ComboboxContentProps>()
const emits = defineEmits<ComboboxContentEmits>()
const forwarded = useForwardPropsEmits(props, emits)
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
</script>

<template>
<Presence :present="context!.open.value">
<Presence :present="rootContext.open.value">
<ComboboxContentImpl v-bind="{ ...forwarded, ...$attrs }">
<slot />
</ComboboxContentImpl>
Expand Down
40 changes: 19 additions & 21 deletions packages/radix-vue/src/Combobox/ComboboxContentImpl.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<script lang="ts">
import {
createContext,
useBodyScrollLock,
useHideOthers,
} from '@/shared'
export type ComboboxContentImplEmits = {
closeAutoFocus: [event: Event]
/**
Expand All @@ -19,26 +25,20 @@ export interface ComboboxContentImplProps extends PopperContentProps {
disableOutsidePointerEvents?: boolean
}
export const COMBOBOX_CONTENT_INJECTION_KEY = Symbol() as InjectionKey<{
position: Ref<'inline' | 'popper'>
}>
export const [injectComboboxContentContext, provideComboboxContentContext]
= createContext<{
position: Ref<'inline' | 'popper'>
}>('ComboboxContent')
</script>

<script setup lang="ts">
import {
type InjectionKey,
type Ref,
computed,
inject,
onMounted,
provide,
toRefs,
} from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import {
useBodyScrollLock,
useHideOthers,
} from '@/shared'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
import {
DismissableLayer,
type PointerDownOutsideEvent,
Expand All @@ -52,7 +52,7 @@ const props = withDefaults(defineProps<ComboboxContentImplProps>(), {
const emits = defineEmits<ComboboxContentImplEmits>()
const { position } = toRefs(props)
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
useBodyScrollLock(props.bodyLock)
Expand All @@ -66,11 +66,11 @@ const pickedProps = computed(() => {
})
function handleLeave(ev: PointerEvent) {
context?.onSelectedValueChange('')
rootContext.onSelectedValueChange('')
}
onMounted(() => {
context?.onContentElementChange(currentElement.value)
rootContext.onContentElementChange(currentElement.value)
})
const popperStyle = {
Expand All @@ -86,31 +86,29 @@ const popperStyle = {
'--radix-combobox-trigger-height': 'var(--radix-popper-anchor-height)',
}
provide(COMBOBOX_CONTENT_INJECTION_KEY, {
position,
})
provideComboboxContentContext({ position })
</script>

<template>
<DismissableLayer
as-child
:disable-outside-pointer-events="disableOutsidePointerEvents"
@focus-outside.prevent
@dismiss="context?.onOpenChange(false)"
@dismiss="rootContext.onOpenChange(false)"
@escape-key-down="emits('escapeKeyDown', $event)"
@pointer-down-outside="(ev) => {
// if clicking inside the combobox, prevent dismiss
if (context?.parentElement.value?.contains(ev.target as Node)) ev.preventDefault()
if (rootContext.parentElement.value?.contains(ev.target as Node)) ev.preventDefault()
emits('pointerDownOutside', ev)
}"
>
<component
:is="position === 'popper' ? PopperContent : Primitive "
v-bind="{ ...$attrs, ...pickedProps }"
:id="context?.contentId"
:id="rootContext.contentId"
ref="primitiveElement"
role="listbox"
:data-state="context?.open.value ? 'open' : 'closed'"
:data-state="rootContext.open.value ? 'open' : 'closed'"
:style="{
// flex layout so we can place the scroll buttons properly
display: 'flex',
Expand Down
8 changes: 4 additions & 4 deletions packages/radix-vue/src/Combobox/ComboboxEmpty.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script setup lang="ts">
import { Primitive, type PrimitiveProps } from '@/Primitive'
import { computed, inject } from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import { computed } from 'vue'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
export interface ComboboxEmptyProps extends PrimitiveProps {}
const props = defineProps<ComboboxEmptyProps>()
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
// if no options, then show this
const isEmpty = computed(() => context?.searchTerm.value && context.filteredOptions.value.length === 0)
const isEmpty = computed(() => rootContext.searchTerm.value && rootContext.filteredOptions.value.length === 0)
</script>

<template>
Expand Down
29 changes: 16 additions & 13 deletions packages/radix-vue/src/Combobox/ComboboxGroup.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
<script lang="ts">
import { createContext, useId } from '@/shared'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
export interface ComboboxGroupProps extends PrimitiveProps {}
interface SelectGroupContextValue {
type ComboboxGroupContext = {
id: string
options?: Ref<Array<string | object>>
}
export const COMBOBOX_GROUP_INJECTION_KEY
= Symbol() as InjectionKey<SelectGroupContextValue>
export const [injectComboboxGroupContext, provideComboboxGroupContext]
= createContext<ComboboxGroupContext>('ComboboxGroup')
</script>

<script setup lang="ts">
import { type InjectionKey, type Ref, computed, inject, provide, ref } from 'vue'
import { type Ref, computed, ref } from 'vue'
import { Primitive, type PrimitiveProps } from '@/Primitive'
import { useId } from '@/shared'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
const props = defineProps<ComboboxGroupProps>()
const id = useId()
const options = ref<Array<string | object>>([])
provide(COMBOBOX_GROUP_INJECTION_KEY, {
id,
options,
})
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
const isAnyChildInFilteredOptions = computed(() =>
!context?.isUserInputted.value
!rootContext.isUserInputted.value
|| options.value.length === 0
|| context?.filteredOptions.value.map(i => JSON.stringify(i)).some(i => options.value.map(i => JSON.stringify(i)).includes(i)))
|| rootContext.filteredOptions.value.map(i => JSON.stringify(i)).some(i => options.value.map(i => JSON.stringify(i)).includes(i)))
provideComboboxGroupContext({
id,
options,
})
</script>

<template>
Expand Down
36 changes: 18 additions & 18 deletions packages/radix-vue/src/Combobox/ComboboxInput.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, inject, onMounted, ref } from 'vue'
import { COMBOBOX_INJECT_KEY } from './ComboboxRoot.vue'
import { computed, onMounted, ref } from 'vue'
import { injectComboboxRootContext } from './ComboboxRoot.vue'
export interface ComboboxInputProps {
type?: string
Expand All @@ -12,44 +12,44 @@ const props = withDefaults(defineProps<ComboboxInputProps>(), {
type: 'text',
})
const context = inject(COMBOBOX_INJECT_KEY)
const rootContext = injectComboboxRootContext()
const elRef = ref()
onMounted(() => {
context!.inputElement = elRef
context?.onInputElementChange(elRef.value)
rootContext.inputElement = elRef
rootContext.onInputElementChange(elRef.value)
})
const disabled = computed(() => props.disabled || context?.disabled.value || false)
const disabled = computed(() => props.disabled || rootContext.disabled.value || false)
function handleKeyDown(ev: KeyboardEvent) {
if (!context?.open.value)
context?.onOpenChange(true)
if (!rootContext.open.value)
rootContext.onOpenChange(true)
else
context.onInputNavigation(ev.key === 'ArrowUp' ? 'up' : 'down')
rootContext.onInputNavigation(ev.key === 'ArrowUp' ? 'up' : 'down')
}
function handleHomeEnd(ev: KeyboardEvent) {
if (!context?.open.value)
if (!rootContext.open.value)
return
context.onInputNavigation(ev.key === 'Home' ? 'home' : 'end')
rootContext.onInputNavigation(ev.key === 'Home' ? 'home' : 'end')
}
function handleInput() {
if (!context?.open.value)
context?.onOpenChange(true)
if (!rootContext.open.value)
rootContext.onOpenChange(true)
context!.isUserInputted.value = true
rootContext.isUserInputted.value = true
}
</script>

<template>
<input
ref="elRef"
v-model="context!.searchTerm.value"
v-model="rootContext.searchTerm.value"
:type="type"
:aria-expanded="context?.open.value"
:aria-controls="context?.contentId"
:aria-expanded="rootContext.open.value"
:aria-controls="rootContext.contentId"
:disabled="disabled"
:aria-disabled="disabled ?? undefined"
aria-autocomplete="list"
Expand All @@ -59,7 +59,7 @@ function handleInput() {
:autofocus="autoFocus"
@input="handleInput"
@keydown.down.up.prevent="handleKeyDown"
@keydown.enter="context?.onInputEnter"
@keydown.enter="rootContext.onInputEnter"
@keydown.home.end.prevent="handleHomeEnd"
>
</template>
Loading

0 comments on commit c432cfa

Please sign in to comment.