} from '@vue/runtime-dom'
import { type Block, isBlock } from './block'
import { pauseTracking, resetTracking } from '@vue/reactivity'
-import { EMPTY_OBJ, isFunction } from '@vue/shared'
+import { EMPTY_OBJ, isFunction, isString } from '@vue/shared'
import {
type RawProps,
getPropsProxyHandlers,
hasFallthroughAttrs,
normalizePropsOptions,
+ resolveDynamicProps,
setupPropsValidation,
} from './componentProps'
-import { setDynamicProp } from './dom/prop'
import { renderEffect } from './renderEffect'
import { emit, normalizeEmitsOptions } from './componentEmits'
+import { setStyle } from './dom/style'
+import { setClass, setDynamicProp } from './dom/prop'
export { currentInstance } from '@vue/runtime-dom'
export class SetupContext<E = EmitsOptions> {
attrs: Record<string, any>
emit: EmitFn<E>
- // slots: Readonly<StaticSlots>
+ // TODO slots: Readonly<StaticSlots>
expose: (exposed?: Record<string, any>) => void
constructor(instance: VaporComponentInstance) {
}
}
}
+
+export function createComponentWithFallback(
+ comp: VaporComponent | string,
+ rawProps: RawProps | undefined,
+ // TODO slots: RawSlots | null
+ isSingleRoot?: boolean,
+): HTMLElement | VaporComponentInstance {
+ if (!isString(comp)) {
+ return createComponent(comp, rawProps, isSingleRoot)
+ }
+
+ // eslint-disable-next-line no-restricted-globals
+ const el = document.createElement(comp)
+
+ if (rawProps) {
+ renderEffect(() => {
+ let classes: unknown[] | undefined
+ let styles: unknown[] | undefined
+ const resolved = resolveDynamicProps(rawProps)
+ for (const key in resolved) {
+ const value = resolved[key]
+ if (key === 'class') (classes ||= []).push(value)
+ else if (key === 'style') (styles ||= []).push(value)
+ else setDynamicProp(el, key, value)
+ }
+ if (classes) setClass(el, classes)
+ if (styles) setStyle(el, styles)
+ })
+ }
+
+ // TODO
+ // if (slots) {
+ // if (!Array.isArray(slots)) slots = [slots]
+ // for (let i = 0; i < slots.length; i++) {
+ // const slot = slots[i]
+ // if (!isDynamicSlotFn(slot) && slot.default) {
+ // const block = slot.default && slot.default()
+ // if (block) el.append(...normalizeBlock(block))
+ // }
+ // }
+ // }
+
+ return el
+}
const rawProps = instance.rawProps
if (!rawProps) return
renderEffect(() => {
- const mergedRawProps: Record<string, any> = {}
- for (const key in rawProps) {
- if (key !== '$') {
- mergedRawProps[key] = rawProps[key]()
- }
- }
- if (rawProps.$) {
- for (const source of rawProps.$) {
- const isDynamic = isFunction(source)
- const resolved = isDynamic ? source() : source
- for (const key in resolved) {
- mergedRawProps[key] = isDynamic
- ? resolved[key]
- : (resolved[key] as Function)()
- }
- }
- }
pushWarningContext(instance)
validateProps(
- mergedRawProps,
+ resolveDynamicProps(rawProps),
instance.props,
normalizePropsOptions(instance.type)[0]!,
)
popWarningContext()
}, true /* noLifecycle */)
}
+
+export function resolveDynamicProps(props: RawProps): Record<string, unknown> {
+ const mergedRawProps: Record<string, any> = {}
+ for (const key in props) {
+ if (key !== '$') {
+ mergedRawProps[key] = props[key]()
+ }
+ }
+ if (props.$) {
+ for (const source of props.$) {
+ const isDynamic = isFunction(source)
+ const resolved = isDynamic ? source() : source
+ for (const key in resolved) {
+ mergedRawProps[key] = isDynamic
+ ? resolved[key]
+ : (resolved[key] as Function)()
+ }
+ }
+ }
+ return mergedRawProps
+}
-export { createComponent } from './component'
+export { createComponent, createComponentWithFallback } from './component'
export { renderEffect } from './renderEffect'
export { createVaporApp } from './apiCreateApp'
export { defineComponent } from './apiDefineComponent'
} from './dom/prop'
export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event'
export { setRef } from './dom/templateRef'
+
+// re-exports
+export { resolveComponent } from '@vue/runtime-dom'