diff --git a/reflex/components/core/banner.py b/reflex/components/core/banner.py index e25951fb0..aa75bb2c7 100644 --- a/reflex/components/core/banner.py +++ b/reflex/components/core/banner.py @@ -175,7 +175,7 @@ class ConnectionBanner(Component): Returns: The connection banner component. """ - from reflex.components.base.bare import Bare + from reflex.components.base.fragment import Fragment if not comp: comp = Flex.create( @@ -191,7 +191,7 @@ class ConnectionBanner(Component): position="fixed", ) - return Bare.create(cond(has_connection_errors, comp)) + return Fragment.create(cond(has_connection_errors, comp)) class ConnectionModal(Component): @@ -207,11 +207,11 @@ class ConnectionModal(Component): Returns: The connection banner component. """ - from reflex.components.base.bare import Bare + from reflex.components.base.fragment import Fragment if not comp: comp = Text.create(*default_connection_error()) - return Bare.create( + return Fragment.create( cond( has_too_many_connection_errors, DialogRoot.create( diff --git a/reflex/components/core/match.py b/reflex/components/core/match.py index 3c1e27004..2def33d65 100644 --- a/reflex/components/core/match.py +++ b/reflex/components/core/match.py @@ -1,17 +1,14 @@ """rx.match.""" import textwrap -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, List, Optional, Sequence, Tuple, Union from reflex.components.base import Fragment from reflex.components.component import BaseComponent, Component, MemoizationLeaf -from reflex.components.tags import MatchTag, Tag -from reflex.style import Style -from reflex.utils import format, types +from reflex.utils import types from reflex.utils.exceptions import MatchTypeError -from reflex.utils.imports import ImportDict -from reflex.vars import VarData -from reflex.vars.base import LiteralVar, Var +from reflex.vars.base import Var +from reflex.vars.number import MatchOperation class Match(MemoizationLeaf): @@ -40,43 +37,32 @@ class Match(MemoizationLeaf): Raises: ValueError: When a default case is not provided for cases with Var return types. """ - match_cond_var = cls._create_condition_var(cond) - cases, default = cls._process_cases(list(cases)) - match_cases = cls._process_match_cases(cases) + cases, default = cls._process_cases(cases) + cls._process_match_cases(cases) - cls._validate_return_types(match_cases) + cls._validate_return_types(cases) - if default is None and types._issubclass(type(match_cases[0][-1]), Var): + if default is None and any( + not ( + isinstance((return_type := case[-1]), Component) + or ( + isinstance(return_type, Var) + and types.typehint_issubclass(return_type._var_type, Component) + ) + ) + for case in cases + ): raise ValueError( "For cases with return types as Vars, a default case must be provided" ) + elif default is None: + default = Fragment.create() - return cls._create_match_cond_var_or_component( - match_cond_var, match_cases, default - ) - - @classmethod - def _create_condition_var(cls, cond: Any) -> Var: - """Convert the condition to a Var. - - Args: - cond: The condition. - - Returns: - The condition as a base var - - Raises: - ValueError: If the condition is not provided. - """ - match_cond_var = LiteralVar.create(cond) - - if match_cond_var is None: - raise ValueError("The condition must be set") - return match_cond_var + return cls._create_match_cond_var_or_component(cond, cases, default) @classmethod def _process_cases( - cls, cases: List + cls, cases: Sequence ) -> Tuple[List, Optional[Union[Var, BaseComponent]]]: """Process the list of match cases and the catchall default case. @@ -99,33 +85,13 @@ class Match(MemoizationLeaf): # Get the default case which should be the last non-tuple arg if not isinstance(cases[-1], tuple): - default = cases.pop() - default = ( - cls._create_case_var_with_var_data(default) - if not isinstance(default, BaseComponent) - else default - ) + default = cases[-1] + cases = cases[:-1] - return cases, default + return list(cases), default @classmethod - def _create_case_var_with_var_data(cls, case_element): - """Convert a case element into a Var.If the case - is a Style type, we extract the var data and merge it with the - newly created Var. - - Args: - case_element: The case element. - - Returns: - The case element Var. - """ - _var_data = case_element._var_data if isinstance(case_element, Style) else None - case_element = LiteralVar.create(case_element, _var_data=_var_data) - return case_element - - @classmethod - def _process_match_cases(cls, cases: List) -> List[List[Var]]: + def _process_match_cases(cls, cases: Sequence): """Process the individual match cases. Args: @@ -137,34 +103,18 @@ class Match(MemoizationLeaf): Raises: ValueError: If the default case is not the last case or the tuple elements are less than 2. """ - match_cases = [] for case in cases: if not isinstance(case, tuple): raise ValueError( "rx.match should have tuples of cases and a default case as the last argument." ) + # There should be at least two elements in a case tuple(a condition and return value) if len(case) < 2: raise ValueError( "A case tuple should have at least a match case element and a return value." ) - case_list = [] - for element in case: - # convert all non component element to vars. - el = ( - cls._create_case_var_with_var_data(element) - if not isinstance(element, BaseComponent) - else element - ) - if not isinstance(el, (Var, BaseComponent)): - raise ValueError("Case element must be a var or component") - case_list.append(el) - - match_cases.append(case_list) - - return match_cases - @classmethod def _validate_return_types(cls, match_cases: List[List[Var]]) -> None: """Validate that match cases have the same return types. @@ -202,7 +152,7 @@ class Match(MemoizationLeaf): cls, match_cond_var: Var, match_cases: List[List[Var]], - default: Optional[Union[Var, BaseComponent]], + default: Union[Var, BaseComponent], ) -> Union[Component, Var]: """Create and return the match condition var or component. @@ -217,64 +167,7 @@ class Match(MemoizationLeaf): Raises: ValueError: If the return types are not vars when creating a match var for Var types. """ - if default is None and types._issubclass( - type(match_cases[0][-1]), BaseComponent - ): - default = Fragment.create() - - if types._issubclass(type(match_cases[0][-1]), BaseComponent): - return Fragment.create( - cls( - cond=match_cond_var, - match_cases=match_cases, - default=default, - children=[case[-1] for case in match_cases] + [default], # type: ignore - ) - ) - - # Validate the match cases (as well as the default case) to have Var return types. - if any( - case for case in match_cases if not types._isinstance(case[-1], Var) - ) or not types._isinstance(default, Var): - raise ValueError("Return types of match cases should be Vars.") - - return Var( - _js_expr=format.format_match( - cond=str(match_cond_var), - match_cases=match_cases, - default=default, # type: ignore - ), - _var_type=default._var_type, # type: ignore - _var_data=VarData.merge( - match_cond_var._get_all_var_data(), - *[el._get_all_var_data() for case in match_cases for el in case], - default._get_all_var_data(), # type: ignore - ), - ) - - def _render(self) -> Tag: - return MatchTag( - cond=self.cond, match_cases=self.match_cases, default=self.default - ) - - def render(self) -> Dict: - """Render the component. - - Returns: - The dictionary for template of component. - """ - tag = self._render() - tag.name = "match" - return dict(tag) - - def add_imports(self) -> ImportDict: - """Add imports for the Match component. - - Returns: - The import dict. - """ - var_data = VarData.merge(self.cond._get_all_var_data()) - return var_data.old_school_imports() if var_data else {} + return MatchOperation.create(match_cond_var, match_cases, default) match = Match.create diff --git a/reflex/vars/number.py b/reflex/vars/number.py index 9b2072b9e..3090e2497 100644 --- a/reflex/vars/number.py +++ b/reflex/vars/number.py @@ -7,18 +7,30 @@ import functools import json import math import sys -from typing import TYPE_CHECKING, Any, Callable, NoReturn, TypeVar, Union, overload +from typing import ( + TYPE_CHECKING, + Any, + Callable, + NoReturn, + Sequence, + TypeVar, + Union, + overload, +) from reflex.constants.base import Dirs from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError from reflex.utils.imports import ImportDict, ImportVar from .base import ( + VAR_TYPE, + CachedVarOperation, CustomVarOperationReturn, LiteralVar, ReflexCallable, Var, VarData, + cached_property_no_lock, nary_type_computer, passthrough_unary_type_computer, unionize, @@ -1056,4 +1068,116 @@ def ternary_operation( return value +TUPLE_ENDS_IN_VAR = ( + tuple[Var[VAR_TYPE]] + | tuple[Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]] + | tuple[ + Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE] + ] +) + + +@dataclasses.dataclass( + eq=False, + frozen=True, + **{"slots": True} if sys.version_info >= (3, 10) else {}, +) +class MatchOperation(CachedVarOperation, Var[VAR_TYPE]): + """Base class for immutable match operations.""" + + _cond: Var[bool] = dataclasses.field( + default_factory=lambda: LiteralBooleanVar.create(True) + ) + _cases: tuple[TUPLE_ENDS_IN_VAR[VAR_TYPE], ...] = dataclasses.field( + default_factory=tuple + ) + _default: Var[VAR_TYPE] = dataclasses.field( + default_factory=lambda: Var.create(None) + ) + + @cached_property_no_lock + def _cached_var_name(self) -> str: + """Get the name of the var. + + Returns: + The name of the var. + """ + switch_code = f"(() => {{ switch (JSON.stringify({self._cond!s})) {{" + + for case in self._cases: + conditions = case[:-1] + return_value = case[-1] + + case_conditions = " ".join( + [f"case JSON.stringify({condition!s}):" for condition in conditions] + ) + case_code = f"{case_conditions} return ({return_value!s}); break;" + switch_code += case_code + + switch_code += f"default: return ({self._default!s}); break;" + switch_code += "};})()" + + return switch_code + + @cached_property_no_lock + def _cached_get_all_var_data(self) -> VarData | None: + """Get the VarData for the var. + + Returns: + The VarData for the var. + """ + return VarData.merge( + self._cond._get_all_var_data(), + *( + case._get_all_var_data() + for cond_or_return in self._cases + for case in cond_or_return + ), + self._default._get_all_var_data(), + self._var_data, + ) + + @classmethod + def create( + cls, + cond: Any, + cases: Sequence[Sequence[Any | Var[VAR_TYPE]]], + default: Var[VAR_TYPE] | VAR_TYPE, + _var_data: VarData | None = None, + _var_type: type[VAR_TYPE] | None = None, + ): + """Create the match operation. + + Args: + cond: The condition. + cases: The cases. + default: The default case. + _var_data: Additional hooks and imports associated with the Var. + _var_type: The type of the Var. + + Returns: + The match operation. + """ + cases = tuple(tuple(Var.create(c) for c in case) for case in cases) + return cls( + _js_expr="", + _var_data=_var_data, + _var_type=_var_type, + _cond=Var.create(cond), + _cases=cases, + _default=Var.create(default), + ) + + NUMBER_TYPES = (int, float, NumberVar) diff --git a/tests/units/components/core/test_colors.py b/tests/units/components/core/test_colors.py index c1295fb41..0a01bfcc0 100644 --- a/tests/units/components/core/test_colors.py +++ b/tests/units/components/core/test_colors.py @@ -39,7 +39,7 @@ def create_color_var(color): create_color_var( rx.color(ColorState.color, ColorState.shade, ColorState.alpha) # type: ignore ), - f'("var(--"+{color_state_name!s}.color+"-"+({color_state_name!s}.alpha ? "a" : "")+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")', + f'("var(--"+{color_state_name!s}.color+"-"+(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))({color_state_name!s}.alpha, "a", ""))+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")', Color, ), ( @@ -78,11 +78,11 @@ def test_color(color, expected, expected_type: Union[Type[str], Type[Color]]): [ ( rx.cond(True, rx.color("mint"), rx.color("tomato", 5)), - '(true ? "var(--mint-7)" : "var(--tomato-5)")', + '((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))(true, (() => "var(--mint-7)"), (() => "var(--tomato-5)")))())', ), ( rx.cond(True, rx.color(ColorState.color), rx.color(ColorState.color, 5)), # type: ignore - f'(true ? ("var(--"+{color_state_name!s}.color+"-7)") : ("var(--"+{color_state_name!s}.color+"-5)"))', + f'((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))(true, (() => ("var(--"+{color_state_name!s}.color+"-7)")), (() => ("var(--"+{color_state_name!s}.color+"-5)"))))())', ), ( rx.match( diff --git a/tests/units/components/core/test_foreach.py b/tests/units/components/core/test_foreach.py index f241bd111..ddc385f65 100644 --- a/tests/units/components/core/test_foreach.py +++ b/tests/units/components/core/test_foreach.py @@ -128,7 +128,7 @@ def display_colors_set(color): def display_nested_list_element( element: ArrayVar[Sequence[str]], index: NumberVar[int] ): - assert element._var_type == Sequence[str] + assert element._var_type == List[str] assert index._var_type is int return box(text(element[index])) diff --git a/tests/units/components/core/test_match.py b/tests/units/components/core/test_match.py index f09e800e5..59111d183 100644 --- a/tests/units/components/core/test_match.py +++ b/tests/units/components/core/test_match.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Tuple +from typing import Tuple import pytest @@ -17,73 +17,6 @@ class MatchState(BaseState): string: str = "random string" -def test_match_components(): - """Test matching cases with return values as components.""" - match_case_tuples = ( - (1, rx.text("first value")), - (2, 3, rx.text("second value")), - ([1, 2], rx.text("third value")), - ("random", rx.text("fourth value")), - ({"foo": "bar"}, rx.text("fifth value")), - (MatchState.num + 1, rx.text("sixth value")), - rx.text("default value"), - ) - match_comp = Match.create(MatchState.value, *match_case_tuples) - match_dict = match_comp.render() # type: ignore - assert match_dict["name"] == "Fragment" - - [match_child] = match_dict["children"] - - assert match_child["name"] == "match" - assert str(match_child["cond"]) == f"{MatchState.get_name()}.value" - - match_cases = match_child["match_cases"] - assert len(match_cases) == 6 - - assert match_cases[0][0]._js_expr == "1" - assert match_cases[0][0]._var_type is int - first_return_value_render = match_cases[0][1].render() - assert first_return_value_render["name"] == "RadixThemesText" - assert first_return_value_render["children"][0]["contents"] == '{"first value"}' - - assert match_cases[1][0]._js_expr == "2" - assert match_cases[1][0]._var_type is int - assert match_cases[1][1]._js_expr == "3" - assert match_cases[1][1]._var_type is int - second_return_value_render = match_cases[1][2].render() - assert second_return_value_render["name"] == "RadixThemesText" - assert second_return_value_render["children"][0]["contents"] == '{"second value"}' - - assert match_cases[2][0]._js_expr == "[1, 2]" - assert match_cases[2][0]._var_type == List[int] - third_return_value_render = match_cases[2][1].render() - assert third_return_value_render["name"] == "RadixThemesText" - assert third_return_value_render["children"][0]["contents"] == '{"third value"}' - - assert match_cases[3][0]._js_expr == '"random"' - assert match_cases[3][0]._var_type is str - fourth_return_value_render = match_cases[3][1].render() - assert fourth_return_value_render["name"] == "RadixThemesText" - assert fourth_return_value_render["children"][0]["contents"] == '{"fourth value"}' - - assert match_cases[4][0]._js_expr == '({ ["foo"] : "bar" })' - assert match_cases[4][0]._var_type == Dict[str, str] - fifth_return_value_render = match_cases[4][1].render() - assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == '{"fifth value"}' - - assert match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)" - assert match_cases[5][0]._var_type is int - fifth_return_value_render = match_cases[5][1].render() - assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}' - - default = match_child["default"].render() - - assert default["name"] == "RadixThemesText" - assert default["children"][0]["contents"] == '{"default value"}' - - @pytest.mark.parametrize( "cases, expected", [ @@ -102,7 +35,7 @@ def test_match_components(): f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return ("first"); break;case JSON.stringify(2): case JSON.stringify(3): return ' '("second value"); break;case JSON.stringify([1, 2]): return ("third-value"); break;case JSON.stringify("random"): ' 'return ("fourth_value"); break;case JSON.stringify(({ ["foo"] : "bar" })): return ("fifth value"); ' - f'break;case JSON.stringify(({MatchState.get_name()}.num + 1)): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' + f'break;case JSON.stringify((((_lhs, _rhs) => (_lhs + _rhs))({MatchState.get_name()}.num, 1))): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' f'return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (({MatchState.get_name()}.value+" - string")); break;default: ' 'return ("default value"); break;};})()', ), @@ -121,7 +54,7 @@ def test_match_components(): f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return ("first"); break;case JSON.stringify(2): case JSON.stringify(3): return ' '("second value"); break;case JSON.stringify([1, 2]): return ("third-value"); break;case JSON.stringify("random"): ' 'return ("fourth_value"); break;case JSON.stringify(({ ["foo"] : "bar" })): return ("fifth value"); ' - f'break;case JSON.stringify(({MatchState.get_name()}.num + 1)): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' + f'break;case JSON.stringify((((_lhs, _rhs) => (_lhs + _rhs))({MatchState.get_name()}.num, 1))): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' f'return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (({MatchState.get_name()}.value+" - string")); break;default: ' f"return ({MatchState.get_name()}.string); break;}};}})()", ), @@ -143,17 +76,14 @@ def test_match_on_component_without_default(): """Test that matching cases with return values as components returns a Fragment as the default case if not provided. """ - from reflex.components.base.fragment import Fragment - match_case_tuples = ( (1, rx.text("first value")), (2, 3, rx.text("second value")), ) match_comp = Match.create(MatchState.value, *match_case_tuples) - default = match_comp.render()["children"][0]["default"] # type: ignore - assert isinstance(default, Fragment) + assert isinstance(match_comp, Var) def test_match_on_var_no_default(): @@ -247,8 +177,8 @@ def test_match_case_tuple_elements(match_case): (MatchState.num + 1, "black"), rx.text("default value"), ), - 'Match cases should have the same return types. Case 3 with return value `"red"` of type ' - " is not ", + "Match cases should have the same return types. Case 3 with return value `red` of type " + " is not ", ), ( ( @@ -261,7 +191,7 @@ def test_match_case_tuple_elements(match_case): rx.text("default value"), ), 'Match cases should have the same return types. Case 3 with return value ` {"first value"} ` ' - "of type is not ", + "of type is not ", ), ], ) diff --git a/tests/units/components/markdown/test_markdown.py b/tests/units/components/markdown/test_markdown.py index 866f32ae1..93e30f0d3 100644 --- a/tests/units/components/markdown/test_markdown.py +++ b/tests/units/components/markdown/test_markdown.py @@ -148,7 +148,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe ( "code", {}, - """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; if (_language) { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Error importing language module for ${_language}:`, error); } })(); } ; return inline ? ( {children} ) : ( ); })""", + '(({node, inline, className, children, ...props}) => { const match = (className || \'\').match(/language-(?.*)/); const _language = match ? match[1] : \'\'; if (_language) { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Error importing language module for ${_language}:`, error); } })(); } ; return inline ? ( {children} ) : ( (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} css={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} customStyle={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} language={_language} style={((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((((_lhs, _rhs) => (_lhs === _rhs))(resolvedColorMode, "light")), (() => oneLight), (() => oneDark)))())} wrapLongLines={true} {...props}/> ); })', ), ( "code", @@ -157,7 +157,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe value, **props ) }, - """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", + '(({node, inline, className, children, ...props}) => { const match = (className || \'\').match(/language-(?.*)/); const _language = match ? match[1] : \'\'; ; return inline ? ( {children} ) : ( (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} decorations={[]} language={_language} theme={((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((((_lhs, _rhs) => (_lhs === _rhs))(resolvedColorMode, "light")), (() => "one-light"), (() => "one-dark-pro")))())} transformers={[]}/> ); })', ), ( "h1", @@ -171,7 +171,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe ( "code", {"codeblock": syntax_highlighter_memoized_component(CodeBlock)}, - """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; if (_language) { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Error importing language module for ${_language}:`, error); } })(); } ; return inline ? ( {children} ) : ( ); })""", + "(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; if (_language) { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Error importing language module for ${_language}:`, error); } })(); } ; return inline ? ( {children} ) : ( (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = \"\") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))(\"\\n\")), children))} language={_language} {...props}/> ); })", ), ( "code", @@ -180,7 +180,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe ShikiHighLevelCodeBlock ) }, - """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", + """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); const _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} language={_language} {...props}/> ); })""", ), ], )