Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the usage of ref #80

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions packages/components/aspect-ratio/src/aspect-ratio.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { defineComponent, h, ref } from 'vue'
import { defineComponent, h, onMounted, ref } from 'vue'
import type { ComponentPropsWithoutRef, ElementRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'

type PrimitiveAspectRatioProps = ComponentPropsWithoutRef<typeof Primitive.div>
type AspectRatioElement = ElementRef<typeof Primitive.div>
type AspectRatioElement = ElementRef<typeof Primitive.div> & { innerRef: AspectRatioElement }

interface AspectRatioProps extends PrimitiveAspectRatioProps {
ratio?: number
Expand All @@ -16,10 +16,14 @@ const AspectRatio = defineComponent<AspectRatioProps, { hello: string }>({
setup(props, { attrs, slots, expose }) {
// TODO: as any how to fix?
const { ratio = 1 / 1, style, ...aspectRatioProps } = attrs as any
const inferRef = ref<AspectRatioElement>()
const innerRef = ref<AspectRatioElement>()

onMounted(() => {
innerRef.value = innerRef.value?.innerRef
})

expose({
inferRef,
innerRef,
})

return () => h(
Expand All @@ -36,7 +40,7 @@ const AspectRatio = defineComponent<AspectRatioProps, { hello: string }>({
Primitive.div,
{
...aspectRatioProps,
ref: inferRef,
ref: innerRef,
style: {
...style,
position: 'absolute',
Expand Down
14 changes: 11 additions & 3 deletions packages/components/avatar/src/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type AvatarProvideValue = {

const [AvatarProvider, useAvatarInject] = createAvatarProvide<AvatarProvideValue>(AVATAR_NAME)

type AvatarElement = ComponentPropsWithoutRef<typeof Primitive.span>
type AvatarElement = ComponentPropsWithoutRef<typeof Primitive.span> & { innerRef: AvatarElement }
type PrimitiveSpanProps = ComponentPropsWithoutRef<typeof Primitive.span>
interface AvatarProps extends PrimitiveSpanProps {}

Expand All @@ -74,6 +74,10 @@ const Avatar = defineComponent<ScopedProps<AvatarProps>>({
},
})

onMounted(() => {
innerRef.value = innerRef.value?.innerRef
})

expose({
innerRef,
})
Expand All @@ -94,7 +98,7 @@ const Avatar = defineComponent<ScopedProps<AvatarProps>>({

const IMAGE_NAME = 'AvatarImage'

type AvatarImageElement = ComponentPropsWithoutRef<typeof Primitive.img>
type AvatarImageElement = ComponentPropsWithoutRef<typeof Primitive.img> & { innerRef: AvatarImageElement }
type PrimitiveImgProps = ComponentPropsWithoutRef<typeof Primitive.img>
interface AvatarImageProps extends PrimitiveImgProps {
onLoadingStatusChange?: (status: ImageLoadingStatus) => void
Expand All @@ -115,6 +119,8 @@ const AvatarImage = defineComponent<ScopedProps<AvatarImageProps>>({
})

onMounted(() => {
innerRef.value = innerRef.value?.innerRef

if (imageLoadingStatus.value !== 'idle')
handleLoadingStatusChange(imageLoadingStatus.value)
})
Expand Down Expand Up @@ -148,7 +154,7 @@ const AvatarImage = defineComponent<ScopedProps<AvatarImageProps>>({
const FALLBACK_NAME = 'AvatarFallback'

type PrimitiveAvatarFallbackProps = ComponentPropsWithoutRef<typeof Primitive.span>
type PrimitiveSpanElement = ComponentPropsWithoutRef<typeof Primitive.span>
type PrimitiveSpanElement = ComponentPropsWithoutRef<typeof Primitive.span> & { innerRef: PrimitiveSpanElement }
interface AvatarFallbackProps extends PrimitiveAvatarFallbackProps, PrimitiveSpanProps {
delayms?: number
}
Expand All @@ -163,6 +169,8 @@ const AvatarFallback = defineComponent<ScopedProps<AvatarFallbackProps>>({
const innerRef = ref<PrimitiveSpanElement>()

onMounted(() => {
innerRef.value = innerRef.value?.innerRef

if (delayms === undefined)
canRender.value = true
else
Expand Down
13 changes: 8 additions & 5 deletions packages/components/label/src/label.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
import { defineComponent, h, ref } from 'vue'
import { defineComponent, h, onMounted, ref } from 'vue'
import type { ComponentPropsWithoutRef, ElementRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'

type PrimitiveLabelProps = ComponentPropsWithoutRef<typeof Primitive.label>

interface LabelProps extends PrimitiveLabelProps { }
type LabelElement = ElementRef<typeof Primitive.label>
type LabelElement = ElementRef<typeof Primitive.label> & { innerRef: LabelElement }

const NAME = 'Label'

const label = defineComponent<LabelProps>({
name: NAME,
inheritAttrs: false,
setup(props, { attrs, slots, expose }) {
const inferRef = ref<LabelElement>()
const innerRef = ref<LabelElement>()
onMounted(() => {
innerRef.value = innerRef.value?.innerRef
})

expose({
inferRef,
innerRef,
})

return () => h(Primitive.label, {
...attrs,
ref: inferRef,
ref: innerRef,
onMousedown: (event: MouseEvent) => {
props.onMousedown?.(event)
// prevent text selection when double clicking label
Expand Down
11 changes: 8 additions & 3 deletions packages/core/primitive/src/primitive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefineComponent, FunctionalComponent, IntrinsicElementAttributes, VNodeRef } from 'vue'
import { defineComponent, h, onMounted } from 'vue'
import { defineComponent, h, onMounted, ref } from 'vue'

/* -------------------------------------------------------------------------------------------------
* Primitive
Expand Down Expand Up @@ -80,16 +80,21 @@ type ElementRef<T extends keyof JSX.IntrinsicElements | ElementConstructor<any>>
interface PrimitiveDefineComponent<E extends ElementType> extends DefineComponent<PrimitivePropsWithRef<E>> {}

const Primitive = NODES.reduce((primitive, node) => {
const innerRef = ref<HTMLElement>()
const Node = defineComponent<PrimitivePropsWithRef<typeof node>>({
name: `Primitive${node}`,
inheritAttrs: false,
setup(props, { attrs, slots }) {
setup(props, { attrs, slots, expose }) {
expose({
innerRef,
})

onMounted(() => {
(window as any)[Symbol.for('okui-vue')] = true
})
const Tag: any = props.asChild ? 'slot' : node

return () => h(Tag, attrs, slots.default && slots.default())
return () => h(Tag, { ...attrs, ref: innerRef }, slots.default && slots.default())
},
})
return { ...primitive, [node]: Node }
Expand Down