diff --git a/Cargo.lock b/Cargo.lock index 9bc51f4..24eadcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -55,9 +55,15 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + [[package]] name = "arrayvec" version = "0.7.6" @@ -187,6 +193,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -226,18 +244,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foldhash" version = "0.2.0" @@ -260,7 +306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bbc252c93499b6d3635d692f892a637db0dbb130ce9b32bf20b28e0dcc470b" dependencies = [ "bytemuck", - "hashbrown", + "hashbrown 0.16.1", "icu_locale_core", "linebender_resource_handle", "memmap2", @@ -301,6 +347,19 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + [[package]] name = "grid" version = "1.0.0" @@ -320,6 +379,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash 0.1.5", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -328,7 +396,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.2.0", ] [[package]] @@ -351,6 +419,7 @@ name = "htvg-core" version = "0.1.0" dependencies = [ "base64", + "insta", "parley", "serde", "serde_json", @@ -384,6 +453,36 @@ dependencies = [ "writeable", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "insta" +version = "1.46.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -406,6 +505,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.180" @@ -434,12 +539,24 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "litemap" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + [[package]] name = "memchr" version = "2.7.6" @@ -471,7 +588,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -554,7 +671,7 @@ checksum = "ada5338c3a9794af7342e6f765b6e78740db37378aced034d7bf72c96b94ed94" dependencies = [ "fontique", "harfrust", - "hashbrown", + "hashbrown 0.16.1", "linebender_resource_handle", "skrifa", "swash", @@ -578,6 +695,16 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.105" @@ -596,6 +723,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "read-fonts" version = "0.35.0" @@ -616,6 +749,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + [[package]] name = "rustversion" version = "1.0.22" @@ -631,6 +777,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -691,6 +843,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "skrifa" version = "0.37.0" @@ -762,6 +920,19 @@ dependencies = [ "slotmap", ] +[[package]] +name = "tempfile" +version = "3.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "thiserror" version = "2.0.18" @@ -805,6 +976,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "utf8parse" version = "0.2.2" @@ -827,6 +1004,24 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.108" @@ -925,6 +1120,40 @@ version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8145dd1593bf0fb137dbfa85b8be79ec560a447298955877804640e40c2d6ea" +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "web-sys" version = "0.3.85" @@ -941,7 +1170,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1014,6 +1243,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -1087,6 +1325,94 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + [[package]] name = "writeable" version = "0.6.2" diff --git a/crates/htvg-core/Cargo.toml b/crates/htvg-core/Cargo.toml index dadf6ab..f4412f5 100644 --- a/crates/htvg-core/Cargo.toml +++ b/crates/htvg-core/Cargo.toml @@ -27,3 +27,6 @@ base64 = "0.22" # Error handling thiserror = "2.0.18" + +[dev-dependencies] +insta = "1.42" diff --git a/crates/htvg-core/src/element.rs b/crates/htvg-core/src/element.rs index b8b29af..6eeff9a 100644 --- a/crates/htvg-core/src/element.rs +++ b/crates/htvg-core/src/element.rs @@ -389,6 +389,10 @@ pub struct BoxStyle { pub margin: Option, pub padding: Option, + // Flex child properties + pub flex_grow: Option, + pub flex_shrink: Option, + // Visual pub background_color: Option, pub border_width: Option, @@ -423,6 +427,10 @@ pub struct FlexStyle { pub gap: Option, pub flex_wrap: Option, + // Flex child properties + pub flex_grow: Option, + pub flex_shrink: Option, + // Visual pub background_color: Option, pub border_width: Option, diff --git a/crates/htvg-core/src/layout.rs b/crates/htvg-core/src/layout.rs index 0d4eb1c..09b8ed9 100644 --- a/crates/htvg-core/src/layout.rs +++ b/crates/htvg-core/src/layout.rs @@ -377,6 +377,8 @@ fn box_style_to_taffy(style: &BoxStyle) -> Style { margin: spacing_to_taffy_rect(&style.margin), padding: spacing_to_taffy_rect_lp(&style.padding), border: spacing_to_taffy_rect_lp(&style.border_width.map(Spacing::Uniform)), + flex_grow: style.flex_grow.unwrap_or(0.0), + flex_shrink: style.flex_shrink.unwrap_or(1.0), ..Default::default() } } @@ -431,6 +433,8 @@ fn flex_style_to_taffy(style: &FlexStyle) -> Style { Some(ElemFlexWrap::Wrap) => taffy::FlexWrap::Wrap, _ => taffy::FlexWrap::NoWrap, }, + flex_grow: style.flex_grow.unwrap_or(0.0), + flex_shrink: style.flex_shrink.unwrap_or(1.0), ..Default::default() } } diff --git a/crates/htvg-core/tests/playbadges_snapshot.rs b/crates/htvg-core/tests/playbadges_snapshot.rs new file mode 100644 index 0000000..9412bd0 --- /dev/null +++ b/crates/htvg-core/tests/playbadges_snapshot.rs @@ -0,0 +1,322 @@ +//! Snapshot tests for PlayBadges recreation using htvg. +//! +//! These tests verify that htvg can recreate PlayBadges-style app badges +//! (originally built with satori) using the JSON element tree format. +//! +//! ## Missing features for full PlayBadges parity +//! +//! The following features would be needed for a pixel-perfect recreation: +//! +//! 1. **boxShadow**: PlayBadges uses `shadow-lg` on the app icon. htvg does not +//! yet support box shadows (drop shadows on elements). +//! +//! 2. **Inline/mixed text styling**: PlayBadges renders the download count, star +//! rating, and rating count as differently-styled spans within the same line +//! (e.g., "4.4" in white + "★" in yellow + "(1.2K)" in gray). htvg's text +//! element only supports a single style per text node. Rich text / inline +//! spans would be needed. +//! +//! 3. **Icon fonts (Material Symbols)**: PlayBadges uses Material Symbols Outlined +//! for the download icon (). htvg would need font loading and icon +//! glyph rendering support. +//! +//! 4. **Font loading from URLs at compile time**: PlayBadges loads fonts from +//! Google Fonts CDN at render time. htvg supports @font-face URL references +//! in SVG output but doesn't fetch and use font metrics from remote URLs +//! during layout computation. +//! +//! 5. **Percentage-based heights**: While htvg supports percentage dimensions, +//! using `height: "100%"` on flex children for full-height content areas +//! could be improved. + +use htvg_core::{compile_document, CompileOptions, compile}; + +/// Helper to load and compile a PlayBadges example JSON file. +fn compile_example(filename: &str) -> htvg_core::CompileResult { + let json = std::fs::read_to_string( + std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .parent() + .unwrap() + .join("examples") + .join(filename), + ) + .unwrap_or_else(|e| panic!("Failed to read example {}: {}", filename, e)); + + compile_document(&json).unwrap_or_else(|e| panic!("Failed to compile {}: {}", filename, e)) +} + +#[test] +fn test_playbadge_dark_compiles() { + let result = compile_example("playbadge-dark.json"); + + // Verify basic SVG structure + assert!(result.svg.contains("")); + + // Verify dimensions + assert_eq!(result.width, 350.0); + assert_eq!(result.height, 150.0); + + // Verify dark theme colors + assert!(result.svg.contains("#000000")); // background + assert!(result.svg.contains("#1f2937")); // border + + // Verify text content (text may be word-wrapped into separate tspan elements) + assert!(result.svg.contains("VR")); + assert!(result.svg.contains("Checker")); + assert!(result.svg.contains("pavi2410")); + assert!(result.svg.contains("150K")); + + // Snapshot the full SVG output + insta::assert_snapshot!("playbadge_dark", result.svg); +} + +#[test] +fn test_playbadge_light_compiles() { + let result = compile_example("playbadge-light.json"); + + // Verify basic SVG structure + assert!(result.svg.contains("")); + + // Verify dimensions + assert_eq!(result.width, 350.0); + assert_eq!(result.height, 150.0); + + // Verify light theme colors + assert!(result.svg.contains("#ffffff")); // background + assert!(result.svg.contains("#f3f4f6")); // border + + // Verify text content (text may be word-wrapped into separate tspan elements) + assert!(result.svg.contains("VR")); + assert!(result.svg.contains("Checker")); + assert!(result.svg.contains("pavi2410")); + assert!(result.svg.contains("150K")); + + // Snapshot the full SVG output + insta::assert_snapshot!("playbadge_light", result.svg); +} + +#[test] +fn test_playbadge_dark_norating_compiles() { + let result = compile_example("playbadge-dark-norating.json"); + + // Verify basic SVG structure + assert!(result.svg.contains("")); + + // Verify dimensions + assert_eq!(result.width, 350.0); + assert_eq!(result.height, 150.0); + + // Verify content for app with no rating (text may be word-wrapped) + assert!(result.svg.contains("Folo:")); + assert!(result.svg.contains("pavi2410")); + assert!(result.svg.contains("N/A")); + + // Snapshot the full SVG output + insta::assert_snapshot!("playbadge_dark_norating", result.svg); +} + +#[test] +fn test_playbadge_has_rounded_corners() { + let result = compile_example("playbadge-dark.json"); + + // The outer container has borderRadius: 24 - should generate a rounded rect + // Border radius 24 is uniform, so it uses rx attribute + assert!(result.svg.contains("rx=\"24")); +} + +#[test] +fn test_playbadge_has_image() { + let result = compile_example("playbadge-dark.json"); + + // Should contain an image element with the icon URL + assert!(result.svg.contains(" +Expanded diff --git a/crates/htvg-core/tests/snapshots/playbadges_snapshot__og_image_layout.snap b/crates/htvg-core/tests/snapshots/playbadges_snapshot__og_image_layout.snap new file mode 100644 index 0000000..8025190 --- /dev/null +++ b/crates/htvg-core/tests/snapshots/playbadges_snapshot__og_image_layout.snap @@ -0,0 +1,6 @@ +--- +source: crates/htvg-core/tests/playbadges_snapshot.rs +expression: result.svg +--- + +Building a CSS-in-Rust SVGGeneratorPavitra Golchhacsswebperformance diff --git a/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark.snap b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark.snap new file mode 100644 index 0000000..6814cfd --- /dev/null +++ b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark.snap @@ -0,0 +1,6 @@ +--- +source: crates/htvg-core/tests/playbadges_snapshot.rs +expression: result.svg +--- + +VRCompatibilityCheckerpavi2410150K4.4 ★(1.2K) diff --git a/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark_norating.snap b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark_norating.snap new file mode 100644 index 0000000..61f441b --- /dev/null +++ b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_dark_norating.snap @@ -0,0 +1,6 @@ +--- +source: crates/htvg-core/tests/playbadges_snapshot.rs +expression: result.svg +--- + +Folo: SocialFollowersTrackerpavi2410220★ N/A diff --git a/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_light.snap b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_light.snap new file mode 100644 index 0000000..3ebfa8f --- /dev/null +++ b/crates/htvg-core/tests/snapshots/playbadges_snapshot__playbadge_light.snap @@ -0,0 +1,6 @@ +--- +source: crates/htvg-core/tests/playbadges_snapshot.rs +expression: result.svg +--- + +VRCompatibilityCheckerpavi2410150K4.4 ★(1.2K) diff --git a/examples/playbadge-dark-norating.json b/examples/playbadge-dark-norating.json new file mode 100644 index 0000000..d0552af --- /dev/null +++ b/examples/playbadge-dark-norating.json @@ -0,0 +1,93 @@ +{ + "meta": { + "width": 350, + "height": 150 + }, + "content": { + "type": "flex", + "style": { + "width": 350, + "height": 150, + "flexDirection": "row", + "alignItems": "center", + "padding": "0 12", + "borderRadius": 24, + "borderWidth": 2, + "borderColor": "#1f2937", + "backgroundColor": "#000000" + }, + "children": [ + { + "type": "image", + "src": "https://play-lh.googleusercontent.com/example-icon-2", + "width": 120, + "height": 120, + "style": { + "borderRadius": 16, + "margin": "0 16 0 0" + } + }, + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1, + "height": 126 + }, + "children": [ + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1 + }, + "children": [ + { + "type": "text", + "content": "Folo: Social Followers Tracker", + "style": { + "fontSize": 20, + "fontWeight": 600, + "color": "#ffffff" + } + }, + { + "type": "text", + "content": "pavi2410", + "style": { + "fontWeight": 600, + "color": "#4ade80" + } + } + ] + }, + { + "type": "flex", + "style": { + "flexDirection": "row", + "justifyContent": "space-between", + "alignItems": "center" + }, + "children": [ + { + "type": "text", + "content": "220", + "style": { + "fontWeight": 600, + "color": "#ffffff" + } + }, + { + "type": "text", + "content": "★ N/A", + "style": { + "color": "#9ca3af" + } + } + ] + } + ] + } + ] + } +} diff --git a/examples/playbadge-dark-norating.svg b/examples/playbadge-dark-norating.svg new file mode 100644 index 0000000..3c20b89 --- /dev/null +++ b/examples/playbadge-dark-norating.svg @@ -0,0 +1,2 @@ + +Folo: SocialFollowersTrackerpavi2410220★ N/A \ No newline at end of file diff --git a/examples/playbadge-dark.json b/examples/playbadge-dark.json new file mode 100644 index 0000000..121580f --- /dev/null +++ b/examples/playbadge-dark.json @@ -0,0 +1,93 @@ +{ + "meta": { + "width": 350, + "height": 150 + }, + "content": { + "type": "flex", + "style": { + "width": 350, + "height": 150, + "flexDirection": "row", + "alignItems": "center", + "padding": "0 12", + "borderRadius": 24, + "borderWidth": 2, + "borderColor": "#1f2937", + "backgroundColor": "#000000" + }, + "children": [ + { + "type": "image", + "src": "https://play-lh.googleusercontent.com/example-icon", + "width": 120, + "height": 120, + "style": { + "borderRadius": 16, + "margin": "0 16 0 0" + } + }, + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1, + "height": 126 + }, + "children": [ + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1 + }, + "children": [ + { + "type": "text", + "content": "VR Compatibility Checker", + "style": { + "fontSize": 20, + "fontWeight": 600, + "color": "#ffffff" + } + }, + { + "type": "text", + "content": "pavi2410", + "style": { + "fontWeight": 600, + "color": "#4ade80" + } + } + ] + }, + { + "type": "flex", + "style": { + "flexDirection": "row", + "justifyContent": "space-between", + "alignItems": "center" + }, + "children": [ + { + "type": "text", + "content": "150K", + "style": { + "fontWeight": 600, + "color": "#ffffff" + } + }, + { + "type": "text", + "content": "4.4 ★ (1.2K)", + "style": { + "color": "#9ca3af" + } + } + ] + } + ] + } + ] + } +} diff --git a/examples/playbadge-dark.svg b/examples/playbadge-dark.svg new file mode 100644 index 0000000..b298833 --- /dev/null +++ b/examples/playbadge-dark.svg @@ -0,0 +1,2 @@ + +VRCompatibilityCheckerpavi2410150K4.4 ★(1.2K) \ No newline at end of file diff --git a/examples/playbadge-light.json b/examples/playbadge-light.json new file mode 100644 index 0000000..42ffdac --- /dev/null +++ b/examples/playbadge-light.json @@ -0,0 +1,93 @@ +{ + "meta": { + "width": 350, + "height": 150 + }, + "content": { + "type": "flex", + "style": { + "width": 350, + "height": 150, + "flexDirection": "row", + "alignItems": "center", + "padding": "0 12", + "borderRadius": 24, + "borderWidth": 2, + "borderColor": "#f3f4f6", + "backgroundColor": "#ffffff" + }, + "children": [ + { + "type": "image", + "src": "https://play-lh.googleusercontent.com/example-icon", + "width": 120, + "height": 120, + "style": { + "borderRadius": 16, + "margin": "0 16 0 0" + } + }, + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1, + "height": 126 + }, + "children": [ + { + "type": "flex", + "style": { + "flexDirection": "column", + "flexGrow": 1 + }, + "children": [ + { + "type": "text", + "content": "VR Compatibility Checker", + "style": { + "fontSize": 20, + "fontWeight": 600, + "color": "#000000" + } + }, + { + "type": "text", + "content": "pavi2410", + "style": { + "fontWeight": 600, + "color": "#15803d" + } + } + ] + }, + { + "type": "flex", + "style": { + "flexDirection": "row", + "justifyContent": "space-between", + "alignItems": "center" + }, + "children": [ + { + "type": "text", + "content": "150K", + "style": { + "fontWeight": 600, + "color": "#000000" + } + }, + { + "type": "text", + "content": "4.4 ★ (1.2K)", + "style": { + "color": "#6b7280" + } + } + ] + } + ] + } + ] + } +} diff --git a/examples/playbadge-light.svg b/examples/playbadge-light.svg new file mode 100644 index 0000000..d1e0a41 --- /dev/null +++ b/examples/playbadge-light.svg @@ -0,0 +1,2 @@ + +VRCompatibilityCheckerpavi2410150K4.4 ★(1.2K) \ No newline at end of file diff --git a/packages/htvg/src/types.ts b/packages/htvg/src/types.ts index 1fb1e01..e956db9 100644 --- a/packages/htvg/src/types.ts +++ b/packages/htvg/src/types.ts @@ -58,6 +58,9 @@ export interface BoxStyle { margin?: Spacing; padding?: Spacing; + flexGrow?: number; + flexShrink?: number; + backgroundColor?: Color; borderWidth?: number; borderColor?: Color; @@ -85,6 +88,9 @@ export interface FlexStyle { gap?: number; flexWrap?: FlexWrap; + flexGrow?: number; + flexShrink?: number; + backgroundColor?: Color; borderWidth?: number; borderColor?: Color;