---
title: "Match Elements"
description: "Experimental match elements for conditional element rendering."
---
A `match` element conditionally renders elements from a set of cases based on the value of an expression (the subject).
It is a more readable alternative to a chain of `if` elements when you need to select between several mutually exclusive states.

> **Note**: `match` is experimental and subject to change.
> Tracking issue: [slint-ui/slint#1307](https://github.com/slint-ui/slint/issues/1307).

## Syntax

```slint no-test
match <match-subject> {
    <case-value>: ElementType { /* ... */ }
    <case-value>: ElementType { /* ... */ }
    *: ElementType { /* ... */ }   // optional wildcard, always last
}
```

Each `<case-value>` is a literal that is compared against the `<match-subject>`.
When the subject equals a case value, that case's element is rendered.
If a wildcard case `*` is present, it renders when none of the explicit cases match.

## Examples

### Matching on an integer

Every value an `int` can take cannot be listed, so a wildcard `*` case is required.

```slint
export component StatusIndicator {
    in property <int> status: 0;

    match status {
       -1: Rectangle { background: red; }
        0: Rectangle { background: green; }
        1: Rectangle { background: yellow; }
        *: Rectangle { background: gray; }
    }
}
```

### Matching on a boolean

`true` and `false` cover every value a `bool` can take, so no wildcard is needed.

```slint
export component Toggle {
    in-out property <bool> checked: false;

    match checked {
        true:  Rectangle { background: blue; }
        false: Rectangle { background: lightgray; }
    }
}
```

### Matching on an enum

When the subject's type is a known enum, case values may use the enum variant name directly, without qualifying it with the enum name.
Listing every variant covers the enum exhaustively, so no wildcard is needed.

```slint
enum Mode { View, Edit, Preview }

export component Editor {
    in-out property <Mode> mode: View;

    match mode {
        View:    Text { text: "Viewing"; }
        Edit:    TextInput { }
        Preview: Rectangle { background: black; }
    }
}
```

### Matching on a string

```slint
export component Greeting {
    in property <string> lang: "en";

    match lang {
        "en": Text { text: "Hello"; }
        "sp": Text { text: "Hola"; }
        "fr": Text { text: "Bonjour"; }
        *:    Text { text: "Hi"; }
    }
}
```

## Wildcard case

The `*` case acts as a catch-all that renders when no explicit case matches the subject.
It must appear as the last case, so any case written after it can never be reached and is an error.

```slint no-test
match answer {
    42: Text { text: "Correct!"; }
    *:  Text { text: "Incorrect"; }
}
```

## Exhaustiveness

A `match` must handle every value its subject can take.

- For `bool` and enum subjects, either list all values explicitly or provide a `*` case. A missing value is an error (for example, `Non-exhaustive match on bool: missing 'false'`).
- For all other types (`int`, `string`, `color`, `length`, …) the set of values is unbounded, so a `*` case is required.

A literal subject (for example `match 1 { … }`) warns, because the same case always applies.

## Duplicate cases

Each case value must be distinct. A value that is already covered by an earlier case is an error, including values that are equal after conversion (for example `2` and `2.0`, or `1s` and `1000ms`).

```slint no-test
match count {
    0: Rectangle { }
    0: Rectangle { }   // error: Duplicate case value
    *: Rectangle { }
}
```

## Empty element

Any case that evaluates to the empty element `{ }` renders nothing. Any case can be empty, including the wildcard case.

```slint no-test
match show {
    true: Text { text: "Hi"; }
    false: { }
}
```

```slint no-test
match toggle {
    0: Rectangle { background: white; }
    1: Rectangle { background: black; }
    *: { }
}
```

## Restrictions

The match element feature is in its early stages. The following restrictions apply:

- A `match` must contain at least one case.

- Cases must be literal values. Computed expressions, property references, and function calls are not allowed as case values. Only plain literals (integers, floats, booleans, strings, enum variants, colors, lengths), optionally negated, are accepted.

  ```slint no-test
  // Property reference as a case value
  match value {
      some-property: Rectangle { }   // error
  }

  // String concatenation as a case value
  match greeting {
      "hello " + "world": Text { }   // error
  }
  ```

- Float comparisons produce a warning. Comparing floating-point values for exact equality is not reliable, so the compiler emits a warning for each fractional float case value.

- `@children` cannot appear inside a match case.

- `match` cannot appear in global components or interfaces. Only regular components support match elements.