reflex-reactbits 0.1.1__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 (30) hide show
  1. reflex_reactbits-0.1.1/LICENSE +21 -0
  2. reflex_reactbits-0.1.1/PKG-INFO +223 -0
  3. reflex_reactbits-0.1.1/README.md +190 -0
  4. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/__init__.py +12 -0
  5. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/animations.py +2128 -0
  6. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/animations.pyi +2043 -0
  7. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/backgrounds.py +3503 -0
  8. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/backgrounds.pyi +3149 -0
  9. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/base.py +97 -0
  10. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/base.pyi +58 -0
  11. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/catalog.json +26580 -0
  12. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/catalog.py +23 -0
  13. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/cli.py +125 -0
  14. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/components.py +2383 -0
  15. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/components.pyi +2430 -0
  16. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/micro.py +2336 -0
  17. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/micro.pyi +1858 -0
  18. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/py.typed +0 -0
  19. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/source.py +236 -0
  20. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/text_animations.py +1629 -0
  21. reflex_reactbits-0.1.1/custom_components/reflex_reactbits/text_animations.pyi +1671 -0
  22. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/PKG-INFO +223 -0
  23. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/SOURCES.txt +28 -0
  24. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/dependency_links.txt +1 -0
  25. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/entry_points.txt +2 -0
  26. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/requires.txt +7 -0
  27. reflex_reactbits-0.1.1/custom_components/reflex_reactbits.egg-info/top_level.txt +1 -0
  28. reflex_reactbits-0.1.1/pyproject.toml +79 -0
  29. reflex_reactbits-0.1.1/setup.cfg +4 -0
  30. reflex_reactbits-0.1.1/tests/test_wrappers.py +214 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ernesto Crespo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,223 @@
