1. Lightning Web Components Slots Free
  2. Salesforce Lightning Web Component Slot
  3. Lightning Web Components Slots Games

# Component Bundles

Lightning Web Components is a lightweight JavaScript framework that leverages the web standards breakthroughs of the last five years. Leverage custom elements, templates, slots, modules, and other new language constructs available in ECMAScript 6 and beyond. Lightning web components have a lifecycle managed by the framework. The framework creates components, adds and removes them from the DOM, and renders DOM updates whenever the state of a component changes. A lifecycle hook is a JavaScript callback method triggered at a specific phase of a component instance’s lifecycle.

To create a component, create a folder that bundles your component’s files. A component folder (bundle) must live in a parent folder that defines the component's namespace. The name of the parent folder is the namespace.

A bundle can be a UI component, which renders UI, or a module, which is a library used to share code.

Tip

To understand the structure of a component and its namespace, look at the lwc-recipes-oss repo. Most components are in the recipe namespace. There are also components in the ui namespace and the data namespace. Most components are UI components. To see an example of a module, see mortgage.

# UI Components

The easiest way to create a UI component is to use the Lightning Web Components CLI, which generates boilerplate files.

A component that renders UI must have an HTML template file and a JavaScript class file. It may include a CSS file, additional JavaScript utility files, and test files. The HTML template, JavaScript class, and CSS file must have the same name. The framework uses the name to autowire the relationship between them.

The folder and its files must follow these naming rules.

  • Must begin with a lowercase letter
  • Must contain only alphanumeric or underscore characters
  • Must be unique in the namespace
  • Can’t include whitespace
  • Can’t end with an underscore
  • Can’t contain two consecutive underscores
  • Can’t contain a hyphen (dash)

Important

Use camel case to name your component. Camel case component folder names map to kebab case in markup. Every component is part of a namespace. Use a hyphen character (-) to separate the namespace from the component name. In markup, to reference a component in the example namespace with the name myComponent, use <example-my-component>.

A bit more information about naming. Lightning web components match web standards wherever possible. The HTML standard requires that custom element names contain a hyphen. You can use underscores in component folder names, but they don’t map to kebab case in markup. The names are legal because the namespace is separated with a hyphen, but most developers expect hyphens instead of underscores in a web component name. For example, the component <example-my_component> is legal, but it looks odd and may confuse developers consuming your component.

Note

Lightning web components slots free

The HTML spec mandates that tags for custom elements (components) aren’t self-closing. Self-closing tags end with />. Therefore, <example-my-component> includes a closing </example-my-component> tag.

# HTML File

Every UI component must have an HTML file with the root tag <template>.

The HTML file follows the naming convention <component>.html, such as myComponent.html.

Slots

Create the HTML for a Lightning web component declaratively, within the <template> tag. The HTML template element contains your component’s HTML.

When a component renders, the <template> tag is replaced with the namespace and name of the component. If this component were in the example namespace, the tag is <example-my-component>.

To create your template, use these techniques:

  • Create slots that component consumers can replace with content.

# JavaScript File

Every UI component must have a JavaScript file, which is a class that defines the HTML element.

The JavaScript file follows the naming convention <component>.js, such as myComponent.js.

This class must include at least this code:

The core module is lwc. The import statement imports LightningElement from the lwc module. LightningElement is a custom wrapper of the standard HTML element.

The convention is for the class name to be Pascal Case, where the first letter of each word is capitalized. For myComponent.js, the class name is MyComponent.

Extend LightningElement to create a JavaScript class for a Lightning web component. The export default keywords export a MyComponent class for other components to use.

JavaScript files in Lightning web components are ES6 modules. By default, everything declared in a module is local—it’s scoped to the module.

The JavaScript class can contain:

  • The component’s public API via public properties and methods annotated with @api.
  • Private properties
  • Event handlers

In addition to this JavaScript file that creates the HTML element, a UI component’s folder can contain other JavaScript files that are used to share code. These utility JavaScript files must be ES6 modules and must have names that are unique within the component’s folder.

See Reactive Properties and Properties and Attributes.

# CSS File

A component can include a CSS file. Use standard CSS syntax to style Lightning web components.

To style a component, create a style sheet in the component bundle with the same name as the component. If the component is called myComponent, the style sheet is myComponent.css. The style sheet is applied automatically.

See CSS.

# Test Files

To create Jest tests for a component, create a folder called __tests__ at the top level of the component’s folder. Save the tests inside the __tests__ folder.

Jest runs JavaScript files in the __tests__ directory. Test files must have names that end in .js, and we recommend that tests end in .test.js. You can have a single test file with all of your component tests, or you can have multiple files to organize related tests. Test files can be placed in sub folders.

See Unit Tests.

