dash-startup-loading-plugin 0.2.0__tar.gz → 0.4.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 (31) hide show
  1. {dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info → dash_startup_loading_plugin-0.4.0}/PKG-INFO +207 -145
  2. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/README.md +205 -141
  3. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/pyproject.toml +6 -3
  4. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin/__init__.py +8 -2
  5. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/__init__.py +5 -0
  6. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/__main__.py +5 -0
  7. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/antd.py +109 -0
  8. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/basic.py +49 -0
  9. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/cli.py +89 -0
  10. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/fac.py +110 -0
  11. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/mantine.py +79 -0
  12. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/shared.py +33 -0
  13. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin/plugin.py +96 -33
  14. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/loading.css +64 -0
  15. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-loading.js → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/loading.js +6 -6
  16. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-theme.js → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/theme.js +2 -2
  17. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info}/PKG-INFO +207 -145
  18. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/SOURCES.txt +24 -0
  19. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/entry_points.txt +5 -0
  20. dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/requires.txt +1 -0
  21. dash_startup_loading_plugin-0.4.0/tests/test_examples.py +150 -0
  22. dash_startup_loading_plugin-0.4.0/tests/test_plugin.py +237 -0
  23. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-loading.css +0 -64
  24. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/SOURCES.txt +0 -15
  25. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/entry_points.txt +0 -2
  26. dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/requires.txt +0 -4
  27. dash_startup_loading_plugin-0.2.0/tests/test_plugin.py +0 -153
  28. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/LICENSE +0 -0
  29. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/setup.cfg +0 -0
  30. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin.egg-info/dependency_links.txt +0 -0
  31. {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin.egg-info/top_level.txt +0 -0
@@ -1,17 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dash-startup-loading-plugin
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: A configurable full-screen startup loading overlay for Dash apps, packaged as a Dash Hooks plugin.
5
5
  Author-email: Ethan Zhang <ethan.zhang2016@gmail.com>
6
6
  License-Expression: MIT
7
- Keywords: dash,plotly,loading,plugin,hooks
7
+ Keywords: dash,plotly,loading,plugin
8
8
  Classifier: Framework :: Dash
9
9
  Requires-Python: >=3.9
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: dash>=3.0.3
13
- Provides-Extra: test
14
- Requires-Dist: pytest>=8; extra == "test"
15
13
  Dynamic: license-file
16
14
 
17
15
  # dash-startup-loading-plugin
@@ -51,7 +49,7 @@ discovery, resource hooks, and the index hook described in the official
51
49
  ## Installation
52
50
 
53
51
  ```bash
54
- pip install "dash-startup-loading-plugin>=0.2.0"
52
+ pip install "dash-startup-loading-plugin>=0.4.0"
55
53
  ```
56
54
 
57
55
  The package declares the following entry point:
@@ -66,6 +64,25 @@ package therefore enables the default startup overlay for Dash applications in
66
64
  that Python environment; an explicit import is only needed when changing its
67
65
  configuration or using its Python API.
68
66
 
67
+ When `dash_antd_components` from Dash Ant Design is installed in the same
68
+ environment, the plugin detects it during automatic hook discovery and applies
69
+ the matching `#ffffff` and `#121212` loading backgrounds. Dash Ant Design
70
+ applications therefore only need to install this plugin; calling
71
+ `configure_antd()` is optional and is reserved for explicit overrides.
72
+
73
+ ## What's new in 0.4.0
74
+
75
+ - Adds `configure_antd()` with matching `#ffffff` and `#121212` loading
76
+ backgrounds plus explicit light/dark overrides.
77
+ - Adds `configure_mantine()` with theme defaults sourced from Dash Mantine
78
+ Components and its pre-render color-scheme hook.
79
+ - Updates the Dash Ant Design example for the structured
80
+ `ConfigProvider.theme.algorithm` API.
81
+ - Adds a Dash Mantine Components example with persisted theme switching.
82
+ - Adds `configure_fac()` and a feffery-antd-components example.
83
+ - Uses one shared set of display copy across all packaged examples.
84
+ - Supports Dash versions from 3.0.3 onward.
85
+
69
86
  ## What's new in 0.2.0
70
87
 
71
88
  - Resolves the loading background before first paint from a persisted
@@ -104,25 +121,73 @@ from dash import Dash, html
104
121
  from dash_startup_loading_plugin import configure
105
122
 
106
123
  configure(
107
- required_selectors=["#page-header", "#sidebar-menu"],
124
+ required_selectors=["#usage-header", "#usage-sidebar-menu"],
108
125
  pending_selector="[data-dac-async-placeholder]",
109
126
  timeout_ms=6000,
110
- minimum_display_ms=200,
111
127
  fade_duration_ms=160,
112
- color="#1677ff",
113
- dark_color="#4096ff",
114
128
  )
115
129
 
116
130
  app = Dash(__name__)
117
131
  app.layout = html.Div(
118
132
  [
119
- html.Header("Dashboard", id="page-header"),
120
- html.Nav("Navigation", id="sidebar-menu"),
133
+ html.Header("Dashboard", id="usage-header"),
134
+ html.Nav("Navigation", id="usage-sidebar-menu"),
121
135
  ]
122
136
  )
123
137
  ```
124
138
 
125
- See [`examples/basic.py`](examples/basic.py) for a runnable example.
139
+ ## Installed demos
140
+
141
+ The example applications are included in the installed Python package. Select a
142
+ packaged example with the `dash-startup-loading-plugin` command:
143
+
144
+ Component libraries are not dependencies of this plugin. Install the library
145
+ used by the selected example separately:
146
+
147
+ ```bash
148
+ pip install dash-mantine-components
149
+ pip install dash-ant-design
150
+ pip install "feffery-antd-components>=0.4.0"
151
+ ```
152
+
153
+ If the selected component library cannot be imported, the command exits with
154
+ an error naming the failed import and the package to install.
155
+
156
+ ```bash
157
+ # Framework-neutral Dash
158
+ dash-startup-loading-plugin examples.dash
159
+
160
+ # Dash Mantine Components
161
+ dash-startup-loading-plugin examples.dash-mantine-components
162
+
163
+ # Dash Ant Design
164
+ dash-startup-loading-plugin examples.dash-ant-design
165
+
166
+ # feffery-antd-components
167
+ dash-startup-loading-plugin examples.feffery-antd-components
168
+ ```
169
+
170
+ Server options can be supplied directly:
171
+
172
+ ```bash
173
+ dash-startup-loading-plugin examples.dash-mantine-components \
174
+ --host 0.0.0.0 --port 8050 --debug
175
+ ```
176
+
177
+ The same launcher is available through Python when a console-script path is not
178
+ available:
179
+
180
+ ```bash
181
+ python -m dash_startup_loading_plugin.examples examples.dash-mantine-components
182
+ ```
183
+
184
+ Application code can create a selected demo without starting its server:
185
+
186
+ ```python
187
+ from dash_startup_loading_plugin.examples import create_demo_app
188
+
189
+ app = create_demo_app("dash-mantine-components")
190
+ ```
126
191
 
127
192
  ## Readiness behavior
128
193
 
@@ -152,7 +217,7 @@ immutable `StartupLoadingConfig` instance.
152
217
  | Option | Default | Description |
153
218
  |---|---:|---|
154
219
  | `enabled` | `True` | Inject the startup overlay. Set to `False` to disable it. |
155
- | `overlay_id` | `"dash-startup-loading"` | HTML `id` of the injected overlay; also used by the browser API. |
220
+ | `overlay_id` | `"dash-loading"` | HTML `id` of the injected overlay; also used by the browser API. |
156
221
  | `aria_label` | `"Loading"` | Accessible label on the overlay's `role="status"` element. |
157
222
  | `root_selector` | `"#react-entry-point"` | Dash renderer root observed for mounted content. |
158
223
  | `required_selectors` | `("#react-entry-point",)` | Iterable of document-level CSS selectors that must all exist. A single string is not accepted. |
@@ -187,35 +252,136 @@ in this order:
187
252
  followed by the common `theme`, `color-theme`, and `color-scheme` keys.
188
253
  6. `prefers-color-scheme`.
189
254
 
190
- The result is written to `data-dash-startup-loading-theme` before the body is
255
+ The result is written to `data-dash-loading-theme` before the body is
191
256
  parsed. This isolates the overlay styling without changing classes or data
192
257
  attributes owned by Tailwind, Dash Mantine Components, or the application.
193
258
  The stylesheet also adjusts its animation for `prefers-reduced-motion`.
194
259
 
260
+ ### Dash Mantine Components
261
+
262
+ Dash Mantine Components 2.6 and later includes `ColorSchemeToggle`, which
263
+ switches the active color scheme without a callback and persists it in
264
+ `mantine-color-scheme-value`. The startup plugin reads that value before Dash
265
+ and React mount. To make the loading transition seamless, use Mantine's current
266
+ default dark body color for the overlay:
267
+
268
+ ```python
269
+ import dash_mantine_components as dmc
270
+ from dash_startup_loading_plugin import configure_mantine
271
+
272
+ configure_mantine()
273
+
274
+ app.layout = dmc.MantineProvider(
275
+ [
276
+ dmc.ColorSchemeToggle(
277
+ lightIcon=dmc.Text("☀"),
278
+ darkIcon=dmc.Text("☾"),
279
+ ),
280
+ dmc.Text("Application content", id="app-ready"),
281
+ ],
282
+ defaultColorScheme="auto",
283
+ )
284
+ ```
285
+
286
+ Run `dash-startup-loading-plugin examples.dash-mantine-components` for the
287
+ complete example.
288
+
289
+ `configure_mantine()` keeps DMC optional. When used, it registers DMC's
290
+ pre-render color-scheme hook, disables the Dash Ant Design placeholder check,
291
+ and derives the light and dark loading backgrounds from DMC's active default
292
+ theme. Any explicit configuration still takes precedence:
293
+
294
+ ```python
295
+ configure_mantine(dark_background="#202020")
296
+ ```
297
+
195
298
  ### Dash Ant Design persistence
196
299
 
197
- `dash_antd_components.ConfigProvider` can persist its `theme` prop. The startup
198
- plugin reads that same Dash persistence record on the next page load:
300
+ Current `dash_antd_components.ConfigProvider.theme` accepts a structured theme
301
+ configuration whose `algorithm` is `"default"`, `"dark"`, `"compact"`, or an
302
+ array of those values. Persist a user-facing system/light/dark selector, resolve
303
+ the system preference in a clientside callback, and store the semantic choice
304
+ in the small conventional `localStorage["theme"]` value that the startup plugin
305
+ reads before Dash mounts:
199
306
 
200
307
  ```python
201
308
  import dash_antd_components as dac
202
- from dash_startup_loading_plugin import configure
309
+ from dash import Input, Output, clientside_callback
310
+ from dash_startup_loading_plugin import configure_antd
203
311
 
204
- configure(dash_theme_component_id="theme-provider")
312
+ configure_antd()
205
313
 
206
314
  provider = dac.ConfigProvider(
207
- app_content,
315
+ [
316
+ app_content,
317
+ dac.Segmented(
318
+ id="theme-mode",
319
+ options=["system", "light", "dark"],
320
+ value="system",
321
+ persistence=True,
322
+ persisted_props=["value"],
323
+ persistence_type="local",
324
+ ),
325
+ ],
208
326
  id="theme-provider",
209
- persistence=True,
210
- persisted_props=["theme"],
211
- persistence_type="local",
327
+ theme={"algorithm": "default"},
328
+ )
329
+
330
+ clientside_callback(
331
+ """function(mode) {
332
+ localStorage.setItem("theme", JSON.stringify(mode));
333
+ const dark = mode === "dark" || (
334
+ mode === "system"
335
+ && window.matchMedia("(prefers-color-scheme: dark)").matches
336
+ );
337
+ return {algorithm: dark ? "dark" : "default"};
338
+ }""",
339
+ Output("theme-provider", "theme"),
340
+ Input("theme-mode", "value"),
341
+ )
342
+ ```
343
+
344
+ The selector owns the semantic `"system"` state; `ConfigProvider` receives only
345
+ the algorithms allowed by its current API. `configure_antd()` uses `#ffffff`
346
+ and `#121212`, matching the component library's default light and dark
347
+ backgrounds. If the application customizes either background, pass the same
348
+ values explicitly:
349
+
350
+ ```python
351
+ configure_antd(
352
+ background="#f5f5f5",
353
+ dark_background="#202020",
354
+ )
355
+ ```
356
+
357
+ Run `dash-startup-loading-plugin examples.dash-ant-design` for the complete
358
+ switcher.
359
+
360
+ ### feffery-antd-components persistence
361
+
362
+ FAC 0.4 and later supports Dash 3 and exposes Ant Design's theme algorithm
363
+ through `AntdConfigProvider.algorithm`. Use `configure_fac()` before creating
364
+ the app, persist a semantic system/light/dark selection, and return either
365
+ `"default"` or `"dark"` to the provider:
366
+
367
+ ```python
368
+ import feffery_antd_components as fac
369
+ from dash import Dash
370
+ from dash_startup_loading_plugin import configure_fac
371
+
372
+ configure_fac(required_selectors=["#fac-app-ready"])
373
+
374
+ app = Dash(__name__)
375
+ app.layout = fac.AntdConfigProvider(
376
+ fac.AntdButton("Example component", id="fac-app-ready"),
377
+ id="fac-theme-provider",
378
+ algorithm="default",
212
379
  )
213
380
  ```
214
381
 
215
- Update `theme-provider.theme` from a regular or clientside callback. Dash stores
216
- the UI edit, `ConfigProvider` restores it after mount, and the startup plugin
217
- uses it for the loading background before mount. See
218
- [`examples/basic.py`](examples/basic.py) for the complete switcher.
382
+ Run `dash-startup-loading-plugin examples.feffery-antd-components` for the
383
+ complete persisted-theme example. FAC remains an external dependency and is
384
+ imported only when that example is selected.
219
385
 
220
386
  ### Custom loader markup
221
387
 
@@ -242,12 +408,22 @@ configuration. Never populate it with user input.
242
408
  from dash_startup_loading_plugin import (
243
409
  StartupLoadingConfig,
244
410
  configure,
411
+ configure_antd,
412
+ configure_fac,
413
+ configure_mantine,
245
414
  get_config,
246
415
  reset_config,
247
416
  )
248
417
  ```
249
418
 
250
419
  - `configure(**changes)` validates and applies a partial configuration update.
420
+ - `configure_antd(**changes)` matches the loading backgrounds to Dash Ant
421
+ Design's light and dark themes. Installed Dash Ant Design is detected
422
+ automatically, so this helper is only needed for explicit overrides.
423
+ - `configure_fac(**changes)` applies the equivalent light and dark loading
424
+ backgrounds for feffery-antd-components.
425
+ - `configure_mantine(**changes)` applies DMC theme defaults and registers DMC's
426
+ pre-render color-scheme hook.
251
427
  - `get_config()` returns the current immutable configuration.
252
428
  - `reset_config()` restores all defaults. It is primarily useful in tests.
253
429
  - `StartupLoadingConfig` is the frozen dataclass containing all options.
@@ -261,21 +437,21 @@ The plugin exposes two methods for integrations that need explicit control:
261
437
 
262
438
  ```javascript
263
439
  // Recheck the configured readiness conditions.
264
- window.dashStartupLoading.check();
440
+ window.dashLoading.check();
265
441
 
266
442
  // Begin a manual dismissal.
267
- window.dashStartupLoading.finish();
443
+ window.dashLoading.finish();
268
444
 
269
445
  // A custom overlay_id can be supplied to either method.
270
- window.dashStartupLoading.finish("my-loading-overlay");
446
+ window.dashLoading.finish("my-loading-overlay");
271
447
  ```
272
448
 
273
449
  Before fading out, the overlay dispatches a bubbling
274
- `dash-startup-loading:ready` event. Its `detail.reason` is `"ready"`,
450
+ `dash-loading:ready` event. Its `detail.reason` is `"ready"`,
275
451
  `"timeout"`, or `"manual"`:
276
452
 
277
453
  ```javascript
278
- document.addEventListener("dash-startup-loading:ready", function (event) {
454
+ document.addEventListener("dash-loading:ready", function (event) {
279
455
  console.log("Startup overlay finished:", event.detail.reason);
280
456
  });
281
457
  ```
@@ -345,120 +521,6 @@ This is expected with automatic `dash_hooks` discovery. Use a dedicated virtual
345
521
  environment, uninstall the package where it is not wanted, or call
346
522
  `configure(enabled=False)` before constructing those Dash apps.
347
523
 
348
- ## Development
349
-
350
- Clone the repository, then install the project and test dependencies:
351
-
352
- ```bash
353
- uv sync --extra test
354
- ```
355
-
356
- Run the tests and example:
357
-
358
- ```bash
359
- uv run pytest
360
- uv run --with dash-ant-design python examples/basic.py
361
- ```
362
-
363
- The example uses `dash_antd_components.ConfigProvider` to demonstrate native
364
- theme persistence, so `dash-ant-design` is an example-only dependency rather
365
- than a runtime dependency of the plugin.
366
-
367
- Build the source distribution and wheel:
368
-
369
- ```bash
370
- uv build
371
- ```
372
-
373
- ## Publishing to PyPI
374
-
375
- PyPI does not allow replacing an existing distribution file. Confirm that the
376
- version in `pyproject.toml` is new before building, then create the artifacts
377
- from a clean `dist/` directory:
378
-
379
- ```bash
380
- rm -rf build dist src/*.egg-info
381
- uv lock
382
- uv run --extra test pytest
383
- uvx ruff check src tests examples
384
- uv build
385
- uvx twine check dist/*
386
- ```
387
-
388
- Inspect the resulting files before upload:
389
-
390
- ```bash
391
- ls -lh dist/
392
- unzip -l dist/dash_startup_loading_plugin-0.2.0-py3-none-any.whl
393
- tar -tzf dist/dash_startup_loading_plugin-0.2.0.tar.gz
394
- uv publish --dry-run dist/*
395
- ```
396
-
397
- ### TestPyPI
398
-
399
- Create a TestPyPI API token, then upload to its legacy upload endpoint:
400
-
401
- ```bash
402
- export UV_PUBLISH_TOKEN="pypi-your-test-token"
403
- uv publish \
404
- --publish-url https://test.pypi.org/legacy/ \
405
- --check-url https://test.pypi.org/simple/ \
406
- dist/*
407
- unset UV_PUBLISH_TOKEN
408
- ```
409
-
410
- Test installation in an isolated environment:
411
-
412
- ```bash
413
- uv run --isolated \
414
- --index-url https://test.pypi.org/simple/ \
415
- --extra-index-url https://pypi.org/simple/ \
416
- --with dash-startup-loading-plugin==0.2.0 \
417
- python -c "import dash_startup_loading_plugin; print('import ok')"
418
- ```
419
-
420
- The extra PyPI index is needed because TestPyPI may not contain the plugin's
421
- runtime dependencies.
422
-
423
- ### PyPI with an API token
424
-
425
- Create a project-scoped PyPI token and publish the checked artifacts:
426
-
427
- ```bash
428
- export UV_PUBLISH_TOKEN="pypi-your-project-token"
429
- uv publish dist/*
430
- unset UV_PUBLISH_TOKEN
431
- ```
432
-
433
- Do not place tokens in `pyproject.toml`, shell history, source control, or CI
434
- logs.
435
-
436
- ### PyPI Trusted Publishing
437
-
438
- For CI releases, configure the repository and workflow as a Trusted Publisher
439
- in the PyPI project settings. The publishing job needs the
440
- `id-token: write` permission and can upload without a long-lived token:
441
-
442
- ```yaml
443
- permissions:
444
- contents: read
445
- id-token: write
446
-
447
- steps:
448
- - uses: actions/checkout@v4
449
- - uses: astral-sh/setup-uv@v8
450
- - run: uv build
451
- - run: uv publish --trusted-publishing always
452
- ```
453
-
454
- After publishing, verify the release:
455
-
456
- ```bash
457
- uv run --isolated \
458
- --with dash-startup-loading-plugin==0.2.0 \
459
- python -c "import dash_startup_loading_plugin; print('import ok')"
460
- ```
461
-
462
524
  ## License
463
525
 
464
526
  MIT. See [`LICENSE`](LICENSE).