1
+ Metadata-Version: 2.4
2
+ Name: reflex-reactbits
3
+ Version: 0.1.1
4
+ Summary: Reflex wrappers for React Bits: 200+ animated text effects, backgrounds, UI components and micro interactions.
5
+ Author-email: Ernesto Crespo <ecrespo@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ecrespo/reflex-reactbits
8
+ Project-URL: Source, https://github.com/ecrespo/reflex-reactbits
9
+ Project-URL: Issues, https://github.com/ecrespo/reflex-reactbits/issues
10
+ Project-URL: React Bits, https://reactbits.dev
11
+ Keywords: reflex,reflex-custom-components,react-bits,reactbits,animations,ui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: User Interfaces
21
+ Classifier: Topic :: Software Development :: Widget Sets
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: reflex>=0.9.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: build; extra == "dev"
29
+ Requires-Dist: twine; extra == "dev"
30
+ Requires-Dist: pytest; extra == "dev"
31
+ Requires-Dist: ruff; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # reflex-reactbits
35
+
36
+ [Reflex](https://reflex.dev) wrappers for **[React Bits](https://reactbits.dev)** — the
37
+ open-source collection of animated, interactive and customizable React components by
38
+ David Haz. Every one of the **202 React Bits components** (plus 4 sub-components) is
39
+ available as a typed Python component: text animations, animations, UI components,
40
+ animated WebGL backgrounds and the new *Micro* interactions.
41
+
42
+ ```python
43
+ import reflex as rx
44
+ import reflex_reactbits as rb
45
+
46
+
47
+ class State(rx.State):
48
+ liked: bool = False
49
+
50
+ @rx.event
51
+ def toggle(self, liked: bool, count: int):
52
+ self.liked = liked
53
+
54
+
55
+ def index():
56
+ return rx.box(
57
+ rx.box(rb.aurora(color_stops=["#3A29FF", "#FF94B4", "#FF3232"], amplitude=1.0),
58
+ position="absolute", inset="0"),
59
+ rb.blur_text(text="Hello from Reflex", animate_by="words", delay=120),
60
+ rb.pulse_heart(count=128, on_change=State.toggle),
61
+ position="relative", height="100vh",
62
+ )
63
+ ```
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install reflex-reactbits # or: uv add reflex-reactbits
69
+ ```
70
+
71
+ Requires `reflex>=0.9`.
72
+
73
+ ## How it works (and why the JS is not bundled)
74
+
75
+ React Bits is distributed as **source code you copy into your project** (via the
76
+ `shadcn`/`jsrepo` CLIs or by hand), not as an npm package, and its license
77
+ (MIT + Commons Clause) does not allow redistributing the components themselves in a
78
+ bundle. So this package ships only the Python side:
79
+
80
+ 1. Each wrapper knows the React Bits category, files and npm dependencies of its component.
81
+ 2. The first time you use a component, its original JS-CSS source is copied into your
82
+ app at `assets/reactbits/<Category>/<Name>/` — the same thing `npx shadcn add` does in
83
+ a React project. The files are pinned to the React Bits commit these wrappers were
84
+ generated from.
85
+ 3. Reflex imports that file client-side only (`NoSSRComponent`) and installs the exact npm
86
+ versions React Bits is locked to (`motion`, `gsap`, `ogl`, `three`, ...).
87
+
88
+ The copied files belong to your app: **edit them freely**, they are never overwritten.
89
+ Commit them if you want reproducible offline builds.
90
+
91
+ Sources are resolved from `REACTBITS_SOURCE_DIR` (a local clone of
92
+ [DavidHDev/react-bits](https://github.com/DavidHDev/react-bits)) when set, otherwise from
93
+ GitHub raw files at `REACTBITS_REF` (defaults to the pinned commit).
94
+
95
+ A few tiny patches make the plain JS-CSS variant work without React Router, Chakra UI
96
+ or Tailwind (`PillNav` uses `<a href>`, `ElasticSlider` renders the `react-icons`
97
+ directly, `BlurText` uses inline styles, `Lanyard` imports its `.glb` with `?url`).
98
+
99
+ ## The `reactbits` CLI
100
+
101
+ ```bash
102
+ reactbits list [--category Backgrounds] # every component and its factory name
103
+ reactbits info pulse_heart # props, types, defaults, events, npm deps
104
+ reactbits add BlurText Aurora # copy sources into ./assets/reactbits now
105
+ reactbits add --all # vendor all components (offline / CI builds)
106
+ reactbits remove Aurora
107
+ ```
108
+
109
+ ## Props, events and children
110
+
111
+ * Props use snake_case and are converted to the React prop names (`animate_by` → `animateBy`,
112
+ `sim_resolution` → `SIM_RESOLUTION`, `from_` → `from`). Unset props keep React Bits' defaults.
113
+ * Every prop is typed and documented (hover it in your editor, or run `reactbits info`).
114
+ Numbers accept `int` and `float`; `ReactNode` props accept strings or Reflex components.
115
+ * Lists/dicts may contain Reflex components, e.g. dock icons:
116
+ `rb.dock(items=[{"icon": rx.icon("house"), "label": "Home"}])`.
117
+ * Callbacks are Reflex event triggers with the right arity — `on_change` of `rubber_segment`
118
+ gives `(value, index)`, `on_send` of `prompt_bar` gives `(text, options)`, and so on.
119
+ Payloads are sanitized before they are sent (React elements, DOM events and functions are
120
+ dropped, `File`s become metadata), so every React Bits callback is safe to bind.
121
+ * JS-function props (easing curves, custom renderers) take a JS expression:
122
+ `rb.blur_text(text="Hi", easing=rx.Var("(t) => t * t"))`.
123
+ * Wrapper components take Reflex children: `rb.fade_content(rx.text("Hi"), blur=True)`.
124
+ * Sub-components: `rb.stepper(rb.step(...), ...)`, `rb.card_swap(rb.card_swap_card(...))`,
125
+ `rb.scroll_stack(rb.scroll_stack_item(...))`, `rb.warm_tooltip_group(...)`.
126
+ * `rb.hyperspeed(preset="three")` uses React Bits' built-in presets.
127
+ * Backgrounds and canvas effects fill their parent: give the parent a size and
128
+ `position="relative"`.
129
+
130
+ `rb.CATALOG` / `rb.find_component()` expose the full metadata (props, types, events,
131
+ docs URL, npm deps) at runtime.
132
+
133
+ ## Components
134
+
135
+ **Text animations (32):** `ascii_text`, `blur_text`, `circular_text`, `count_up`, `curved_loop`, `decrypted_text`, `depth_text`, `echo_text`, `falling_text`, `fold_text`, `fuzzy_text`, `glitch_text`, `gradient_text`, `masked_heading`, `particle_text`, `rotating_text`, `scrambled_text`, `scroll_float`, `scroll_reveal`, `scroll_velocity`, `shiny_text`, `shuffle`, `split_flap_text`, `split_text`, `stroke_text`, `text_cursor`, `text_loop`, `text_pressure`, `text_type`, `true_focus`, `variable_proximity`, `warp_text`
136
+
137
+ **Animations (38):** `animated_content`, `antigravity`, `blob_cursor`, `click_spark`, `crosshair`, `cubes`, `cursor_grid`, `elastic_mesh`, `electric_border`, `fade_content`, `ghost_cursor`, `glare_hover`, `glow_cursor`, `gradual_blur`, `halftone_reveal`, `image_trail`, `laser_flow`, `logo_loop`, `magic_rings`, `magnet`, `magnet_lines`, `meta_balls`, `metallic_paint`, `noise`, `orbit_images`, `pixel_swap`, `pixel_trail`, `pixel_transition`, `ribbons`, `ripple_distortion`, `scroll_expand`, `shape_blur`, `splash_cursor`, `star_border`, `sticker_peel`, `strands`, `swarm_cursor`, `target_cursor`
138
+
139
+ **Components (45 + 3 sub-components):** `accordion_gallery`, `animated_list`, `border_glow`, `bounce_cards`, `bubble_menu`, `card_nav`, `card_swap`, `card_swap_card`, `carousel`, `chroma_grid`, `circular_gallery`, `counter`, `curved_input`, `decay_card`, `depth_carousel`, `dock`, `dome_gallery`, `drift_wall`, `elastic_slider`, `flowing_menu`, `fluid_glass`, `flying_posters`, `folder`, `glass_icons`, `glass_surface`, `gooey_nav`, `infinite_menu`, `infinite_spiral`, `lanyard`, `line_sidebar`, `magic_bento`, `masonry`, `model_viewer`, `morph_slider`, `option_wheel`, `pill_nav`, `pixel_card`, `profile_card`, `reflective_card`, `scroll_stack`, `scroll_stack_item`, `specular_button`, `spotlight_card`, `stack`, `staggered_menu`, `stepper`, `step`, `tilted_card`
140
+
141
+ **Backgrounds (57):** `acid_squares`, `aero_shards`, `aurora`, `balatro`, `ballpit`, `beams`, `crt_warp`, `color_bends`, `dark_veil`, `dither`, `dot_field`, `dot_grid`, `evil_eye`, `faulty_terminal`, `ferrofluid`, `floating_lines`, `galaxy`, `ghost_fibers`, `gradient_blinds`, `gradient_waves`, `grainient`, `grid_distortion`, `grid_motion`, `grid_scan`, `hyperspeed`, `iridescence`, `letter_glitch`, `light_pillar`, `light_rays`, `light_tunnel`, `lightfall`, `lightning`, `line_waves`, `liquid_chrome`, `liquid_ether`, `molten_metal`, `orb`, `particles`, `pixel_blast`, `pixel_snow`, `plasma`, `plasma_wave`, `prism`, `prismatic_burst`, `radar`, `ripple_grid`, `scanner`, `shape_grid`, `shape_waves`, `side_rays`, `silk`, `sliced_waves`, `soft_aurora`, `threads`, `topography`, `waves`, `web_threads`
142
+
143
+ **Micro interactions (30 + 1 sub-component):** `bell_toggle`, `branched_menu`, `call_chip`, `code_slots`, `comet_dial`, `dodge_field`, `folder_float`, `fuse_button`, `glide_select`, `hold_button`, `jelly_radio`, `lattice_loader`, `peek_rating`, `prompt_bar`, `pulse_heart`, `refine_frame`, `rubber_segment`, `scrub_field`, `slide_commit`, `sling_button`, `slosh_gauge`, `spring_check`, `squish_switch`, `status_mark`, `swipe_row`, `swipe_toast`, `thought_line`, `voice_pill`, `wake_slider`, `warm_tooltip`, `warm_tooltip_group`
144
+
145
+ Full docs, previews and prop descriptions for each component live at
146
+ [reactbits.dev](https://reactbits.dev).
147
+
148
+ ## Demo app
149
+
150
+ `reactbits_demo/` is a gallery with a page per component (live preview, replay, event
151
+ log wired to Reflex state, generated Python usage and the props table), a playground
152
+ where props are bound to state vars, and a landing page built only with React Bits.
153
+
154
+ ```bash
155
+ uv sync --extra dev
156
+ cd reactbits_demo
157
+ uv run reflex run
158
+ ```
159
+
160
+ ## Regenerating the wrappers
161
+
162
+ The wrappers are generated from the React Bits sources, so new React Bits releases can be
163
+ picked up automatically:
164
+
165
+ ```bash
166
+ git clone https://github.com/DavidHDev/react-bits /tmp/react-bits
167
+ (cd scripts && npm install)
168
+ node scripts/extract_metadata.mjs /tmp/react-bits scripts/components.json
169
+ python scripts/generate_wrappers.py scripts/components.json /tmp/react-bits
170
+ ```
171
+
172
+ Update `PINNED_REF` in `custom_components/reflex_reactbits/source.py` to the new commit.
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ uv sync --extra dev
178
+ uv run pytest
179
+ # type stubs (.pyi) for editor autocomplete, then sdist + wheel in dist/
180
+ (cd custom_components && uv run python -c "from reflex_base.utils.pyi_generator import PyiGenerator; PyiGenerator().scan_all(['reflex_reactbits'])")
181
+ uv build
182
+ ```
183
+
184
+ ## Continuous integration
185
+
186
+ Three workflows run in `.github/workflows/`:
187
+
188
+ | Workflow | Runs on | What it checks |
189
+ | --- | --- | --- |
190
+ | `quality.yml` | push and PR to `main`/`develop` | `ruff check`; `pytest` on Python 3.10-3.13; builds the sdist and wheel, runs `twine check`, and fails if any React Bits source slipped into the distribution or into git |
191
+ | `security.yml` | push, PR, and weekly | `pip-audit` on the dependency tree, `bandit` over the hand-written modules, `gitleaks` over the full history, CodeQL, and a dependency review on PRs |
192
+
193
+ The dependency-review job needs GitHub's dependency graph to be provisioned for the
194
+ repository, which it is not yet: until you enable it at *Settings → Code security →
195
+ Dependency graph*, that job reports "not supported on this repository" and is marked
196
+ `continue-on-error` so it cannot block a merge. Drop that line once it is on. Vulnerable
197
+ dependencies are caught by `pip-audit` regardless; the job only adds the diff of what a
198
+ given pull request introduces.
199
+ | `release.yml` | a `v*` tag, or manually | Rebuilds, refuses a tag that disagrees with the version in `pyproject.toml`, publishes a GitHub release and uploads to PyPI |
200
+
201
+ ## Releasing
202
+
203
+ ```bash
204
+ # 1. bump the version
205
+ $EDITOR pyproject.toml # [project] version = "0.2.0"
206
+
207
+ # 2. tag it; the tag must match that version or release.yml stops
208
+ git tag v0.2.0 && git push origin v0.2.0
209
+ ```
210
+
211
+ The tag triggers `release.yml`, which builds, creates the GitHub release with the
212
+ artifacts attached, and uploads to PyPI. `workflow_dispatch` runs the same thing on
213
+ demand and can target TestPyPI instead.
214
+
215
+
216
+ ## License
217
+
218
+ The Python wrappers in this repository are MIT licensed (see `LICENSE`).
219
+ React Bits itself is © David Haz under the
220
+ [MIT + Commons Clause license](https://github.com/DavidHDev/react-bits/blob/main/LICENSE.md):
221
+ you may use the components in your applications, including commercially, but not sell or
222
+ redistribute the components themselves. That is why their source is fetched into your
223
+ app instead of being bundled here. This project is not affiliated with React Bits.
@@ -0,0 +1,190 @@
1
+ # reflex-reactbits
2
+
3
+ [Reflex](https://reflex.dev) wrappers for **[React Bits](https://reactbits.dev)** — the
4
+ open-source collection of animated, interactive and customizable React components by
5
+ David Haz. Every one of the **202 React Bits components** (plus 4 sub-components) is
6
+ available as a typed Python component: text animations, animations, UI components,
7
+ animated WebGL backgrounds and the new *Micro* interactions.
8
+
9
+ ```python
10
+ import reflex as rx
11
+ import reflex_reactbits as rb
12
+
13
+
14
+ class State(rx.State):
15
+ liked: bool = False
16
+
17
+ @rx.event
18
+ def toggle(self, liked: bool, count: int):
19
+ self.liked = liked
20
+
21
+
22
+ def index():
23
+ return rx.box(
24
+ rx.box(rb.aurora(color_stops=["#3A29FF", "#FF94B4", "#FF3232"], amplitude=1.0),
25
+ position="absolute", inset="0"),
26
+ rb.blur_text(text="Hello from Reflex", animate_by="words", delay=120),
27
+ rb.pulse_heart(count=128, on_change=State.toggle),
28
+ position="relative", height="100vh",
29
+ )
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install reflex-reactbits # or: uv add reflex-reactbits
36
+ ```
37
+
38
+ Requires `reflex>=0.9`.
39
+
40
+ ## How it works (and why the JS is not bundled)
41
+
42
+ React Bits is distributed as **source code you copy into your project** (via the
43
+ `shadcn`/`jsrepo` CLIs or by hand), not as an npm package, and its license
44
+ (MIT + Commons Clause) does not allow redistributing the components themselves in a
45
+ bundle. So this package ships only the Python side:
46
+
47
+ 1. Each wrapper knows the React Bits category, files and npm dependencies of its component.
48
+ 2. The first time you use a component, its original JS-CSS source is copied into your
49
+ app at `assets/reactbits/<Category>/<Name>/` — the same thing `npx shadcn add` does in
50
+ a React project. The files are pinned to the React Bits commit these wrappers were
51
+ generated from.
52
+ 3. Reflex imports that file client-side only (`NoSSRComponent`) and installs the exact npm
53
+ versions React Bits is locked to (`motion`, `gsap`, `ogl`, `three`, ...).
54
+
55
+ The copied files belong to your app: **edit them freely**, they are never overwritten.
56
+ Commit them if you want reproducible offline builds.
57
+
58
+ Sources are resolved from `REACTBITS_SOURCE_DIR` (a local clone of
59
+ [DavidHDev/react-bits](https://github.com/DavidHDev/react-bits)) when set, otherwise from
60
+ GitHub raw files at `REACTBITS_REF` (defaults to the pinned commit).
61
+
62
+ A few tiny patches make the plain JS-CSS variant work without React Router, Chakra UI
63
+ or Tailwind (`PillNav` uses `<a href>`, `ElasticSlider` renders the `react-icons`
64
+ directly, `BlurText` uses inline styles, `Lanyard` imports its `.glb` with `?url`).
65
+
66
+ ## The `reactbits` CLI
67
+
68
+ ```bash
69
+ reactbits list [--category Backgrounds] # every component and its factory name
70
+ reactbits info pulse_heart # props, types, defaults, events, npm deps
71
+ reactbits add BlurText Aurora # copy sources into ./assets/reactbits now
72
+ reactbits add --all # vendor all components (offline / CI builds)
73
+ reactbits remove Aurora
74
+ ```
75
+
76
+ ## Props, events and children
77
+
78
+ * Props use snake_case and are converted to the React prop names (`animate_by` → `animateBy`,
79
+ `sim_resolution` → `SIM_RESOLUTION`, `from_` → `from`). Unset props keep React Bits' defaults.
80
+ * Every prop is typed and documented (hover it in your editor, or run `reactbits info`).
81
+ Numbers accept `int` and `float`; `ReactNode` props accept strings or Reflex components.
82
+ * Lists/dicts may contain Reflex components, e.g. dock icons:
83
+ `rb.dock(items=[{"icon": rx.icon("house"), "label": "Home"}])`.
84
+ * Callbacks are Reflex event triggers with the right arity — `on_change` of `rubber_segment`
85
+ gives `(value, index)`, `on_send` of `prompt_bar` gives `(text, options)`, and so on.
86
+ Payloads are sanitized before they are sent (React elements, DOM events and functions are
87
+ dropped, `File`s become metadata), so every React Bits callback is safe to bind.
88
+ * JS-function props (easing curves, custom renderers) take a JS expression:
89
+ `rb.blur_text(text="Hi", easing=rx.Var("(t) => t * t"))`.
90
+ * Wrapper components take Reflex children: `rb.fade_content(rx.text("Hi"), blur=True)`.
91
+ * Sub-components: `rb.stepper(rb.step(...), ...)`, `rb.card_swap(rb.card_swap_card(...))`,
92
+ `rb.scroll_stack(rb.scroll_stack_item(...))`, `rb.warm_tooltip_group(...)`.
93
+ * `rb.hyperspeed(preset="three")` uses React Bits' built-in presets.
94
+ * Backgrounds and canvas effects fill their parent: give the parent a size and
95
+ `position="relative"`.
96
+
97
+ `rb.CATALOG` / `rb.find_component()` expose the full metadata (props, types, events,
98
+ docs URL, npm deps) at runtime.
99
+
100
+ ## Components
101
+
102
+ **Text animations (32):** `ascii_text`, `blur_text`, `circular_text`, `count_up`, `curved_loop`, `decrypted_text`, `depth_text`, `echo_text`, `falling_text`, `fold_text`, `fuzzy_text`, `glitch_text`, `gradient_text`, `masked_heading`, `particle_text`, `rotating_text`, `scrambled_text`, `scroll_float`, `scroll_reveal`, `scroll_velocity`, `shiny_text`, `shuffle`, `split_flap_text`, `split_text`, `stroke_text`, `text_cursor`, `text_loop`, `text_pressure`, `text_type`, `true_focus`, `variable_proximity`, `warp_text`
103
+
104
+ **Animations (38):** `animated_content`, `antigravity`, `blob_cursor`, `click_spark`, `crosshair`, `cubes`, `cursor_grid`, `elastic_mesh`, `electric_border`, `fade_content`, `ghost_cursor`, `glare_hover`, `glow_cursor`, `gradual_blur`, `halftone_reveal`, `image_trail`, `laser_flow`, `logo_loop`, `magic_rings`, `magnet`, `magnet_lines`, `meta_balls`, `metallic_paint`, `noise`, `orbit_images`, `pixel_swap`, `pixel_trail`, `pixel_transition`, `ribbons`, `ripple_distortion`, `scroll_expand`, `shape_blur`, `splash_cursor`, `star_border`, `sticker_peel`, `strands`, `swarm_cursor`, `target_cursor`
105
+
106
+ **Components (45 + 3 sub-components):** `accordion_gallery`, `animated_list`, `border_glow`, `bounce_cards`, `bubble_menu`, `card_nav`, `card_swap`, `card_swap_card`, `carousel`, `chroma_grid`, `circular_gallery`, `counter`, `curved_input`, `decay_card`, `depth_carousel`, `dock`, `dome_gallery`, `drift_wall`, `elastic_slider`, `flowing_menu`, `fluid_glass`, `flying_posters`, `folder`, `glass_icons`, `glass_surface`, `gooey_nav`, `infinite_menu`, `infinite_spiral`, `lanyard`, `line_sidebar`, `magic_bento`, `masonry`, `model_viewer`, `morph_slider`, `option_wheel`, `pill_nav`, `pixel_card`, `profile_card`, `reflective_card`, `scroll_stack`, `scroll_stack_item`, `specular_button`, `spotlight_card`, `stack`, `staggered_menu`, `stepper`, `step`, `tilted_card`
107
+
108
+ **Backgrounds (57):** `acid_squares`, `aero_shards`, `aurora`, `balatro`, `ballpit`, `beams`, `crt_warp`, `color_bends`, `dark_veil`, `dither`, `dot_field`, `dot_grid`, `evil_eye`, `faulty_terminal`, `ferrofluid`, `floating_lines`, `galaxy`, `ghost_fibers`, `gradient_blinds`, `gradient_waves`, `grainient`, `grid_distortion`, `grid_motion`, `grid_scan`, `hyperspeed`, `iridescence`, `letter_glitch`, `light_pillar`, `light_rays`, `light_tunnel`, `lightfall`, `lightning`, `line_waves`, `liquid_chrome`, `liquid_ether`, `molten_metal`, `orb`, `particles`, `pixel_blast`, `pixel_snow`, `plasma`, `plasma_wave`, `prism`, `prismatic_burst`, `radar`, `ripple_grid`, `scanner`, `shape_grid`, `shape_waves`, `side_rays`, `silk`, `sliced_waves`, `soft_aurora`, `threads`, `topography`, `waves`, `web_threads`
109
+
110
+ **Micro interactions (30 + 1 sub-component):** `bell_toggle`, `branched_menu`, `call_chip`, `code_slots`, `comet_dial`, `dodge_field`, `folder_float`, `fuse_button`, `glide_select`, `hold_button`, `jelly_radio`, `lattice_loader`, `peek_rating`, `prompt_bar`, `pulse_heart`, `refine_frame`, `rubber_segment`, `scrub_field`, `slide_commit`, `sling_button`, `slosh_gauge`, `spring_check`, `squish_switch`, `status_mark`, `swipe_row`, `swipe_toast`, `thought_line`, `voice_pill`, `wake_slider`, `warm_tooltip`, `warm_tooltip_group`
111
+
112
+ Full docs, previews and prop descriptions for each component live at
113
+ [reactbits.dev](https://reactbits.dev).
114
+
115
+ ## Demo app
116
+
117
+ `reactbits_demo/` is a gallery with a page per component (live preview, replay, event
118
+ log wired to Reflex state, generated Python usage and the props table), a playground
119
+ where props are bound to state vars, and a landing page built only with React Bits.
120
+
121
+ ```bash
122
+ uv sync --extra dev
123
+ cd reactbits_demo
124
+ uv run reflex run
125
+ ```
126
+
127
+ ## Regenerating the wrappers
128
+
129
+ The wrappers are generated from the React Bits sources, so new React Bits releases can be
130
+ picked up automatically:
131
+
132
+ ```bash
133
+ git clone https://github.com/DavidHDev/react-bits /tmp/react-bits
134
+ (cd scripts && npm install)
135
+ node scripts/extract_metadata.mjs /tmp/react-bits scripts/components.json
136
+ python scripts/generate_wrappers.py scripts/components.json /tmp/react-bits
137
+ ```
138
+
139
+ Update `PINNED_REF` in `custom_components/reflex_reactbits/source.py` to the new commit.
140
+
141
+ ## Development
142
+
143
+ ```bash
144
+ uv sync --extra dev
145
+ uv run pytest
146
+ # type stubs (.pyi) for editor autocomplete, then sdist + wheel in dist/
147
+ (cd custom_components && uv run python -c "from reflex_base.utils.pyi_generator import PyiGenerator; PyiGenerator().scan_all(['reflex_reactbits'])")
148
+ uv build
149
+ ```
150
+
151
+ ## Continuous integration
152
+
153
+ Three workflows run in `.github/workflows/`:
154
+
155
+ | Workflow | Runs on | What it checks |
156
+ | --- | --- | --- |
157
+ | `quality.yml` | push and PR to `main`/`develop` | `ruff check`; `pytest` on Python 3.10-3.13; builds the sdist and wheel, runs `twine check`, and fails if any React Bits source slipped into the distribution or into git |
158
+ | `security.yml` | push, PR, and weekly | `pip-audit` on the dependency tree, `bandit` over the hand-written modules, `gitleaks` over the full history, CodeQL, and a dependency review on PRs |
159
+
160
+ The dependency-review job needs GitHub's dependency graph to be provisioned for the
161
+ repository, which it is not yet: until you enable it at *Settings → Code security →
162
+ Dependency graph*, that job reports "not supported on this repository" and is marked
163
+ `continue-on-error` so it cannot block a merge. Drop that line once it is on. Vulnerable
164
+ dependencies are caught by `pip-audit` regardless; the job only adds the diff of what a
165
+ given pull request introduces.
166
+ | `release.yml` | a `v*` tag, or manually | Rebuilds, refuses a tag that disagrees with the version in `pyproject.toml`, publishes a GitHub release and uploads to PyPI |
167
+
168
+ ## Releasing
169
+
170
+ ```bash
171
+ # 1. bump the version
172
+ $EDITOR pyproject.toml # [project] version = "0.2.0"
173
+
174
+ # 2. tag it; the tag must match that version or release.yml stops
175
+ git tag v0.2.0 && git push origin v0.2.0
176
+ ```
177
+
178
+ The tag triggers `release.yml`, which builds, creates the GitHub release with the
179
+ artifacts attached, and uploads to PyPI. `workflow_dispatch` runs the same thing on
180
+ demand and can target TestPyPI instead.
181
+
182
+
183
+ ## License
184
+
185
+ The Python wrappers in this repository are MIT licensed (see `LICENSE`).
186
+ React Bits itself is © David Haz under the
187
+ [MIT + Commons Clause license](https://github.com/DavidHDev/react-bits/blob/main/LICENSE.md):
188
+ you may use the components in your applications, including commercially, but not sell or
189
+ redistribute the components themselves. That is why their source is fetched into your
190
+ app instead of being bundled here. This project is not affiliated with React Bits.
@@ -0,0 +1,12 @@
1
+ """Reflex wrappers for React Bits (https://reactbits.dev)."""
2
+
3
+ from .animations import *
4
+ from .backgrounds import *
5
+ from .base import ReactBitsComponent
6
+ from .catalog import CATALOG, find_component
7
+ from .components import *
8
+ from .micro import *
9
+ from .source import ensure_component_source
10
+ from .text_animations import *
11
+
12
+ __all__ = ['CATALOG', 'ASCIIText', 'AccordionGallery', 'AcidSquares', 'AeroShards', 'AnimatedContent', 'AnimatedList', 'Antigravity', 'Aurora', 'Balatro', 'Ballpit', 'Beams', 'BellToggle', 'BlobCursor', 'BlurText', 'BorderGlow', 'BounceCards', 'BranchedMenu', 'BubbleMenu', 'CRTWarp', 'CallChip', 'CardNav', 'CardSwap', 'CardSwapCard', 'Carousel', 'ChromaGrid', 'CircularGallery', 'CircularText', 'ClickSpark', 'CodeSlots', 'ColorBends', 'CometDial', 'CountUp', 'Counter', 'Crosshair', 'Cubes', 'CursorGrid', 'CurvedInput', 'CurvedLoop', 'DarkVeil', 'DecayCard', 'DecryptedText', 'DepthCarousel', 'DepthText', 'Dither', 'Dock', 'DodgeField', 'DomeGallery', 'DotField', 'DotGrid', 'DriftWall', 'EchoText', 'ElasticMesh', 'ElasticSlider', 'ElectricBorder', 'EvilEye', 'FadeContent', 'FallingText', 'FaultyTerminal', 'Ferrofluid', 'FloatingLines', 'FlowingMenu', 'FluidGlass', 'FlyingPosters', 'FoldText', 'Folder', 'FolderFloat', 'FuseButton', 'FuzzyText', 'Galaxy', 'GhostCursor', 'GhostFibers', 'GlareHover', 'GlassIcons', 'GlassSurface', 'GlideSelect', 'GlitchText', 'GlowCursor', 'GooeyNav', 'GradientBlinds', 'GradientText', 'GradientWaves', 'GradualBlur', 'Grainient', 'GridDistortion', 'GridMotion', 'GridScan', 'HalftoneReveal', 'HoldButton', 'Hyperspeed', 'ImageTrail', 'InfiniteMenu', 'InfiniteSpiral', 'Iridescence', 'JellyRadio', 'Lanyard', 'LaserFlow', 'LatticeLoader', 'LetterGlitch', 'LightPillar', 'LightRays', 'LightTunnel', 'Lightfall', 'Lightning', 'LineSidebar', 'LineWaves', 'LiquidChrome', 'LiquidEther', 'LogoLoop', 'MagicBento', 'MagicRings', 'Magnet', 'MagnetLines', 'MaskedHeading', 'Masonry', 'MetaBalls', 'MetallicPaint', 'ModelViewer', 'MoltenMetal', 'MorphSlider', 'Noise', 'OptionWheel', 'Orb', 'OrbitImages', 'ParticleText', 'Particles', 'PeekRating', 'PillNav', 'PixelBlast', 'PixelCard', 'PixelSnow', 'PixelSwap', 'PixelTrail', 'PixelTransition', 'Plasma', 'PlasmaWave', 'Prism', 'PrismaticBurst', 'ProfileCard', 'PromptBar', 'PulseHeart', 'Radar', 'ReactBitsComponent', 'RefineFrame', 'ReflectiveCard', 'Ribbons', 'RippleDistortion', 'RippleGrid', 'RotatingText', 'RubberSegment', 'Scanner', 'ScrambledText', 'ScrollExpand', 'ScrollFloat', 'ScrollReveal', 'ScrollStack', 'ScrollStackItem', 'ScrollVelocity', 'ScrubField', 'ShapeBlur', 'ShapeGrid', 'ShapeWaves', 'ShinyText', 'Shuffle', 'SideRays', 'Silk', 'SlicedWaves', 'SlideCommit', 'SlingButton', 'SloshGauge', 'SoftAurora', 'SpecularButton', 'SplashCursor', 'SplitFlapText', 'SplitText', 'SpotlightCard', 'SpringCheck', 'SquishSwitch', 'Stack', 'StaggeredMenu', 'StarBorder', 'StatusMark', 'Step', 'Stepper', 'StickerPeel', 'Strands', 'StrokeText', 'SwarmCursor', 'SwipeRow', 'SwipeToast', 'TargetCursor', 'TextCursor', 'TextLoop', 'TextPressure', 'TextType', 'ThoughtLine', 'Threads', 'TiltedCard', 'Topography', 'TrueFocus', 'VariableProximity', 'VoicePill', 'WakeSlider', 'WarmTooltip', 'WarmTooltipGroup', 'WarpText', 'Waves', 'WebThreads', 'accordion_gallery', 'acid_squares', 'aero_shards', 'animated_content', 'animated_list', 'antigravity', 'ascii_text', 'aurora', 'balatro', 'ballpit', 'beams', 'bell_toggle', 'blob_cursor', 'blur_text', 'border_glow', 'bounce_cards', 'branched_menu', 'bubble_menu', 'call_chip', 'card_nav', 'card_swap', 'card_swap_card', 'carousel', 'chroma_grid', 'circular_gallery', 'circular_text', 'click_spark', 'code_slots', 'color_bends', 'comet_dial', 'count_up', 'counter', 'crosshair', 'crt_warp', 'cubes', 'cursor_grid', 'curved_input', 'curved_loop', 'dark_veil', 'decay_card', 'decrypted_text', 'depth_carousel', 'depth_text', 'dither', 'dock', 'dodge_field', 'dome_gallery', 'dot_field', 'dot_grid', 'drift_wall', 'echo_text', 'elastic_mesh', 'elastic_slider', 'electric_border', 'ensure_component_source', 'evil_eye', 'fade_content', 'falling_text', 'faulty_terminal', 'ferrofluid', 'find_component', 'floating_lines', 'flowing_menu', 'fluid_glass', 'flying_posters', 'fold_text', 'folder', 'folder_float', 'fuse_button', 'fuzzy_text', 'galaxy', 'ghost_cursor', 'ghost_fibers', 'glare_hover', 'glass_icons', 'glass_surface', 'glide_select', 'glitch_text', 'glow_cursor', 'gooey_nav', 'gradient_blinds', 'gradient_text', 'gradient_waves', 'gradual_blur', 'grainient', 'grid_distortion', 'grid_motion', 'grid_scan', 'halftone_reveal', 'hold_button', 'hyperspeed', 'image_trail', 'infinite_menu', 'infinite_spiral', 'iridescence', 'jelly_radio', 'lanyard', 'laser_flow', 'lattice_loader', 'letter_glitch', 'light_pillar', 'light_rays', 'light_tunnel', 'lightfall', 'lightning', 'line_sidebar', 'line_waves', 'liquid_chrome', 'liquid_ether', 'logo_loop', 'magic_bento', 'magic_rings', 'magnet', 'magnet_lines', 'masked_heading', 'masonry', 'meta_balls', 'metallic_paint', 'model_viewer', 'molten_metal', 'morph_slider', 'noise', 'option_wheel', 'orb', 'orbit_images', 'particle_text', 'particles', 'peek_rating', 'pill_nav', 'pixel_blast', 'pixel_card', 'pixel_snow', 'pixel_swap', 'pixel_trail', 'pixel_transition', 'plasma', 'plasma_wave', 'prism', 'prismatic_burst', 'profile_card', 'prompt_bar', 'pulse_heart', 'radar', 'refine_frame', 'reflective_card', 'ribbons', 'ripple_distortion', 'ripple_grid', 'rotating_text', 'rubber_segment', 'scanner', 'scrambled_text', 'scroll_expand', 'scroll_float', 'scroll_reveal', 'scroll_stack', 'scroll_stack_item', 'scroll_velocity', 'scrub_field', 'shape_blur', 'shape_grid', 'shape_waves', 'shiny_text', 'shuffle', 'side_rays', 'silk', 'sliced_waves', 'slide_commit', 'sling_button', 'slosh_gauge', 'soft_aurora', 'specular_button', 'splash_cursor', 'split_flap_text', 'split_text', 'spotlight_card', 'spring_check', 'squish_switch', 'stack', 'staggered_menu', 'star_border', 'status_mark', 'step', 'stepper', 'sticker_peel', 'strands', 'stroke_text', 'swarm_cursor', 'swipe_row', 'swipe_toast', 'target_cursor', 'text_cursor', 'text_loop', 'text_pressure', 'text_type', 'thought_line', 'threads', 'tilted_card', 'topography', 'true_focus', 'variable_proximity', 'voice_pill', 'wake_slider', 'warm_tooltip', 'warm_tooltip_group', 'warp_text', 'waves', 'web_threads']