lustre/dev/query

Types

A Query that describes how to locate certain elements in an Element tree. You can pass a Query to functions like find and find_all write tests that assert certain elements are present in your views.

pub opaque type Query

A Selector describes how to match a specific element in an Element tree. It might be the element’s tag name, a class name, an attribute, or some combination of these.

pub opaque type Selector

Values

pub fn and(first: Selector, second: Selector) -> Selector

Combine two selectors into one that must match both. For example, if you have a selector for div elements and a selector for elements with the class “wibble” then they can be combined into a selector that matches only div elements with the class “wibble”.

import lustre/dev/query

pub fn example() {
  let div = query.tag("div")
  let wibble = query.class("wibble")

  query.element(matching: div |> query.and(wibble))
}

You can chain multiple and calls together to combine many selectors into something more specific.

import lustre/dev/query

pub fn example() {
  query.tag("div")
  |> query.and(query.class("wibble"))
  |> query.and(query.data("open", "true"))
}

Note: if you find yourself crafting complex selectors, consider using a test id on the element(s) you want to find instead.

pub fn aria(name: String, value: String) -> Selector

Select elements that have the given aria-* attribute. For example you can select the trigger of a dropdown menu with:

import lustre/dev/query

pub fn example() {
  query.element(matching: query.aria("expanded", "true"))
}
pub fn attribute(name: String, value: String) -> Selector

Select elements that have the specified attribute with the given value. If the value is left blank, this selector will match any element that has the attribute, regardless of its value.

For example, to select a form input with the name “username”, you would use:

import lustre/dev/query

pub fn example() {
  query.element(matching: query.attribute("name", "username"))
}

Or to select elements with the disabled attribute:

import lustre/dev/query

pub fn example() {
  query.element(matching: query.attribute("disabled", ""))
}
pub fn child(
  of parent: Query,
  matching selector: Selector,
) -> Query

Given a Query that finds an element, find any of that element’s direct children that match the given Selector. This is similar to the CSS > combinator.

pub fn class(name: String) -> Selector

Select elements that include the given space-separated class name(s). For example given the element <div class="foo bar baz">, the following selectors would match:

  • query.class("foo")

  • query.class("bar baz")

If you need to match the class attribute exactly, you can use the attribute selector instead.

pub fn data(name: String, value: String) -> Selector

Select elements that have the given data-* attribute. For example you can select a custom disclosure element that is currently open with:

import lustre/dev/query

pub fn example() {
  query.element(matching: query.data("open", "true"))
}
pub fn descendant(
  of parent: Query,
  matching selector: Selector,
) -> Query

Given a Query that finds an element, find any of that element’s descendants that match the given Selector. This will walk the entire tree from the matching parent.

pub fn element(matching selector: Selector) -> Query

Find any elements in a view that match the given Selector.

pub fn find(
  in root: @internal Element(msg),
  matching query: Query,
) -> Result(@internal Element(msg), Nil)

Find the first element in a view that matches the given Query. This is useful for tests when combined with element.to_readable_string, allowing you to render large views but take more precise snapshots.

pub fn find_all(
  in root: @internal Element(msg),
  matching query: Query,
) -> List(@internal Element(msg))

Like find but returns every element in the view that matches the given query.

pub fn has(
  in element: @internal Element(msg),
  matching selector: Selector,
) -> Bool

Check if an element or any of its descendants match the given Selector.

pub fn id(name: String) -> Selector

Select an element based on its id attribute. Well-formed HTML means that only one element should have a given id.

pub fn matches(
  target element: @internal Element(msg),
  selector selector: Selector,
) -> Bool

Check if the given target element matches the given Selector.

pub fn namespaced(namespace: String, tag: String) -> Selector

Select elements based on their tag name and XML namespace. This is useful for selecting SVG elements or other XML elements that have a namespace. For example, to select an SVG circle element, you would use:

import lustre/dev/query

pub fn example() {
  let svg = "http://www.w3.org/2000/svg"

  query.element(matching: query.namespaced(svg, "circle"))
}
pub fn style(name: String, value: String) -> Selector

Select elements that have the specified inline style with the given value. If the value is left blank, this selector will match any element that has the given style, regardless of its value.

pub fn tag(value: String) -> Selector

Select elements based on their tag name, like "div", "span", or "a". To select elements with an XML namespace - such as SVG elements - use the namespaced selector instead.

pub fn test_id(value: String) -> Selector

It is a common convention to use the data-test-id attribute to mark elements for easy selection in tests. This function is a shorthand for writing query.data("test-id", value)

pub fn text(content: String) -> Selector

Select elements whose text content matches the given string exactly. This includes text from inline children, but not from block children. For example, given the following HTML:

<p>Hello, <span class="font-bold">Joe</span>!</p>

The selector query.text("Hello, Joe!") would match the <p> element because the text content of the inline <span> element is included in the paragraph’s text content.

Whitespace must match exactly, so the selector query.text("Hello, Joe!") would not match an element like:

html.p([], [html.text("Hello,     Joe!")])

Note: while this selector makes a best-effort attempt to include the text content of inline children, this cannot account for block elements that are styled as inline by CSS stylesheets.

Note: often it is better to use more precise selectors such as id, class, or test_id. You should reach for this selector only when you want to assert that an element contains some specific text, such as in a hero banner or a copyright notice.

pub fn to_readable_string(query: Query) -> String

Print a Query as a human-readable string similar to a CSS selector. This function is primarily intended for debugging and testing purposes: for example, you might use this to include the selector in a snapshot test for easier review.

Note: while similar, this function is not guaranteed to produce a valid CSS selector. Specifically, queries that use the text selector will not be valid CSS selectors as they use the :contains pseudo-class, which is not part of the CSS spec!

Search Document