pycascadeui 2.0.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. pycascadeui-2.1.0/PKG-INFO +407 -0
  2. pycascadeui-2.1.0/README.md +365 -0
  3. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/__init__.py +1 -1
  4. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/v2_patterns.py +10 -12
  5. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/store.py +64 -16
  6. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/base.py +108 -20
  7. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/layout_patterns.py +0 -6
  8. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/patterns.py +0 -6
  9. pycascadeui-2.1.0/pycascadeui.egg-info/PKG-INFO +407 -0
  10. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/pyproject.toml +1 -1
  11. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_owner_only.py +98 -1
  12. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_session_limit.py +211 -4
  13. pycascadeui-2.0.0/PKG-INFO +0 -562
  14. pycascadeui-2.0.0/README.md +0 -520
  15. pycascadeui-2.0.0/pycascadeui.egg-info/PKG-INFO +0 -562
  16. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/LICENSE +0 -0
  17. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/__init__.py +0 -0
  18. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/base.py +0 -0
  19. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/buttons.py +0 -0
  20. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/inputs.py +0 -0
  21. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/selects.py +0 -0
  22. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/v1_composition.py +0 -0
  23. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/v1_patterns.py +0 -0
  24. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/components/wrappers.py +0 -0
  25. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/devtools.py +0 -0
  26. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/__init__.py +0 -0
  27. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/migration.py +0 -0
  28. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/redis.py +0 -0
  29. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/serialization.py +0 -0
  30. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/sqlite.py +0 -0
  31. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/persistence/storage.py +0 -0
  32. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/py.typed +0 -0
  33. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/__init__.py +0 -0
  34. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/actions.py +0 -0
  35. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/computed.py +0 -0
  36. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/middleware.py +0 -0
  37. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/reducers.py +0 -0
  38. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/singleton.py +0 -0
  39. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/types.py +0 -0
  40. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/state/undo.py +0 -0
  41. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/theming/__init__.py +0 -0
  42. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/theming/core.py +0 -0
  43. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/theming/themes.py +0 -0
  44. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/__init__.py +0 -0
  45. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/decorators.py +0 -0
  46. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/errors.py +0 -0
  47. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/helpers.py +0 -0
  48. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/logging.py +0 -0
  49. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/utils/tasks.py +0 -0
  50. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/validation.py +0 -0
  51. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/__init__.py +0 -0
  52. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/layout.py +0 -0
  53. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/layout_specialized.py +0 -0
  54. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/persistent.py +0 -0
  55. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/cascadeui/views/specialized.py +0 -0
  56. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/pycascadeui.egg-info/SOURCES.txt +0 -0
  57. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/pycascadeui.egg-info/dependency_links.txt +0 -0
  58. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/pycascadeui.egg-info/requires.txt +0 -0
  59. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/pycascadeui.egg-info/top_level.txt +0 -0
  60. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/setup.cfg +0 -0
  61. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_auto_defer.py +0 -0
  62. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_backends.py +0 -0
  63. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_batching.py +0 -0
  64. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_components.py +0 -0
  65. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_computed.py +0 -0
  66. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_devtools.py +0 -0
  67. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_hooks.py +0 -0
  68. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_layout_pagination.py +0 -0
  69. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_layout_patterns.py +0 -0
  70. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_layout_persistent.py +0 -0
  71. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_layout_view.py +0 -0
  72. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_middleware.py +0 -0
  73. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_nav_stack.py +0 -0
  74. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_nav_version.py +0 -0
  75. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_pagination.py +0 -0
  76. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_persistent_views.py +0 -0
  77. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_rebuild_callback.py +0 -0
  78. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_reducers.py +0 -0
  79. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_scoping.py +0 -0
  80. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_state_store.py +0 -0
  81. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_theming.py +0 -0
  82. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_undo.py +0 -0
  83. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_v2_helpers.py +0 -0
  84. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_validation.py +0 -0
  85. {pycascadeui-2.0.0 → pycascadeui-2.1.0}/tests/test_view_init.py +0 -0
