Skip to content

Commit

Permalink
feat: support slotProps type inference
Browse files Browse the repository at this point in the history
  • Loading branch information
zernonia committed Jan 15, 2025
1 parent 913a7d4 commit 16d3542
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 28 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/Accordion/AccordionRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const emits = defineEmits<AccordionRootEmits<S>>()
defineSlots<{
default: (props: {
/** Current active value */
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleTypeProps<S, T>['modelValue']
}) => any
}>()
Expand Down Expand Up @@ -113,6 +113,6 @@ provideAccordionRootContext({
:as-child="asChild"
:as="as"
>
<slot :model-value="modelValue" />
<slot :model-value="modelValue as any" />
</Primitive>
</template>
6 changes: 3 additions & 3 deletions packages/core/src/Combobox/ComboboxRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Ref } from 'vue'
import type { ListboxRootProps } from '@/Listbox'
import { createContext, useDirection, useFilter } from '@/shared'
import { usePrimitiveElement } from '@/Primitive'
import type { AcceptableValue, GenericComponentInstance } from '@/shared/types'
import type { AcceptableValue, GenericComponentInstance, SingleOrMultipleProps } from '@/shared/types'
type ComboboxRootContext<T> = {
modelValue: Ref<T | Array<T>>
Expand Down Expand Up @@ -76,7 +76,7 @@ defineSlots<{
/** Current open state */
open: typeof open.value
/** Current active value */
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleProps<S, T>['modelValue']
}) => any
}>()
Expand Down Expand Up @@ -239,7 +239,7 @@ provideComboboxRootContext({
>
<slot
:open="open"
:model-value="modelValue"
:model-value="modelValue as any"
/>
</ListboxRoot>
</PopperRoot>
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/Listbox/ListboxRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface ListboxRootProps<S extends boolean = false, T = AcceptableValue
by?: string | ((a: T, b: T) => boolean)
}
export type ListboxRootEmits<S extends boolean = false, T = AcceptableValue> = {
export type ListboxRootEmits<S extends boolean = false, T extends AcceptableValue = AcceptableValue> = {
/** Event handler called when the value changes. */
'update:modelValue': [value: S extends true ? T[] : T]
/** Event handler when highlighted element changes. */
Expand All @@ -79,12 +79,12 @@ const props = withDefaults(defineProps<ListboxRootProps<S, T>>(), {
selectionBehavior: 'toggle',
orientation: 'vertical',
})
const emits = defineEmits<ListboxRootEmits<S>>()
const emits = defineEmits<ListboxRootEmits<S, T>>()
defineSlots<{
default: (props: {
/** Current active value */
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleProps<S, T>['modelValue']
}) => any
}>()
Expand Down Expand Up @@ -392,7 +392,7 @@ provideListboxRootContext({
}
}"
>
<slot :model-value="modelValue" />
<slot :model-value="modelValue as any" />

<VisuallyHiddenInput
v-if="isFormControl && name"
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/Select/SelectRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const emits = defineEmits<SelectRootEmits<S, T>>()
defineSlots<{
default: (props: {
/** Current input values */
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleProps<S, T>['modelValue']
/** Current open state */
open: typeof open.value
}) => any
Expand Down Expand Up @@ -172,7 +172,7 @@ provideSelectRootContext({
<template>
<PopperRoot>
<slot
:model-value="modelValue"
:model-value="modelValue as any"
:open="open"
/>

Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/ToggleGroup/ToggleGroupRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { AcceptableValue, DataOrientation, Direction, FormFieldProps, Singl
import { createContext, useDirection, useFormControl, useForwardExpose } from '@/shared'
import VisuallyHiddenInput from '@/VisuallyHidden/VisuallyHiddenInput.vue'
export interface ToggleGroupRootProps<S extends SingleOrMultipleType = SingleOrMultipleType, T = AcceptableValue | AcceptableValue[]>
export interface ToggleGroupRootProps<S extends SingleOrMultipleType = SingleOrMultipleType, T extends AcceptableValue = AcceptableValue>
extends PrimitiveProps, FormFieldProps, SingleOrMultipleTypeProps<S, T> {
/** When `false`, navigating through the items using arrow keys will be disabled. */
rovingFocus?: boolean
Expand All @@ -18,9 +18,9 @@ export interface ToggleGroupRootProps<S extends SingleOrMultipleType = SingleOrM
/** When `loop` and `rovingFocus` is `true`, keyboard navigation will loop from last item to first, and vice versa. */
loop?: boolean
}
export type ToggleGroupRootEmits<U extends SingleOrMultipleType = SingleOrMultipleType> = {
export type ToggleGroupRootEmits<S extends SingleOrMultipleType = SingleOrMultipleType, T extends AcceptableValue = AcceptableValue> = {
/** Event handler called when the value changes. */
'update:modelValue': [payload: (U extends 'single' ? AcceptableValue : AcceptableValue[]) ]
'update:modelValue': [payload: (S extends 'single' ? T : T[]) ]
}
interface ToggleGroupRootContext {
Expand Down Expand Up @@ -49,12 +49,12 @@ const props = withDefaults(defineProps<ToggleGroupRootProps<S, T>>(), {
rovingFocus: true,
disabled: false,
})
const emits = defineEmits<ToggleGroupRootEmits<S>>()
const emits = defineEmits<ToggleGroupRootEmits<S, T>>()
defineSlots<{
default: (props: {
/** Current toggle values */
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleTypeProps<S, T>['modelValue']
}) => any
}>()
Expand Down Expand Up @@ -91,7 +91,7 @@ provideToggleGroupRootContext({
:as-child="asChild"
:as="as"
>
<slot :model-value="modelValue" />
<slot :model-value="modelValue as any" />

<VisuallyHiddenInput
v-if="isFormControl && name"
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/ToggleGroup/story/ToggleGroup.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ref } from 'vue'
import { ToggleGroupItem, ToggleGroupRoot } from '..'
const toggleStateSingle = ref<string | null>(null)
const toggleStateMultiple = ref<string[] | string | null>('123')
const toggleStateMultiple = ref<string[] | null>(['123'])
const toggleGroupItemClasses
= 'hover:bg-violet3 color-mauve11 data-[state=on]:bg-violet6 data-[state=on]:text-violet12 flex h-[35px] w-[35px] items-center justify-center bg-white text-base leading-4 first:rounded-l last:rounded-r focus:z-10 focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none'
Expand Down Expand Up @@ -54,7 +54,6 @@ const toggleGroupItemClasses
<br>
<ToggleGroupRoot
v-model="toggleStateMultiple"
type="multiple"
class="flex"
>
<ToggleGroupItem
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/Tree/TreeRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createContext, useDirection, useSelectionBehavior, useTypeahead } from
import type { Direction, SingleOrMultipleProps } from '@/shared/types'
import { flatten } from './utils'
export interface TreeRootProps<S extends boolean = false, T = Record<string, any>, U extends Record<string, any> = Record<string, any>> extends PrimitiveProps, SingleOrMultipleProps<S, U> {
export interface TreeRootProps<S extends boolean = false, T extends Record<string, any> = Record<string, any>, U extends Record<string, any> = Record<string, any>> extends PrimitiveProps, SingleOrMultipleProps<S, U> {
/** List of items */
items?: T[]
/** The controlled value of the expanded item. Can be binded with with `v-model`. */
Expand All @@ -24,8 +24,8 @@ export interface TreeRootProps<S extends boolean = false, T = Record<string, any
propagateSelect?: boolean
}
export type TreeRootEmits<S extends boolean = false, T = Record<string, any>> = {
'update:modelValue': [val: S extends false ? T : T[]]
export type TreeRootEmits<S extends boolean = false, U extends Record<string, any> = Record<string, any>> = {
'update:modelValue': [val: S extends false ? U : U[]]
'update:expanded': [val: string[]]
}
Expand Down Expand Up @@ -83,7 +83,7 @@ const emits = defineEmits<TreeRootEmits<S, U>>()
defineSlots<{
default: (props: {
flattenItems: FlattenedItem<T>[]
modelValue: typeof modelValue.value
modelValue: SingleOrMultipleProps<S, U>['modelValue']
expanded: typeof expanded.value
}) => any
}>()
Expand Down Expand Up @@ -245,7 +245,7 @@ provideTreeRootContext({
>
<slot
:flatten-items="expandedItems"
:model-value="modelValue"
:model-value="modelValue as any"
:expanded="expanded"
/>
</Primitive>
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ interface SingleOrMultipleTypeProps<U extends SingleOrMultipleType = SingleOrMul
*
* Use this when you need to control the state of the items. Can be binded with `v-model`
*/
modelValue?: ValueType<U, T>
modelValue?: ValueType<U, T> | null

/**
* The default active value of the item(s).
*
* Use when you do not need to control the state of the item(s).
*/
defaultValue?: ValueType<U, T>
defaultValue?: ValueType<U, T> | null
}

interface SingleOrMultipleProps<S extends boolean = boolean, T = any> {
Expand All @@ -44,14 +44,14 @@ interface SingleOrMultipleProps<S extends boolean = boolean, T = any> {
*
* Use this when you need to control the state of the items. Can be binded with `v-model`
*/
modelValue?: ValueType2<S, T>
modelValue?: ValueType2<S, T> | null

/**
* The default active value of the item(s).
*
* Use when you do not need to control the state of the item(s).
*/
defaultValue?: ValueType2<S, T>
defaultValue?: ValueType2<S, T> | null
}

/**
Expand Down

0 comments on commit 16d3542

Please sign in to comment.