Skip to content

Commit

Permalink
refactor: use createContext composable in many other components
Browse files Browse the repository at this point in the history
  • Loading branch information
MellKam committed Oct 15, 2023
1 parent b624a69 commit 809e1c7
Show file tree
Hide file tree
Showing 137 changed files with 1,202 additions and 1,256 deletions.
23 changes: 11 additions & 12 deletions packages/radix-vue/src/Accordion/AccordionContent.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
<script setup lang="ts">
import { inject } from 'vue'
import { CollapsibleContent } from '../Collapsible'
import { ACCORDION_ITEM_INJECTION_KEY } from './AccordionItem.vue'
import { ACCORDION_INJECTION_KEY } from './AccordionRoot.vue'
import { injectAccordionItemContext } from './AccordionItem.vue'
import { injectAccordionRootContext } from './AccordionRoot.vue'
import type { PrimitiveProps } from '@/Primitive'
export interface AccordionContentProps extends PrimitiveProps {}
const props = defineProps<AccordionContentProps>()
const injectedRoot = inject(ACCORDION_INJECTION_KEY)
const injectedItem = inject(ACCORDION_ITEM_INJECTION_KEY)
const rootContext = injectAccordionRootContext()
const itemContext = injectAccordionItemContext()
</script>

<template>
<CollapsibleContent
:id="injectedItem?.triggerId"
:id="itemContext.triggerId"
role="region"
:open="injectedItem?.open.value"
:hidden="!injectedItem?.open.value"
:open="itemContext.open.value"
:hidden="!itemContext.open.value"
:as-child="props.asChild"
:aria-labelledby="injectedItem?.triggerId"
:data-state="injectedItem?.dataState.value"
:data-disabled="injectedItem?.dataDisabled.value"
:data-orientation="injectedRoot?.orientation"
:aria-labelledby="itemContext.triggerId"
:data-state="itemContext.dataState.value"
:data-disabled="itemContext.dataDisabled.value"
:data-orientation="rootContext.orientation"
style="
--radix-accordion-content-width: var(--radix-collapsible-content-width);
--radix-accordion-content-height: var(--radix-collapsible-content-height);
Expand Down
15 changes: 7 additions & 8 deletions packages/radix-vue/src/Accordion/AccordionHeader.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
<script setup lang="ts">
import { inject } from 'vue'
import { ACCORDION_ITEM_INJECTION_KEY } from './AccordionItem.vue'
import { ACCORDION_INJECTION_KEY } from './AccordionRoot.vue'
import { injectAccordionItemContext } from './AccordionItem.vue'
import { injectAccordionRootContext } from './AccordionRoot.vue'
import { Primitive, type PrimitiveProps } from '@/Primitive'
export interface AccordionHeaderProps extends PrimitiveProps {}
const props = defineProps<AccordionHeaderProps>()
const injectedRoot = inject(ACCORDION_INJECTION_KEY)
const injectedItem = inject(ACCORDION_ITEM_INJECTION_KEY)
const rootContext = injectAccordionRootContext()
const itemContext = injectAccordionItemContext()
</script>