@@ -0,0 +1,407 @@
1
+ Metadata-Version: 2.4
2
+ Name: pycascadeui
3
+ Version: 2.1.0
4
+ Summary: Redux-inspired UI framework for discord.py
5
+ Author-email: HollowTheSilver <hollow@users.noreply.github.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/HollowTheSilver/CascadeUI
8
+ Project-URL: Repository, https://github.com/HollowTheSilver/CascadeUI
9
+ Project-URL: Issues, https://github.com/HollowTheSilver/CascadeUI/issues
10
+ Project-URL: Documentation, https://hollowthesilver.github.io/CascadeUI/
11
+ Keywords: discord,discord.py,ui,components,state-management
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Communications :: Chat
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Classifier: Framework :: AsyncIO
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: discord.py>=2.7
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
31
+ Requires-Dist: black>=26.3; extra == "dev"
32
+ Requires-Dist: isort>=8.0; extra == "dev"
33
+ Provides-Extra: docs
34
+ Requires-Dist: mkdocs>=1.5; extra == "docs"
35
+ Requires-Dist: mkdocs-material>=9.0; extra == "docs"
36
+ Requires-Dist: pymdown-extensions>=10.0; extra == "docs"
37
+ Provides-Extra: sqlite
38
+ Requires-Dist: aiosqlite>=0.19; extra == "sqlite"
39
+ Provides-Extra: redis
40
+ Requires-Dist: redis>=5.0; extra == "redis"
41
+ Dynamic: license-file
42
+
43
+ <p align="center">
44
+ <img src="https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/docs/assets/banner.png" alt="CascadeUI - A Redux-Inspired Framework for Discord.py" width="100%">
45
+ </p>
46
+
47
+ <p align="center">
48
+ <a href="https://github.com/HollowTheSilver/CascadeUI/stargazers"><img src="https://img.shields.io/github/stars/HollowTheSilver/CascadeUI?style=flat&logo=github&label=stars" alt="Stars"></a>
49
+ <a href="https://pypi.org/project/pycascadeui/"><img src="https://img.shields.io/pypi/dm/pycascadeui?logo=pypi&logoColor=white&label=downloads" alt="Downloads"></a>
50
+ <a href="https://pypi.org/project/pycascadeui/"><img src="https://img.shields.io/pypi/v/pycascadeui?logo=pypi&logoColor=white" alt="PyPI"></a>
51
+ <a href="https://github.com/Rapptz/discord.py"><img src="https://img.shields.io/badge/discord.py-2.7+-738adb.svg?logo=discord&logoColor=white" alt="discord.py 2.7+"></a>
52
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%20|%203.11%20|%203.12%20|%203.13%20|%203.14-blue.svg?logo=python&logoColor=white" alt="Python 3.10-3.14"></a>
53
+ <a href="https://discord.com/invite/9Xj68BpKRb"><img src="https://img.shields.io/discord/1405822635920855040?logo=discord&logoColor=white&label=Discord&color=5865F2" alt="Discord"></a>
54
+ <a href="https://hollowthesilver.github.io/CascadeUI/"><img src="https://img.shields.io/badge/docs-GitHub%20Pages-8A2BE2?logo=readthedocs" alt="Docs"></a>
55
+ <a href="https://github.com/HollowTheSilver/CascadeUI/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/HollowTheSilver/CascadeUI/ci.yml?logo=github&label=CI" alt="CI"></a>
56
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
57
+ </p>
58
+
59
+ <p align="center">
60
+ <strong>Build predictable, state-driven interfaces with <a href="https://github.com/Rapptz/discord.py">discord.py</a>.</strong><br>
61
+ Design complex interactive systems with centralized state, composable UI patterns, and a clear data flow.<br>
62
+ </p>
63
+
64
+ <div align="center">
65
+ <img src="https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-hero.gif" alt="CascadeUI TicTacToe" width="600">
66
+ </div>
67
+
68
+ <p align="center">
69
+ <a href="https://hollowthesilver.github.io/CascadeUI/"><strong>Read the Docs</strong></a>
70
+ </p>
71
+
72
+ ---
73
+
74
+ ## Why CascadeUI
75
+
76
+ > Interactive Discord UIs become difficult to manage as they grow. State is scattered across callbacks, views become tightly coupled, and behavior becomes harder to reason about.
77
+
78
+ CascadeUI introduces structure:
79
+
80
+ - Centralized state instead of scattered variables
81
+ - Predictable updates through dispatched actions
82
+ - Clear separation between logic and presentation
83
+ - Reusable UI patterns instead of one-off implementations
84
+ - Built-in solutions for persistence, navigation, and state history
85
+
86
+ This approach scales from simple panels to full application-style interfaces.
87
+
88
+ ---
89
+
90
+ ## Architecture
91
+
92
+ CascadeUI follows a unidirectional data flow model:
93
+
94
+ ```
95
+ User interaction -> dispatch(action)
96
+ -> middleware
97
+ -> reducer (state update)
98
+ -> subscribers notified
99
+ -> views re-render
100
+ ```
101
+
102
+ All state lives in a single store. Actions describe what happened. Reducers define how state changes. Views subscribe to relevant state and update automatically.
103
+
104
+ ---
105
+
106
+ ## When to Use
107
+
108
+ > CascadeUI is designed for building complex interfaces that go beyond simple interactions.
109
+
110
+ A powerful, fully featured UI library should be leveraged when your app requires:
111
+
112
+ - Shared state across multiple views
113
+ - Real data and message persistence
114
+ - Maintainable complex interaction logic
115
+ - Message lifecycle and ownership control
116
+ - Consistent UI composition
117
+ - Cross-view reactivity
118
+ - Multi-step flows and validation
119
+
120
+ It may be unnecessary for small or simple interfaces.
121
+
122
+ ---
123
+
124
+ ## Features
125
+
126
+ > For full details, see the official <a href="https://hollowthesilver.github.io/CascadeUI/"><strong>documentation</strong></a>.
127
+
128
+ ### State and Data Flow
129
+ - Centralized store with dispatch and reducer cycle
130
+ - Custom reducers via `@cascade_reducer` decorator with automatic deep copy
131
+ - Action batching for grouped, atomic updates
132
+ - Computed state and derived values
133
+ - Selector-based subscriptions for targeted re-renders
134
+ - Cross-view reactivity: dispatch from any view, all subscribers update instantly
135
+ - Middleware pipeline for logging, persistence, and transformation
136
+ - Event hooks for lifecycle observation and side effects
137
+
138
+ ### Views and Interaction Patterns
139
+ - Layout-based V2 system for structured interfaces
140
+ - Full support for traditional discord.py Views (V1)
141
+ - Pre-built patterns: tabs, wizards, forms, pagination
142
+ - Navigation stack with push, pop, and replace
143
+ - Session limiting per user, guild, or globally with replace or reject policies
144
+ - Multi-user access control via `allowed_users` with participant-aware session limiting
145
+ - Interaction ownership control (owner-only by default)
146
+ - Auto-defer for slow callbacks and interaction serialization for rapid input
147
+ - Theming with per-view overrides and V2 accent colors
148
+
149
+ ### Components and Composition
150
+ - Stateful buttons, selects, and modals with state integration
151
+ - V2 layout helpers: `card()`, `key_value()`, `alert()`, `action_section()`, and more
152
+ - Built-in form system with validation and per-field error handling
153
+ - Component wrappers: loading states, confirmation dialogs, cooldowns
154
+
155
+ ### Persistence and Infrastructure
156
+ - Persistent views that survive bot restarts with automatic message re-attachment
157
+ - State persistence backends: JSON, SQLite, Redis
158
+ - Undo and redo via snapshot-based state history
159
+ - Scoped state isolation (user, guild, global)
160
+ - Developer tools for live state inspection and debugging
161
+
162
+ ---
163
+
164
+ ## Showcase
165
+
166
+ ### Dashboard Pattern
167
+
168
+ > Structured, multi-section interfaces with tab-based navigation and composable layouts.
169
+
170
+ ![Dashboard](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-dashboard.gif)
171
+
172
+ ---
173
+
174
+ ### Navigation and Flow
175
+
176
+ > Navigate between views without sending new messages. Maintain context across layered interfaces.
177
+
178
+ ![Navigation](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-settings.gif)
179
+
180
+ ---
181
+
182
+ ### State History (Undo/Redo)
183
+
184
+ > Snapshot-based state history per session with built-in undo and redo support.
185
+
186
+ ![Undo/Redo](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-undo-redo.gif)
187
+
188
+ ---
189
+
190
+ ### Cross-View Reactivity
191
+
192
+ > Dispatch actions from any view and update all subscribers instantly across the interface.
193
+
194
+ ![Cross-View](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-cross-view-reactivity.gif)
195
+
196
+ ---
197
+
198
+ ### Lifecycle Control
199
+
200
+ > Control active sessions per user, guild, or globally with automatic cleanup and replacement policies.
201
+
202
+ ```python
203
+ class DashboardView(TabLayoutView):
204
+ session_limit = 1 # Only one open at a time
205
+ session_scope = "user_guild" # Per user per guild
206
+ session_policy = "replace" # Exit the old one, open the new one
207
+ ```
208
+
209
+ ![V2 Session Limiting](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-session-limiting.gif)
210
+
211
+ ---
212
+
213
+ ### Persistence and Continuity
214
+
215
+ > Persist views and state across restarts with automatic restoration.
216
+
217
+ ```python
218
+ # Enable persistence once in your bot's setup_hook:
219
+ async def setup_hook(self):
220
+ await setup_persistence(bot=self, backend=SQLiteBackend("cascadeui.db"))
221
+ ```
222
+
223
+ ![Persistence](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-persistence-restart.gif)
224
+
225
+ ---
226
+
227
+ ### Dynamic Pagination
228
+
229
+ > Generate paginated interfaces from raw data with built-in navigation and formatting helpers.
230
+
231
+ ```python
232
+ from cascadeui import PaginatedLayoutView
233
+
234
+ def format_page(items):
235
+ lines = [f"**{item['name']}** | {item['rarity']} | {item['value']}g" for item in items]
236
+ return [Container(
237
+ TextDisplay("## Inventory"),
238
+ Separator(),
239
+ TextDisplay("\n".join(lines)),
240
+ accent_colour=discord.Color.blue(),
241
+ )]
242
+
243
+ view = await PaginatedLayoutView.from_data(
244
+ items=all_items,
245
+ per_page=4,
246
+ formatter=format_page,
247
+ context=ctx,
248
+ )
249
+ await view.send()
250
+ ```
251
+
252
+ ![Pagination](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-pagination.gif)
253
+
254
+ ---
255
+
256
+ ### Forms and Validation
257
+
258
+ > Define structured input flows with automatic validation and per-field error handling.
259
+
260
+ ```python
261
+ from cascadeui import FormLayoutView, choices, card, key_value, divider
262
+
263
+ class RegistrationForm(FormLayoutView):
264
+ session_limit = 1
265
+
266
+ def __init__(self, *args, **kwargs):
267
+ fields = [
268
+ {
269
+ "id": "role",
270
+ "label": "Role",
271
+ "type": "select",
272
+ "required": True,
273
+ "options": [
274
+ {"label": "Developer", "value": "developer"},
275
+ {"label": "Designer", "value": "designer"},
276
+ {"label": "Manager", "value": "manager"},
277
+ ],
278
+ "validators": [choices(["developer", "designer", "manager"])],
279
+ },
280
+ {
281
+ "id": "terms",
282
+ "label": "Accept Terms of Service",
283
+ "type": "boolean",
284
+ "required": True,
285
+ },
286
+ ]
287
+
288
+ super().__init__(
289
+ *args,
290
+ title="Registration",
291
+ fields=fields,
292
+ on_submit=self.handle_submit,
293
+ **kwargs,
294
+ )
295
+
296
+ def _rebuild_display(self):
297
+ """Override display with V2 helpers for a richer presentation."""
298
+ v = self.values
299
+ action_rows = [c for c in self.children if isinstance(c, ActionRow)]
300
+ self.clear_items()
301
+
302
+ self.add_item(card(
303
+ "## Registration Form",
304
+ key_value({"Role": v.get("role", "-").title() if v.get("role") else "-"}),
305
+ divider(),
306
+ TextDisplay(f"Terms: {'Accepted' if v.get('terms') else 'Pending'}"),
307
+ ))
308
+
309
+ for row in action_rows:
310
+ self.add_item(row)
311
+ ```
312
+
313
+ ![Forms](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-form.gif)
314
+
315
+ ---
316
+
317
+ ### Developer Tools
318
+
319
+ > Live state inspection and debugging with a tabbed inspector view. Add one line to your bot.
320
+
321
+ ```python
322
+ from cascadeui.devtools import DevToolsCog
323
+
324
+ # In your bot's setup_hook:
325
+ await bot.add_cog(DevToolsCog(bot))
326
+ ```
327
+
328
+ ![DevTools](https://raw.githubusercontent.com/HollowTheSilver/CascadeUI/main/assets/gifs/v2-devtools.gif)
329
+
330
+ ---
331
+
332
+ ## V1 Components
333
+
334
+ > CascadeUI supports traditional discord.py Views and embeds.
335
+
336
+ Use V1 when you need:
337
+ - Embed-specific features such as fields or timestamps
338
+ - Simpler layouts without containers
339
+
340
+ All core features such as navigation, persistence, and undo/redo are supported.
341
+
342
+ ---
343
+
344
+ ## Examples
345
+
346
+ > The <a href="https://hollowthesilver.github.io/CascadeUI/examples/"><strong>documentation</strong></a> includes full implementations demonstrating practical usage:
347
+
348
+ - Dashboards and control panels
349
+ - Settings systems
350
+ - Pagination
351
+ - Forms and wizards
352
+ - Persistent views
353
+ - Ticket systems
354
+ - Multi-user games
355
+
356
+ ---
357
+
358
+ ## Getting Started
359
+
360
+ ```bash
361
+ pip install pycascadeui
362
+ ```
363
+
364
+ Optional dependencies:
365
+
366
+ ```bash
367
+ pip install pycascadeui[sqlite]
368
+ pip install pycascadeui[redis]
369
+ ```
370
+
371
+ Requirements:
372
+ - Python 3.10+
373
+ - discord.py 2.7+
374
+
375
+ ---
376
+
377
+ ## Documentation
378
+
379
+ - https://hollowthesilver.github.io/CascadeUI/
380
+
381
+ ---
382
+
383
+ ## Support
384
+
385
+ - Discord: https://discord.com/invite/9Xj68BpKRb
386
+ - Issues: https://github.com/HollowTheSilver/CascadeUI/issues
387
+
388
+ ---
389
+
390
+ ## Development
391
+
392
+ ```bash
393
+ git clone https://github.com/HollowTheSilver/CascadeUI.git
394
+ cd CascadeUI
395
+ pip install -e ".[dev]"
396
+
397
+ pytest tests/ -v
398
+ black cascadeui/
399
+ isort cascadeui/
400
+ ```
401
+
402
+ ---
403
+
404
+ <p align="center">
405
+ MIT License
406
+ </p>
407
+