diff --git a/reflex_ui/__init__.py b/reflex_ui/__init__.py index 68efa4f..f830f4f 100644 --- a/reflex_ui/__init__.py +++ b/reflex_ui/__init__.py @@ -8,6 +8,7 @@ "components.base.button": ["button"], "components.base.card": ["card"], "components.base.checkbox": ["checkbox"], + "components.base.collapsible": ["collapsible"], "components.base.dialog": ["dialog"], "components.base.gradient_profile": ["gradient_profile"], "components.base.input": ["input"], diff --git a/reflex_ui/__init__.pyi b/reflex_ui/__init__.pyi index 8507311..9db5ab3 100644 --- a/reflex_ui/__init__.pyi +++ b/reflex_ui/__init__.pyi @@ -10,6 +10,7 @@ from .components.base.badge import badge from .components.base.button import button from .components.base.card import card from .components.base.checkbox import checkbox +from .components.base.collapsible import collapsible from .components.base.dialog import dialog from .components.base.gradient_profile import gradient_profile from .components.base.input import input @@ -39,6 +40,7 @@ _REFLEX_UI_MAPPING = { "components.base.button": ["button"], "components.base.card": ["card"], "components.base.checkbox": ["checkbox"], + "components.base.collapsible": ["collapsible"], "components.base.dialog": ["dialog"], "components.base.gradient_profile": ["gradient_profile"], "components.base.input": ["input"], @@ -76,6 +78,7 @@ __all__ = [ "card", "checkbox", "cn", + "collapsible", "components", "dialog", "gradient_profile", diff --git a/reflex_ui/components/base/__init__.pyi b/reflex_ui/components/base/__init__.pyi index 1049ddf..a87ba93 100644 --- a/reflex_ui/components/base/__init__.pyi +++ b/reflex_ui/components/base/__init__.pyi @@ -10,6 +10,7 @@ from .badge import badge from .button import button from .card import card from .checkbox import checkbox +from .collapsible import collapsible from .dialog import dialog from .gradient_profile import gradient_profile from .input import input @@ -41,6 +42,7 @@ __all__ = [ "button", "card", "checkbox", + "collapsible", "dialog", "gradient_profile", "input", diff --git a/reflex_ui/components/base/collapsible.py b/reflex_ui/components/base/collapsible.py new file mode 100644 index 0000000..ba7f452 --- /dev/null +++ b/reflex_ui/components/base/collapsible.py @@ -0,0 +1,140 @@ +"""Custom collapsible component.""" + +from reflex.components.component import Component, ComponentNamespace +from reflex.event import EventHandler, passthrough_event_spec +from reflex.utils.imports import ImportVar +from reflex.vars.base import Var + +from reflex_ui.components.base_ui import PACKAGE_NAME, BaseUIComponent + + +class ClassNames: + """Class names for collapsible components.""" + + ROOT = "flex flex-col justify-center text-secondary-12" + TRIGGER = "group flex items-center gap-2" + PANEL = "flex h-[var(--collapsible-panel-height)] flex-col justify-end overflow-hidden text-sm transition-all ease-out data-[ending-style]:h-0 data-[starting-style]:h-0" + + +class CollapsibleBaseComponent(BaseUIComponent): + """Base component for collapsible components.""" + + library = f"{PACKAGE_NAME}/collapsible" + + @property + def import_var(self): + """Return the import variable for the collapsible component.""" + return ImportVar(tag="Collapsible", package_path="", install=False) + + +class CollapsibleRoot(CollapsibleBaseComponent): + """Groups all parts of the collapsible. Renders a
element.""" + + tag = "Collapsible.Root" + + # Whether the collapsible panel is initially open. To render a controlled collapsible, use the `open` prop instead. Defaults to False. + default_open: Var[bool] + + # Whether the collapsible panel is currently open. To render an uncontrolled collapsible, use the `default_open` prop instead. + open: Var[bool] + + # Event handler called when the panel is opened or closed. + on_open_change: EventHandler[passthrough_event_spec(bool)] + + # Whether the component should ignore user interaction. Defaults to False. + disabled: Var[bool] + + # The render prop. + render_: Var[Component] + + @classmethod + def create(cls, *children, **props) -> BaseUIComponent: + """Create the collapsible root component.""" + props["data-slot"] = "collapsible" + cls.set_class_name(ClassNames.ROOT, props) + return super().create(*children, **props) + + +class CollapsibleTrigger(CollapsibleBaseComponent): + """A button that opens and closes the collapsible panel. Renders a