MCPcopy Create free account
hub / github.com/formkit/formkit / addChild

Function addChild

packages/core/src/node.ts:2410–2496  ·  view source on GitHub ↗

* Adds a child to the node. * * @param node - A FormKitNode | FormKitNode * @param context - A parent FormKitContext | FormKitContext * @param child - A FormKitNode | FormKitNode * @param listIndex - A index number to be added at * * @internal

(
  parent: FormKitNode,
  parentContext: FormKitContext,
  child: FormKitNode,
  listIndex?: number
)

Source from the content-addressed store, hash-verified

2408 * @internal
2409 */
2410function addChild(
2411 parent: FormKitNode,
2412 parentContext: FormKitContext,
2413 child: FormKitNode,
2414 listIndex?: number
2415) {
2416 if (parent.type === 'input') error(100, parent)
2417 if (child.parent && child.parent !== parent) {
2418 child.parent.remove(child)
2419 }
2420 // Synchronously set the initial value on the parent
2421 if (!parentContext.children.includes(child)) {
2422 if (listIndex !== undefined && parent.type === 'list') {
2423 // Inject the child:
2424 const existingNode = parentContext.children[listIndex]
2425 if (existingNode && '__FKP' in existingNode) {
2426 // The node index is populated by a placeholderNode so we need to
2427 // remove that replace it with the real node (the current child).
2428 child._c.uid = existingNode.uid
2429 parentContext.children.splice(listIndex, 1, child)
2430 } else if (existingNode && parent.sync) {
2431 // Synced lists always have a placeholder waiting for a mounting child,
2432 // so a real node sitting here means the framework re-mounted and put the
2433 // new child in before pulling the old one out. Take over its slot and
2434 // uid instead of inserting a duplicate, which would grow the value and
2435 // spin up an endless re-mount loop (#1758).
2436 child._c.uid = existingNode.uid
2437 parentContext.children.splice(listIndex, 1, child)
2438 } else {
2439 // Same re-mount, opposite order: the old child left first, so the slot's
2440 // empty. Reuse its uid if we stashed one this tick so the key holds.
2441 if (!existingNode && parent.sync) {
2442 const removedUids = recentlyRemovedSyncUids.get(parent)
2443 const reusableUid = removedUids?.get(listIndex)
2444 if (reusableUid) {
2445 child._c.uid = reusableUid
2446 removedUids?.delete(listIndex)
2447 }
2448 }
2449 parentContext.children.splice(listIndex, 0, child)
2450 }
2451
2452 if (
2453 Array.isArray(parent.value) &&
2454 parent.value.length < parentContext.children.length
2455 ) {
2456 // When adding an node or value to a list it is absolutely critical to
2457 // know if, at the moment of injection, the parent’s value or the node
2458 // children are the source of truth. For example, if a user pushes or
2459 // splices a new value onto the lists’s array then we want to use that
2460 // value as the value of the new node, but if a user adds a node to the
2461 // list then we want the node’s value. In this specific case, we
2462 // assume (due to length) that a new node was injected into the list, so
2463 // we want that new node’s value injected into the parent list value.
2464 parent.disturb().calm({
2465 name: listIndex,
2466 value: child.value,
2467 from: valueInserted,

Callers

nothing calls this directly

Calls 2

errorFunction · 0.90
commitFunction · 0.85

Tested by

no test coverage detected