Skip to content

Commit

Permalink
fix: optimize expose (#84)
Browse files Browse the repository at this point in the history
* fix: expose components

* fix: primitive  slots

* fix: provide ts

* fix: general

* fix: seperator component
  • Loading branch information
productdevbook authored May 4, 2023
1 parent a74e05a commit 0d3aabf
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 71 deletions.
21 changes: 13 additions & 8 deletions packages/components/aspect-ratio/src/aspect-ratio.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineComponent, h, ref } from 'vue'
import type { ComponentPublicInstance } from 'vue'
import { computed, defineComponent, h, ref } from 'vue'
import type { ComponentPropsWithoutRef, ElementRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'

Expand All @@ -10,19 +11,19 @@ interface AspectRatioProps extends PrimitiveAspectRatioProps {
}
const NAME = 'AspectRatio'

const AspectRatio = defineComponent<AspectRatioProps, { hello: string }>({
const AspectRatio = defineComponent({
name: NAME,
inheritAttrs: false,
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<ComponentPublicInstance>()

expose({
inferRef,
innerRef: computed(() => innerRef.value?.$el),
})

return () => h(
const originalReturn = () => h(
'div', {
'style': {
position: 'relative',
Expand All @@ -36,7 +37,7 @@ const AspectRatio = defineComponent<AspectRatioProps, { hello: string }>({
Primitive.div,
{
...aspectRatioProps,
ref: inferRef,
ref: innerRef,
style: {
...style,
position: 'absolute',
Expand All @@ -50,10 +51,14 @@ const AspectRatio = defineComponent<AspectRatioProps, { hello: string }>({
),
],
)

return originalReturn as unknown as {
innerRef: AspectRatioElement
}
},
})

const OkuAspectRatio = AspectRatio
const OkuAspectRatio = AspectRatio as typeof AspectRatio & (new () => { $props: AspectRatioProps })

export { OkuAspectRatio, AspectRatio }
export { OkuAspectRatio }
export type { AspectRatioProps }
1 change: 0 additions & 1 deletion packages/components/aspect-ratio/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export {
AspectRatio,
OkuAspectRatio,
} from './aspect-ratio'
export type { AspectRatioProps } from './aspect-ratio'
49 changes: 30 additions & 19 deletions packages/components/avatar/src/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable vue/one-component-per-file */
import { defineComponent, h, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import type { ComponentPublicInstance } from 'vue'
import { computed, defineComponent, h, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import type { ComponentPropsWithoutRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'
import type { Scope } from '@oku-ui/provide'
Expand Down Expand Up @@ -58,12 +59,12 @@ type AvatarElement = ComponentPropsWithoutRef<typeof Primitive.span>
type PrimitiveSpanProps = ComponentPropsWithoutRef<typeof Primitive.span>
interface AvatarProps extends PrimitiveSpanProps {}

const Avatar = defineComponent<ScopedProps<AvatarProps>>({
const Avatar = defineComponent({
name: AVATAR_NAME,
inheritAttrs: false,
setup(props, { attrs, slots, expose }) {
const { __scopeAvatar, ...avatarProps } = attrs as any
const innerRef = ref<AvatarElement>()
const { __scopeAvatar, ...avatarProps } = attrs as ScopedProps<AvatarProps>
const innerRef = ref()
const imageLoadingStatus = ref<ImageLoadingStatus>('idle')

AvatarProvider({
Expand All @@ -75,16 +76,19 @@ const Avatar = defineComponent<ScopedProps<AvatarProps>>({
})

expose({
innerRef,
inferRef: computed(() => innerRef.value?.$el),
})

return () => h(
const originalReturn = () => h(
Primitive.span, {
...avatarProps,
ref: innerRef,
},
slots.default && slots.default(),
)
return originalReturn as unknown as {
innerRef: AvatarElement
}
},
})

Expand All @@ -100,13 +104,13 @@ interface AvatarImageProps extends PrimitiveImgProps {
onLoadingStatusChange?: (status: ImageLoadingStatus) => void
}

const AvatarImage = defineComponent<ScopedProps<AvatarImageProps>>({
const AvatarImage = defineComponent({
name: IMAGE_NAME,
inheritAttrs: false,
setup(props, { attrs, slots, expose }) {
const { __scopeAvatar, src, onLoadingStatusChange = () => {}, ...imageProps } = attrs as any
const { __scopeAvatar, src, onLoadingStatusChange = () => {}, ...imageProps } = attrs as ScopedProps<AvatarImageProps>
const inject = useAvatarInject(IMAGE_NAME, __scopeAvatar)
const innerRef = ref<AvatarImageElement>()
const innerRef = ref<ComponentPublicInstance>()
const imageLoadingStatus = useImageLoadingStatus(src)

const handleLoadingStatusChange = useCallbackRef((status: ImageLoadingStatus) => {
Expand All @@ -125,10 +129,10 @@ const AvatarImage = defineComponent<ScopedProps<AvatarImageProps>>({
})

expose({
innerRef,
innerRef: computed(() => innerRef.value?.$el),
})

return () => imageLoadingStatus.value === 'loaded'
const originalReturn = () => imageLoadingStatus.value === 'loaded'
? h(
Primitive.img, {
...imageProps,
Expand All @@ -138,6 +142,10 @@ const AvatarImage = defineComponent<ScopedProps<AvatarImageProps>>({
slots.default && slots.default(),
)
: null

return originalReturn as unknown as {
innerRef: AvatarImageElement
}
},
})

Expand All @@ -152,15 +160,14 @@ type PrimitiveSpanElement = ComponentPropsWithoutRef<typeof Primitive.span>
interface AvatarFallbackProps extends PrimitiveAvatarFallbackProps, PrimitiveSpanProps {
delayms?: number
}

const AvatarFallback = defineComponent<ScopedProps<AvatarFallbackProps>>({
const AvatarFallback = defineComponent({
name: FALLBACK_NAME,
inheritAttrs: false,
setup(props, { attrs, expose, slots }) {
const { __scopeAvatar, delayms, ...fallbackProps } = attrs as any
const provide = useAvatarInject(FALLBACK_NAME, __scopeAvatar)
const canRender = ref(delayms === undefined)
const innerRef = ref<PrimitiveSpanElement>()
const innerRef = ref<ComponentPublicInstance>()

onMounted(() => {
if (delayms === undefined)
Expand All @@ -179,10 +186,10 @@ const AvatarFallback = defineComponent<ScopedProps<AvatarFallbackProps>>({
})

expose({
innerRef,
innerRef: computed(() => innerRef.value?.$el),
})

return () => {
const originalReturn = () => {
return (canRender.value && (provide.value.imageLoadingStatus !== 'loaded'))
? h(
Primitive.span, {
Expand All @@ -193,14 +200,18 @@ const AvatarFallback = defineComponent<ScopedProps<AvatarFallbackProps>>({
)
: canRender.value
}

return originalReturn as unknown as {
innerRef: PrimitiveSpanElement
}
},
})

/* ----------------------------------------------------------------------------------------------- */

const OkuAvatar = Avatar
const OkuAvatarImage = AvatarImage
const OkuAvatarFallback = AvatarFallback
const OkuAvatar = Avatar as typeof Avatar & (new () => { $props: ScopedProps<AvatarProps> })
const OkuAvatarImage = AvatarImage as typeof AvatarImage & (new () => { $props: ScopedProps<AvatarImageProps> })
const OkuAvatarFallback = AvatarFallback as typeof AvatarFallback & (new () => { $props: ScopedProps<AvatarFallbackProps> })

export {
OkuAvatar,
Expand Down
1 change: 0 additions & 1 deletion packages/components/label/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export {
OkuLabel,
label,
} from './label'
export type { LabelProps } from './label'
24 changes: 14 additions & 10 deletions packages/components/label/src/label.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineComponent, h, ref } from 'vue'
import { computed, defineComponent, h, ref } from 'vue'
import type { ComponentPropsWithoutRef, ElementRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'

Expand All @@ -9,32 +9,36 @@ type LabelElement = ElementRef<typeof Primitive.label>

const NAME = 'Label'

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

expose({
inferRef,
innerRef: computed(() => innerRef.value?.$el),
})

return () => h(Primitive.label, {
...attrs,
ref: inferRef,
const originalReturn = () => h(Primitive.label, {
...restAttrs,
ref: innerRef,
onMousedown: (event: MouseEvent) => {
props.onMousedown?.(event)
restAttrs.onMousedown?.(event)
// prevent text selection when double clicking label
if (!event.defaultPrevented && event.detail > 1)
event.preventDefault()
},
},
slots.default?.(),
)
return originalReturn as unknown as {
innerRef: LabelElement
}
},
})

const OkuLabel = label
const OkuLabel = label as typeof label & (new () => { $props: LabelProps })

export { OkuLabel, label }
export { OkuLabel }
export type { LabelProps }
1 change: 0 additions & 1 deletion packages/components/separator/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export {
OkuSeparator,
Separator,
} from './separator'
export type { SeparatorProps } from './separator'
29 changes: 14 additions & 15 deletions packages/components/separator/src/separator.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { defineComponent, h, ref } from 'vue'
import type { ComponentPublicInstance } from 'vue'
import { computed, defineComponent, h, ref } from 'vue'
import type { ComponentPropsWithoutRef, ElementRef } from '@oku-ui/primitive'
import { Primitive } from '@oku-ui/primitive'

type PrimitiveSeparatorProps = ComponentPropsWithoutRef<typeof Primitive.div>

// interface SeparatorProps extends PrimitiveSeparatorProps {}
// type SeparatorElement = ElementRef<typeof Primitive.div>

const NAME = 'Separator'
const DEFAULT_ORIENTATION = 'horizontal'
const ORIENTATIONS = ['horizontal', 'vertical'] as const
Expand All @@ -23,46 +21,47 @@ interface SeparatorProps extends PrimitiveSeparatorProps {
* are updated so that that the rendered element is removed from the accessibility tree.
*/
decorative?: boolean
// height?: string
// width?: string
}

const Separator = defineComponent<SeparatorProps>({
name: NAME,
inheritAttrs: false,
setup(props, { attrs, slots, expose }) {
const { decorative, orientation: orientationProp = DEFAULT_ORIENTATION, style } = attrs as any

const { decorative, orientation: orientationProp = DEFAULT_ORIENTATION, ...domProps } = attrs as SeparatorProps
const orientation = ORIENTATIONS.includes(orientationProp) ? orientationProp : DEFAULT_ORIENTATION
// `aria-orientation` defaults to `horizontal` so we only need it if `orientation` is vertical
const ariaOrientation = orientation === 'vertical' ? orientation : undefined
const semanticProps = decorative ? { role: 'none' } : { 'aria-orientation': ariaOrientation, 'role': 'separator' }

const inferRef = ref<SeparatorElement>()
const innerRef = ref<ComponentPublicInstance>()

expose({
inferRef,
innerRef: computed(() => innerRef.value?.$el),
})

return () =>
const originalReturn = () =>
h(
Primitive.div,
{
...attrs,
ref: inferRef,
ref: innerRef,
...semanticProps,
dataOrientation: orientation,
style: {
...style,
...domProps,
border: 'none',
},
},
slots.default?.(),
)

return originalReturn as unknown as {
innerRef: SeparatorElement
}
},
})

const OkuSeparator = Separator
const OkuSeparator = Separator as typeof Separator & (new () => { $props: SeparatorProps })

export { OkuSeparator, Separator }
export { OkuSeparator }
export type { SeparatorProps }
4 changes: 2 additions & 2 deletions packages/core/primitive/src/primitive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ const Primitive = NODES.reduce((primitive, node) => {
inheritAttrs: false,
setup(props, { attrs, slots }) {
onMounted(() => {
(window as any)[Symbol.for('okui-vue')] = true
(window as any)[Symbol.for('oku-ui')] = true
})
const Tag: any = props.asChild ? 'slot' : node

return () => h(Tag, attrs, slots.default && slots.default())
return () => props.asChild ? slots.default?.() : h(Tag, { ...attrs }, slots.default?.())
},
})
return { ...primitive, [node]: Node }
Expand Down
Loading

0 comments on commit 0d3aabf

Please sign in to comment.