import { emit, normalizeEmitsOptions } from './componentEmits'
import { setStyle } from './dom/style'
import { setClass, setDynamicProp } from './dom/prop'
+import {
+ type RawSlots,
+ type Slot,
+ getSlotsProxyHandlers,
+} from './componentSlots'
export { currentInstance } from '@vue/runtime-dom'
block: Block
scope: EffectScope
- rawProps: RawProps | undefined
+ rawProps: RawProps
props: Record<string, any>
attrs: Record<string, any>
+ slots: Record<string, Slot>
exposed: Record<string, any> | null
emitted: Record<string, boolean> | null
propsOptions?: NormalizedPropsOptions
emitsOptions?: ObjectEmitsOptions | null
- constructor(comp: VaporComponent, rawProps?: RawProps) {
+ constructor(comp: VaporComponent, rawProps?: RawProps, rawSlots?: RawSlots) {
this.vapor = true
this.uid = nextUid()
this.type = comp
false
// init props
- const target = rawProps || EMPTY_OBJ
- const handlers = getPropsProxyHandlers(comp, this)
- this.rawProps = rawProps
- this.props = comp.props ? new Proxy(target, handlers[0]!) : {}
- this.attrs = new Proxy(target, handlers[1])
+ this.rawProps = rawProps || EMPTY_OBJ
this.hasFallthrough = hasFallthroughAttrs(comp, rawProps)
+ if (rawProps || comp.props) {
+ const [propsHandlers, attrsHandlers] = getPropsProxyHandlers(comp)
+ this.props = comp.props ? new Proxy(this, propsHandlers!) : {}
+ this.attrs = new Proxy(this, attrsHandlers)
+ } else {
+ this.props = this.attrs = EMPTY_OBJ
+ }
+
+ // init slots
+ this.slots = rawSlots
+ ? new Proxy(rawSlots, getSlotsProxyHandlers(comp))
+ : EMPTY_OBJ
if (__DEV__) {
// validate props
}
}
+/**
+ * Used when a component cannot be resolved at compile time
+ * and needs rely on runtime resolution - where it might fallback to a plain
+ * element if the resolution fails.
+ */
export function createComponentWithFallback(
comp: VaporComponent | string,
rawProps: RawProps | undefined,
import { renderEffect } from './renderEffect'
export type RawProps = Record<string, () => unknown> & {
+ // generated by compiler for :[key]="x" or v-bind="x"
$?: DynamicPropsSource[]
}
return isFunction(source) ? source() : source
}
-const passThrough = (val: any) => val
-
export function getPropsProxyHandlers(
comp: VaporComponent,
- instance: VaporComponentInstance,
-): [ProxyHandler<RawProps> | null, ProxyHandler<RawProps>] {
+): [
+ ProxyHandler<VaporComponentInstance> | null,
+ ProxyHandler<VaporComponentInstance>,
+] {
if (comp.__propsHandlers) {
return comp.__propsHandlers
}
key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
: YES
- const castProp = propsOptions
- ? (value: any, key: string, isAbsent = false) =>
- resolvePropValue(
- propsOptions,
- key as string,
- value,
- instance,
- resolveDefault,
- isAbsent,
- )
- : passThrough
-
- const getProp = (target: RawProps, key: string) => {
+ const getProp = (instance: VaporComponentInstance, key: string) => {
if (key === '$' || !isProp(key)) {
return
}
- const dynamicSources = target.$
+ const rawProps = instance.rawProps
+ const dynamicSources = rawProps.$
if (dynamicSources) {
let i = dynamicSources.length
let source, isDynamic, rawKey
source = isDynamic ? (source as Function)() : source
for (rawKey in source) {
if (camelize(rawKey) === key) {
- return castProp(isDynamic ? source[rawKey] : source[rawKey](), key)
+ return resolvePropValue(
+ propsOptions!,
+ key,
+ isDynamic ? source[rawKey] : source[rawKey](),
+ instance,
+ resolveDefault,
+ )
}
}
}
}
- for (const rawKey in target) {
+ for (const rawKey in rawProps) {
if (camelize(rawKey) === key) {
- return castProp(target[rawKey](), key)
+ return resolvePropValue(
+ propsOptions!,
+ key,
+ rawProps[rawKey](),
+ instance,
+ resolveDefault,
+ )
}
}
- return castProp(undefined, key, true)
+ return resolvePropValue(
+ propsOptions!,
+ key,
+ undefined,
+ instance,
+ resolveDefault,
+ )
}
const propsHandlers = propsOptions
ownKeys: () => Object.keys(propsOptions),
set: NO,
deleteProperty: NO,
- } satisfies ProxyHandler<RawProps>)
+ } satisfies ProxyHandler<VaporComponentInstance>)
: null
const getAttr = (target: RawProps, key: string) => {
}
const attrsHandlers = {
- get: (target, key: string) => {
- return getAttr(target, key)
- },
- has: hasAttr,
+ get: (target, key: string) => getAttr(target.rawProps, key),
+ has: (target, key: string) => hasAttr(target.rawProps, key),
getOwnPropertyDescriptor(target, key: string) {
- if (hasAttr(target, key)) {
+ if (hasAttr(target.rawProps, key)) {
return {
configurable: true,
enumerable: true,
- get: () => getAttr(target, key),
+ get: () => getAttr(target.rawProps, key),
}
}
},
ownKeys(target) {
+ const rawProps = target.rawProps
const keys: string[] = []
- for (const key in target) {
+ for (const key in rawProps) {
if (isAttr(key)) keys.push(key)
}
- const dynamicSources = target.$
+ const dynamicSources = rawProps.$
if (dynamicSources) {
let i = dynamicSources.length
let source
},
set: NO,
deleteProperty: NO,
- } satisfies ProxyHandler<RawProps>
+ } satisfies ProxyHandler<VaporComponentInstance>
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
}