Skip to content

Latest commit

 

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dash-loading-components (dlc)

Loading indicators for Plotly Dash, wrapping eleven React spinner libraries as one install. 301 components under stable namespaces, with a common factory over the top so you can switch families without relearning each one's props.

Browse them all in the live gallery: https://dash-loading-components.phylatech.com

pip install dash-loading-components

One contract, every component

import dash_loading_components as dlc

dlc.loading_dev.Dual(size=48, color="#f97316", rate=1.5)
dlc.premium.OrbitRings(size=48, color="#f97316", ring_count=4, playing=False)
dlc.ldrs.Ring(size=48, color="#f97316", stroke=5)

Every component takes the same four props with the same meaning:

prop meaning
size pixels (react-loading-indicators takes its own "small" / "medium" / "large" tokens)
color any CSS color
rate relative tempo: 1.0 is this spinner's own tempo, 2.0 twice as fast. Unset keeps the upstream tempo
playing False pauses the animation

Each library's own props are there too, in snake_case, in the library's own units: dlc.loading_dev.Arc(duration=1600, easing="stacked"), dlc.spinners.ClipLoader(speed_multiplier=2). A native tempo or pause prop passed alongside rate or playing wins.

Need a loading overlay? Use Dash's own:

dcc.Loading(children, custom_spinner=dlc.ldrs.Ring(size=48))

Discover what is available at runtime:

dlc.list_libraries()          # ['loading_dev', 'ldrs', 'spinners', ..., 'gridora']
dlc.list_spinners("ldrs")     # ['Ring', 'Helix', 'DotPulse', ...]
dlc.list_spinners("gridora")  # ['GridLoader', 'Text']

Requirements

React ≥19 and Dash ≥4.5, both hard requirements. The loading_dev family needs React 19, and this package will not claim Dash 4.4 / React 18 compatibility.

Dash 4.5 is not on PyPI as a stable release yet, so the dependency is pinned as dash>=4.5.0rc0. That specifier names the pre-release, which is what lets pip resolve it; it will accept the final 4.5 release once published.

Families

Namespace Upstream Components
loading_dev loading-dev 29
premium premium-react-loaders 15
ldrs ldrs 12
spinners react-spinners 12
indicators react-loading-indicators 11
loader_spinner react-loader-spinner 10
spinners_react spinners-react 9
epic react-epic-spinners 8
m3 @alerix/m3-loading-indicator 1
flicker flicker-dot 61
gridora gridora 133

Flip-dot presets

flicker-dot is a player: it animates whatever 7x7 frames it is given. dlc.flicker ships 61 original presets for it, drawn by PhylaTech and MIT licensed with this package, in six sets: Field (the naturalist set: Mycelium, Diatom, Cladogram, Chromatogram, MassSpec, TestTube, Jellyfish, ...), Data (Scatter, Histogram, LineChart, PieChart, Heatmap, Database), Everyday (Cart, Upload, Download, Mail, Wifi, Heart, Lock, ...), Board (flip-dot panel classics), Geometry, and Solids (the five Platonic solids). Each is the player with its frames filled in:

dlc.flicker.Mycelium(size=48, color="#f97316")
dlc.flicker.Helix(size=48, variant="5x5", off_color="#e5e5e5", off_opacity=1)

To play frames of your own, give dlc.flicker.Spinner a list of frames. A frame is 7 strings of 7 characters, # lit and . dark (or upstream's 49 booleans, or 7 lists of 7):

blink = ["...#...", "..###..", ".#####.", "#######", ".#####.", "..###..", "...#..."]
dlc.flicker.Spinner(grids=[blink, [row.replace("#", ".") for row in blink]])

dlc.flicker.PRESETS holds every preset's frames, a starting point for your own. rotate (0, 90, 180 or 270, clockwise) and mirror orient any preset, so dlc.flicker.Cladogram(rotate=90) grows left to right. variant picks the grid: "7x7", its inner "5x5" (bigger dots) or "9x9", the 7x7 padded with a ring of unlit dots (smaller dots at the same size). Lit dots are color at on_opacity (default 1). Unlit dots are off_color (default: color) at off_opacity (default 0.16) rather than upstream's fixed light grey, so one color reads on light and dark pages; off_opacity=0 shows only the lit dots.

Grid-dot loaders

gridora ships 133 motion variants of grid-dot animations plus a bitmap-font text component. dlc.gridora.GridLoader renders any motion variant; dlc.gridora.Text renders text using gridora's built-in glyph font.

dlc.gridora.GridLoader(variant="orbit", color="#f97316", rate=1.5)
dlc.gridora.Text(text="LOAD", color="#f97316", effect="bounce")

size is overall px, not cell size. Upstream size is an alias for cellSize (the individual cell), which would make a 3×3 grid 12 px wide. When you set the common size, dlc.gridora derives the cell size from the grid geometry. Pass cell_size explicitly if you need direct control. The upstream speed prop is cycle duration in seconds (higher = slower), not a multiplier; rate translates: speed = 1 / rate.

Every component is also exported prefixed at the top level (dlc.LoadingDevArc, dlc.LdrsRing) for Dash callbacks that want a flat name.

Version pins, SPDX licenses, upstream URLs and React peers: docs/UPSTREAM-INVENTORY.md. Attribution: NOTICE.

Relative tempo

rate is a rate, not a duration. 1.0 reproduces the tempo the upstream component runs at on its own, and the value is translated per family in the wrappers: a duration in milliseconds for loading-dev, epic and premium, seconds per loop for ldrs, a multiplier for react-spinners, m3 and flicker, a percentage for spinners-react, an offset for react-loading-indicators, and seconds per cycle (inverted) for gridora.

That baseline is per spinner, not per family. loading_dev.Compass is normally 500ms and loading_dev.Slide is 2400ms, so rate=1.0 gives each of them its own tempo and rate=2.0 halves both. react-loader-spinner has no tempo prop, so rate does nothing there.

Compared with dash-loading-spinners

dash-loading-spinners is a focused package built largely around react-spinners-era indicators. dlc is not a rename or a silent re-export of it. The goals differ:

  • A multi-upstream umbrella with stable namespaces, dlc.<family>.<Component>
  • An explicit React 19 / Dash ≥4.5 floor, driven by loading-dev
  • A license inventory and NOTICE covering every wrapped family
  • Room to add families without flattening name collisions

Where the APIs overlap, credit upstream; this is honest coexistence, not a drop-in replacement.

Contributing

Pull requests only, against main. Family wrappers land as focused follow-up PRs, one family or a small batch per PR. This repo squash-merges, so the PR title becomes the commit subject on main. Releases are cut by release-please from that subject, so the PR title must carry a Conventional Commits type (feat:, fix:, etc.). See CONTRIBUTING.md for the full rules.

Local setup:

pixi install           # Python, Node, Dash, the gallery's deps, test tooling
npm install
pixi run build         # JS bundle + generated Python wrappers
pixi run python usage.py   # minimal demo app
pixi run gallery       # the full gallery, http://127.0.0.1:8050/
pixi run test

The deployed gallery runs under gunicorn (gallery:server); pixi run serve does the same locally.

pixi run build-js alone is enough when you have only changed React or CSS under src/.

License

MIT, Copyright (c) 2026 Phyla Technologies. See LICENSE. Wrapped third-party libraries remain under their own licenses, listed in the inventory.

About

Dash component library wrapping modern React loading indicators: loading-dev, ldrs, react-spinners, spinners-react, and more. Requires Dash ≥4.5 / React 19.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages