return [
NEWLINE,
- // @ts-expect-error
...genCall(helper('withVaporDirectives'), element, directives),
]
--- /dev/null
+import type { DirectiveModifiers } from '@vue/runtime-dom'
+import type { VaporComponentInstance } from '../component'
+import { renderEffect } from '../renderEffect'
+
+// !! vapor directive is different from vdom directives
+export type VaporDirective = (
+ node: Element | VaporComponentInstance,
+ value?: () => any,
+ argument?: string,
+ modifiers?: DirectiveModifiers,
+) => (() => void) | void
+
+type DirectiveArguments = Array<
+ | [VaporDirective | undefined]
+ | [VaporDirective | undefined, () => any]
+ | [VaporDirective | undefined, () => any, argument: string]
+ | [
+ VaporDirective | undefined,
+ value: () => any,
+ argument: string,
+ modifiers: DirectiveModifiers,
+ ]
+>
+
+export function withVaporDirectives(
+ node: Element | VaporComponentInstance,
+ dirs: DirectiveArguments,
+): void {
+ // TODO handle custom directive on component
+ for (const [dir, value, argument, modifiers] of dirs) {
+ if (dir) {
+ const ret = dir(node, value, argument, modifiers)
+ if (ret) renderEffect(ret)
+ }
+ }
+}
import {
+ currentInstance,
onMounted,
vModelCheckboxInit,
vModelCheckboxUpdate,
modifiers?: { [key in Modifiers]?: true },
) => void
+function ensureMounted(cb: () => void) {
+ if (currentInstance!.isMounted) {
+ cb()
+ } else {
+ onMounted(cb)
+ }
+}
+
export const applyTextModel: VaporModelDirective<
HTMLInputElement | HTMLTextAreaElement,
'trim' | 'number' | 'lazy'
> = (el, get, set, { trim, number, lazy } = {}) => {
vModelTextInit(el, trim, number, lazy, set)
- onMounted(() => {
+ ensureMounted(() => {
let value: any
renderEffect(() => {
vModelTextUpdate(el, value, (value = get()), trim, number, lazy)
set,
) => {
vModelCheckboxInit(el, set)
- onMounted(() => {
+ ensureMounted(() => {
let value: any
renderEffect(() => {
vModelCheckboxUpdate(
set,
) => {
addEventListener(el, 'change', () => set(vModelGetValue(el)))
- onMounted(() => {
+ ensureMounted(() => {
let value: any
renderEffect(() => {
if (value !== (value = get())) {
'number'
> = (el, get, set, modifiers) => {
vModelSelectInit(el, get(), modifiers && modifiers.number, set)
- onMounted(() => {
+ ensureMounted(() => {
renderEffect(() => vModelSetSelected(el, traverse(get())))
})
}
export { createVaporApp } from './apiCreateApp'
export { defineVaporComponent } from './apiDefineComponent'
export { vaporInteropPlugin } from './vdomInterop'
+export type { VaporDirective } from './directives/custom'
// compiler-use only
export { insert, prepend, remove } from './block'
applySelectModel,
applyDynamicModel,
} from './directives/vModel'
+export { withVaporDirectives } from './directives/custom'