-
Notifications
You must be signed in to change notification settings - Fork 439
Expand file tree
/
Copy pathlwc-component.ts
More file actions
80 lines (75 loc) · 3.19 KB
/
lwc-component.ts
File metadata and controls
80 lines (75 loc) · 3.19 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import { is } from 'estree-toolkit';
import { isUndefined } from '@lwc/shared';
import { expressionIrToEs } from '../../expression';
import { esTemplateWithYield } from '../../../estemplate';
import { getChildAttrsOrProps } from '../../shared';
import { getSlottedContent } from './slotted-content';
import type { Transformer } from '../../types';
import type {
LwcComponent as IrLwcComponent,
Expression as IrExpression,
} from '@lwc/template-compiler';
import type { Statement as EsStatement } from 'estree';
const bYieldFromDynamicComponentConstructorGenerator = esTemplateWithYield`
const Ctor = '${/* lwcIs attribute value */ is.expression}';
if (Ctor) {
if (typeof Ctor !== 'function' || !(Ctor.prototype instanceof LightningElement)) {
throw new Error(\`Invalid constructor: "\${String(Ctor)}" is not a LightningElement constructor.\`)
}
const childProps = ${/* child props */ is.objectExpression};
const childAttrs = ${/* child attrs */ is.objectExpression};
/*
If 'slotAttributeValue' is set, it references a slot that does not exist, and the 'slot' attribute should be set in the DOM. This behavior aligns with engine-server and engine-dom.
See: engine-server/src/__tests__/fixtures/slot-forwarding/slots/dangling/ for example case.
*/
if (slotAttributeValue) {
childAttrs.slot = slotAttributeValue;
}
${
/*
Slotted content is inserted here.
Note that the slotted content will be stored in variables named
`shadowSlottedContent`/`lightSlottedContentMap / scopedSlottedContentMap` which are used below
when the child's generateMarkup function is invoked.
*/
is.statement
}
const scopeToken = hasScopedStylesheets ? stylesheetScopeToken : undefined;
yield* Ctor[__SYMBOL__GENERATE_MARKUP](
null,
childProps,
childAttrs,
instance,
scopeToken,
contextfulParent,
shadowSlottedContent,
lightSlottedContentMap,
scopedSlottedContentMap
);
}
`<EsStatement[]>;
export const LwcComponent: Transformer<IrLwcComponent> = function LwcComponent(node, cxt) {
const { directives } = node;
const lwcIs = directives.find((directive) => directive.name === 'Is');
if (!isUndefined(lwcIs)) {
cxt.import({
LightningElement: undefined,
SYMBOL__GENERATE_MARKUP: '__SYMBOL__GENERATE_MARKUP',
});
return bYieldFromDynamicComponentConstructorGenerator(
// The template compiler has validation to prevent lwcIs.value from being a literal
expressionIrToEs(lwcIs.value as IrExpression, cxt),
getChildAttrsOrProps(node.properties, cxt),
getChildAttrsOrProps(node.attributes, cxt),
getSlottedContent(node, cxt)
);
} else {
return [];
}
};