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 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 172x 4x 172x 167x 167x 167x 80x 167x 85x 62x 85x 23x 23x 85x 168x 1x 1x 172x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x  
/** @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);
}