Skip to main content

Mantine UI input components for Reflex with type safety and comprehensive examples

Project description

appkit-mantine

PyPI version Python 3.12+ License: MIT Pre-release

reflex.dev components based on MantineUI

A Reflex wrapper library focusing on Mantine UI v8.3.3 input components, designed for building robust forms and data entry interfaces in Python web applications.


✨ Features

  • 🎯 Input-Focused - Comprehensive coverage of form inputs: text, password, number, date, masked inputs, textarea, and rich text editor
  • 🔒 Type-Safe - Full type annotations with IDE autocomplete support for all props and event handlers
  • 📚 Rich Examples - Production-ready code examples for every component with common patterns and edge cases
  • 🏗️ Clean Architecture - Inheritance-based design eliminating code duplication across 40+ common props
  • 🎨 Mantine Integration - Seamless integration with Mantine's theming, color modes, and design system
  • ⚡ Modern Stack - Built on Reflex 0.8.13+ with React 18 and Mantine 8.3.3

📦 Installation

Using pip

pip install appkit-mantine

Using uv (recommended)

uv add appkit-mantine

Development Installation

For local development or to run the demo application:

# Clone the repository
git clone https://github.com/jenreh/appkit.git
cd appkit

# Install with uv (installs workspace components)
uv sync

# Run the demo app
reflex run

⚠️ Pre-release Notice: This library is in development. APIs may change before the 1.0 release.


🚀 Quick Start

import reflex as rx
import appkit_mantine as mn

class FormState(rx.State):
    email: str = ""
    password: str = ""

def login_form() -> rx.Component:
    return rx.container(
        rx.vstack(
            rx.heading("Login"),

            # Basic input with validation
            mn.form.input(
                label="Email",
                placeholder="you@example.com",
                value=FormState.email,
                on_change=FormState.set_email,
                required=True,
                type="email",
            ),

            # Password input with visibility toggle
            mn.password_input(
                label="Password",
                value=FormState.password,
                on_change=FormState.set_password,
                required=True,
            ),

            rx.button("Sign In", on_click=FormState.handle_login),
            spacing="4",
        ),
        max_width="400px",
    )

app = rx.App()
app.add_page(login_form)

📋 Available Components

Inputs

Component Description Documentation
text_input Basic text input / text inputs showcase Guide
input Polymorphic base input element with sections, variants, sizes Examples
password_input Password field with visibility toggle Examples
date_input Date picker with range constraints and formatting Examples
number_input Numeric input with formatting, min/max, step controls Examples
textarea Multi-line text input with auto-resize Guide
json_input JSON input with formatting, validation, parser, pretty printing Examples
select Dropdown select with data array, inherits input props Examples
multi_select Multi-select dropdown for selecting multiple values Examples
rich_select Advanced select component with search and grouping Examples
tags_input Free-form tags input component Examples
autocomplete Autocomplete input with string data array Examples
rich_text_editor WYSIWYG editor powered by Tiptap Guide
masked_input Input masking for phone numbers, credit cards, custom patterns Guide

Buttons

Component Description Documentation
action_icon Lightweight button for icons with size, variant, radius, disabled state Examples
button Button with variants, sizes, gradient, loading states, sections Examples

Overlays

Component Description Documentation
modal Accessible overlay dialog with focus trap and scroll lock Examples
drawer Overlay drawer area sliding from any side Docs

Others

Component Description Documentation
markdown_preview Markdown renderer with Mermaid diagrams and math support Examples
navigation_progress Page loading progress indicator Examples
nav_link Navigation link with label, description, icons, nested links, active/disabled states Examples
number_formatter Formats numeric input with parser/formatter, returns parsed value Examples
scroll_area Scrollable container with custom scrollbars and virtualization Examples
table Table component for tabular data display Examples

Common Props (Inherited by All Inputs)

All input components inherit ~40 common props from MantineInputComponentBase:

# Input.Wrapper props
label="Field Label"
description="Helper text"
error="Validation error"
required=True
with_asterisk=True  # Show red asterisk for required fields

# Visual variants
variant="filled"  # "default" | "filled" | "unstyled"
size="md"  # "xs" | "sm" | "md" | "lg" | "xl"
radius="md"  # "xs" | "sm" | "md" | "lg" | "xl"

# State management
value=State.field_value
default_value="Initial value"
placeholder="Enter text..."
disabled=False

# Sections (icons, buttons)
left_section=rx.icon("search")
right_section=rx.button("Clear")
left_section_pointer_events="none"  # Click-through

# Mantine style props
w="100%"  # width
maw="500px"  # max-width
m="md"  # margin
p="sm"  # padding

# Event handlers
on_change=State.handle_change
on_focus=State.handle_focus
on_blur=State.handle_blur

📖 Usage Examples

Basic Input with Validation

import reflex as rx
import appkit_mantine as mn

class EmailState(rx.State):
    email: str = ""
    error: str = ""

    def validate_email(self):
        if "@" not in self.email:
            self.error = "Invalid email format"
        else:
            self.error = ""

def email_input():
    return mn.form.input(
        label="Email Address",
        description="We'll never share your email",
        placeholder="you@example.com",
        value=EmailState.email,
        on_change=EmailState.set_email,
        on_blur=EmailState.validate_email,
        error=EmailState.error,
        required=True,
        type="email",
        left_section=rx.icon("mail"),
    )

