//! React + Tailwind code for pages: utilities instead of a stylesheet, theme utilities for bound //! variables, fluid boxes, inlined instances, per-side borders, mobile-first responsive merges and //! the Tailwind theme export. use crate::Session; use crate::components::tests::{ex, idv}; use crate::tailwind::{classes, merge}; use figcraft_doc::NodeId; use serde_json::json; fn code(s: &mut Session, id: NodeId, extra: serde_json::Value) -> String { let mut p = json!({"id": id, "language": "tailwind"}); if let (Some(p), Some(e)) = (p.as_object_mut(), extra.as_object()) { p.extend(e.clone()); } ex(s, "inspect.code", p)["code"].as_str().unwrap_or_default().to_string() } /// A 1440 "Page" (vertical auto layout, bg bound to Brand/Accent) holding a 960 "Hero" text and a /// horizontal "Row" of two "Card" frames that fill it. Returns (page, row). fn page(s: &mut Session, name: &str, width: f64, row_dir: &str) -> (NodeId, NodeId) { let p = idv(&ex(s, "frame.create", json!({"x": 0, "y": 0, "width": width, "height": 900, "name": name}))); ex(s, "layout.add", json!({"ids": [p], "direction": "vertical"})); ex(s, "node.set", json!({"id": p, "props": {"gap": 24, "padding": 32}})); let t = idv(&ex(s, "text.create", json!({"text": "Seu site em 7 dias", "x": 0, "y": 0, "parent": p, "props": {"name": "Hero"}}))); ex(s, "node.set", json!({"id": t, "props": {"width": 960, "textAutoResize": "height"}})); let row = idv(&ex(s, "frame.create", json!({"x": 0, "y": 0, "width": 800, "height": 200, "parent": p, "name": "Row"}))); ex(s, "layout.add", json!({"ids": [row], "direction": row_dir})); for _ in 0..2 { let c = idv(&ex(s, "frame.create", json!({"x": 0, "y": 0, "width": 100, "height": 100, "parent": row, "name": "Card"}))); ex(s, "node.set", json!({"id": c, "props": {"sizingH": "fill"}})); } (p, row) } fn brand(s: &mut Session) { ex(s, "variable.createCollection", json!({"name": "Brand"})); ex(s, "variable.create", json!({"collection": "Brand", "name": "Brand/Accent", "type": "color", "value": "#3DDC97"})); ex(s, "variable.create", json!({"collection": "Brand", "name": "card", "type": "number", "value": 12})); ex(s, "variable.create", json!({"collection": "Brand", "name": "fade", "type": "number", "value": 0.5})); } #[test] fn utilities_replace_the_stylesheet_and_variables_become_theme_utilities() { let mut s = Session::new(); brand(&mut s); let (p, row) = page(&mut s, "Landing", 1440.0, "horizontal"); ex(&mut s, "variable.bind", json!({"ids": [p], "field": "fill", "variable": "Brand/Accent"})); ex(&mut s, "node.set", json!({"id": row, "props": {"cornerRadius": 12}})); ex(&mut s, "variable.bind", json!({"ids": [row], "field": "cornerRadius", "variable": "card"})); let out = code(&mut s, p, json!({})); assert!(out.contains("export function Landing() {"), "{out}"); assert!(!out.contains("import") && !out.contains("