From b5f9b04ac241d863bbd169334f96f6d9622048d9 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Tue, 5 Dec 2023 17:15:16 -0800 Subject: [PATCH 01/10] Implement accordion component --- .../jinja/web/pages/base_page.js.jinja2 | 1 + reflex/components/radix/themes/__init__.py | 8 + .../radix/themes/components/textfield.py | 172 ++++++++++++++++++ reflex/components/radix/themes/typography.py | 141 ++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 reflex/components/radix/themes/typography.py diff --git a/reflex/.templates/jinja/web/pages/base_page.js.jinja2 b/reflex/.templates/jinja/web/pages/base_page.js.jinja2 index 3fce5849fc..038a38a65e 100644 --- a/reflex/.templates/jinja/web/pages/base_page.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/base_page.js.jinja2 @@ -1,4 +1,5 @@ {% import 'web/pages/utils.js.jinja2' as utils %} +/** @jsxImportSource @emotion/react */ {%- block imports_libs %} {% for module in imports%} diff --git a/reflex/components/radix/themes/__init__.py b/reflex/components/radix/themes/__init__.py index 7ecdfb7499..d99ff429fc 100644 --- a/reflex/components/radix/themes/__init__.py +++ b/reflex/components/radix/themes/__init__.py @@ -6,3 +6,11 @@ theme = Theme.create theme_panel = ThemePanel.create + +accordion_root = AccordionRoot.create +accordion_item = AccordionItem.create +accordion_trigger = AccordionTrigger.create +accordion_content = AccordionContent.create +accordion_header = AccordionHeader.create +chevron_down_icon = ChevronDownIcon.create + diff --git a/reflex/components/radix/themes/components/textfield.py b/reflex/components/radix/themes/components/textfield.py index 2f8cb18924..cc407d7a20 100644 --- a/reflex/components/radix/themes/components/textfield.py +++ b/reflex/components/radix/themes/components/textfield.py @@ -90,3 +90,175 @@ class TextFieldSlot(RadixThemesComponent): # Override the gap spacing between slot and input: "1" - "9" gap: Var[LiteralSize] + + +from reflex.utils import imports + + +class AccordionComponent(Component): + """Base class for all @radix-ui/accordion components.""" + + library = "@radix-ui/react-accordion" + + css: Var[dict] + + as_child: Var[bool] + + +class AccordionRoot(AccordionComponent): + """An accordion component.""" + + tag = "Root" + + alias = "RadixAccordionRoot" + + css: Var[dict] = { + "borderRadius": "6px", + "width": "300px", + "backgroundColor": "var(--accent-6)", + "boxShadow": "0 2px 10px var(--black-a4)", + } + + value: Var[str] + + default_value: Var[str] + + collapsible: Var[bool] + + disabled: Var[bool] + + dir: Var[str] + + orientation: Var[str] + + +class AccordionItem(AccordionComponent): + """An accordion component.""" + + tag = "Item" + + alias = "RadixAccordionItem" + + css: Var[dict] = { + "overflow": "hidden", + "marginTop": "1px", + "&:first-child": { + "marginTop": 0, + "borderTopLeftRadius": "4px", + "borderTopRightRadius": "4px", + }, + "&:last-child": { + "borderBottomLeftRadius": "4px", + "borderBottomRightRadius": "4px", + }, + "&:focus-within": { + "position": "relative", + "zIndex": 1, + "boxShadow": "0 0 0 2px var(--accent-7)", + }, + } + + value: Var[str] + + disabled: Var[bool] + + +class AccordionHeader(AccordionComponent): + """An accordion component.""" + + tag = "Header" + + alias = "RadixAccordionHeader" + + css: Var[dict] = { + "display": "flex", + } + + +class AccordionTrigger(AccordionComponent): + """An accordion component.""" + + tag = "Trigger" + + alias = "RadixAccordionTrigger" + + css: Var[dict] = { + "fontFamily": "inherit", + "backgroundColor": "transparent", + "padding": "0 20px", + "height": "45px", + "flex": 1, + "display": "flex", + "alignItems": "center", + "justifyContent": "space-between", + "fontSize": "15px", + "lineHeight": 1, + "color": "var(--accent-11)", + "boxShadow": "0 1px 0 var(--accent-6)", + "backgroundColor": "white", + "&:hover": { + "backgroundColor": "var(--gray-2)", + }, + "&[data-state='open'] > .AccordionChevron": { + "transform": "rotate(180deg)", + }, + } + + +class AccordionContent(AccordionComponent): + """An accordion component.""" + + tag = "Content" + + alias = "RadixAccordionContent" + + css: Var[dict] = { + "overflow": "hidden", + "fontSize": "15px", + "color": "var(--accent-11)", + "backgroundColor": "var(--accent-2)", + "padding": "15px, 20px", + "&[data-state='open']": { + "animation": Var.create("${slideDown} 500ms cubic-bezier(0.87, 0, 0.13, 1)", _var_is_string=True), + }, + "&[data-state='closed']": { + "animation": Var.create("${slideUp} 500ms cubic-bezier(0.87, 0, 0.13, 1)", _var_is_string=True), + }, + } + + def _get_imports(self): + return { + **super()._get_imports(), + "@emotion/react": [imports.ImportVar(tag="keyframes")], + } + + def _get_custom_code(self) -> str: + return """ +const slideDown = keyframes` +from { + height: 0; +} +to { + height: var(--radix-accordion-content-height); +} +` +const slideUp = keyframes` +from { + height: var(--radix-accordion-content-height); +} +to { + height: 0; +} +` +""" + + +class ChevronDownIcon(Component): + library = "@radix-ui/react-icons" + + tag = "ChevronDownIcon" + + css: Var[dict] = { + "color": "var(--accent-10)", + "transition": "transform 300ms cubic-bezier(0.87, 0, 0.13, 1)", + } diff --git a/reflex/components/radix/themes/typography.py b/reflex/components/radix/themes/typography.py new file mode 100644 index 0000000000..492cf952bd --- /dev/null +++ b/reflex/components/radix/themes/typography.py @@ -0,0 +1,141 @@ +"""Components for rendering text. + +https://www.radix-ui.com/themes/docs/theme/typography +""" +from __future__ import annotations + +from typing import Literal + +from reflex.vars import Var + +from .base import ( + CommonMarginProps, + LiteralAccentColor, + LiteralVariant, + RadixThemesComponent, +) + +LiteralTextWeight = Literal["light", "regular", "medium", "bold"] +LiteralTextAlign = Literal["left", "center", "right"] +LiteralTextSize = Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"] +LiteralTextTrim = Literal["normal", "start", "end", "both"] + + +class Text(CommonMarginProps, RadixThemesComponent): + """A foundational text primitive based on the element.""" + + tag = "Text" + + # Change the default rendered element for the one passed as a child, merging their props and behavior. + as_child: Var[bool] + + # Change the default rendered element into a semantically appropriate alternative (cannot be used with asChild) + as_: Var[str] + + # Text size: "1" - "9" + size: Var[LiteralTextSize | dict] + + # Thickness of text: "light" | "regular" | "medium" | "bold" + weight: Var[LiteralTextWeight] + + # Alignment of text in element: "left" | "center" | "right" + align: Var[LiteralTextAlign] + + # Removes the leading trim space: "normal" | "start" | "end" | "both" + trim: Var[LiteralTextTrim] + + # Overrides the accent color inherited from the Theme. + color: Var[LiteralAccentColor] + + # Whether to render the text with higher contrast color + high_contrast: Var[bool] + + +class Heading(Text): + """A semantic heading element.""" + + tag = "Heading" + + +class Blockquote(CommonMarginProps, RadixThemesComponent): + """A block level extended quotation.""" + + tag = "Blockquote" + + # Text size: "1" - "9" + size: Var[LiteralTextSize] + + # Thickness of text: "light" | "regular" | "medium" | "bold" + weight: Var[LiteralTextWeight] + + # Overrides the accent color inherited from the Theme. + color: Var[LiteralAccentColor] + + # Whether to render the text with higher contrast color + high_contrast: Var[bool] + + +class Code(Blockquote): + """Marks text to signify a short fragment of computer code.""" + + tag = "Code" + + # The visual variant to apply: "solid" | "soft" | "outline" | "ghost" + variant: Var[LiteralVariant] + + +class Em(CommonMarginProps, RadixThemesComponent): + """Marks text to stress emphasis.""" + + tag = "Em" + + +class Kbd(CommonMarginProps, RadixThemesComponent): + """Represents keyboard input or a hotkey.""" + + tag = "Kbd" + + # Text size: "1" - "9" + size: Var[LiteralTextSize] + + +LiteralLinkUnderline = Literal["auto", "hover", "always"] + + +class Link(CommonMarginProps, RadixThemesComponent): + """A semantic element for navigation between pages.""" + + tag = "Link" + + # Change the default rendered element for the one passed as a child, merging their props and behavior. + as_child: Var[bool] + + # Text size: "1" - "9" + size: Var[LiteralTextSize] + + # Thickness of text: "light" | "regular" | "medium" | "bold" + weight: Var[LiteralTextWeight] + + # Removes the leading trim space: "normal" | "start" | "end" | "both" + trim: Var[LiteralTextTrim] + + # Sets the visibility of the underline affordance: "auto" | "hover" | "always" + underline: Var[LiteralLinkUnderline] + + # Overrides the accent color inherited from the Theme. + color: Var[LiteralAccentColor] + + # Whether to render the text with higher contrast color + high_contrast: Var[bool] + + +class Quote(CommonMarginProps, RadixThemesComponent): + """A short inline quotation.""" + + tag = "Quote" + + +class Strong(CommonMarginProps, RadixThemesComponent): + """Marks text to signify strong importance.""" + + tag = "Strong" From eb1e5b7888812586b08a131fd3540425a2498ba3 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Tue, 5 Dec 2023 17:46:46 -0800 Subject: [PATCH 02/10] Fix literal annotation --- reflex/components/radix/themes/typography.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflex/components/radix/themes/typography.py b/reflex/components/radix/themes/typography.py index 492cf952bd..1464e99384 100644 --- a/reflex/components/radix/themes/typography.py +++ b/reflex/components/radix/themes/typography.py @@ -33,7 +33,7 @@ class Text(CommonMarginProps, RadixThemesComponent): as_: Var[str] # Text size: "1" - "9" - size: Var[LiteralTextSize | dict] + size: Var[LiteralTextSize] # Thickness of text: "light" | "regular" | "medium" | "bold" weight: Var[LiteralTextWeight] From 90a26e431029bf846d6459f24e8d27d95223582b Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Wed, 6 Dec 2023 17:54:07 -0800 Subject: [PATCH 03/10] Use style prop instead of css --- reflex/components/component.py | 3 +- reflex/components/radix/themes/__init__.py | 1 - .../radix/themes/components/textfield.py | 151 ++++++++++-------- reflex/style.py | 2 +- reflex/utils/format.py | 8 +- 5 files changed, 92 insertions(+), 73 deletions(-) diff --git a/reflex/components/component.py b/reflex/components/component.py index e85b6dd364..595bb14cd5 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -288,6 +288,7 @@ def __init__(self, *args, **kwargs): kwargs["style"] = Style( { + **self.get_fields()["style"].default, **style, **{attr: value for attr, value in kwargs.items() if attr not in fields}, } @@ -603,7 +604,7 @@ def _get_style(self) -> dict: Returns: The dictionary of the component style as value and the style notation as key. """ - return {"style": self.style} + return {"css": self.style} def render(self) -> Dict: """Render the component. diff --git a/reflex/components/radix/themes/__init__.py b/reflex/components/radix/themes/__init__.py index d99ff429fc..025871633e 100644 --- a/reflex/components/radix/themes/__init__.py +++ b/reflex/components/radix/themes/__init__.py @@ -13,4 +13,3 @@ accordion_content = AccordionContent.create accordion_header = AccordionHeader.create chevron_down_icon = ChevronDownIcon.create - diff --git a/reflex/components/radix/themes/components/textfield.py b/reflex/components/radix/themes/components/textfield.py index cc407d7a20..ac09f33947 100644 --- a/reflex/components/radix/themes/components/textfield.py +++ b/reflex/components/radix/themes/components/textfield.py @@ -92,6 +92,7 @@ class TextFieldSlot(RadixThemesComponent): gap: Var[LiteralSize] +from reflex.style import Style from reflex.utils import imports @@ -100,8 +101,6 @@ class AccordionComponent(Component): library = "@radix-ui/react-accordion" - css: Var[dict] - as_child: Var[bool] @@ -112,12 +111,14 @@ class AccordionRoot(AccordionComponent): alias = "RadixAccordionRoot" - css: Var[dict] = { - "borderRadius": "6px", - "width": "300px", - "backgroundColor": "var(--accent-6)", - "boxShadow": "0 2px 10px var(--black-a4)", - } + style: Style = Style( + { + "borderRadius": "6px", + "width": "300px", + "backgroundColor": "var(--accent-6)", + "boxShadow": "0 2px 10px var(--black-a4)", + } + ) value: Var[str] @@ -139,24 +140,26 @@ class AccordionItem(AccordionComponent): alias = "RadixAccordionItem" - css: Var[dict] = { - "overflow": "hidden", - "marginTop": "1px", - "&:first-child": { - "marginTop": 0, - "borderTopLeftRadius": "4px", - "borderTopRightRadius": "4px", - }, - "&:last-child": { - "borderBottomLeftRadius": "4px", - "borderBottomRightRadius": "4px", - }, - "&:focus-within": { - "position": "relative", - "zIndex": 1, - "boxShadow": "0 0 0 2px var(--accent-7)", - }, - } + style: Style = Style( + { + "overflow": "hidden", + "marginTop": "1px", + "&:first-child": { + "marginTop": 0, + "borderTopLeftRadius": "4px", + "borderTopRightRadius": "4px", + }, + "&:last-child": { + "borderBottomLeftRadius": "4px", + "borderBottomRightRadius": "4px", + }, + "&:focus-within": { + "position": "relative", + "zIndex": 1, + "boxShadow": "0 0 0 2px var(--accent-7)", + }, + } + ) value: Var[str] @@ -170,9 +173,11 @@ class AccordionHeader(AccordionComponent): alias = "RadixAccordionHeader" - css: Var[dict] = { - "display": "flex", - } + style: Style = Style( + { + "display": "flex", + } + ) class AccordionTrigger(AccordionComponent): @@ -182,27 +187,29 @@ class AccordionTrigger(AccordionComponent): alias = "RadixAccordionTrigger" - css: Var[dict] = { - "fontFamily": "inherit", - "backgroundColor": "transparent", - "padding": "0 20px", - "height": "45px", - "flex": 1, - "display": "flex", - "alignItems": "center", - "justifyContent": "space-between", - "fontSize": "15px", - "lineHeight": 1, - "color": "var(--accent-11)", - "boxShadow": "0 1px 0 var(--accent-6)", - "backgroundColor": "white", - "&:hover": { - "backgroundColor": "var(--gray-2)", - }, - "&[data-state='open'] > .AccordionChevron": { - "transform": "rotate(180deg)", - }, - } + style: Style = Style( + { + "fontFamily": "inherit", + "backgroundColor": "transparent", + "padding": "0 20px", + "height": "45px", + "flex": 1, + "display": "flex", + "alignItems": "center", + "justifyContent": "space-between", + "fontSize": "15px", + "lineHeight": 1, + "color": "var(--accent-11)", + "boxShadow": "0 1px 0 var(--accent-6)", + "backgroundColor": "white", + "&:hover": { + "backgroundColor": "var(--gray-2)", + }, + "&[data-state='open'] > .AccordionChevron": { + "transform": "rotate(180deg)", + }, + } + ) class AccordionContent(AccordionComponent): @@ -212,19 +219,27 @@ class AccordionContent(AccordionComponent): alias = "RadixAccordionContent" - css: Var[dict] = { - "overflow": "hidden", - "fontSize": "15px", - "color": "var(--accent-11)", - "backgroundColor": "var(--accent-2)", - "padding": "15px, 20px", - "&[data-state='open']": { - "animation": Var.create("${slideDown} 500ms cubic-bezier(0.87, 0, 0.13, 1)", _var_is_string=True), - }, - "&[data-state='closed']": { - "animation": Var.create("${slideUp} 500ms cubic-bezier(0.87, 0, 0.13, 1)", _var_is_string=True), - }, - } + style: Style = Style( + { + "overflow": "hidden", + "fontSize": "15px", + "color": "var(--accent-11)", + "backgroundColor": "var(--accent-2)", + "padding": "15px, 20px", + "&[data-state='open']": { + "animation": Var.create( + "${slideDown} 500ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + "&[data-state='closed']": { + "animation": Var.create( + "${slideUp} 500ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + } + ) def _get_imports(self): return { @@ -258,7 +273,9 @@ class ChevronDownIcon(Component): tag = "ChevronDownIcon" - css: Var[dict] = { - "color": "var(--accent-10)", - "transition": "transform 300ms cubic-bezier(0.87, 0, 0.13, 1)", - } + style: Style = Style( + { + "color": "var(--accent-10)", + "transition": "transform 300ms cubic-bezier(0.87, 0, 0.13, 1)", + } + ) diff --git a/reflex/style.py b/reflex/style.py index 1e5d94fa26..74a1092f9d 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -48,7 +48,7 @@ def convert(style_dict): var_data = None # Track import/hook data from any Vars in the style dict. out = {} for key, value in style_dict.items(): - key = format.to_camel_case(key) + key = format.to_camel_case(key, allow_hyphens=True) new_var_data = None if isinstance(value, dict): # Recursively format nested style dictionaries. diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 4d95d44d9b..e6e0a356d7 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -125,7 +125,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) -> str: +def to_camel_case(text: str, allow_hyphens: bool = False) -> str: """Convert a string to camel case. The first word in the text is converted to lowercase and @@ -133,12 +133,14 @@ def to_camel_case(text: str) -> str: Args: text: The string to convert. + allow_hyphens: Whether to allow hyphens in the text. Returns: The camel case string. """ - words = re.split("[_-]", text.lstrip("-_")) - leading_underscores_or_hyphens = "".join(re.findall(r"^[_-]+", text)) + chars = "-_" if not allow_hyphens else "_" + words = re.split(f"[{chars}]", text.lstrip(chars)) + leading_underscores_or_hyphens = "".join(re.findall(rf"^[{chars}]+", 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 From c213cfa05ba6eb3c053a377501feecfb21b5175c Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 7 Dec 2023 12:43:58 -0800 Subject: [PATCH 04/10] Move accordion to primitives folder --- .../components/radix/primitives/__init__.py | 17 ++ .../components/radix/primitives/accordion.py | 226 ++++++++++++++++++ reflex/components/radix/themes/__init__.py | 7 - .../radix/themes/components/textfield.py | 189 --------------- 4 files changed, 243 insertions(+), 196 deletions(-) create mode 100644 reflex/components/radix/primitives/__init__.py create mode 100644 reflex/components/radix/primitives/accordion.py diff --git a/reflex/components/radix/primitives/__init__.py b/reflex/components/radix/primitives/__init__.py new file mode 100644 index 0000000000..647ce849c8 --- /dev/null +++ b/reflex/components/radix/primitives/__init__.py @@ -0,0 +1,17 @@ +"""Radix primitive components (https://www.radix-ui.com/primitives).""" + +from .accordion import ( + AccordionContent, + AccordionHeader, + AccordionItem, + AccordionRoot, + AccordionTrigger, + ChevronDownIcon, +) + +accordion_root = AccordionRoot.create +accordion_item = AccordionItem.create +accordion_trigger = AccordionTrigger.create +accordion_content = AccordionContent.create +accordion_header = AccordionHeader.create +chevron_down_icon = ChevronDownIcon.create diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py new file mode 100644 index 0000000000..e850a288e2 --- /dev/null +++ b/reflex/components/radix/primitives/accordion.py @@ -0,0 +1,226 @@ +"""Radix accordion components.""" + +from typing import Literal + +from reflex.components.component import Component +from reflex.components.tags import Tag +from reflex.style import Style +from reflex.utils import format, imports +from reflex.vars import Var + +LiteralAccordionType = Literal["single", "multiple"] +LiteralAccordionDir = Literal["ltr", "rtl"] +LiteralAccordionOrientation = Literal["vertical", "horizontal"] + + +DEFAULT_ANIMATION_DURATION = 250 + + +class AccordionComponent(Component): + """Base class for all @radix-ui/accordion components.""" + + library = "@radix-ui/react-accordion@^1.1.2" + + # Change the default rendered element for the one passed as a child. + as_child: Var[bool] + + def _render(self) -> Tag: + return ( + super() + ._render() + .add_props( + **{ + "class_name": format.to_title_case(self.tag), + } + ) + ) + + +class AccordionRoot(AccordionComponent): + """An accordion component.""" + + tag = "Root" + + alias = "RadixAccordionRoot" + + style: Style = Style( + { + "borderRadius": "6px", + "width": "300px", + "backgroundColor": "var(--accent-6)", + "boxShadow": "0 2px 10px var(--black-a4)", + } + ) + + # The type of accordion (single or multiple). + type_: Var[LiteralAccordionType] + + # The value of the item to expand. + value: Var[str] + + # The default value of the item to expand. + default_value: Var[str] + + # Whether or not the accordion is collapsible. + collapsible: Var[bool] + + # Whether or not the accordion is disabled. + disabled: Var[bool] + + # The reading direction of the accordion when applicable. + dir: Var[LiteralAccordionDir] + + # The orientation of the accordion. + orientation: Var[LiteralAccordionOrientation] + + +class AccordionItem(AccordionComponent): + """An accordion component.""" + + tag = "Item" + + alias = "RadixAccordionItem" + + style: Style = Style( + { + "overflow": "hidden", + "marginTop": "1px", + "&:first-child": { + "marginTop": 0, + "borderTopLeftRadius": "4px", + "borderTopRightRadius": "4px", + }, + "&:last-child": { + "borderBottomLeftRadius": "4px", + "borderBottomRightRadius": "4px", + }, + "&:focus-within": { + "position": "relative", + "zIndex": 1, + "boxShadow": "0 0 0 2px var(--accent-7)", + }, + } + ) + + # A unique identifier for the item. + value: Var[str] + + # When true, prevents the user from interacting with the item. + disabled: Var[bool] + + +class AccordionHeader(AccordionComponent): + """An accordion component.""" + + tag = "Header" + + alias = "RadixAccordionHeader" + + style: Style = Style( + { + "display": "flex", + } + ) + + +class AccordionTrigger(AccordionComponent): + """An accordion component.""" + + tag = "Trigger" + + alias = "RadixAccordionTrigger" + + style: Style = Style( + { + "fontFamily": "inherit", + "backgroundColor": "transparent", + "padding": "0 20px", + "height": "45px", + "flex": 1, + "display": "flex", + "alignItems": "center", + "justifyContent": "space-between", + "fontSize": "15px", + "lineHeight": 1, + "color": "var(--accent-11)", + "boxShadow": "0 1px 0 var(--accent-6)", + "&:hover": { + "backgroundColor": "var(--gray-2)", + }, + "&[data-state='open'] > .AccordionChevron": { + "transform": "rotate(180deg)", + }, + } + ) + + +class AccordionContent(AccordionComponent): + """An accordion component.""" + + tag = "Content" + + alias = "RadixAccordionContent" + + style: Style = Style( + { + "overflow": "hidden", + "fontSize": "15px", + "color": "var(--accent-11)", + "backgroundColor": "var(--accent-2)", + "padding": "15px, 20px", + "&[data-state='open']": { + "animation": Var.create( + f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + "&[data-state='closed']": { + "animation": Var.create( + f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + } + ) + + def _get_imports(self): + return { + **super()._get_imports(), + "@emotion/react": [imports.ImportVar(tag="keyframes")], + } + + def _get_custom_code(self) -> str: + return """ +const slideDown = keyframes` +from { + height: 0; +} +to { + height: var(--radix-accordion-content-height); +} +` +const slideUp = keyframes` +from { + height: var(--radix-accordion-content-height); +} +to { + height: 0; +} +` +""" + + +# TODO: Remove this once the radix-icons PR is merged in. +class ChevronDownIcon(Component): + """A chevron down icon.""" + + library = "@radix-ui/react-icons" + + tag = "ChevronDownIcon" + + style: Style = Style( + { + "color": "var(--accent-10)", + "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + } + ) diff --git a/reflex/components/radix/themes/__init__.py b/reflex/components/radix/themes/__init__.py index 025871633e..7ecdfb7499 100644 --- a/reflex/components/radix/themes/__init__.py +++ b/reflex/components/radix/themes/__init__.py @@ -6,10 +6,3 @@ theme = Theme.create theme_panel = ThemePanel.create - -accordion_root = AccordionRoot.create -accordion_item = AccordionItem.create -accordion_trigger = AccordionTrigger.create -accordion_content = AccordionContent.create -accordion_header = AccordionHeader.create -chevron_down_icon = ChevronDownIcon.create diff --git a/reflex/components/radix/themes/components/textfield.py b/reflex/components/radix/themes/components/textfield.py index ac09f33947..2f8cb18924 100644 --- a/reflex/components/radix/themes/components/textfield.py +++ b/reflex/components/radix/themes/components/textfield.py @@ -90,192 +90,3 @@ class TextFieldSlot(RadixThemesComponent): # Override the gap spacing between slot and input: "1" - "9" gap: Var[LiteralSize] - - -from reflex.style import Style -from reflex.utils import imports - - -class AccordionComponent(Component): - """Base class for all @radix-ui/accordion components.""" - - library = "@radix-ui/react-accordion" - - as_child: Var[bool] - - -class AccordionRoot(AccordionComponent): - """An accordion component.""" - - tag = "Root" - - alias = "RadixAccordionRoot" - - style: Style = Style( - { - "borderRadius": "6px", - "width": "300px", - "backgroundColor": "var(--accent-6)", - "boxShadow": "0 2px 10px var(--black-a4)", - } - ) - - value: Var[str] - - default_value: Var[str] - - collapsible: Var[bool] - - disabled: Var[bool] - - dir: Var[str] - - orientation: Var[str] - - -class AccordionItem(AccordionComponent): - """An accordion component.""" - - tag = "Item" - - alias = "RadixAccordionItem" - - style: Style = Style( - { - "overflow": "hidden", - "marginTop": "1px", - "&:first-child": { - "marginTop": 0, - "borderTopLeftRadius": "4px", - "borderTopRightRadius": "4px", - }, - "&:last-child": { - "borderBottomLeftRadius": "4px", - "borderBottomRightRadius": "4px", - }, - "&:focus-within": { - "position": "relative", - "zIndex": 1, - "boxShadow": "0 0 0 2px var(--accent-7)", - }, - } - ) - - value: Var[str] - - disabled: Var[bool] - - -class AccordionHeader(AccordionComponent): - """An accordion component.""" - - tag = "Header" - - alias = "RadixAccordionHeader" - - style: Style = Style( - { - "display": "flex", - } - ) - - -class AccordionTrigger(AccordionComponent): - """An accordion component.""" - - tag = "Trigger" - - alias = "RadixAccordionTrigger" - - style: Style = Style( - { - "fontFamily": "inherit", - "backgroundColor": "transparent", - "padding": "0 20px", - "height": "45px", - "flex": 1, - "display": "flex", - "alignItems": "center", - "justifyContent": "space-between", - "fontSize": "15px", - "lineHeight": 1, - "color": "var(--accent-11)", - "boxShadow": "0 1px 0 var(--accent-6)", - "backgroundColor": "white", - "&:hover": { - "backgroundColor": "var(--gray-2)", - }, - "&[data-state='open'] > .AccordionChevron": { - "transform": "rotate(180deg)", - }, - } - ) - - -class AccordionContent(AccordionComponent): - """An accordion component.""" - - tag = "Content" - - alias = "RadixAccordionContent" - - style: Style = Style( - { - "overflow": "hidden", - "fontSize": "15px", - "color": "var(--accent-11)", - "backgroundColor": "var(--accent-2)", - "padding": "15px, 20px", - "&[data-state='open']": { - "animation": Var.create( - "${slideDown} 500ms cubic-bezier(0.87, 0, 0.13, 1)", - _var_is_string=True, - ), - }, - "&[data-state='closed']": { - "animation": Var.create( - "${slideUp} 500ms cubic-bezier(0.87, 0, 0.13, 1)", - _var_is_string=True, - ), - }, - } - ) - - def _get_imports(self): - return { - **super()._get_imports(), - "@emotion/react": [imports.ImportVar(tag="keyframes")], - } - - def _get_custom_code(self) -> str: - return """ -const slideDown = keyframes` -from { - height: 0; -} -to { - height: var(--radix-accordion-content-height); -} -` -const slideUp = keyframes` -from { - height: var(--radix-accordion-content-height); -} -to { - height: 0; -} -` -""" - - -class ChevronDownIcon(Component): - library = "@radix-ui/react-icons" - - tag = "ChevronDownIcon" - - style: Style = Style( - { - "color": "var(--accent-10)", - "transition": "transform 300ms cubic-bezier(0.87, 0, 0.13, 1)", - } - ) From b8c2084f2efdb140d4dca9e4c94dcf20489cd030 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 7 Dec 2023 12:44:51 -0800 Subject: [PATCH 05/10] Add pyi file --- .../components/radix/primitives/accordion.pyi | 610 ++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 reflex/components/radix/primitives/accordion.pyi diff --git a/reflex/components/radix/primitives/accordion.pyi b/reflex/components/radix/primitives/accordion.pyi new file mode 100644 index 0000000000..8bc5da6726 --- /dev/null +++ b/reflex/components/radix/primitives/accordion.pyi @@ -0,0 +1,610 @@ +"""Stub file for reflex/components/radix/primitives/accordion.py""" +# ------------------- DO NOT EDIT ---------------------- +# This file was generated by `scripts/pyi_generator.py`! +# ------------------------------------------------------ + +from typing import Any, Dict, Literal, Optional, Union, overload +from reflex.vars import Var, BaseVar, ComputedVar +from reflex.event import EventChain, EventHandler, EventSpec +from reflex.style import Style +from typing import Literal +from reflex.components.component import Component +from reflex.components.tags import Tag +from reflex.style import Style +from reflex.utils import format, imports +from reflex.vars import Var + +LiteralAccordionType = Literal["single", "multiple"] +LiteralAccordionDir = Literal["ltr", "rtl"] +LiteralAccordionOrientation = Literal["vertical", "horizontal"] +DEFAULT_ANIMATION_DURATION = 250 + +class AccordionComponent(Component): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + as_child: Optional[Union[Var[bool], bool]] = 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, Union[Var, 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 + ) -> "AccordionComponent": + """Create the component. + + Args: + *children: The children of the component. + as_child: Change the default rendered element for the one passed as a child. + 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 AccordionRoot(AccordionComponent): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + style: Optional[Style] = None, + type_: Optional[ + Union[Var[Literal["single", "multiple"]], Literal["single", "multiple"]] + ] = None, + value: Optional[Union[Var[str], str]] = None, + default_value: Optional[Union[Var[str], str]] = None, + collapsible: Optional[Union[Var[bool], bool]] = None, + disabled: Optional[Union[Var[bool], bool]] = None, + dir: Optional[Union[Var[Literal["ltr", "rtl"]], Literal["ltr", "rtl"]]] = None, + orientation: Optional[ + Union[ + Var[Literal["vertical", "horizontal"]], + Literal["vertical", "horizontal"], + ] + ] = None, + as_child: Optional[Union[Var[bool], bool]] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, 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 + ) -> "AccordionRoot": + """Create the component. + + Args: + *children: The children of the component. + type_: The type of accordion (single or multiple). + value: The value of the item to expand. + default_value: The default value of the item to expand. + collapsible: Whether or not the accordion is collapsible. + disabled: Whether or not the accordion is disabled. + dir: The reading direction of the accordion when applicable. + orientation: The orientation of the accordion. + as_child: Change the default rendered element for the one passed as a child. + 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 AccordionItem(AccordionComponent): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + style: Optional[Style] = None, + value: Optional[Union[Var[str], str]] = None, + disabled: Optional[Union[Var[bool], bool]] = None, + as_child: Optional[Union[Var[bool], bool]] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, 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 + ) -> "AccordionItem": + """Create the component. + + Args: + *children: The children of the component. + value: A unique identifier for the item. + disabled: When true, prevents the user from interacting with the item. + as_child: Change the default rendered element for the one passed as a child. + 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 AccordionHeader(AccordionComponent): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + style: Optional[Style] = None, + as_child: Optional[Union[Var[bool], bool]] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, 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 + ) -> "AccordionHeader": + """Create the component. + + Args: + *children: The children of the component. + as_child: Change the default rendered element for the one passed as a child. + 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 AccordionTrigger(AccordionComponent): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + style: Optional[Style] = None, + as_child: Optional[Union[Var[bool], bool]] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, 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 + ) -> "AccordionTrigger": + """Create the component. + + Args: + *children: The children of the component. + as_child: Change the default rendered element for the one passed as a child. + 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 AccordionContent(AccordionComponent): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + style: Optional[Style] = None, + as_child: Optional[Union[Var[bool], bool]] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, 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 + ) -> "AccordionContent": + """Create the component. + + Args: + *children: The children of the component. + as_child: Change the default rendered element for the one passed as a child. + 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 ChevronDownIcon(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, Union[Var, 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 + ) -> "ChevronDownIcon": + """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. + """ + ... From 4cde6a40751da144ebdf9661484e870f61ea3607 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 7 Dec 2023 12:50:24 -0800 Subject: [PATCH 06/10] Fix pyright --- reflex/components/radix/primitives/accordion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py index e850a288e2..989fc6877b 100644 --- a/reflex/components/radix/primitives/accordion.py +++ b/reflex/components/radix/primitives/accordion.py @@ -30,7 +30,7 @@ def _render(self) -> Tag: ._render() .add_props( **{ - "class_name": format.to_title_case(self.tag), + "class_name": format.to_title_case(self.tag or ""), } ) ) From 4cb01e785a6255bd8f883f106e364935b12c6324 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 7 Dec 2023 13:54:01 -0800 Subject: [PATCH 07/10] Add apply_theme method --- reflex/app.py | 3 +++ reflex/components/component.py | 14 +++++++++++ .../components/graphing/recharts/cartesian.py | 5 ++++ reflex/components/graphing/recharts/charts.py | 4 ++++ reflex/components/graphing/recharts/polar.py | 5 ++++ .../components/radix/primitives/accordion.py | 2 +- reflex/vars.py | 23 +++++++++++++++++++ 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/reflex/app.py b/reflex/app.py index b0be08f559..63930acea1 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -667,6 +667,9 @@ def mark_complete(_=None): # Merge the component style with the app style. component.add_style(self.style) + if self.theme is not None: + component.apply_theme(self.theme) + # Add component.get_imports() to all_imports. all_imports.update(component.get_imports()) diff --git a/reflex/components/component.py b/reflex/components/component.py index 595bb14cd5..b04d6b2dd9 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -446,6 +446,20 @@ def __str__(self) -> str: return _compile_component(self) + def _apply_theme(self, theme: Component): + pass + + def apply_theme(self, theme: Component): + """Apply a theme to the component. + + Args: + theme: The theme to apply. + """ + for child in self.children: + if not isinstance(child, Component): + continue + child._apply_theme(theme) + def _render(self, props: dict[str, Any] | None = None) -> Tag: """Define how to render the component in React. diff --git a/reflex/components/graphing/recharts/cartesian.py b/reflex/components/graphing/recharts/cartesian.py index 136bddf9f8..e9b98c5ffa 100644 --- a/reflex/components/graphing/recharts/cartesian.py +++ b/reflex/components/graphing/recharts/cartesian.py @@ -3,6 +3,7 @@ from typing import Any, Dict, List, Union +from reflex.components import Component from reflex.constants import EventTriggers from reflex.vars import Var @@ -195,6 +196,10 @@ class Cartesian(Recharts): # The type of icon in legend. If set to 'none', no legend item will be rendered. 'line' | 'plainline' | 'square' | 'rect'| 'circle' | 'cross' | 'diamond' | 'star' | 'triangle' | 'wye' | 'none'optional # legend_type: Var[LiteralLegendType] + def _apply_theme(self, theme: Component): + self.stroke = Var.create(f"var(--accent-8)") + self.fill = Var.create(f"var(--accent-5)") + def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. diff --git a/reflex/components/graphing/recharts/charts.py b/reflex/components/graphing/recharts/charts.py index b0150cc342..62eef67087 100644 --- a/reflex/components/graphing/recharts/charts.py +++ b/reflex/components/graphing/recharts/charts.py @@ -262,6 +262,10 @@ class PieChart(ChartBase): "Pie", ] + def _apply_theme(self, theme: Component): + self.stroke = Var.create_safe(f"var(--accent-8)") + self.fill = Var.create_safe(f"var(--accent-5)") + def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. diff --git a/reflex/components/graphing/recharts/polar.py b/reflex/components/graphing/recharts/polar.py index 2566957403..b7ff2bb424 100644 --- a/reflex/components/graphing/recharts/polar.py +++ b/reflex/components/graphing/recharts/polar.py @@ -3,6 +3,7 @@ from typing import Any, Dict, List, Union +from reflex.components import Component from reflex.constants import EventTriggers from reflex.vars import Var @@ -73,6 +74,10 @@ class Pie(Recharts): # stroke color stroke: Var[str] + def _apply_theme(self, theme: Component): + self.stroke = Var.create_safe(f"var(--accent-8)") + self.fill = Var.create_safe(f"var(--accent-5)") + def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py index 989fc6877b..cceed37e04 100644 --- a/reflex/components/radix/primitives/accordion.py +++ b/reflex/components/radix/primitives/accordion.py @@ -133,7 +133,7 @@ class AccordionTrigger(AccordionComponent): style: Style = Style( { "fontFamily": "inherit", - "backgroundColor": "transparent", + "backgroundColor": "white", "padding": "0 20px", "height": "45px", "flex": 1, diff --git a/reflex/vars.py b/reflex/vars.py index af02eb54de..49b395ac72 100644 --- a/reflex/vars.py +++ b/reflex/vars.py @@ -1284,6 +1284,29 @@ def upper(self) -> Var: _var_type=str, ) + def strip(self, other: str | Var[str] = " ") -> Var: + """Strip a string var. + + Args: + other: The string to strip the var with. + + Returns: + A var with the stripped string. + + Raises: + TypeError: If the var is not a string. + """ + if not types._issubclass(self._var_type, str): + raise TypeError(f"Cannot strip non-string var {self._var_full_name}.") + + other = Var.create_safe(json.dumps(other)) if isinstance(other, str) else other + + return self._replace( + _var_name=f"{self._var_name}.replace(/^${other._var_full_name}|${other._var_full_name}$/g, '')", + _var_is_string=False, + merge_var_data=other._var_data, + ) + def split(self, other: str | Var[str] = " ") -> Var: """Split a string var into a list. From 1c07d0b93f2b2da43b28b4382e5ec25a7f2cbc07 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 7 Dec 2023 15:15:47 -0800 Subject: [PATCH 08/10] Fix apply_theme --- reflex/components/component.py | 3 ++- reflex/components/graphing/recharts/charts.py | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/reflex/components/component.py b/reflex/components/component.py index b04d6b2dd9..a46de945d7 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -455,10 +455,11 @@ def apply_theme(self, theme: Component): Args: theme: The theme to apply. """ + self._apply_theme(theme) for child in self.children: if not isinstance(child, Component): continue - child._apply_theme(theme) + child.apply_theme(theme) def _render(self, props: dict[str, Any] | None = None) -> Tag: """Define how to render the component in React. diff --git a/reflex/components/graphing/recharts/charts.py b/reflex/components/graphing/recharts/charts.py index 62eef67087..b0150cc342 100644 --- a/reflex/components/graphing/recharts/charts.py +++ b/reflex/components/graphing/recharts/charts.py @@ -262,10 +262,6 @@ class PieChart(ChartBase): "Pie", ] - def _apply_theme(self, theme: Component): - self.stroke = Var.create_safe(f"var(--accent-8)") - self.fill = Var.create_safe(f"var(--accent-5)") - def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. From 5fe339f99a09be5cf2aee8d59d0b2eda864567e3 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Fri, 8 Dec 2023 17:00:23 -0800 Subject: [PATCH 09/10] Use apply_theme method --- .../jinja/web/pages/base_page.js.jinja2 | 1 + reflex/components/component.py | 7 +- .../components/graphing/recharts/cartesian.py | 5 - reflex/components/graphing/recharts/polar.py | 5 - .../components/radix/primitives/__init__.py | 16 +- .../components/radix/primitives/accordion.py | 219 +++++++++++------- reflex/style.py | 2 +- reflex/utils/format.py | 8 +- 8 files changed, 148 insertions(+), 115 deletions(-) diff --git a/reflex/.templates/jinja/web/pages/base_page.js.jinja2 b/reflex/.templates/jinja/web/pages/base_page.js.jinja2 index 038a38a65e..2a1a509443 100644 --- a/reflex/.templates/jinja/web/pages/base_page.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/base_page.js.jinja2 @@ -1,4 +1,5 @@ {% import 'web/pages/utils.js.jinja2' as utils %} + /** @jsxImportSource @emotion/react */ {%- block imports_libs %} diff --git a/reflex/components/component.py b/reflex/components/component.py index a46de945d7..211a85b0ba 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -447,10 +447,15 @@ def __str__(self) -> str: return _compile_component(self) def _apply_theme(self, theme: Component): + """Apply the theme to this component. + + Args: + theme: The theme to apply. + """ pass def apply_theme(self, theme: Component): - """Apply a theme to the component. + """Apply a theme to the component and its children. Args: theme: The theme to apply. diff --git a/reflex/components/graphing/recharts/cartesian.py b/reflex/components/graphing/recharts/cartesian.py index e9b98c5ffa..136bddf9f8 100644 --- a/reflex/components/graphing/recharts/cartesian.py +++ b/reflex/components/graphing/recharts/cartesian.py @@ -3,7 +3,6 @@ from typing import Any, Dict, List, Union -from reflex.components import Component from reflex.constants import EventTriggers from reflex.vars import Var @@ -196,10 +195,6 @@ class Cartesian(Recharts): # The type of icon in legend. If set to 'none', no legend item will be rendered. 'line' | 'plainline' | 'square' | 'rect'| 'circle' | 'cross' | 'diamond' | 'star' | 'triangle' | 'wye' | 'none'optional # legend_type: Var[LiteralLegendType] - def _apply_theme(self, theme: Component): - self.stroke = Var.create(f"var(--accent-8)") - self.fill = Var.create(f"var(--accent-5)") - def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. diff --git a/reflex/components/graphing/recharts/polar.py b/reflex/components/graphing/recharts/polar.py index b7ff2bb424..2566957403 100644 --- a/reflex/components/graphing/recharts/polar.py +++ b/reflex/components/graphing/recharts/polar.py @@ -3,7 +3,6 @@ from typing import Any, Dict, List, Union -from reflex.components import Component from reflex.constants import EventTriggers from reflex.vars import Var @@ -74,10 +73,6 @@ class Pie(Recharts): # stroke color stroke: Var[str] - def _apply_theme(self, theme: Component): - self.stroke = Var.create_safe(f"var(--accent-8)") - self.fill = Var.create_safe(f"var(--accent-5)") - def get_event_triggers(self) -> dict[str, Union[Var, Any]]: """Get the event triggers that pass the component's value to the handler. diff --git a/reflex/components/radix/primitives/__init__.py b/reflex/components/radix/primitives/__init__.py index 647ce849c8..82e4c55e42 100644 --- a/reflex/components/radix/primitives/__init__.py +++ b/reflex/components/radix/primitives/__init__.py @@ -1,17 +1,3 @@ """Radix primitive components (https://www.radix-ui.com/primitives).""" -from .accordion import ( - AccordionContent, - AccordionHeader, - AccordionItem, - AccordionRoot, - AccordionTrigger, - ChevronDownIcon, -) - -accordion_root = AccordionRoot.create -accordion_item = AccordionItem.create -accordion_trigger = AccordionTrigger.create -accordion_content = AccordionContent.create -accordion_header = AccordionHeader.create -chevron_down_icon = ChevronDownIcon.create +from .accordion import accordion diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py index cceed37e04..e8d3ed57f3 100644 --- a/reflex/components/radix/primitives/accordion.py +++ b/reflex/components/radix/primitives/accordion.py @@ -43,15 +43,6 @@ class AccordionRoot(AccordionComponent): alias = "RadixAccordionRoot" - style: Style = Style( - { - "borderRadius": "6px", - "width": "300px", - "backgroundColor": "var(--accent-6)", - "boxShadow": "0 2px 10px var(--black-a4)", - } - ) - # The type of accordion (single or multiple). type_: Var[LiteralAccordionType] @@ -73,6 +64,16 @@ class AccordionRoot(AccordionComponent): # The orientation of the accordion. orientation: Var[LiteralAccordionOrientation] + def _apply_theme(self, theme: Component): + self.style = Style( + { + "border_radius": "6px", + "background_color": "var(--accent-6)", + "box_shadow": "0 2px 10px var(--black-a4)", + **self.style, + } + ) + class AccordionItem(AccordionComponent): """An accordion component.""" @@ -81,33 +82,35 @@ class AccordionItem(AccordionComponent): alias = "RadixAccordionItem" - style: Style = Style( - { - "overflow": "hidden", - "marginTop": "1px", - "&:first-child": { - "marginTop": 0, - "borderTopLeftRadius": "4px", - "borderTopRightRadius": "4px", - }, - "&:last-child": { - "borderBottomLeftRadius": "4px", - "borderBottomRightRadius": "4px", - }, - "&:focus-within": { - "position": "relative", - "zIndex": 1, - "boxShadow": "0 0 0 2px var(--accent-7)", - }, - } - ) - # A unique identifier for the item. value: Var[str] # When true, prevents the user from interacting with the item. disabled: Var[bool] + def _apply_theme(self, theme: Component): + self.style = Style( + { + "overflow": "hidden", + "margin_top": "1px", + "&:first-child": { + "margin_top": 0, + "border_top_left_radius": "4px", + "border_top_right_radius": "4px", + }, + "&:last-child": { + "border_bottom_left_radius": "4px", + "border_bottom_right_radius": "4px", + }, + "&:focus-within": { + "position": "relative", + "z_index": 1, + "box_shadow": "0 0 0 2px var(--accent-7)", + }, + **self.style, + } + ) + class AccordionHeader(AccordionComponent): """An accordion component.""" @@ -116,11 +119,13 @@ class AccordionHeader(AccordionComponent): alias = "RadixAccordionHeader" - style: Style = Style( - { - "display": "flex", - } - ) + def _apply_theme(self, theme: Component): + self.style = Style( + { + "display": "flex", + **self.style, + } + ) class AccordionTrigger(AccordionComponent): @@ -130,28 +135,29 @@ class AccordionTrigger(AccordionComponent): alias = "RadixAccordionTrigger" - style: Style = Style( - { - "fontFamily": "inherit", - "backgroundColor": "white", - "padding": "0 20px", - "height": "45px", - "flex": 1, - "display": "flex", - "alignItems": "center", - "justifyContent": "space-between", - "fontSize": "15px", - "lineHeight": 1, - "color": "var(--accent-11)", - "boxShadow": "0 1px 0 var(--accent-6)", - "&:hover": { - "backgroundColor": "var(--gray-2)", - }, - "&[data-state='open'] > .AccordionChevron": { - "transform": "rotate(180deg)", - }, - } - ) + def _apply_theme(self, theme: Component): + self.style = Style( + { + "font_family": "inherit", + "padding": "0 20px", + "height": "45px", + "flex": 1, + "display": "flex", + "align_items": "center", + "justify_content": "space-between", + "font_size": "15px", + "line_height": 1, + "color": "var(--accent-11)", + "box_shadow": "0 1px 0 var(--accent-6)", + "&:hover": { + "background_color": "var(--gray-2)", + }, + "&[data-state='open'] > .AccordionChevron": { + "transform": "rotate(180deg)", + }, + **self.style, + } + ) class AccordionContent(AccordionComponent): @@ -161,27 +167,29 @@ class AccordionContent(AccordionComponent): alias = "RadixAccordionContent" - style: Style = Style( - { - "overflow": "hidden", - "fontSize": "15px", - "color": "var(--accent-11)", - "backgroundColor": "var(--accent-2)", - "padding": "15px, 20px", - "&[data-state='open']": { - "animation": Var.create( - f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", - _var_is_string=True, - ), - }, - "&[data-state='closed']": { - "animation": Var.create( - f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", - _var_is_string=True, - ), - }, - } - ) + def _apply_theme(self, theme: Component): + self.style = Style( + { + "overflow": "hidden", + "fontSize": "15px", + "color": "var(--accent-11)", + "backgroundColor": "var(--accent-2)", + "padding": "15px, 20px", + "&[data-state='open']": { + "animation": Var.create( + f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + "&[data-state='closed']": { + "animation": Var.create( + f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + _var_is_string=True, + ), + }, + **self.style, + } + ) def _get_imports(self): return { @@ -218,9 +226,54 @@ class ChevronDownIcon(Component): tag = "ChevronDownIcon" - style: Style = Style( - { - "color": "var(--accent-10)", - "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", - } + def _apply_theme(self, theme: Component): + self.style = Style( + { + "color": "var(--accent-10)", + "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)", + **self.style, + } + ) + + +accordion_root = AccordionRoot.create +accordion_item = AccordionItem.create +accordion_trigger = AccordionTrigger.create +accordion_content = AccordionContent.create +accordion_header = AccordionHeader.create +chevron_down_icon = ChevronDownIcon.create + + +def accordion(items: list[tuple[str, str]], **props) -> AccordionRoot: + """High level API for the Radix accordion. + + #TODO: We need to handle taking in state here. This is just for a POC. + + + Args: + items: The items of the accordion component: list of tuples (label,panel) + **props: The properties of the component. + + Returns: + The accordion component. + """ + return accordion_root( + *[ + accordion_item( + accordion_header( + accordion_trigger( + label, + chevron_down_icon( + class_name="AccordionChevron", + ), + ), + ), + accordion_content( + panel, + ), + value=f"item-{i}", + ) + for i, (label, panel) in enumerate(items) + ], + **props, ) diff --git a/reflex/style.py b/reflex/style.py index 74a1092f9d..1e5d94fa26 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -48,7 +48,7 @@ def convert(style_dict): var_data = None # Track import/hook data from any Vars in the style dict. out = {} for key, value in style_dict.items(): - key = format.to_camel_case(key, allow_hyphens=True) + key = format.to_camel_case(key) new_var_data = None if isinstance(value, dict): # Recursively format nested style dictionaries. diff --git a/reflex/utils/format.py b/reflex/utils/format.py index e6e0a356d7..4d95d44d9b 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -125,7 +125,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) -> str: """Convert a string to camel case. The first word in the text is converted to lowercase and @@ -133,14 +133,12 @@ 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 text. Returns: The camel case string. """ - chars = "-_" if not allow_hyphens else "_" - words = re.split(f"[{chars}]", text.lstrip(chars)) - leading_underscores_or_hyphens = "".join(re.findall(rf"^[{chars}]+", text)) + words = re.split("[_-]", text.lstrip("-_")) + leading_underscores_or_hyphens = "".join(re.findall(r"^[_-]+", 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 From ff4f2c4c4d3ead74f53d9e299d41309f631ea05b Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Fri, 8 Dec 2023 17:27:17 -0800 Subject: [PATCH 10/10] Fix lint --- .../components/radix/primitives/accordion.py | 2 +- .../components/radix/primitives/accordion.pyi | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py index e8d3ed57f3..c3cb662861 100644 --- a/reflex/components/radix/primitives/accordion.py +++ b/reflex/components/radix/primitives/accordion.py @@ -244,7 +244,7 @@ def _apply_theme(self, theme: Component): chevron_down_icon = ChevronDownIcon.create -def accordion(items: list[tuple[str, str]], **props) -> AccordionRoot: +def accordion(items: list[tuple[str, str]], **props) -> Component: """High level API for the Radix accordion. #TODO: We need to handle taking in state here. This is just for a POC. diff --git a/reflex/components/radix/primitives/accordion.pyi b/reflex/components/radix/primitives/accordion.pyi index 8bc5da6726..119220e56b 100644 --- a/reflex/components/radix/primitives/accordion.pyi +++ b/reflex/components/radix/primitives/accordion.pyi @@ -106,7 +106,6 @@ class AccordionRoot(AccordionComponent): def create( # type: ignore cls, *children, - style: Optional[Style] = None, type_: Optional[ Union[Var[Literal["single", "multiple"]], Literal["single", "multiple"]] ] = None, @@ -122,6 +121,7 @@ class AccordionRoot(AccordionComponent): ] ] = None, as_child: Optional[Union[Var[bool], bool]] = None, + style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None, class_name: Optional[Any] = None, @@ -208,10 +208,10 @@ class AccordionItem(AccordionComponent): def create( # type: ignore cls, *children, - style: Optional[Style] = None, value: Optional[Union[Var[str], str]] = None, disabled: Optional[Union[Var[bool], bool]] = None, as_child: Optional[Union[Var[bool], bool]] = None, + style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None, class_name: Optional[Any] = None, @@ -293,8 +293,8 @@ class AccordionHeader(AccordionComponent): def create( # type: ignore cls, *children, - style: Optional[Style] = None, as_child: Optional[Union[Var[bool], bool]] = None, + style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None, class_name: Optional[Any] = None, @@ -374,8 +374,8 @@ class AccordionTrigger(AccordionComponent): def create( # type: ignore cls, *children, - style: Optional[Style] = None, as_child: Optional[Union[Var[bool], bool]] = None, + style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None, class_name: Optional[Any] = None, @@ -455,8 +455,8 @@ class AccordionContent(AccordionComponent): def create( # type: ignore cls, *children, - style: Optional[Style] = None, as_child: Optional[Union[Var[bool], bool]] = None, + style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None, class_name: Optional[Any] = None, @@ -608,3 +608,12 @@ class ChevronDownIcon(Component): TypeError: If an invalid child is passed. """ ... + +accordion_root = AccordionRoot.create +accordion_item = AccordionItem.create +accordion_trigger = AccordionTrigger.create +accordion_content = AccordionContent.create +accordion_header = AccordionHeader.create +chevron_down_icon = ChevronDownIcon.create + +def accordion(items: list[tuple[str, str]], **props) -> Component: ...