0.0.3: Exotic Type Gymnastics #3
|
@ -8,7 +8,9 @@
|
|||
"build": "tsc && rollup -c && npm run cleanup-intermediate",
|
||||
"prepare": "npm run build",
|
||||
"cleanup-intermediate": "rimraf dist/main.js dist/types",
|
||||
"quality-check": "biome ci ."
|
||||
"quality-check": "biome ci .",
|
||||
"qc": "npm run quality-check",
|
||||
"lint": "biome format . --write"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
32
src/main.ts
32
src/main.ts
|
@ -156,7 +156,6 @@ export default (options: ComponentOptions) => {
|
|||
setupArrowFunctionHandler: this._setupArrowFunctionHandler.bind(this),
|
||||
setupFunctionCallHandler: this._setupFunctionCallHandler.bind(this),
|
||||
setupExpressionHandler: this._setupExpressionHandler.bind(this),
|
||||
setupTwoWayBinding: this._setupTwoWayBinding.bind(this),
|
||||
setupConditionRendering: this._setupConditionRendering.bind(this),
|
||||
setupListRendering: this._setupListRendering.bind(this),
|
||||
stateToElementsMap: this._stateToElementsMap,
|
||||
|
@ -168,6 +167,7 @@ export default (options: ComponentOptions) => {
|
|||
typeof (this as Record<string, unknown>)[name] === 'function' &&
|
||||
name !== 'constructor',
|
||||
),
|
||||
stateListeners: this._statesListeners,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -200,36 +200,6 @@ export default (options: ComponentOptions) => {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle two-way data binding (%connect macro)
|
||||
private _setupTwoWayBinding(element: Element, expr: string) {
|
||||
// Get the initial value
|
||||
const value = this._getNestedState(expr)
|
||||
|
||||
// Set the initial value
|
||||
if (value !== undefined)
|
||||
element.setAttribute('data-laterano-connect', String(value))
|
||||
else
|
||||
console.error(
|
||||
`State \`${expr}\` not found in the component state. Although Laterano will try to work with it, it may has potentially unexpected behavior.`,
|
||||
)
|
||||
|
||||
// Add event listener for input events
|
||||
element.addEventListener('input', (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
const newValue = target.value
|
||||
|
||||
// Update the state
|
||||
this.setState(expr, newValue)
|
||||
})
|
||||
|
||||
// Add event listener for state changes
|
||||
this._statesListeners[expr] = (newValue: unknown) => {
|
||||
if (element instanceof HTMLInputElement)
|
||||
element.value = newValue as string
|
||||
else element.setAttribute('data-laterano-connect', String(newValue))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle condition rendering (%if macro)
|
||||
private _setupConditionRendering(element: Element, expr: string) {
|
||||
const placeholder = document.createComment(` %if: ${expr} `)
|
||||
|
|
|
@ -24,7 +24,6 @@ export default function processTemplateMacros(
|
|||
eventName: string,
|
||||
handlerValue: string,
|
||||
) => void
|
||||
setupTwoWayBinding: (element: Element, expr: string) => void
|
||||
setupConditionRendering: (element: Element, expr: string) => void
|
||||
setupListRendering: (element: Element, expr: string) => void
|
||||
stateToElementsMap: Record<string, Set<HTMLElement>>
|
||||
|
@ -34,6 +33,7 @@ export default function processTemplateMacros(
|
|||
originalContent: string
|
||||
}[]
|
||||
availableFuncs: string[]
|
||||
stateListeners: Record<string, (newValue: unknown) => void>
|
||||
},
|
||||
) {
|
||||
/*
|
||||
|
@ -194,7 +194,11 @@ export default function processTemplateMacros(
|
|||
// Handle different types of macros
|
||||
if (macroName === 'connect')
|
||||
// Handle state connection: %connect="stateName"
|
||||
options.setupTwoWayBinding(currentElementNode, expr)
|
||||
setupTwoWayBinding(currentElementNode, expr, {
|
||||
getNestedState: context.getState.bind(context),
|
||||
setState: context.setState.bind(context),
|
||||
statesListeners: options.stateListeners,
|
||||
})
|
||||
else if (macroName === 'if') {
|
||||
ifDirectivesToProcess.push({ element: currentElementNode, expr })
|
||||
} else if (macroName === 'for')
|
||||
|
@ -213,3 +217,40 @@ export default function processTemplateMacros(
|
|||
options.setupConditionRendering(ifElement, expr)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle two-way data binding (%connect macro)
|
||||
function setupTwoWayBinding(
|
||||
element: Element,
|
||||
expr: string,
|
||||
ops: {
|
||||
getNestedState: (path: string) => unknown
|
||||
setState: (path: string, value: unknown) => void
|
||||
statesListeners: Record<string, (newValue: unknown) => void>
|
||||
},
|
||||
) {
|
||||
// Get the initial value
|
||||
const value = ops.getNestedState(expr)
|
||||
|
||||
// Set the initial value
|
||||
if (value !== undefined)
|
||||
element.setAttribute('data-laterano-connect', String(value))
|
||||
else
|
||||
console.error(
|
||||
`State \`${expr}\` not found in the component state. Although Laterano will try to work with it, it may has potentially unexpected behavior.`,
|
||||
)
|
||||
|
||||
// Add event listener for input events
|
||||
element.addEventListener('input', (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
const newValue = target.value
|
||||
|
||||
// Update the state
|
||||
ops.setState(expr, newValue)
|
||||
})
|
||||
|
||||
// Add event listener for state changes
|
||||
ops.statesListeners[expr] = (newValue: unknown) => {
|
||||
if (element instanceof HTMLInputElement) element.value = newValue as string
|
||||
else element.setAttribute('data-laterano-connect', String(newValue))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user