Number Input with Formatting

class PriceState(rx.State):
    price: float = 0.0

def price_input():
    return mn.number_input(
        label="Product Price",
        value=PriceState.price,
        on_change=PriceState.set_price,
        prefix="$",
        decimal_scale=2,
        fixed_decimal_scale=True,
        thousand_separator=",",
        min=0,
        max=999999.99,
        step=0.01,
    )

Masked Input (Phone Number)

class PhoneState(rx.State):
    phone: str = ""

def phone_input():
    return mn.masked_input(
        label="Phone Number",
        mask="+1 (000) 000-0000",
        value=PhoneState.phone,
        on_accept=PhoneState.set_phone,  # Note: on_accept, not on_change
        placeholder="+1 (555) 123-4567",
    )

Date Input with Constraints

from datetime import date, timedelta

class BookingState(rx.State):
    checkin: str = ""

def date_picker():
    today = date.today()
    max_date = today + timedelta(days=365)

    return mn.date_input(
        label="Check-in Date",
        value=BookingState.checkin,
        on_change=BookingState.set_checkin,
        min_date=today.isoformat(),
        max_date=max_date.isoformat(),
        clear_button_props={"aria_label": "Clear date"},
    )

Rich Text Editor

class EditorState(rx.State):
    content: str = "<p>Start typing...</p>"

def editor():
    return mn.rich_text_editor(
        value=EditorState.content,
        on_change=EditorState.set_content,
        toolbar_config=mn.EditorToolbarConfig(
            controls=[
                mn.ToolbarControlGroup.FORMATTING,
                mn.ToolbarControlGroup.LISTS,
                mn.ToolbarControlGroup.LINKS,
            ]
        ),
    )

Action Icon

def action_icon_example():
    return mn.action_icon(
        rx.icon("heart"),
        variant="filled",
        color="red",
        size="lg",
        on_click=State.like_item,
    )

Autocomplete

class SearchState(rx.State):
    query: str = ""

def autocomplete_example():
    return mn.autocomplete(
        label="Search",
        placeholder="Type to search...",
        data=["Apple", "Banana", "Cherry"],
        value=SearchState.query,
        on_change=SearchState.set_query,
    )

Button

def button_example():
    return mn.button(
        "Click me",
        variant="gradient",
        gradient={"from": "blue", "to": "cyan"},
        size="lg",
        on_click=State.handle_click,
    )

Combobox

def combobox_example():
    return mn.combobox(
        label="Select option",
        data=[
            {"value": "react", "label": "React"},
            {"value": "vue", "label": "Vue"},
        ],
        on_option_submit=State.set_selected,
    )

Input

def input_example():
    return mn.input(
        placeholder="Enter text...",
        left_section=rx.icon("search"),
        right_section=rx.button("Clear"),
    )

JSON Input

class JsonState(rx.State):
    data: str = '{"name": "example"}'

def json_input_example():
    return mn.json_input(
        label="JSON Data",
        value=JsonState.data,
        on_change=JsonState.set_data,
        format_on_blur=True,
    )

Nav Link

def nav_link_example():
    return mn.nav_link(
        label="Dashboard",
        left_section=rx.icon("home"),
        active=True,
        on_click=State.navigate_to_dashboard,
    )

Number Formatter

class PriceState(rx.State):
    amount: float = 1234.56

def number_formatter_example():
    return mn.number_formatter(
        value=PriceState.amount,
        prefix="$",
        thousand_separator=",",
        decimal_scale=2,
    )

Select

class SelectState(rx.State):
    choice: str = ""

def select_example():
    return mn.select(
        label="Choose one",
        data=["Option 1", "Option 2", "Option 3"],
        value=SelectState.choice,
        on_change=SelectState.set_choice,
    )

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

appkit_mantine-1.2.5.tar.gz (69.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

appkit_mantine-1.2.5-py3-none-any.whl (64.5 kB view details)

Uploaded Python 3

File details

Details for the file appkit_mantine-1.2.5.tar.gz.

File metadata

  • Download URL: appkit_mantine-1.2.5.tar.gz
  • Upload date:
  • Size: 69.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for appkit_mantine-1.2.5.tar.gz
Algorithm Hash digest
SHA256 7e36b9838d86a73a99e4d91d042cca72d03d8e5def300b3d31f5f7183986715a
MD5 0b082de58c7e5e45be94918ceec5ae57
BLAKE2b-256 05cd8e4362bf1fb87e757e6f99ebad5e254e71f34809a92b08fd51c4fd637a28

See more details on using hashes here.

File details

Details for the file appkit_mantine-1.2.5-py3-none-any.whl.

File metadata

  • Download URL: appkit_mantine-1.2.5-py3-none-any.whl
  • Upload date:
  • Size: 64.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for appkit_mantine-1.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 0825a220f1028b941037dc356521f3d1cea4d57949432d713db694899fbb3ce9
MD5 4ab74e2b5196b407f5e690d0a375366a
BLAKE2b-256 58a41566f535849f2d85bfea8600cc66b786bb8ced340d9f9b948c91633b591a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page