<template>
<Primitive
:as="props.as || 'h3'"
:as-child="props.asChild"
:data-orientation="injectedRoot?.orientation"
:data-state="injectedItem?.dataState.value"
:data-disabled="injectedItem?.dataDisabled.value"
:data-orientation="rootContext.orientation"
:data-state="itemContext.dataState.value"
:data-disabled="itemContext.dataDisabled.value"
>
<slot />
</Primitive>
Expand Down
40 changes: 20 additions & 20 deletions packages/radix-vue/src/Accordion/AccordionItem.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts" context="module">
import type { ComputedRef, InjectionKey, VNodeRef } from 'vue'
import type { ComputedRef, VNodeRef } from 'vue'
import type { CollapsibleRootProps } from '../Collapsible'
import { ACCORDION_INJECTION_KEY } from './AccordionRoot.vue'
import { injectAccordionRootContext } from './AccordionRoot.vue'
import { createContext, useArrowNavigation, useId } from '@/shared'
enum AccordionItemState {
Open = 'open',
Expand All @@ -23,7 +24,7 @@ export interface AccordionItemProps
value: string
}
interface AccordionItemProvideValue {
interface AccordionItemContext {
open: ComputedRef<boolean>
dataState: ComputedRef<AccordionItemState>
disabled: ComputedRef<boolean>
Expand All @@ -34,32 +35,31 @@ interface AccordionItemProvideValue {
value: ComputedRef<string>
}
export const ACCORDION_ITEM_INJECTION_KEY
= Symbol() as InjectionKey<AccordionItemProvideValue>
export const [injectAccordionItemContext, provideAccordionItemContext]
= createContext<AccordionItemContext>('AccordionItem')
</script>

<script setup lang="ts">
import { CollapsibleRoot } from '@/Collapsible'
import { usePrimitiveElement } from '@/Primitive'
import { useArrowNavigation, useId } from '@/shared'
import { computed, inject, provide } from 'vue'
import { computed } from 'vue'
const props = defineProps<AccordionItemProps>()
const injectedRoot = inject(ACCORDION_INJECTION_KEY)
const rootContext = injectAccordionRootContext()
const open = computed(() =>
injectedRoot?.isSingle.value
? props.value === injectedRoot.modelValue.value
: Array.isArray(injectedRoot?.modelValue.value)
&& !!injectedRoot?.modelValue.value.includes(props.value),
rootContext.isSingle.value
? props.value === rootContext.modelValue.value
: Array.isArray(rootContext.modelValue.value)
&& rootContext.modelValue.value.includes(props.value),
)
const disabled = computed(() => {
return (
injectedRoot?.disabled
rootContext.disabled
|| props.disabled
|| (!!injectedRoot?.isSingle.value && open.value && !injectedRoot?.collapsible)
|| (rootContext.isSingle.value && open.value && !rootContext.collapsible)
)
})
Expand All @@ -71,7 +71,7 @@ const dataState = computed(() =>
const { primitiveElement, currentElement } = usePrimitiveElement()
provide(ACCORDION_ITEM_INJECTION_KEY, {
provideAccordionItemContext({
open,
dataState,
disabled,
Expand All @@ -85,11 +85,11 @@ provide(ACCORDION_ITEM_INJECTION_KEY, {
function handleArrowKey(e: KeyboardEvent) {
useArrowNavigation(
e,
currentElement.value!,
injectedRoot?.parentElement.value!,
currentElement.value,
rootContext.parentElement.value!,
{
arrowKeyOptions: injectedRoot?.orientation,
dir: injectedRoot?.direction,
arrowKeyOptions: rootContext.orientation,
dir: rootContext.direction,
focus: true,
},
)
Expand All @@ -100,7 +100,7 @@ defineExpose({ open })

<template>
<CollapsibleRoot
:data-orientation="injectedRoot?.orientation"
:data-orientation="rootContext.orientation"
:data-disabled="dataDisabled"
:data-state="dataState"
:disabled="disabled"
Expand Down
15 changes: 8 additions & 7 deletions packages/radix-vue/src/Accordion/AccordionRoot.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import type { ComputedRef, InjectionKey, Ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type { DataOrientation, Direction, Type } from '@/shared/types'
import { createContext } from '@/shared'
export interface AccordionRootProps extends PrimitiveProps {
/**
Expand Down Expand Up @@ -53,10 +54,7 @@ export type AccordionRootEmits = {
'update:modelValue': [value: string | string[] | undefined]
}
export const ACCORDION_INJECTION_KEY
= Symbol() as InjectionKey<AccordionProvideValue>
export interface AccordionProvideValue {
export type AccordionRootContext = {
disabled?: AccordionRootProps['disabled']
direction: AccordionRootProps['dir']
orientation: AccordionRootProps['orientation']
Expand All @@ -66,6 +64,9 @@ export interface AccordionProvideValue {
modelValue: Ref<string | undefined | string[]>
collapsible: boolean
}
export const [injectAccordionRootContext, provideAccordionRootContext]
= createContext<AccordionRootContext>('AccordionRoot')
</script>

<script setup lang="ts">
Expand All @@ -75,7 +76,7 @@ import {
usePrimitiveElement,
} from '@/Primitive'
import { useSingleOrMultipleValue } from '@/shared/useSingleOrMultipleValue'
import { computed, provide } from 'vue'
import { computed } from 'vue'
const props = withDefaults(defineProps<AccordionRootProps>(), {
asChild: false,
Expand All @@ -92,7 +93,7 @@ const { modelValue, changeModelValue } = useSingleOrMultipleValue(props, emits)
const { primitiveElement, currentElement: parentElement }
= usePrimitiveElement()
provide<AccordionProvideValue>(ACCORDION_INJECTION_KEY, {
provideAccordionRootContext({
disabled: props.disabled,
direction: props.dir,
orientation: props.orientation,
Expand Down
31 changes: 15 additions & 16 deletions packages/radix-vue/src/Accordion/AccordionTrigger.vue
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
<script setup lang="ts">
import { inject } from 'vue'
import { ACCORDION_ITEM_INJECTION_KEY } from './AccordionItem.vue'
import { ACCORDION_INJECTION_KEY } from './AccordionRoot.vue'
import { injectAccordionItemContext } from './AccordionItem.vue'
import { injectAccordionRootContext } from './AccordionRoot.vue'
import { type PrimitiveProps } from '@/Primitive'
import { CollapsibleTrigger } from '@/Collapsible'
export interface AccordionTriggerProps extends PrimitiveProps {}
const props = defineProps<AccordionTriggerProps>()
const injectedRoot = inject(ACCORDION_INJECTION_KEY)
const injectedItem = inject(ACCORDION_ITEM_INJECTION_KEY)
const rootContext = injectAccordionRootContext()
const itemContext = injectAccordionItemContext()
function changeItem() {
if (injectedItem?.disabled.value)
if (itemContext.disabled.value)
return
injectedItem && injectedRoot?.changeModelValue(injectedItem.value.value)
rootContext.changeModelValue(itemContext.value.value)
}
</script>

<template>
<CollapsibleTrigger
:id="injectedItem?.triggerId"
:ref="injectedItem?.primitiveElement"
:id="itemContext.triggerId"
:ref="itemContext.primitiveElement"
data-radix-vue-collection-item
:as="props.as"
:as-child="props.asChild"
:aria-controls="injectedItem?.triggerId"
:aria-disabled="injectedItem?.disabled.value || undefined"
:aria-expanded="injectedItem?.open.value || false"
:data-disabled="injectedItem?.dataDisabled.value"
:data-orientation="injectedRoot?.orientation"
:data-state="injectedItem?.dataState.value"
:disabled="injectedItem?.disabled?.value"
:aria-controls="itemContext.triggerId"
:aria-disabled="itemContext.disabled.value || undefined"
:aria-expanded="itemContext.open.value || false"
:data-disabled="itemContext.dataDisabled.value"
:data-orientation="rootContext.orientation"
:data-state="itemContext.dataState.value"
:disabled="itemContext.disabled.value"
@click="changeItem"
>
<slot />
Expand Down
8 changes: 4 additions & 4 deletions packages/radix-vue/src/AlertDialog/AlertDialogCancel.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<script setup lang="ts">
import { inject, onMounted } from 'vue'
import { ALERT_DIALOG_CONTENT_INJECTION_KEY } from './AlertDialogContent.vue'
import { onMounted } from 'vue'
import { injectAlertDialogContentContext } from './AlertDialogContent.vue'
import { DialogClose, type DialogCloseProps } from '@/Dialog'
import { usePrimitiveElement } from '@/Primitive'
export interface AlertDialogCancelProps extends DialogCloseProps {}
const props = defineProps<AlertDialogCancelProps>()
const contentContext = inject(ALERT_DIALOG_CONTENT_INJECTION_KEY)
const contentContext = injectAlertDialogContentContext()
const { primitiveElement, currentElement } = usePrimitiveElement()
onMounted(() => {
contentContext!.onCancelElementChange(currentElement.value)
contentContext.onCancelElementChange(currentElement.value)
})
</script>

Expand Down
13 changes: 7 additions & 6 deletions packages/radix-vue/src/AlertDialog/AlertDialogContent.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
<script lang="ts">
interface AlertDialogContentContextValue {
import { createContext, useEmitAsProps } from '@/shared'
interface AlertDialogContentContext {
onCancelElementChange(el: HTMLElement | undefined): void
}
export const ALERT_DIALOG_CONTENT_INJECTION_KEY
= Symbol() as InjectionKey<AlertDialogContentContextValue>
export const [injectAlertDialogContentContext, provideAlertDialogContentContext]
= createContext<AlertDialogContentContext>('AlertDialogContent')
export interface AlertDialogContentProps extends DialogContentProps {}
export type AlertDialogContentEmits = DialogContentEmits
</script>
<script setup lang="ts">
import { type InjectionKey, nextTick, provide, ref } from 'vue'
import { nextTick, ref } from 'vue'
import {
DialogContent,
type DialogContentEmits,
type DialogContentProps,
} from '@/Dialog'
import { useEmitAsProps } from '@/shared'
const props = defineProps<AlertDialogContentProps>()
const emits = defineEmits<AlertDialogContentEmits>()
Expand All @@ -26,7 +27,7 @@ const emitsAsProps = useEmitAsProps(emits)
const cancelElement = ref<HTMLElement | undefined>()
provide(ALERT_DIALOG_CONTENT_INJECTION_KEY, {
provideAlertDialogContentContext({
onCancelElementChange: (el) => {
cancelElement.value = el
},
Expand Down
10 changes: 5 additions & 5 deletions packages/radix-vue/src/Avatar/AvatarFallback.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ export interface AvatarFallbackProps extends PrimitiveProps {
</script>

<script setup lang="ts">
import { inject, ref, watch } from 'vue'
import { ref, watch } from 'vue'
import { Primitive, type PrimitiveProps } from '../Primitive'
import { AVATAR_INJECTION_KEY } from './AvatarRoot.vue'
import { injectAvatarRootContext } from './AvatarRoot.vue'
const props = withDefaults(defineProps<AvatarFallbackProps>(), {
delayMs: 0,
as: 'span',
})
const context = inject(AVATAR_INJECTION_KEY)
const rootContext = injectAvatarRootContext()
const canRender = ref(false)
let timeout: ReturnType<typeof setTimeout> | undefined
watch(() => context?.imageLoadingStatus.value, (value) => {
watch(rootContext.imageLoadingStatus, (value) => {
if (value === 'loading') {
canRender.value = false
if (props.delayMs) {
Expand All @@ -37,7 +37,7 @@ watch(() => context?.imageLoadingStatus.value, (value) => {

<template>
<Primitive
v-if="canRender && context?.imageLoadingStatus.value !== 'loaded'"
v-if="canRender && rootContext.imageLoadingStatus.value !== 'loaded'"
:as-child="props.asChild"
:as="as"
>
Expand Down
8 changes: 4 additions & 4 deletions packages/radix-vue/src/Avatar/AvatarImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ export interface AvatarImageProps extends PrimitiveProps {
</script>

<script setup lang="ts">
import { inject, toRefs, watch } from 'vue'
import { toRefs, watch } from 'vue'
import { Primitive, type PrimitiveProps } from '../Primitive'
import { AVATAR_INJECTION_KEY } from './AvatarRoot.vue'
import { injectAvatarRootContext } from './AvatarRoot.vue'
import { type ImageLoadingStatus, useImageLoadingStatus } from './utils'
const props = withDefaults(defineProps<AvatarImageProps>(), { as: 'img' })
const emits = defineEmits<AvatarImageEmits>()
const { src } = toRefs(props)
const context = inject(AVATAR_INJECTION_KEY)
const rootContext = injectAvatarRootContext()
const imageLoadingStatus = useImageLoadingStatus(src)
Expand All @@ -26,7 +26,7 @@ watch(
(newValue) => {
emits('loadingStatusChange', newValue)
if (newValue !== 'idle')
context!.imageLoadingStatus.value = newValue
rootContext.imageLoadingStatus.value = newValue
},
{ immediate: true },
)
Expand Down
Loading

0 comments on commit 809e1c7

Please sign in to comment.