Skip to content

if:*

Just like on:* is the output channel for event actions, so too is the if:* attribute the output channel for state actions.

All of the following, along with any future additions, are behaviorally identical and differ only in how their conditions are calculated.


if:loading

KEML has no special concept of a loading indicator, because it does not need one — loading is just another state condition.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<h4 class="mt0">This endpoint takes 2 seconds to respond.</h4>

<button
  type="button"
  class="btn"
  on:click="sendIfLoading"
  on="sendIfLoading"
  href="/if-loading"
  if:loading="isLoading"
>
  click me
</button>

<div
  if="isLoading"
  x-class="spinner mt3"
></div>

This endpoint takes 2 seconds to respond.


if:error

The error condition becomes true when the server returns an unsuccessful status code.

 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
<button
  class="btn mr3"
  on:click="sendIfError"
  on="sendIfError"
  href="/if-error"
  name="switch"
  value="success"
  result="ifErrorResult"
  error="ifErrorResult"
  render="ifErrorResult"
  position="replaceWith"
  if:error="isError"
>
  Get error code
</button>

<small
  if="isError"
  class="dn"
  x-class="chip error"
>
  Error
</small>

<small
  if="isError"
  class="chip success"
  x-class="dn"
>
  No errors
</small>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{ server.status = server.getParam('switch') === 'error' ? 200 : 500 }}

<button
  class="btn mr3"
  on:click="sendIfError"
  on="sendIfError"
  href="/if-error"
  name="switch"
  value="{ server.getParam('switch') === 'error' ? 'success' : 'error' }"
  result="ifErrorResult"
  error="ifErrorResult"
  render="ifErrorResult"
  position="replaceWith"
  if:error="isError"
>
  Get { server.getParam("switch") } code
</button>
Error No errors

if:invalid

The invalid condition becomes true when the element's value is invalid.

For custom elements (e.g. Web Components) to participate, they must implement the standard checkValidity method and notify the system of their value changes by emitting one or more of the following event types: change, input, reset.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<input
  type="email"
  class="input"
  placeholder="Email address"
  if:invalid="isInvalidEmail"
>

<small
  if="isInvalidEmail"
  class="dn"
  x-class
>
  Please enter a valid email address.
</small>
Please enter a valid email address.

if:value

The value condition becomes true when the element's value is truthy.

Custom elements (like Web Components) can participate if they follow the same input-like behavior as native input elements:

  • They must expose a type property.
  • They may expose additional input-like properties depending on type: checked, files, src, and value.
  • When their value changes, they notify the system using one or more of these events: input, change, reset.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<input
  type="text"
  class="input"
  placeholder="Say something..."
  if:value="isValue"
>

<small
  if="isValue"
  class="dn"
  x-class
>
  The input is not empty.
</small>
The input is not empty.

if:intersects

The intersects condition becomes true when the element enters the viewport.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<p
  if="isIntersecting"
  class="mt0"
  x-class="mt0 green"
>
  Scroll the container down to reveal the green <code>div</code>, and watch this
  paragraph turn green as well.
</p>

<div class="overflow-y-auto h4">
  <div class="h5"></div>

  <div
    class="h5 bg-green"
    if:intersects="isIntersecting"
  ></div>
</div>

Scroll the container down to reveal the green div, and watch this paragraph turn green as well.