# Adding, Removing, and Reordering Components

![](/files/-LGAddAXUsEy94vRwT6t)

## Component Lists

Components are added, removed, and reordered in fields called *component lists*, of which there are **four types**.

### Basic Lists

Components that contain child component lists need to do two things: Render an *editable* list in their template, and specify a *config* in their `schema.yml`.

```
<div data-editable="myList">{{> component-list myList }}</div>
```

{% hint style="info" %}
You'll notice that `data-editable` is the same attribute used to specify editable fields. The `component-list` handlebars partial comes from [our included library of helpers and partials](https://github.com/clay/handlebars#partials), and renders a list of components with their data. The element with `data-editable` must be the *immediate parent* of the components in the list.
{% endhint %}

```yaml
myList:
  _componentList:
    include:
      - some-component
      - some-other-component
```

This would create a basic list with drag & drop functionality. When selecting components inside this list, you'd see *Remove* and *Add Component* buttons that would allow you to remove those components or add new instances of `some-component` and `some-other-component`. When adding components to a list, a component's default data is cloned into a new instance.

#### Placeholders

Basic lists also allow placeholders, which will display (and prompt users to add components) when the list is empty.

```yaml
myList:
  _placeholder:
    height: 600px
  _componentList:
    include:
      - some-component
      - some-other-component
```

![](/files/-LGAddB2k501G2KyI-NA)

#### Collapsible Lists

In edit mode, basic component lists may be expanded and collapsed. This feature only affects edit mode, so it's useful for removing visual clutter in component lists that aren't displayed in view mode. Note that this is different than *invisible* component lists, which are editable through the "Find on Page" / "Find on Layout" drawer.

```yaml
myList:
  _placeholder:
      text: Article Content
  _componentList:
    include:
      - tweet
    collapse: true
```

![](/files/-LLoa47jie5O5bHu0VoS)

Collapsible lists will *always* display their placeholder, as well as an expand/collapse toggle.

![](/files/-LLoa47lWic604TTxRd8)

When collapsible lists are empty, they'll display the same "Add Component" button as other component lists.

![](/files/-LLoa47nUrSJnb8r1N_n)

#### Validation

Similarly to [editable fields](https://claycms.gitbooks.io/kiln/editing-components.html#standard-input-arguments), component lists may contain validation for `min` and `max` lengths.

```yaml
myList:
  _componentList:
    include:
      - some-component
      - some-other-component
    validate:
      min: 1
      max: 10
```

Similarly to text inputs, component lists may also prevent users from adding components over the maximum with `enforceMaxlength`.

```yaml
myList:
  _componentList:
    include:
      - some-component
      - some-other-component
    validate:
      max: 10
    enforceMaxlength: true
```

### Head Lists

Components in the `<head>` of the page require a different syntax. Much like how you denote the start of `<head>` components with a `<!-- data-editable -->` comment, you use html comments for the beginning *and the end* of these component lists.

```
<!-- data-editable="myList" -->
{{> component-list myList }}
<!-- data-editable-end -->
```

The `schema.yml` config of a head list is the same as a basic list.

```yaml
myList:
  _componentList:
    include:
      - some-component
      - some-other-component
```

Head component lists get added as tabs to the *Find on Page* drawer in Kiln automatically, allowing them to be edited.

![](/files/-LGAddBEPwUBFfdH3mbk)

### Invisible Lists

It's useful to have a component list for various components that might not have public-facing visual elements, such as tracking scripts, affiliate marketing scripts, pixels, or lightboxes. If these components must live in the `<body>` (rather than the `<head>`), you may add a property to the component list to make them appear as tabs in the *Find on Page* drawer, allowing them to be edited.

```
<div data-editable="myList">{{> component-list myList }}</div>
```

```yaml
myList:
  _componentList:
    invisible: true
    include:
      - some-component
      - some-other-component
```

### Page Areas

Page areas are a special type of component list that only exists in layouts. By adding a property to the layout's `schema.yml`, you can specify that certain component lists exist in the page's data (and thus are specific to that page) rather than the layout's data (thus being shared amongst all pages with that layout).

```
<div data-editable="myList">{{> component-list myList }}</div>
```

```yaml
myList:
  _componentList:
    page: true
    include:
      - some-component
      - some-other-component
```

The data for component lists inside components (including layouts) looks like an array of objects:

```javascript
{
  "myList": [{
    "_ref": "domain.com/_components/some-component/instances/some-instance"
  }, {
    "_ref": "domain.com/_components/some-other-component/instances/some-instance"
  }]
}
```

Meanwhile, the data for component lists inside page data looks like an array of strings:

```javascript
{
  "myList": [
    "domain.com/_components/some-component/instances/some-instance",
    "domain.com/_components/some-other-component/instances/some-instance"
  ]
}
```

Page areas may also have placeholders.

## Site-Specific Components

All types of component lists allow whitelisting of components using the `include` property in the config. You may also specify that components in a list should be included or excluded on a specific site. To do so, add a comma-separated list of sites in parenthesis after the name of the component in the include list:

```yaml
content:
  _componentList:
    include:
      - blockquote (site1, site2) # allow on site1 and site2 ONLY
      - paragraph # allow on all sites
      - image (not:site1) # allow on all sites EXCEPT site1
      - link (site1, site2, site3, not:site2, not:site3) # only allow on site1
      # if (for some reason) you both include and exclude a site, it'll filter by the
      # included sites first, then filter out the excluded.
```

## Fuzzy Lists

Additionally, all types of component lists may be set to *fuzzy*. The default `include` list is appropriate for most situations, but there are certain scenarios where you might want to be less strict. For example, the body of an article might be restricted to paragraphs and images 99% of the time, but you still want to allow your interactives team to create one-off components and add them through Kiln's UI.

You may make any component list *fuzzy* by adding that property in the config. This will add a *View All Components* button into the header of the Add Components modal, which will list *all components available in your Clay installation*.

![](/files/-LGAddB_Ti2NpI-5vMD0)

## Component Properties

In addition to component lists, you can use *component properties* if you want a single child component instead of an array of children.

```yaml
tags:
  _component:
    include:
      - normal-tags
      - fancy-tags
```

This allows you to swap out different components in a specific place, for example if you have two different tagging components with different styles and functionality. As with component lists, you may include a `_placeholder`. If your component property is editable, the child component's selector will allow you to remove it (and the placeholder that displays will allow you to add it).

{% hint style="info" %}
Component properties are not allowed in the layout or page data, only in normal components. Because of this, they are also not allowed in the `<head>` of the page.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://claycms.gitbook.io/kiln/kiln-fundamentals/components/manipulating-components.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
