Top-level namespace tweaks (#2523)

* pyi_generator: always ignore files starting with `tests`

* Move CodeBlock out of chakra namespace

* Expose additional names in the top-level namespace

* code pyi fixup

* expose input and quote at the top-level

* add text_field to top-level namespace (maybe)

* fixup chakra code.pyi

* Remove `text_field` from top level namespace

* Remove top-level big C Cond

* fixup top level pyi
This commit is contained in:
Masen Furer 2024-02-05 11:14:02 -08:00 committed by GitHub
parent 05d1be2182
commit f99c48806a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1663 additions and 1627 deletions

View File

@ -26,6 +26,7 @@ _ALL_COMPONENTS = [
"debounce_input", "debounce_input",
# Base # Base
"fragment", "fragment",
"Fragment",
"image", "image",
"script", "script",
# Responsive # Responsive
@ -68,11 +69,12 @@ _ALL_COMPONENTS = [
# "icon" (lucide) # "icon" (lucide)
"icon_button", "icon_button",
"inset", "inset",
"input",
"kbd", "kbd",
"link", "link",
"popover", "popover",
"progress", "progress",
# "quote", "quote",
"radio_group", "radio_group",
"scroll_area", "scroll_area",
"section", "section",
@ -82,19 +84,21 @@ _ALL_COMPONENTS = [
"slider", "slider",
"spacer", "spacer",
# "strong" (bold?) # "strong" (bold?)
"stack",
"switch", "switch",
"table", "table",
"tabs", "tabs",
"text", "text",
"text_area", "text_area",
# "text_field" (input)
"theme", "theme",
"theme_panel", "theme_panel",
"tooltip", "tooltip",
"vstack", "vstack",
# Other # Other
"code_block",
"data_editor", "data_editor",
"data_editor_theme", "data_editor_theme",
"data_table",
"plotly", "plotly",
"audio", "audio",
"video", "video",
@ -102,6 +106,7 @@ _ALL_COMPONENTS = [
"EditorButtonList", "EditorButtonList",
"EditorOptions", "EditorOptions",
"icon", "icon",
"markdown",
] ]
_MAPPING = { _MAPPING = {

View File

@ -15,6 +15,7 @@ from reflex.components import connection_banner as connection_banner
from reflex.components import connection_modal as connection_modal from reflex.components import connection_modal as connection_modal
from reflex.components import debounce_input as debounce_input from reflex.components import debounce_input as debounce_input
from reflex.components import fragment as fragment from reflex.components import fragment as fragment
from reflex.components import Fragment as Fragment
from reflex.components import image as image from reflex.components import image as image
from reflex.components import script as script from reflex.components import script as script
from reflex.components import desktop_only as desktop_only from reflex.components import desktop_only as desktop_only
@ -52,10 +53,12 @@ from reflex.components import hover_card as hover_card
from reflex.components import hstack as hstack from reflex.components import hstack as hstack
from reflex.components import icon_button as icon_button from reflex.components import icon_button as icon_button
from reflex.components import inset as inset from reflex.components import inset as inset
from reflex.components import input as input
from reflex.components import kbd as kbd from reflex.components import kbd as kbd
from reflex.components import link as link from reflex.components import link as link
from reflex.components import popover as popover from reflex.components import popover as popover
from reflex.components import progress as progress from reflex.components import progress as progress
from reflex.components import quote as quote
from reflex.components import radio_group as radio_group from reflex.components import radio_group as radio_group
from reflex.components import scroll_area as scroll_area from reflex.components import scroll_area as scroll_area
from reflex.components import section as section from reflex.components import section as section
@ -63,6 +66,7 @@ from reflex.components import select as select
from reflex.components import separator as separator from reflex.components import separator as separator
from reflex.components import slider as slider from reflex.components import slider as slider
from reflex.components import spacer as spacer from reflex.components import spacer as spacer
from reflex.components import stack as stack
from reflex.components import switch as switch from reflex.components import switch as switch
from reflex.components import table as table from reflex.components import table as table
from reflex.components import tabs as tabs from reflex.components import tabs as tabs
@ -72,8 +76,10 @@ from reflex.components import theme as theme
from reflex.components import theme_panel as theme_panel from reflex.components import theme_panel as theme_panel
from reflex.components import tooltip as tooltip from reflex.components import tooltip as tooltip
from reflex.components import vstack as vstack from reflex.components import vstack as vstack
from reflex.components import code_block as code_block
from reflex.components import data_editor as data_editor from reflex.components import data_editor as data_editor
from reflex.components import data_editor_theme as data_editor_theme from reflex.components import data_editor_theme as data_editor_theme
from reflex.components import data_table as data_table
from reflex.components import plotly as plotly from reflex.components import plotly as plotly
from reflex.components import audio as audio from reflex.components import audio as audio
from reflex.components import video as video from reflex.components import video as video
@ -81,6 +87,7 @@ from reflex.components import editor as editor
from reflex.components import EditorButtonList as EditorButtonList from reflex.components import EditorButtonList as EditorButtonList
from reflex.components import EditorOptions as EditorOptions from reflex.components import EditorOptions as EditorOptions
from reflex.components import icon as icon from reflex.components import icon as icon
from reflex.components import markdown as markdown
from reflex.components.component import Component as Component from reflex.components.component import Component as Component
from reflex.components.component import NoSSRComponent as NoSSRComponent from reflex.components.component import NoSSRComponent as NoSSRComponent
from reflex.components.component import memo as memo from reflex.components.component import memo as memo

View File

@ -1,13 +1,13 @@
"""Import all the components.""" """Import all the components."""
from __future__ import annotations from __future__ import annotations
from . import lucide
from .base import Fragment, Script, fragment, script from .base import Fragment, Script, fragment, script
from .component import Component from .component import Component
from .component import NoSSRComponent as NoSSRComponent from .component import NoSSRComponent as NoSSRComponent
from .core import * from .core import *
from .datadisplay import * from .datadisplay import *
from .gridjs import * from .gridjs import *
from .lucide import icon
from .markdown import * from .markdown import *
from .moment import * from .moment import *
from .next import NextLink, image, next_link from .next import NextLink, image, next_link
@ -15,3 +15,5 @@ from .plotly import *
from .radix import * from .radix import *
from .react_player import * from .react_player import *
from .suneditor import * from .suneditor import *
icon = lucide.icon

View File

@ -49,7 +49,6 @@ circle = Circle.create
circular_progress = CircularProgress.create circular_progress = CircularProgress.create
circular_progress_label = CircularProgressLabel.create circular_progress_label = CircularProgressLabel.create
code = Code.create code = Code.create
code_block = CodeBlock.create
collapse = Collapse.create collapse = Collapse.create
color_mode_button = ColorModeButton.create color_mode_button = ColorModeButton.create
color_mode_icon = ColorModeIcon.create color_mode_icon = ColorModeIcon.create

View File

@ -1,9 +1,7 @@
"""Data display components.""" """Data display components."""
from .badge import Badge from .badge import Badge
from .code import Code, CodeBlock from .code import Code
from .code import LiteralCodeBlockTheme as LiteralCodeBlockTheme
from .code import LiteralCodeLanguage as LiteralCodeLanguage
from .divider import Divider from .divider import Divider
from .keyboard_key import KeyboardKey as Kbd from .keyboard_key import KeyboardKey as Kbd
from .list import List, ListItem, OrderedList, UnorderedList from .list import List, ListItem, OrderedList, UnorderedList

View File

@ -1,518 +1,7 @@
"""A code component.""" """A code component."""
import re
from typing import Dict, Literal, Optional, Union
from reflex.components.chakra import ( from reflex.components.chakra import (
ChakraComponent, ChakraComponent,
) )
from reflex.components.chakra.forms import Button, color_mode_cond
from reflex.components.chakra.layout import Box
from reflex.components.chakra.media import Icon
from reflex.components.component import Component
from reflex.event import set_clipboard
from reflex.style import Style
from reflex.utils import format, imports
from reflex.utils.imports import ImportVar
from reflex.vars import Var
LiteralCodeBlockTheme = Literal[
"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):
"""A code block."""
library = "react-syntax-highlighter@15.5.0"
tag = "PrismAsyncLight"
alias = "SyntaxHighlighter"
# The theme to use ("light" or "dark").
theme: Var[LiteralCodeBlockTheme] = "one-light" # type: ignore
# The language to use.
language: Var[LiteralCodeLanguage] = "python" # type: ignore
# The code to display.
code: Var[str]
# If this is enabled line numbers will be shown next to the code block.
show_line_numbers: Var[bool]
# The starting line number to use.
starting_line_number: Var[int]
# Whether to wrap long lines.
wrap_long_lines: Var[bool]
# A custom style for the code block.
custom_style: Dict[str, str] = {}
# Props passed down to the code tag.
code_tag_props: Var[Dict[str, str]]
def _get_imports(self) -> imports.ImportDict:
merged_imports = super()._get_imports()
# Get all themes from a cond literal
themes = re.findall(r"`(.*?)`", self.theme._var_name)
if not themes:
themes = [self.theme._var_name]
merged_imports = imports.merge_imports(
merged_imports,
{
f"react-syntax-highlighter/dist/cjs/styles/prism/{theme}": {
ImportVar(
tag=format.to_camel_case(theme),
is_default=True,
install=False,
)
}
for theme in themes
},
)
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
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
def create(
cls,
*children,
can_copy: Optional[bool] = False,
copy_button: Optional[Union[bool, Component]] = None,
**props,
):
"""Create a text component.
Args:
*children: The children of the component.
can_copy: Whether a copy button should appears.
copy_button: A custom copy button to override the default one.
**props: The props to pass to the component.
Returns:
The text component.
"""
# This component handles style in a special prop.
custom_style = props.pop("custom_style", {})
if "theme" not in props:
# Default color scheme responds to global color mode.
props["theme"] = color_mode_cond(light="one-light", dark="one-dark")
# 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 and not isinstance(props["theme"], Var):
props["theme"] = (
"one-light"
if props["theme"] == "light"
else "one-dark"
if props["theme"] == "dark"
else props["theme"]
)
if can_copy:
code = children[0]
copy_button = ( # type: ignore
copy_button
if copy_button is not None
else Button.create(
Icon.create(tag="copy"),
on_click=set_clipboard(code),
style=Style({"position": "absolute", "top": "0.5em", "right": "0"}),
)
)
custom_style.update({"padding": "1em 3.2em 1em 1em"})
else:
copy_button = None
# Transfer style props to the custom style prop.
for key, value in props.items():
if key not in cls.get_fields():
custom_style[key] = value
# Carry the children (code) via props
if children:
props["code"] = children[0]
if not isinstance(props["code"], Var):
props["code"] = Var.create(props["code"], _var_is_string=True)
# Create the component.
code_block = super().create(
**props,
custom_style=Style(custom_style),
)
if copy_button:
return Box.create(code_block, copy_button, position="relative")
else:
return code_block
def _add_style(self, style):
self.custom_style.update(style) # type: ignore
def _render(self):
out = super()._render()
predicate, qmark, value = self.theme._var_name.partition("?")
out.add_props(
style=Var.create(
format.to_camel_case(f"{predicate}{qmark}{value.replace('`', '')}"),
_var_is_local=False,
)
).remove_props("theme", "code")
if self.code is not None:
out.special_props.add(Var.create_safe(f"children={str(self.code)}"))
return out
class Code(ChakraComponent): class Code(ChakraComponent):

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,10 @@
"""Data grid components.""" """Data grid components."""
from .code import CodeBlock
from .code import LiteralCodeBlockTheme as LiteralCodeBlockTheme
from .code import LiteralCodeLanguage as LiteralCodeLanguage
from .dataeditor import DataEditor, DataEditorTheme from .dataeditor import DataEditor, DataEditorTheme
code_block = CodeBlock.create
data_editor = DataEditor.create data_editor = DataEditor.create
data_editor_theme = DataEditorTheme data_editor_theme = DataEditorTheme

View File

@ -0,0 +1,512 @@
"""A code component."""
import re
from typing import Dict, Literal, Optional, Union
from reflex.components.chakra.forms import Button, color_mode_cond
from reflex.components.chakra.layout import Box
from reflex.components.chakra.media import Icon
from reflex.components.component import Component
from reflex.event import set_clipboard
from reflex.style import Style
from reflex.utils import format, imports
from reflex.utils.imports import ImportVar
from reflex.vars import Var
LiteralCodeBlockTheme = Literal[
"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):
"""A code block."""
library = "react-syntax-highlighter@15.5.0"
tag = "PrismAsyncLight"
alias = "SyntaxHighlighter"
# The theme to use ("light" or "dark").
theme: Var[LiteralCodeBlockTheme] = "one-light" # type: ignore
# The language to use.
language: Var[LiteralCodeLanguage] = "python" # type: ignore
# The code to display.
code: Var[str]
# If this is enabled line numbers will be shown next to the code block.
show_line_numbers: Var[bool]
# The starting line number to use.
starting_line_number: Var[int]
# Whether to wrap long lines.
wrap_long_lines: Var[bool]
# A custom style for the code block.
custom_style: Dict[str, str] = {}
# Props passed down to the code tag.
code_tag_props: Var[Dict[str, str]]
def _get_imports(self) -> imports.ImportDict:
merged_imports = super()._get_imports()
# Get all themes from a cond literal
themes = re.findall(r"`(.*?)`", self.theme._var_name)
if not themes:
themes = [self.theme._var_name]
merged_imports = imports.merge_imports(
merged_imports,
{
f"react-syntax-highlighter/dist/cjs/styles/prism/{theme}": {
ImportVar(
tag=format.to_camel_case(theme),
is_default=True,
install=False,
)
}
for theme in themes
},
)
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
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
def create(
cls,
*children,
can_copy: Optional[bool] = False,
copy_button: Optional[Union[bool, Component]] = None,
**props,
):
"""Create a text component.
Args:
*children: The children of the component.
can_copy: Whether a copy button should appears.
copy_button: A custom copy button to override the default one.
**props: The props to pass to the component.
Returns:
The text component.
"""
# This component handles style in a special prop.
custom_style = props.pop("custom_style", {})
if "theme" not in props:
# Default color scheme responds to global color mode.
props["theme"] = color_mode_cond(light="one-light", dark="one-dark")
# 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 and not isinstance(props["theme"], Var):
props["theme"] = (
"one-light"
if props["theme"] == "light"
else "one-dark"
if props["theme"] == "dark"
else props["theme"]
)
if can_copy:
code = children[0]
copy_button = ( # type: ignore
copy_button
if copy_button is not None
else Button.create(
Icon.create(tag="copy"),
on_click=set_clipboard(code),
style=Style({"position": "absolute", "top": "0.5em", "right": "0"}),
)
)
custom_style.update({"padding": "1em 3.2em 1em 1em"})
else:
copy_button = None
# Transfer style props to the custom style prop.
for key, value in props.items():
if key not in cls.get_fields():
custom_style[key] = value
# Carry the children (code) via props
if children:
props["code"] = children[0]
if not isinstance(props["code"], Var):
props["code"] = Var.create(props["code"], _var_is_string=True)
# Create the component.
code_block = super().create(
**props,
custom_style=Style(custom_style),
)
if copy_button:
return Box.create(code_block, copy_button, position="relative")
else:
return code_block
def _add_style(self, style):
self.custom_style.update(style) # type: ignore
def _render(self):
out = super()._render()
predicate, qmark, value = self.theme._var_name.partition("?")
out.add_props(
style=Var.create(
format.to_camel_case(f"{predicate}{qmark}{value.replace('`', '')}"),
_var_is_local=False,
)
).remove_props("theme", "code")
if self.code is not None:
out.special_props.add(Var.create_safe(f"children={str(self.code)}"))
return out

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,8 @@ def get_base_component_map() -> dict[str, Callable]:
Returns: Returns:
The base component map. The base component map.
""" """
from reflex.components.chakra.datadisplay.code import Code, CodeBlock from reflex.components.chakra.datadisplay.code import Code
from reflex.components.datadisplay.code import CodeBlock
return { return {
"h1": lambda value: Heading.create( "h1": lambda value: Heading.create(
@ -164,7 +165,8 @@ class Markdown(Component):
def _get_imports(self) -> imports.ImportDict: def _get_imports(self) -> imports.ImportDict:
# Import here to avoid circular imports. # Import here to avoid circular imports.
from reflex.components.chakra.datadisplay.code import Code, CodeBlock from reflex.components.chakra.datadisplay.code import Code
from reflex.components.datadisplay.code import CodeBlock
imports = super()._get_imports() imports = super()._get_imports()

View File

@ -28,6 +28,8 @@ from .textarea import text_area as text_area
from .textfield import text_field as text_field from .textfield import text_field as text_field
from .tooltip import tooltip as tooltip from .tooltip import tooltip as tooltip
input = text_field
__all__ = [ __all__ = [
"alert_dialog", "alert_dialog",
"aspect_ratio", "aspect_ratio",
@ -43,6 +45,7 @@ __all__ = [
"hover_card", "hover_card",
"icon_button", "icon_button",
"icon", "icon",
"input",
"inset", "inset",
"popover", "popover",
"radio_group", "radio_group",

View File

@ -7,7 +7,7 @@ from .flex import Flex
from .grid import Grid from .grid import Grid
from .section import Section from .section import Section
from .spacer import Spacer from .spacer import Spacer
from .stack import HStack, VStack from .stack import HStack, Stack, VStack
box = Box.create box = Box.create
center = Center.create center = Center.create
@ -16,6 +16,7 @@ flex = Flex.create
grid = Grid.create grid = Grid.create
section = Section.create section = Section.create
spacer = Spacer.create spacer = Spacer.create
stack = Stack.create
hstack = HStack.create hstack = HStack.create
vstack = VStack.create vstack = VStack.create
@ -27,6 +28,7 @@ __all__ = [
"grid", "grid",
"section", "section",
"spacer", "spacer",
"stack",
"hstack", "hstack",
"vstack", "vstack",
] ]

View File

@ -914,7 +914,11 @@ if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.INFO) logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.INFO)
targets = sys.argv[1:] if len(sys.argv) > 1 else ["reflex/components"] targets = (
[arg for arg in sys.argv[1:] if not arg.startswith("tests")]
if len(sys.argv) > 1
else ["reflex/components"]
)
logger.info(f"Running .pyi generator for {targets}") logger.info(f"Running .pyi generator for {targets}")
changed_files = _get_changed_files() changed_files = _get_changed_files()

View File

@ -1,6 +1,6 @@
import pytest import pytest
from reflex.components.chakra.datadisplay.code import CodeBlock from reflex.components.datadisplay.code import CodeBlock
@pytest.mark.parametrize( @pytest.mark.parametrize(