Skip to main content

hypen_engine/
lib.rs

1pub mod dispatch;
2pub mod engine;
3pub mod error;
4pub mod ir;
5pub mod lifecycle;
6pub mod logger;
7pub mod reactive;
8pub mod reconcile;
9pub mod render;
10pub mod serialize;
11pub mod state;
12
13// WASM bindings module
14// The FFI types (wasm::ffi) are always available for testing and cross-platform use.
15// The actual WASM bindings are conditionally compiled:
16// - `js` feature: JavaScript bindings via wasm-bindgen (Node.js, Bun, browsers)
17// - `wasi` feature: WASI-compatible C FFI (Go, Python, Rust, etc.)
18pub mod wasm;
19
20// UniFFI bindings for native platforms (Kotlin, Swift, Python, Ruby)
21#[cfg(feature = "uniffi")]
22pub mod uniffi;
23
24// UniFFI scaffolding must be in crate root
25#[cfg(feature = "uniffi")]
26::uniffi::setup_scaffolding!();
27
28pub use engine::Engine;
29pub use error::EngineError;
30
31pub use ir::{ast_to_ir, Element, Value};
32pub use lifecycle::{Module, ModuleInstance};
33pub use reconcile::Patch;
34pub use state::StateChange;
35
36#[cfg(test)]
37mod tailwind_tests {
38    use hypen_tailwind_parse::parse_classes;
39
40    #[test]
41    fn test_tailwind_parse_basic() {
42        let output = parse_classes("p-4 text-blue-500 bg-white");
43        assert_eq!(output.base.len(), 3);
44
45        let props = output.to_props();
46        assert_eq!(props.get("padding"), Some(&"1rem".to_string()));
47        assert_eq!(props.get("color"), Some(&"#3b82f6".to_string()));
48        assert_eq!(props.get("background-color"), Some(&"#ffffff".to_string()));
49    }
50
51    #[test]
52    fn test_tailwind_parse_with_breakpoints() {
53        let output = parse_classes("p-4 md:p-8 lg:p-12");
54
55        let props = output.to_props();
56        assert_eq!(props.get("padding"), Some(&"1rem".to_string()));
57        assert_eq!(props.get("padding@md"), Some(&"2rem".to_string()));
58        assert_eq!(props.get("padding@lg"), Some(&"3rem".to_string()));
59    }
60
61    #[test]
62    fn test_tailwind_parse_with_hover() {
63        let output = parse_classes("bg-white hover:bg-blue-500");
64
65        let props = output.to_props();
66        assert_eq!(props.get("background-color"), Some(&"#ffffff".to_string()));
67        assert_eq!(
68            props.get("background-color:hover"),
69            Some(&"#3b82f6".to_string())
70        );
71    }
72
73    #[test]
74    fn test_tailwind_parse_layout() {
75        let output = parse_classes("flex justify-center items-center gap-4");
76
77        let props = output.to_props();
78        assert_eq!(props.get("display"), Some(&"flex".to_string()));
79        assert_eq!(props.get("justify-content"), Some(&"center".to_string()));
80        assert_eq!(props.get("align-items"), Some(&"center".to_string()));
81        assert_eq!(props.get("gap"), Some(&"1rem".to_string()));
82    }
83
84    #[test]
85    fn test_tailwind_parse_sizing() {
86        let output = parse_classes("w-full h-screen max-w-lg");
87
88        let props = output.to_props();
89        assert_eq!(props.get("width"), Some(&"100%".to_string()));
90        assert_eq!(props.get("height"), Some(&"100vh".to_string()));
91        assert_eq!(props.get("max-width"), Some(&"32rem".to_string()));
92    }
93}