lustre/dev/query
Types
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
, ortest_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!