# Modules

To share code between components, create an ES6 module and export the variables or functions that you want to expose.

The module folder and file name must follow the same naming conventions as a UI component.

An ES6 module is a file that explicitly exports functionality that other modules can use. Modules make it easier to structure your code without polluting the global scope.

Within a JavaScript class, to reference a module, use namespace/module. The forward slash character (/) separates the namespace from the module name.

See Share JavaScript Code.

# JavaScript Decorators

Decorators add functionality to a property or function. The ability to create decorators is part of ECMAScript, but these decorators are unique to Lightning Web Components.

#@api

To expose a public property, decorate a field with @api. Public properties define the API for a component. An owner component that uses the component in its HTML markup can access the component’s public properties via HTML attributes.

Public properties are reactive. If the value of a property changes, the component’s template re-renders any content that references the property. For more information, see Public Properties.

To expose a public method, decorate it with @api. Public methods also define the API for a component. To communicate down the component hierarchy, owner and parent components can call JavaScript methods on child components.

#@track

All fields are reactive. When the framework observes a change to a field used in a template or used in the getter of a property used in a template, the component re-renders. However, there is a limit to the depth of changes that the framework observes.

If a field contains an object value or an array value, the framework observes changes that assign a new value to the field. If the value that you assign to the field is not to the previous value, the component re-renders.

Decorate a field with @track to tell the framework to observe changes to the properties of an object or to the elements of an array.

For code samples, see Field Reactivity.

#@wire

LWC has an elegant way to provide a stream of data to a component. Declare a component's data requirements in a wire adapter. Use the @wire decorator to connect or wire a component to the wire adapter.

Wire adapters are a statically analyzable expression of data. Wire adapters can also have dynamic configuration parameters. If a configuration value changes, new data is provisioned and the component rerenders.

See Wire Adapters.

# HTML Template Directives

Write templates using standard HTML and a few directives that are unique to Lightning Web Components. Directives are special HTML attributes that add dynamic behavior to an HTML template. Directives give you more power to manipulate the DOM in markup.

These are the directives supported in Lightning Web Components templates.

#for:each={array}

Use this directive to iterate over an array and render a list.

See Render Lists.

#for:index='index'

Use this directive to access the current item's zero-based index.

The index placeholder is a new identifier that the model injects into the current scope.

See Render Lists.

#if:true false={expression}

Use this directive to conditionally render DOM elements in a template.

The expression can be a JavaScript identifier (for example, person) or dot notation that accesses a property from an object (person.firstName). The engine doesn’t allow computed expressions (person[2].name['John']). To compute the value of expression, use a getter in the JavaScript class.

See Render DOM Elements Conditionally.

#iterator:iteratorName={array}

Use this directive to apply special behavior to the first or last item in an array and render a list.

Access these properties on the iteratorName:

  • value—The value of the item in the list. Use this property to access the properties of the array. For example, iteratorName.value.propertyName.
  • index—The index of the item in the list.*first—A boolean value indicating whether this item is the first item in the list.
  • last—A boolean value indicating whether this item is the last item in the list.

See Render Lists.

#key={uniqueId}

Use this directive to improve rendering performance by assigning a unique identifier to each item in a list. The key must be a string or a number, it can’t be an object. The engine uses the keys to determine which items have changed.

See Render Lists.

#lwc:dom='manual'

Lightning Web Components Slots Free

Add this directive to a native HTML element to call appendChild() on the element from the owner’s JavaScript class and preserve styling.

If a call to appendChild() manipulates the DOM, styling isn’t applied to the appended element. Using JavaScript to manipulate the DOM isn’t recommended when programming Lightning web components, but some third-party JavaScript libraries require it.

See Third-Party JavaScript Libraries.

I've blogged about a few of the behaviours of Lightning Web Components, but the proof is really in building useful bits. What happens when you actually try to make a re-usable component?

For our example, we'll rebuild 'ui:message'. A now (seemingly) defunct base component that would render a message in a box that is coloured based on the 'severity' of the message being shown. In the original it could be set to 'closable', although we're going to ignore that and focus on just the rendering of it.

In a Lightning component we would use it like this:

Original usage - Lightning Component

Ideally, the version we will create, would be used like this:

Salesforce Lightning Web Component Slot

Desired usage

Looks pretty straightforward, and actually - it is. Just as long as we know about a few simple concepts.

Before we go into them, let's see what a working example could look like:

Javascript component

HTML Template

OK then, let's pick a few of these bits apart, and hopefully we'll explain a few little behaviours along the way.

First up, let's take a look at the '@api' declarations.

@api

The @api property lines are pretty simple to understand - they define that 'title' and 'severity' are publicly available properties of the component. In the context of Lightning Web Components, public and private mean 'available outside of the component, and invisible to the outside of the component'. It's tempting to think that this is to do with the scope of the Javascript, but it's not.

