diff --git a/reflex/components/tags/tag.py b/reflex/components/tags/tag.py index 515d9e05f5..7f7a8c74d6 100644 --- a/reflex/components/tags/tag.py +++ b/reflex/components/tags/tag.py @@ -101,7 +101,7 @@ def add_props(self, **kwargs: Optional[Any]) -> Tag: """ self.props.update( { - format.to_camel_case(name, allow_hyphens=True): ( + format.to_camel_case(name, treat_hyphens_as_underscores=False): ( prop if types._isinstance(prop, (EventChain, Mapping)) else LiteralVar.create(prop) diff --git a/reflex/style.py b/reflex/style.py index 192835ca3f..fbcfb5d345 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -191,11 +191,12 @@ def update_out_dict( for key, value in style_dict.items(): keys = ( format_style_key(key) - if not isinstance(value, (dict, ObjectVar)) + if not isinstance(value, (dict, ObjectVar, list)) or ( isinstance(value, Breakpoints) and all(not isinstance(v, dict) for v in value.values()) ) + or (isinstance(value, list) and all(not isinstance(v, dict) for v in value)) or ( isinstance(value, ObjectVar) and not issubclass(get_origin(value._var_type) or value._var_type, dict) @@ -237,7 +238,9 @@ def format_style_key(key: str) -> Tuple[str, ...]: Returns: Tuple of css style names corresponding to the key provided. """ - key = format.to_camel_case(key, allow_hyphens=True) + if key.startswith("--"): + return (key,) + key = format.to_camel_case(key) return STYLE_PROP_SHORTHAND_MAPPING.get(key, (key,)) diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 214c845f87..14ef8fb468 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -168,7 +168,7 @@ def to_snake_case(text: str) -> str: return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower().replace("-", "_") -def to_camel_case(text: str, allow_hyphens: bool = False) -> str: +def to_camel_case(text: str, treat_hyphens_as_underscores: bool = True) -> str: """Convert a string to camel case. The first word in the text is converted to lowercase and @@ -176,17 +176,16 @@ def to_camel_case(text: str, allow_hyphens: bool = False) -> str: Args: text: The string to convert. - allow_hyphens: Whether to allow hyphens in the string. + treat_hyphens_as_underscores: Whether to allow hyphens in the string. Returns: The camel case string. """ - char = "_" if allow_hyphens else "-_" - words = re.split(f"[{char}]", text.lstrip(char)) - leading_underscores_or_hyphens = "".join(re.findall(rf"^[{char}]+", text)) + char = "_" if not treat_hyphens_as_underscores else "-_" + words = re.split(f"[{char}]", text) # Capitalize the first letter of each word except the first one converted_word = words[0] + "".join(x.capitalize() for x in words[1:]) - return leading_underscores_or_hyphens + converted_word + return converted_word def to_title_case(text: str, sep: str = "") -> str: diff --git a/tests/units/components/markdown/test_markdown.py b/tests/units/components/markdown/test_markdown.py index c6d395eb1d..15d662ef64 100644 --- a/tests/units/components/markdown/test_markdown.py +++ b/tests/units/components/markdown/test_markdown.py @@ -157,7 +157,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe value, **props ) }, - r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", + r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", ), ( "h1", diff --git a/tests/units/components/test_component.py b/tests/units/components/test_component.py index 8cffa6e0ee..36ff17b6ec 100644 --- a/tests/units/components/test_component.py +++ b/tests/units/components/test_component.py @@ -651,7 +651,7 @@ def test_create_filters_none_props(test_component): # Assert that the style prop is present in the component's props assert str(component.style["color"]) == '"white"' - assert str(component.style["text-align"]) == '"center"' + assert str(component.style["textAlign"]) == '"center"' @pytest.mark.parametrize( diff --git a/tests/units/utils/test_format.py b/tests/units/utils/test_format.py index 89197a03ee..053d5a3ae2 100644 --- a/tests/units/utils/test_format.py +++ b/tests/units/utils/test_format.py @@ -189,11 +189,11 @@ def test_to_snake_case(input: str, output: str): ("kebab-case", "kebabCase"), ("kebab-case-two", "kebabCaseTwo"), ("snake_kebab-case", "snakeKebabCase"), - ("_hover", "_hover"), - ("-starts-with-hyphen", "-startsWithHyphen"), - ("--starts-with-double-hyphen", "--startsWithDoubleHyphen"), - ("_starts_with_underscore", "_startsWithUnderscore"), - ("__starts_with_double_underscore", "__startsWithDoubleUnderscore"), + ("_hover", "Hover"), + ("-starts-with-hyphen", "StartsWithHyphen"), + ("--starts-with-double-hyphen", "StartsWithDoubleHyphen"), + ("_starts_with_underscore", "StartsWithUnderscore"), + ("__starts_with_double_underscore", "StartsWithDoubleUnderscore"), (":start-with-colon", ":startWithColon"), (":-start-with-colon-dash", ":StartWithColonDash"), ],