MoonStyle — Typed atomic CSS for MoonBit.
pub fn registry() -> @moonstyle.Registry {
@moonstyle.registry("example/styles", [
@moonstyle.rule("card")
.padding(@moonstyle.px(12))
.color(@moonstyle.rgb(24, 32, 40))
.opacity(0.8, when=@moonstyle.hover),
])
}let attrs = @css.attrs(@styles.card)let composed = @moonstyle.compose(@styles.card)
.when(active, @styles.active)
.add(@styles.meter(progress))
match @css.try_attrs(composed) {
Ok(attrs) => render(attrs)
Err(errors) => render_dynamic_errors(errors)
}moon update
vp install --frozen-lockfile
vp devvp run check-docs
vp check
vp run validatepub struct RegistryBuilder {
module_name : String
sheets : Array[StyleSheet]
contracts : Array[StyleContract]
themes : Array[Theme]
recipes : Array[Recipe]
markers : Array[MarkerDefinition]
position_tries : Array[PositionTryRule]
view_transition_classes : Array[ViewTransitionClassDefinition]
dependencies : Array[DependencyRef]
extra_tokens : Array[VariableUse]
}fn RegistryBuilder::position_try(self : RegistryBuilder, value : PositionTryRule) -> RegistryBuilderfn RegistryBuilder::rules(self : RegistryBuilder, rules : Array[Rule], export_name? : String) -> RegistryBuilderfn RegistryBuilder::view_transition_class(self : RegistryBuilder, value : ViewTransitionClassDefinition) -> RegistryBuilderfn attribute(name : String, operator? : AttributeOperator, value? : String, case_mode? : AttributeCase) -> Whenfn attribute_state(name : String, operator? : AttributeOperator, value? : String, case_mode? : AttributeCase) -> SelectorStatefn[I : ImageInput] background_layer(image : I, position? : GradientPosition, size? : LayerSize, repeat? : RepeatStyle, attachment? : LayerAttachment, origin? : LayerBox, clip? : LayerBox) -> BackgroundLayerfn border_radii(horizontal : Array[MathExpr[LengthPercentage]], vertical? : Array[MathExpr[LengthPercentage]]) -> BorderRadiifn checked_when(style : Result[CompiledStyle, Array[DynamicValueError]], enabled : Bool) -> Result[CompiledStyle, Array[DynamicValueError]]fn[R : LengthPercentageMathInput] circle_shape(radius : R, center? : GradientPosition) -> BasicShapefn[A : GradientColorInput, B : GradientColorInput] color_mix(space : ColorSpace, first : A, second : B, first_weight? : Percentage, second_weight? : Percentage, hue? : HueInterpolation) -> ColorExprfn color_space(space : ColorSpace, first : Double, second : Double, third : Double, alpha? : Double) -> Colorfn[C : GradientColorInput] color_stop(color : C, position? : MathExpr[LengthPercentage]?, end? : MathExpr[LengthPercentage]?) -> GradientStop[LengthPercentage]fn conic_gradient(stops : Array[GradientStop[ConicPosition]], angle? : MathExpr[Angle]?, center? : GradientPosition, repeating? : Bool, interpolation? : ColorInterpolation) -> Imagefn[C : GradientColorInput] conic_stop(color : C, position? : ConicPosition?, end? : ConicPosition?) -> GradientStop[ConicPosition]fn container_feature(axis : ContainerAxis, operator : ContainerOperator, value : Length) -> ContainerFeaturefn[T : CssValue] container_style_slot_equals(slot : DynamicSlot[T], value : T) -> ContainerStyleQueryfn[T : BoxSizeValueInput] corner_radius(horizontal : T, vertical? : LengthPercentage?) -> CornerRadiustest {
let transition = @builder.define_view_transition_class("card")
.old(@builder.rule("outgoing").opacity(0.5))
.new(@builder.rule("incoming").opacity(1.0))
assert_eq(transition.to_ir().styles.length(), 2)
}fn[X : LengthPercentageMathInput, Y : LengthPercentageMathInput] ellipse_shape(x : X, y : Y, center? : GradientPosition) -> BasicShapefn[X : LengthPercentageMathInput, Y : LengthPercentageMathInput] gradient_position(x : X, y : Y) -> GradientPositionfn[I : ImageInput] image_candidate(value : I, resolution? : Resolution, mime? : String) -> ImageCandidatefn inset_shape(offsets : Array[MathExpr[LengthPercentage]], radius? : MathExpr[LengthPercentage]) -> BasicShapefn[X : LengthPercentageMathInput, Y : LengthPercentageMathInput] layer_dimensions(width : X, height : Y) -> LayerSizefn length_percentage_slot(scope : String, name : String, default : LengthPercentage) -> DynamicSlot[LengthPercentage]fn length_percentage_token(scope : String, name : String, default : LengthPercentage) -> Token[LengthPercentage]fn linear_gradient(stops : Array[GradientStop[LengthPercentage]], direction? : GradientDirection, repeating? : Bool, interpolation? : ColorInterpolation) -> Imagefn[I : ImageInput] mask_layer(image : I, position? : GradientPosition, size? : LayerSize, repeat? : RepeatStyle, origin? : MaskBox, clip? : MaskClip, mode? : MaskMode, composite? : MaskComposite) -> MaskLayerfn media_query(features : Array[MediaFeature], negated? : Bool, media_type? : MediaType?) -> MediaQueryfn[A : AngleMathInput] offset_rotation(angle : A, automatic? : Bool, reverse? : Bool) -> OffsetRotatetest {
assert_eq(@values.page_name("Report").to_css(), "Report")
assert_eq(@values.page_auto().to_css(), "auto")
}fn position_area(horizontal : PositionAreaHorizontal, vertical : PositionAreaVertical) -> PositionAreatest {
let fallback = @builder.position_try_rule("tooltip")
.inset_inline_start(@values.px(8))
.max_inline_size(@values.percent(90))
assert_eq(fallback.to_ir().descriptors.length(), 2)
}fn position_try_value(fallbacks : PositionTryFallbacks, order? : PositionTryOrder?) -> PositionTryValuefn props_checked(checked_styles : Array[Result[CompiledStyle, Array[DynamicValueError]]], base_styles? : Array[CompiledStyle]) -> Result[AppliedStyle, Array[DynamicValueError]]fn radial_gradient(stops : Array[GradientStop[LengthPercentage]], shape? : RadialShape, size? : RadialSize, center? : GradientPosition, repeating? : Bool, interpolation? : ColorInterpolation) -> Imagefn[X : LengthPercentageMathInput, Y : LengthPercentageMathInput] radial_radii(x : X, y : Y) -> RadialSizefn[A : AngleMathInput] ray_path(angle : A, size? : RaySize, contain? : Bool, center? : GradientPosition) -> MotionPathfn registry(module_name : String, rules : Array[Rule], export_name? : String, contracts? : Array[StyleContract], themes? : Array[Theme], recipes? : Array[Recipe], markers? : Array[MarkerDefinition], position_tries? : Array[PositionTryRule], view_transition_classes? : Array[ViewTransitionClassDefinition], dependencies? : Array[DependencyRef], extra_tokens? : Array[VariableUse]) -> Registryfn registry_sheets(module_name : String, sheets : Array[StyleSheet], contracts? : Array[StyleContract], themes? : Array[Theme], recipes? : Array[Recipe], markers? : Array[MarkerDefinition], position_tries? : Array[PositionTryRule], view_transition_classes? : Array[ViewTransitionClassDefinition], dependencies? : Array[DependencyRef], extra_tokens? : Array[VariableUse]) -> Registryfn[X : NumberMathInput, Y : NumberMathInput, Z : NumberMathInput, A : AngleMathInput] rotate3d(x : X, y : Y, z : Z, angle : A) -> TransformFunctionfn[X : NumberMathInput, Y : NumberMathInput, Z : NumberMathInput] scale3d(x : X, y : Y, z : Z) -> TransformFunctionfn[A : GradientColorInput, B : GradientColorInput] scrollbar_colors(thumb~ : A, track~ : B) -> ScrollbarColorfn[T : MarkerInput] selector_attribute_equals(marker : T, name : String, value : String) -> MarkerSelectorfn[X : LengthMathInput, Y : LengthMathInput] shadow(x : X, y : Y, blur? : Length?, spread? : Length?, color? : Color?, inset? : Bool) -> Shadowfn source_span(file : String, line : Int, column : Int, end_line? : Int, end_column? : Int, symbol? : String) -> SourceSpan#deprecated("Use compose(input) for a non-empty composition or style_list() for an empty composition")
fn[T : StyleInput] styles(initial : Array[T]) -> StyleListfn[X : LengthPercentageMathInput, Y : LengthPercentageMathInput, Z : LengthMathInput] translate3d(x : X, y : Y, z : Z) -> TransformFunctionfn view_timeline(axis? : TimelineAxis, inset? : MathExpr[LengthPercentage], end_inset? : MathExpr[LengthPercentage]) -> AnimationTimeline