That is, every property of the Javascript component is available to be referenced in the HTML template - whether it is 'public' or 'private'. One way of thinking about it is that the HTML template forms part of the component, and so it can see private properties.

Another (probably more accurate) way of thinking about it is that the template is processed by the Javascript component (that code it's immediately obvious, but it's almost certainly in LightningComponent - which this class extends), and the Javascript can see its own properties, so the private ones are available.

However, other components (like ones that include this in their templates) can only see public properties. @api is how you make them public. Doing so means that they are available as attributes on the tag you use to include the component (hence <c-message... is possible)

Not only that, but every @api decorated property is also 'reactive'. That is, whenever its value changes the component is re-rendered. The documentation is pretty clear on that point - and is presented as a fundamental property of a public property:

Public Properties

To expose a public property, decorate it with @api. Public properties define the API for a component. An owner component that uses the component in its markup can access the component’s public properties. Public properties are reactive. If the value of a reactive property changes, the component’s template rerenders any content that references the property.


Why would a public property be reactive?

Put simply, if we change the value of one of those properties in a parent component, we want the component to re-render - and it's pretty much guaranteed that we ALWAYS want the component to re-render.

For example, we may do the following:

When the value of 'title' or 'severity' changes, we would always want the message box to re-render to show our new values. And so the framework takes care of that and makes EVERY public property of the component reactive

So that takes care of the attributes we need to pass in, what about the content?

Slots

Lightning Components had facets. And they weren't intuitive. I mean they weren't complex, but they weren't in keeping with HTML - they always felt unnatural - especially in the simplest of cases.

Lightning Web Components fixes that, with slots. And in the simple case they are trivial. The documentation isn't long, and doesn't need to be.

All we need to do, in this simple case, is add <slot></slot> into our component, and the body of any tag that instantiates the component will be rendered in that slot.

Now something that's missing from the documentation, which is a fairly obvious behaviour once you see it in action, is that slots are effectively reactive.

That is, if you change the content of the tag, that content is immediately reflected in the component's rendered output.

So, in our example:

Whenever the value of 'errorMessages' changes, the slot inside the 'message' component is re-rendered to include the new content.

I admit, I had assumed that this would be the case, but I didn't immediately realise that it was an assumption. So I thought it was worth calling out

Getters

Lightning web components slots games

The final part of the example that I want to explain is the use of the 'getter':

What we're doing here is building a list of CSS classes for a node in the component that includes one of the passed in attributes plus a standard class that must be applied

The use of the getter illustrates an important difference between the behaviour of the templates in Lightning Components (LC) and Lightning Web Components (LWC), as well a reminder of the behaviour of properties.

That is, in LC we could have done the following in our template:

In LC, our replacements could include expressions, so we could build up strings in the template. In LWC, we can't do this, we can only reference properties or getters.

Not only that, but we can't build up the strings in the attribute assignment.

Lightning Web Components Slots Games

I.E. We can't do this:

In LWC we don't assign properties to attributes in this way, the framework takes care of the wrapping in double quotes, escaping the strings, and other such things, so we can only assign the property, and that's it.

I.E. This is what is allowed:

So, if we want to assign more than just the value of 'severity' to the class attribute, we need to build that string up outside of the template.

Your first reaction might be - OK, we can create a trackable property to store it, right?

But this doesn't work. You'll end up with the classes property defined as 'undefined uiMessage', and it won't change. Why is that?

Well, it's tempting to think that 'track' and 'api' mean that Javascript will re-run when things change, but that's not what they do - nor what the documentation says they'll do

Rather, if a property is reactive it means that the component will be re-rendered when the property changes. That says nothing about running Javascript.

So when we look at the above, what happens is the property 'classes' is set when the Javascript object is constructed. At this point the property 'severity' is undefined. When the 'severity' is updated via the attribute, the component is re-rendered and the 'classes' property is re-injected into the template, but the Javascript that sets the classes property is not re-run - that is only executed when the object is instantiated.

So, instead of setting the 'classes' property directly, we set up a getter for it:

Javascript component

Now, when the 'severity' property changes, the 'classes' property is re-injected. In order to get the value for 'classes', the getter is executed - this is the only way the property can be retrieved. In doing so, the string concatenation is re-evaluated and the new value is retrieved.

Summary

None of the concepts here are particularly difficult, or really that earth shattering, but building even the simplest of re-usable components starts to shed some light on what the parts do any why.

The framework has been very thoughtfully put together, and some of the techniques will be different to what people are used to, having cut their Javascript teeth with Lightning Components, but the changes are for very good reasons. An example like this really shows how those changes make for simple components.