///|
pub struct MarkerDefinition {
name : String
}
///|
pub fn define_marker(name : String) -> MarkerDefinition {
{ name, }
}
///|
pub(open) trait MarkerInput {
fn marker_reference(Self) -> @ir.SelectorMarkerRef
}
///|
pub impl MarkerInput for MarkerDefinition with fn marker_reference(self) {
@ir.selector_marker_ref("", self.name, "")
}
///|
pub impl MarkerInput for @runtime.SelectorMarker with fn marker_reference(self) {
@ir.selector_marker_ref(self.module_name(), self.name(), self.class_name())
}
///|
pub struct MarkerSelector {
reference : @ir.SelectorMarkerRef
}
///|
pub impl MarkerInput for MarkerSelector with fn marker_reference(self) {
self.reference
}
///|
fn[T : MarkerInput] marker_with_state(
marker : T,
state : @ir.SelectorState,
) -> MarkerSelector {
let reference = marker.marker_reference()
let states = reference.states.copy()
states.push(state)
{
reference: {
module_name: reference.module_name,
name: reference.name,
class_name: reference.class_name,
states,
},
}
}
///|
pub fn[T : MarkerInput] selector_pseudo(
marker : T,
state : @ir.PseudoClass,
) -> MarkerSelector {
marker_with_state(marker, @ir.SelectorPseudo(state))
}
///|
pub fn[T : MarkerInput] selector_attribute(
marker : T,
name : String,
) -> MarkerSelector {
marker_with_state(marker, @ir.SelectorAttribute(name))
}
///|
pub fn[T : MarkerInput] selector_attribute_equals(
marker : T,
name : String,
value : String,
) -> MarkerSelector {
marker_with_state(marker, @ir.SelectorAttributeEquals(name, value))
}
///|
pub fn[T : MarkerInput] marker_ancestor(marker : T) -> When {
when([@ir.relational(marker.marker_reference(), MarkerAncestor)])
}
///|
pub fn[T : MarkerInput] marker_descendant(marker : T) -> When {
when([@ir.relational(marker.marker_reference(), MarkerDescendant)])
}
///|
pub fn[T : MarkerInput] marker_sibling_before(marker : T) -> When {
when([@ir.relational(marker.marker_reference(), MarkerSiblingBefore)])
}
///|
pub fn[T : MarkerInput] marker_sibling_after(marker : T) -> When {
when([@ir.relational(marker.marker_reference(), MarkerSiblingAfter)])
}
///|
pub fn[T : MarkerInput] marker_any_sibling(marker : T) -> When {
when([@ir.relational(marker.marker_reference(), MarkerAnySibling)])
}
///|
pub fn MarkerDefinition::to_ir(self : MarkerDefinition) -> @ir.MarkerDefinition {
{ name: self.name, }
}
///|
pub(all) enum ContainerAxis {
ContainerWidth
ContainerHeight
ContainerInlineSize
ContainerBlockSize
} derive(Eq, Debug)
///|
pub(all) enum ContainerOperator {
ContainerMin
ContainerMax
ContainerEqual
ContainerLessThan
ContainerGreaterThan
} derive(Eq, Debug)
///|
pub struct ContainerName {
value : String
}
///|
pub fn container_name(value : String) -> ContainerName {
{ value, }
}
///|
pub struct ContainerFeature {
axis : ContainerAxis
operator : ContainerOperator
value : @values.Length
}
///|
pub fn container_feature(
axis : ContainerAxis,
operator : ContainerOperator,
value : @values.Length,
) -> ContainerFeature {
{ axis, operator, value, }
}
///|
fn ContainerAxis::to_name(self : ContainerAxis) -> String {
match self {
ContainerWidth => "width"
ContainerHeight => "height"
ContainerInlineSize => "inline-size"
ContainerBlockSize => "block-size"
}
}
///|
fn ContainerOperator::to_media_operator(
self : ContainerOperator,
) -> @ir.MediaFeatureOperator {
match self {
ContainerMin => Min
ContainerMax => Max
ContainerEqual => Equal
ContainerLessThan => LessThan
ContainerGreaterThan => GreaterThan
}
}
///|
pub fn container_query(
features : Array[ContainerFeature],
name~ : ContainerName? = None,
) -> When {
when([
@ir.container(
@ir.container_query(
features.map(feature => {
@ir.media_feature(
feature.axis.to_name(),
feature.operator.to_media_operator(),
feature.value.to_css(),
)
}),
name=name.map(value => value.value),
),
),
])
}
///|
pub fn container_min_width(
value : @values.Length,
name~ : ContainerName? = None,
) -> When {
container_query(
[container_feature(ContainerWidth, ContainerMin, value)],
name~,
)
}
///|
pub fn container_max_width(
value : @values.Length,
name~ : ContainerName? = None,
) -> When {
container_query(
[container_feature(ContainerWidth, ContainerMax, value)],
name~,
)
}
///|
pub fn container_width_between(
minimum : @values.Length,
maximum : @values.Length,
name~ : ContainerName? = None,
) -> When {
container_query(
[
container_feature(ContainerWidth, ContainerMin, minimum),
container_feature(ContainerWidth, ContainerMax, maximum),
],
name~,
)
}