From 523f2a08ae78ac2d09b6f6f67a1a8d2ba360a703 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 24 Sep 2026 21:01:14 +0900 Subject: [PATCH 01/12] fix(css): encode values in debug class names Debug class names encoded the selector but appended the style value verbatim. Values such as .8, $text, 50% or calc() made the emitted selector invalid, so browsers dropped the rule. #FFF turned into an ID selector, and values with spaces split one class into several class tokens, so those rules never matched. Run the value through the same encoder as the selector. Production builds are unaffected; they use base-37 names. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- libs/css/src/lib.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/libs/css/src/lib.rs b/libs/css/src/lib.rs index ea1e9225b..f9479f02e 100644 --- a/libs/css/src/lib.rs +++ b/libs/css/src/lib.rs @@ -502,20 +502,22 @@ pub fn sheet_to_classname( } else { encode_selector(selector) }; + // Encode the value like the selector: `.8`, `$text` or `#FFF` would break the + // CSS selector, and spaces would split the class attribute into several classes. + let value = encode_selector(&optimized); let file_suffix = filename.map(get_file_num_by_filename); let order = style_order.unwrap_or(255); let prop = property.trim(); with_prefix(|prefix| { - // Estimate capacity: prefix + prop + separators + level(1-3) + optimized + encoded + order(1-3) + file - let mut result = String::with_capacity( - prefix.len() + prop.len() + optimized.len() + encoded.len() + 16, - ); + // Estimate capacity: prefix + prop + separators + level(1-3) + value + encoded + order(1-3) + file + let mut result = + String::with_capacity(prefix.len() + prop.len() + value.len() + encoded.len() + 16); result.push_str(prefix); result.push_str(prop); result.push('-'); write_u8(&mut result, level); result.push('-'); - result.push_str(&optimized); + result.push_str(&value); result.push('-'); result.push_str(&encoded); result.push('-'); @@ -1038,6 +1040,29 @@ mod tests { ); } + #[test] + #[serial] + fn test_debug_sheet_to_classname_encodes_value() { + set_debug(true); + for (property, value, expected) in [ + ("scale", "0.8", "scale-0-_d_8--255"), + ("background", "$text", "background-0-_dl_text--255"), + ("color", "#fff", "color-0-_h_FFF--255"), + ("height", "50%", "height-0-50_pc_--255"), + ( + "transition", + "all .2s ease-in-out", + "transition-0-all_s__d_2s_s_ease-in-out--255", + ), + ] { + assert_eq!( + sheet_to_classname(property, 0, Some(value), None, None, None), + expected + ); + } + set_debug(false); + } + #[test] #[serial] fn test_debug_sheet_to_classname_with_filename() { From f14dde02c66ea2756355d3763f39e3e31306ec0f Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 24 Sep 2026 21:03:19 +0900 Subject: [PATCH 02/12] test(components): expect encoded values in Input and Textarea debug classes Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../__snapshots__/index.browser.test.tsx.snap | 30 +++++++++---------- .../Input/__tests__/index.browser.test.tsx | 4 +-- .../__snapshots__/index.browser.test.tsx.snap | 22 +++++++------- .../Textarea/__tests__/index.browser.test.tsx | 4 +-- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/components/src/components/Input/__tests__/__snapshots__/index.browser.test.tsx.snap b/packages/components/src/components/Input/__tests__/__snapshots__/index.browser.test.tsx.snap index b920c9c38..be182a6d2 100644 --- a/packages/components/src/components/Input/__tests__/__snapshots__/index.browser.test.tsx.snap +++ b/packages/components/src/components/Input/__tests__/__snapshots__/index.browser.test.tsx.snap @@ -3,7 +3,7 @@ exports[`Input should render with default props 1`] = ` "
- +
" `; @@ -11,7 +11,7 @@ exports[`Input should render with default props 1`] = ` exports[`Input should render with disabled prop 1`] = ` "
- +
" `; @@ -19,7 +19,7 @@ exports[`Input should render with disabled prop 1`] = ` exports[`Input should render with allowClear prop 1`] = ` "
- +
" `; @@ -27,7 +27,7 @@ exports[`Input should render with allowClear prop 1`] = ` exports[`Input should not have padding right when allowClear is false 1`] = ` "
- +
" `; @@ -35,7 +35,7 @@ exports[`Input should not have padding right when allowClear is false 1`] = ` exports[`Input should not show clear button when value is empty 1`] = ` "
- +
" `; @@ -43,7 +43,7 @@ exports[`Input should not show clear button when value is empty 1`] = ` exports[`Input should render error style when error is true 1`] = ` "
- +
" `; @@ -51,7 +51,7 @@ exports[`Input should render error style when error is true 1`] = ` exports[`Input should have typography when typography is provided 1`] = ` "
- +
" `; @@ -59,8 +59,8 @@ exports[`Input should have typography when typography is provided 1`] = ` exports[`Input should pass className prop to error message component 1`] = ` "
- - + + Error message
@@ -70,20 +70,20 @@ exports[`Input should pass className prop to error message component 1`] = ` exports[`Input should pass className prop to icon component 1`] = ` "
-
+
- +
" `; exports[`Input should pass props to ClearButton component 1`] = ` "
-