All files / src/compiler/phases/3-transform/server/visitors SlotElement.js

100% Statements 62/62
100% Branches 15/15
100% Functions 1/1
100% Lines 60/60

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 612x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 169x 4x 169x 164x 164x 164x 79x 164x 83x 60x 83x 23x 23x 83x 165x 1x 1x 169x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x 232x  
/** @import { BlockStatement, Expression, ExpressionStatement, Property } from 'estree' */
/** @import { SlotElement } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '../../../../utils/builders.js';
import { empty_comment, serialize_attribute_value } from './shared/utils.js';
 
/**
 * @param {SlotElement} node
 * @param {ComponentContext} context
 */
export function SlotElement(node, context) {
	/** @type {Property[]} */
	const props = [];
 
	/** @type {Expression[]} */
	const spreads = [];
 
	/** @type {ExpressionStatement[]} */
	const lets = [];
 
	/** @type {Expression} */
	let expression = b.call('$.default_slot', b.id('$$props'));
 
	for (const attribute of node.attributes) {
		if (attribute.type === 'SpreadAttribute') {
			spreads.push(/** @type {Expression} */ (context.visit(attribute)));
		} else if (attribute.type === 'Attribute') {
			const value = serialize_attribute_value(attribute.value, context, false, true);
 
			if (attribute.name === 'name') {
				expression = b.member(b.member_id('$$props.$$slots'), value, true, true);
			} else if (attribute.name !== 'slot') {
				if (attribute.metadata.dynamic) {
					props.push(b.get(attribute.name, [b.return(value)]));
				} else {
					props.push(b.init(attribute.name, value));
				}
			}
		} else if (attribute.type === 'LetDirective') {
			lets.push(/** @type {ExpressionStatement} */ (context.visit(attribute)));
		}
	}
 
	// Let bindings first, they can be used on attributes
	context.state.init.push(...lets);
 
	const props_expression =
		spreads.length === 0
			? b.object(props)
			: b.call('$.spread_props', b.array([b.object(props), ...spreads]));
 
	const fallback =
		node.fragment.nodes.length === 0
			? b.literal(null)
			: b.thunk(/** @type {BlockStatement} */ (context.visit(node.fragment)));
 
	const slot = b.call('$.slot', b.id('$$payload'), expression, props_expression, fallback);
 
	context.state.template.push(empty_comment, b.stmt(slot), empty_comment);
}