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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2024 the Xilem Authors
// SPDX-License-Identifier: Apache-2.0
//! This module contains DOM element modifiers, e.g. to add attributes/classes/styles.
//!
//! A modifier is usually a part/attribute of a [`ViewElement`](crate::core::ViewElement),
//! and has corresponding Views, usually meant to be used in a builder-style.
//!
//! One such example is setting attributes on a DOM element, like this:
//! ```
//! use xilem_web::{interfaces::Element, elements::html::{a, canvas, input}};
//! // ...
//! # use xilem_web::elements::html::div;
//! # fn component() -> impl Element<()> {
//! # div((
//! a("a link to an anchor").attr("href", "#anchor"),
//! // attribute will only appear if condition is met
//! // previous attribute is overwritten (and removed if condition is false)
//! a("a link to a new anchor - *maybe*")
//! .attr("href", "#anchor")
//! .attr("href", true.then_some("#new-anchor")),
//! input(()).attr("autofocus", true),
//! canvas(()).attr("width", 300)
//! # ))
//! # }
//! ```
//!
//! These modifiers have to fulfill some properties to be able to be used without unwanted side-effects.
//! As the modifier-views are usually depending on a bound on its `View::Element`, the following needs to be supported:
//!
//! ```
//! use xilem_web::{
//! core::{frozen, one_of::Either},
//! interfaces::Element,
//! elements::html::{div, span},
//! modifiers::style as s,
//! };
//! // ...
//! # fn component() -> impl Element<()> {
//! # div((
//! // Memoized views may never update their memoized modifiers:
//! frozen(|| div("this will be created only once").class("shadow"))
//! .class(["text-center", "flex"]),
//! // For some cases be able to read possibly memoized modifiers.
//! // Following results in the style attribute:
//! // `transform: translate(10px, 10px) scale(2.0)` and is updated, when `.scale` changes
//! frozen(|| div("transformed").style(s("transform", "translate(10px, 10px)")))
//! .scale(2.0),
//! // OneOf/Either views can change their underlying element type, while supporting the same modifier:
//! (if true { Either::A(div("div").class("w-full")) } else { Either::B(span("span")) })
//! .class("text-center")
//! # ))
//! # }
//! ```
//!
//! They should also aim to produce as little DOM traffic (i.e. js calls to modify the DOM-tree) as possible to be efficient.
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
use crate::;
/// This struct is a container, with the current Element state (e.g. whether it was created/hydrated or generally needs an update), and the modifier itself.
/// This trait is intended to give access to modifiers of a [`ViewElement`](crate::core::ViewElement).
pub type Children = ;