Reduce Syntax highlighter footprint (#2037)

This commit is contained in:
Elijah Ahianyo 2023-11-13 20:47:55 +00:00 committed by GitHub
parent 39cc1b2f12
commit ea22452b27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1928 additions and 1074 deletions

View File

@ -3,8 +3,25 @@
{% block export %} {% block export %}
{% for component in components %} {% for component in components %}
export const {{component.name}} = memo(({ {{-component.props|join(", ")-}} }) => ( export const {{component.name}} = memo(({ {{-component.props|join(", ")-}} }) => {
{% if component.name == "CodeBlock" and "language" in component.props %}
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);
}
})();
}
{% endif %}
return(
{{utils.render(component.render)}} {{utils.render(component.render)}}
)) )
})
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,8 @@
from .badge import Badge from .badge import Badge
from .code import Code, CodeBlock from .code import Code, CodeBlock
from .code import LiteralCodeBlockTheme as LiteralCodeBlockTheme
from .code import LiteralCodeLanguage as LiteralCodeLanguage
from .dataeditor import DataEditor, DataEditorTheme from .dataeditor import DataEditor, DataEditorTheme
from .datatable import DataTable from .datatable import DataTable
from .divider import Divider from .divider import Divider

View File

@ -1,19 +1,349 @@
"""A code component.""" """A code component."""
from typing import Dict, Optional, Union from typing import Dict, Literal, Optional, Union
from reflex.components.component import Component from reflex.components.component import Component
from reflex.components.forms import Button from reflex.components.forms import Button
from reflex.components.layout import Box from reflex.components.layout import Box
from reflex.components.libs.chakra import ChakraComponent, LiteralTheme from reflex.components.libs.chakra import (
ChakraComponent,
)
from reflex.components.media import Icon from reflex.components.media import Icon
from reflex.event import set_clipboard from reflex.event import set_clipboard
from reflex.style import Style from reflex.style import Style
from reflex.utils import imports from reflex.utils import format, imports
from reflex.vars import ImportVar, Var from reflex.vars import ImportVar, Var
# Path to the prism styles. LiteralCodeBlockTheme = Literal[
PRISM_STYLES_PATH: str = "/styles/code/prism" "a11y-dark",
"atom-dark",
"cb",
"coldark-cold",
"coldark-dark",
"coy",
"coy-without-shadows",
"darcula",
"dark",
"dracula",
"duotone-dark",
"duotone-earth",
"duotone-forest",
"duotone-light",
"duotone-sea",
"duotone-space",
"funky",
"ghcolors",
"gruvbox-dark",
"gruvbox-light",
"holi-theme",
"hopscotch",
"light", # not present in react-syntax-highlighter styles
"lucario",
"material-dark",
"material-light",
"material-oceanic",
"night-owl",
"nord",
"okaidia",
"one-dark",
"one-light",
"pojoaque",
"prism",
"shades-of-purple",
"solarized-dark-atom",
"solarizedlight",
"synthwave84",
"tomorrow",
"twilight",
"vs",
"vs-dark",
"vsc-dark-plus",
"xonokai",
"z-touch",
]
LiteralCodeLanguage = Literal[
"abap",
"abnf",
"actionscript",
"ada",
"agda",
"al",
"antlr4",
"apacheconf",
"apex",
"apl",
"applescript",
"aql",
"arduino",
"arff",
"asciidoc",
"asm6502",
"asmatmel",
"aspnet",
"autohotkey",
"autoit",
"avisynth",
"avro-idl",
"bash",
"basic",
"batch",
"bbcode",
"bicep",
"birb",
"bison",
"bnf",
"brainfuck",
"brightscript",
"bro",
"bsl",
"c",
"cfscript",
"chaiscript",
"cil",
"clike",
"clojure",
"cmake",
"cobol",
"coffeescript",
"concurnas",
"coq",
"core",
"cpp",
"crystal",
"csharp",
"cshtml",
"csp",
"css",
"css-extras",
"csv",
"cypher",
"d",
"dart",
"dataweave",
"dax",
"dhall",
"diff",
"django",
"dns-zone-file",
"docker",
"dot",
"ebnf",
"editorconfig",
"eiffel",
"ejs",
"elixir",
"elm",
"erb",
"erlang",
"etlua",
"excel-formula",
"factor",
"false",
"firestore-security-rules",
"flow",
"fortran",
"fsharp",
"ftl",
"gap",
"gcode",
"gdscript",
"gedcom",
"gherkin",
"git",
"glsl",
"gml",
"gn",
"go",
"go-module",
"graphql",
"groovy",
"haml",
"handlebars",
"haskell",
"haxe",
"hcl",
"hlsl",
"hoon",
"hpkp",
"hsts",
"http",
"ichigojam",
"icon",
"icu-message-format",
"idris",
"iecst",
"ignore",
"index",
"inform7",
"ini",
"io",
"j",
"java",
"javadoc",
"javadoclike",
"javascript",
"javastacktrace",
"jexl",
"jolie",
"jq",
"js-extras",
"js-templates",
"jsdoc",
"json",
"json5",
"jsonp",
"jsstacktrace",
"jsx",
"julia",
"keepalived",
"keyman",
"kotlin",
"kumir",
"kusto",
"latex",
"latte",
"less",
"lilypond",
"liquid",
"lisp",
"livescript",
"llvm",
"log",
"lolcode",
"lua",
"magma",
"makefile",
"markdown",
"markup",
"markup-templating",
"matlab",
"maxscript",
"mel",
"mermaid",
"mizar",
"mongodb",
"monkey",
"moonscript",
"n1ql",
"n4js",
"nand2tetris-hdl",
"naniscript",
"nasm",
"neon",
"nevod",
"nginx",
"nim",
"nix",
"nsis",
"objectivec",
"ocaml",
"opencl",
"openqasm",
"oz",
"parigp",
"parser",
"pascal",
"pascaligo",
"pcaxis",
"peoplecode",
"perl",
"php",
"php-extras",
"phpdoc",
"plsql",
"powerquery",
"powershell",
"processing",
"prolog",
"promql",
"properties",
"protobuf",
"psl",
"pug",
"puppet",
"pure",
"purebasic",
"purescript",
"python",
"q",
"qml",
"qore",
"qsharp",
"r",
"racket",
"reason",
"regex",
"rego",
"renpy",
"rest",
"rip",
"roboconf",
"robotframework",
"ruby",
"rust",
"sas",
"sass",
"scala",
"scheme",
"scss",
"shell-session",
"smali",
"smalltalk",
"smarty",
"sml",
"solidity",
"solution-file",
"soy",
"sparql",
"splunk-spl",
"sqf",
"sql",
"squirrel",
"stan",
"stylus",
"swift",
"systemd",
"t4-cs",
"t4-templating",
"t4-vb",
"tap",
"tcl",
"textile",
"toml",
"tremor",
"tsx",
"tt2",
"turtle",
"twig",
"typescript",
"typoscript",
"unrealscript",
"uorazor",
"uri",
"v",
"vala",
"vbnet",
"velocity",
"verilog",
"vhdl",
"vim",
"visual-basic",
"warpscript",
"wasm",
"web-idl",
"wiki",
"wolfram",
"wren",
"xeora",
"xml-doc",
"xojo",
"xquery",
"yaml",
"yang",
"zig",
]
class CodeBlock(Component): class CodeBlock(Component):
@ -21,13 +351,15 @@ class CodeBlock(Component):
library = "react-syntax-highlighter@15.5.0" library = "react-syntax-highlighter@15.5.0"
tag = "Prism" tag = "PrismAsyncLight"
alias = "SyntaxHighlighter"
# The theme to use ("light" or "dark"). # The theme to use ("light" or "dark").
theme: Var[LiteralTheme] theme: Var[LiteralCodeBlockTheme] = "one-light" # type: ignore
# The language to use. # The language to use.
language: Var[str] language: Var[LiteralCodeLanguage] = "python" # type: ignore
# If this is enabled line numbers will be shown next to the code block. # If this is enabled line numbers will be shown next to the code block.
show_line_numbers: Var[bool] show_line_numbers: Var[bool]
@ -46,13 +378,43 @@ class CodeBlock(Component):
def _get_imports(self) -> imports.ImportDict: def _get_imports(self) -> imports.ImportDict:
merged_imports = super()._get_imports() merged_imports = super()._get_imports()
if self.theme is not None:
merged_imports = imports.merge_imports( merged_imports = imports.merge_imports(
merged_imports, merged_imports,
{PRISM_STYLES_PATH: {ImportVar(tag=self.theme._var_name)}}, {
f"react-syntax-highlighter/dist/cjs/styles/prism/{self.theme._var_name}": {
ImportVar(
tag=format.to_camel_case(self.theme._var_name),
is_default=True,
install=False,
)
}
},
)
if (
self.language is not None
and self.language._var_name in LiteralCodeLanguage.__args__ # type: ignore
):
merged_imports = imports.merge_imports(
merged_imports,
{
f"react-syntax-highlighter/dist/cjs/languages/prism/{self.language._var_name}": {
ImportVar(
tag=format.to_camel_case(self.language._var_name),
is_default=True,
install=False,
)
}
},
) )
return merged_imports return merged_imports
def _get_custom_code(self) -> Optional[str]:
if (
self.language is not None
and self.language._var_name in LiteralCodeLanguage.__args__ # type: ignore
):
return f"{self.alias}.registerLanguage('{self.language._var_name}', {format.to_camel_case(self.language._var_name)})"
@classmethod @classmethod
def create( def create(
cls, cls,
@ -75,6 +437,17 @@ class CodeBlock(Component):
# This component handles style in a special prop. # This component handles style in a special prop.
custom_style = props.pop("custom_style", {}) custom_style = props.pop("custom_style", {})
# react-syntax-highlighter doesnt have an explicit "light" or "dark" theme so we use one-light and one-dark
# themes respectively to ensure code compatibility.
if "theme" in props:
props["theme"] = (
"one-light"
if props["theme"] == "light"
else "one-dark"
if props["theme"] == "dark"
else props["theme"]
)
if can_copy: if can_copy:
code = children[0] code = children[0]
copy_button = ( # type: ignore copy_button = ( # type: ignore
@ -112,9 +485,10 @@ class CodeBlock(Component):
def _render(self): def _render(self):
out = super()._render() out = super()._render()
if self.theme is not None:
out.add_props( out.add_props(
style=Var.create(self.theme._var_name, _var_is_local=False) style=Var.create(
format.to_camel_case(self.theme._var_name), _var_is_local=False
)
).remove_props("theme") ).remove_props("theme")
return out return out

File diff suppressed because it is too large Load Diff

View File

@ -122,6 +122,8 @@ LiteralColorScheme = Literal[
LiteralVariant = Literal["solid", "subtle", "outline"] LiteralVariant = Literal["solid", "subtle", "outline"]
LiteralDividerVariant = Literal["solid", "dashed"] LiteralDividerVariant = Literal["solid", "dashed"]
LiteralTheme = Literal["light", "dark"] LiteralTheme = Literal["light", "dark"]
LiteralTagColorScheme = Literal[ LiteralTagColorScheme = Literal[
"gray", "gray",
"red", "red",

View File

@ -1,14 +1,330 @@
"""Stub file for chakra.py""" """Stub file for reflex/components/libs/chakra.py"""
# ------------------- DO NOT EDIT ---------------------- # ------------------- DO NOT EDIT ----------------------
# This file was generated by `scripts/pyi_generator.py`! # This file was generated by `scripts/pyi_generator.py`!
# ------------------------------------------------------ # ------------------------------------------------------
from typing import Literal, Optional, Union, overload from typing import Optional, Literal, Any, overload, List, Union, Dict
from reflex.components.component import Component
from reflex.vars import Var, BaseVar, ComputedVar from reflex.vars import Var, BaseVar, ComputedVar
from reflex.event import EventHandler, EventChain, EventSpec from reflex.event import EventChain, EventHandler, EventSpec
from reflex.style import Style
from typing import List, Literal
from reflex.components.component import Component
from reflex.utils import imports
from reflex.vars import ImportVar, Var
class ChakraComponent(Component):
...
@overload
@classmethod
def create( # type: ignore
cls,
*children,
style: Optional[Style] = None,
key: Optional[Any] = None,
id: Optional[Any] = None,
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, str]] = None,
on_blur: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_context_menu: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_double_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_focus: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_down: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_enter: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_leave: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_move: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_out: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_over: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_up: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_scroll: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_unmount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
**props
) -> "ChakraComponent":
"""Create the component.
Args:
*children: The children of the component.
style: The style of the component.
key: A unique key for the component.
id: The id for the component.
class_name: The class name for the component.
autofocus: Whether the component should take the focus once the page is loaded
custom_attrs: custom attribute
**props: The props of the component.
Returns:
The component.
Raises:
TypeError: If an invalid child is passed.
"""
...
class Global(Component):
...
@overload
@classmethod
def create( # type: ignore
cls,
*children,
styles: Optional[Union[Var[str], str]] = None,
style: Optional[Style] = None,
key: Optional[Any] = None,
id: Optional[Any] = None,
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, str]] = None,
on_blur: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_context_menu: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_double_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_focus: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_down: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_enter: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_leave: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_move: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_out: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_over: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_up: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_scroll: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_unmount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
**props
) -> "Global":
"""Create the component.
Args:
*children: The children of the component.
style: The style of the component.
key: A unique key for the component.
id: The id for the component.
class_name: The class name for the component.
autofocus: Whether the component should take the focus once the page is loaded
custom_attrs: custom attribute
**props: The props of the component.
Returns:
The component.
Raises:
TypeError: If an invalid child is passed.
"""
...
class ChakraProvider(ChakraComponent):
@overload
@classmethod
def create( # type: ignore
cls,
*children,
theme: Optional[Union[Var[str], str]] = None,
style: Optional[Style] = None,
key: Optional[Any] = None,
id: Optional[Any] = None,
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, str]] = None,
on_blur: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_context_menu: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_double_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_focus: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_down: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_enter: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_leave: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_move: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_out: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_over: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_up: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_scroll: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_unmount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
**props
) -> "ChakraProvider":
"""Create a new ChakraProvider component.
Returns:
A new ChakraProvider component.
"""
...
class ChakraColorModeProvider(Component):
...
@overload
@classmethod
def create( # type: ignore
cls,
*children,
style: Optional[Style] = None,
key: Optional[Any] = None,
id: Optional[Any] = None,
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, str]] = None,
on_blur: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_context_menu: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_double_click: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_focus: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_down: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_enter: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_leave: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_move: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_out: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_over: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_mouse_up: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_scroll: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
on_unmount: Optional[
Union[EventHandler, EventSpec, List, function, BaseVar]
] = None,
**props
) -> "ChakraColorModeProvider":
"""Create the component.
Args:
*children: The children of the component.
style: The style of the component.
key: A unique key for the component.
id: The id for the component.
class_name: The class name for the component.
autofocus: Whether the component should take the focus once the page is loaded
custom_attrs: custom attribute
**props: The props of the component.
Returns:
The component.
Raises:
TypeError: If an invalid child is passed.
"""
...
LiteralColorScheme = Literal[ LiteralColorScheme = Literal[
"none",
"gray", "gray",
"red", "red",
"orange", "orange",
@ -32,6 +348,7 @@ LiteralColorScheme = Literal[
LiteralVariant = Literal["solid", "subtle", "outline"] LiteralVariant = Literal["solid", "subtle", "outline"]
LiteralDividerVariant = Literal["solid", "dashed"] LiteralDividerVariant = Literal["solid", "dashed"]
LiteralTheme = Literal["light", "dark"] LiteralTheme = Literal["light", "dark"]
LiteralTagColorScheme = Literal[ LiteralTagColorScheme = Literal[
"gray", "gray",
"red", "red",
@ -94,8 +411,8 @@ LiteralCardVariant = Literal["outline", "filled", "elevated", "unstyled"]
LiteralStackDirection = Literal["row", "column"] LiteralStackDirection = Literal["row", "column"]
LiteralImageLoading = Literal["eager", "lazy"] LiteralImageLoading = Literal["eager", "lazy"]
LiteralTagSize = Literal["sm", "md", "lg"] LiteralTagSize = Literal["sm", "md", "lg"]
LiteralSpinnerSize = Literal[Literal[LiteralTagSize], "xs"] LiteralSpinnerSize = Literal[Literal[LiteralTagSize], "xs", "xl"]
LiteralAvatarSize = Literal[Literal[LiteralTagSize], "xs", "2xl", "full", "2xs"] LiteralAvatarSize = Literal[Literal[LiteralTagSize], "xl", "xs", "2xl", "full", "2xs"]
LiteralButtonSize = Literal["sm", "md", "lg", "xs"] LiteralButtonSize = Literal["sm", "md", "lg", "xs"]
# Applies to AlertDialog and Modal # Applies to AlertDialog and Modal
LiteralAlertDialogSize = Literal[ LiteralAlertDialogSize = Literal[
@ -108,21 +425,3 @@ LiteralMenuOption = Literal["checkbox", "radio"]
LiteralPopOverTrigger = Literal["click", "hover"] LiteralPopOverTrigger = Literal["click", "hover"]
LiteralHeadingSize = Literal["lg", "md", "sm", "xs", "xl", "2xl", "3xl", "4xl"] LiteralHeadingSize = Literal["lg", "md", "sm", "xs", "xl", "2xl", "3xl", "4xl"]
class ChakraComponent(Component):
@overload
@classmethod
def create(cls, *children, on_blur: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_click: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_context_menu: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_double_click: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_focus: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mount: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_down: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_enter: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_leave: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_move: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_out: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_over: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_mouse_up: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_scroll: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, on_unmount: Optional[Union[EventHandler, EventSpec, List, function, BaseVar]] = None, **props) -> "ChakraComponent": # type: ignore
"""Create the component.
Args:
*children: The children of the component.
**props: The props of the component.
Returns:
The component.
Raises:
TypeError: If an invalid child is passed.
"""
...

View File

@ -240,6 +240,16 @@ class Markdown(Component):
] = f"""{{({{inline, className, {_CHILDREN._var_name}, {_PROPS._var_name}}}) => {{ ] = f"""{{({{inline, className, {_CHILDREN._var_name}, {_PROPS._var_name}}}) => {{
const match = (className || '').match(/language-(?<lang>.*)/); const match = (className || '').match(/language-(?<lang>.*)/);
const language = match ? match[1] : ''; 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 ? ( return inline ? (
{self.format_component("code")} {self.format_component("code")}
) : ( ) : (

View File

@ -137,14 +137,9 @@ def to_camel_case(text: str) -> str:
Returns: Returns:
The camel case string. The camel case string.
""" """
if "_" not in text: words = re.split("[_-]", text)
return text # Capitalize the first letter of each word except the first one
camel = "".join( return words[0] + "".join(x.capitalize() for x in words[1:])
word.capitalize() if i > 0 else word.lower()
for i, word in enumerate(text.lstrip("_").split("_"))
)
prefix = "_" if text.startswith("_") else ""
return prefix + camel
def to_title_case(text: str) -> str: def to_title_case(text: str) -> str:

View File

@ -0,0 +1,31 @@
import pytest
from reflex.components.datadisplay.code import CodeBlock
@pytest.mark.parametrize(
"theme, expected", [("light", "one-light"), ("dark", "one-dark")]
)
def test_code_light_dark_theme(theme, expected):
code_block = CodeBlock.create(theme=theme)
assert code_block.theme._var_name == expected # type: ignore
def generate_custom_code(language, expected_case):
return f"SyntaxHighlighter.registerLanguage('{language}', {expected_case})"
@pytest.mark.parametrize(
"language, expected_case",
[
("python", "python"),
("firestore-security-rules", "firestoreSecurityRules"),
("typescript", "typescript"),
],
)
def test_get_custom_code(language, expected_case):
code_block = CodeBlock.create(language=language)
assert code_block._get_custom_code() == generate_custom_code(
language, expected_case
)

View File

@ -139,6 +139,9 @@ def test_to_snake_case(input: str, output: str):
("Hello", "Hello"), ("Hello", "Hello"),
("snake_case", "snakeCase"), ("snake_case", "snakeCase"),
("snake_case_two", "snakeCaseTwo"), ("snake_case_two", "snakeCaseTwo"),
("kebab-case", "kebabCase"),
("kebab-case-two", "kebabCaseTwo"),
("snake_kebab-case", "snakeKebabCase"),
], ],
) )
def test_to_camel_case(input: str, output: str): def test_to_camel_case(input: str, output: str):