reflex-silverpoint-react 0.6.0__tar.gz → 0.7.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.
- {reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react.egg-info → reflex_silverpoint_react-0.7.0}/PKG-INFO +185 -11
- reflex_silverpoint_react-0.6.0/PKG-INFO → reflex_silverpoint_react-0.7.0/README.md +177 -32
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/__init__.py +85 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/surface.jsx +219 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/surfaces.css +375 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/timeline.css +225 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/timeline.jsx +64 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/base.py +36 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/base.pyi +159 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/charts.pyi +126 -3597
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/composed.py +702 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/dashboard.py +6 -1
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/dashboard.pyi +179 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/overlays.py +835 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/palette.py +362 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/surfaces.py +329 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/surfaces.pyi +364 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/timeline.py +157 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/timeline.pyi +72 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/ui.py +16 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/ui.pyi +942 -0
- reflex_silverpoint_react-0.6.0/README.md → reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react.egg-info/PKG-INFO +206 -6
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react.egg-info/SOURCES.txt +13 -1
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react.egg-info/requires.txt +11 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/pyproject.toml +14 -6
- reflex_silverpoint_react-0.7.0/tests/test_v07.py +234 -0
- reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/base.pyi +0 -274
- reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/dashboard.pyi +0 -314
- reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/ui.pyi +0 -1687
- reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react.egg-info/requires.txt +0 -7
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/LICENSE +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/catalog.py +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/charts.py +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/helpers.py +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react/ui_catalog.py +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react.egg-info/dependency_links.txt +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/custom_components/reflex_silverpoint_react.egg-info/top_level.txt +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/setup.cfg +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/tests/test_components.py +0 -0
- {reflex_silverpoint_react-0.6.0 → reflex_silverpoint_react-0.7.0}/tests/test_demo_data.py +0 -0
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reflex-silverpoint-react
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: The 60 silverpoint charts, the
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: The 60 silverpoint charts, the Dashboard, 17 UI components, palettes, 20 composed components and a Knight Lab timeline (Renaissance silverpoint drawing style) for Reflex, wrapping @silverpoint/react
|
|
5
5
|
Author-email: Ernesto Crespo <ecrespo@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/ecrespo/reflex-silverpoint-react
|
|
8
8
|
Project-URL: Source, https://github.com/ecrespo/reflex-silverpoint-react
|
|
9
9
|
Project-URL: Issues, https://github.com/ecrespo/reflex-silverpoint-react/issues
|
|
10
10
|
Project-URL: Upstream, https://github.com/ecrespo/silverpoint
|
|
11
|
-
Keywords: reflex,reflex-custom-components,charts,silverpoint,data-visualization,svg,ui-components
|
|
11
|
+
Keywords: reflex,reflex-custom-components,charts,silverpoint,data-visualization,svg,ui-components,palette,timeline
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
15
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: reflex>=0.
|
|
19
|
+
Requires-Dist: reflex>=0.10.0
|
|
20
|
+
Provides-Extra: timeline
|
|
21
|
+
Requires-Dist: reflex-knightlab-timeline>=0.1.2; extra == "timeline"
|
|
20
22
|
Provides-Extra: dev
|
|
21
23
|
Requires-Dist: build; extra == "dev"
|
|
22
24
|
Requires-Dist: twine; extra == "dev"
|
|
23
25
|
Requires-Dist: pytest; extra == "dev"
|
|
24
26
|
Requires-Dist: ruff; extra == "dev"
|
|
27
|
+
Requires-Dist: reflex-knightlab-timeline>=0.1.2; extra == "dev"
|
|
25
28
|
Dynamic: license-file
|
|
26
29
|
|
|
27
30
|
# reflex-silverpoint-react
|
|
@@ -39,6 +42,30 @@ components** (buttons, inputs, tabs, cards, alerts…), the `SilverpointProvider
|
|
|
39
42
|
(`silverpoint` and `cyanotype`), the interaction events, custom readouts and the imperative handle
|
|
40
43
|
(SVG export and geometry) as Python.
|
|
41
44
|
|
|
45
|
+
On top of that it adds, in Reflex: **palettes** for every chart and component, **20 composed
|
|
46
|
+
components** built on silverpoint's own frames and tones (tables, overlays, toasts…), and the
|
|
47
|
+
**Knight Lab timeline** drawn in silverpoint.
|
|
48
|
+
|
|
49
|
+
### New in 0.7
|
|
50
|
+
|
|
51
|
+
- **Reflex 0.10.0**, and therefore **Python 3.11 or later** (Python 3.10 is no longer supported).
|
|
52
|
+
Reflex 0.10 removed `reflex component build`: stubs are regenerated with `scripts/make_stubs.py`.
|
|
53
|
+
- **Palettes** — `palette=` on every chart, UI component, dashboard and composed component,
|
|
54
|
+
`silverpoint_palette(...)` for a whole section, six presets named after drawing media
|
|
55
|
+
(`silverpoint`, `sanguine`, `sepia`, `iron_gall`, `verdigris`, `indigo`) and `check_palette()`
|
|
56
|
+
against the contrast thresholds of the data model. See [Palettes](#palettes).
|
|
57
|
+
- **Composed components, level A** (native markup): `sp_table` (+ `sort_rows`), `sp_pagination`,
|
|
58
|
+
`sp_breadcrumb`, `sp_avatar` (+ `sp_avatar_group`), `sp_statistic`, `sp_descriptions`,
|
|
59
|
+
`sp_timeline_list`, `sp_collapse` (+ `sp_collapse_item`), `sp_empty`, `sp_result`, `sp_textarea`
|
|
60
|
+
and `sp_input_number`.
|
|
61
|
+
- **Composed components, level B** (overlays on Radix primitives): `sp_modal`, `sp_drawer`,
|
|
62
|
+
`sp_popover`, `sp_tooltip`, `sp_select`, `sp_dropdown_menu` and `sp_toast` (+ `sp_toaster`), with
|
|
63
|
+
`sp_trigger` as their drawn button. See [Composed components](#composed-components).
|
|
64
|
+
- **`sp_timeline`** — Knight Lab TimelineJS drawn in silverpoint: a skin on the ground's colours and
|
|
65
|
+
type, plus the ground's own hand-inked frames and tone tiles on its markers, eras and buttons.
|
|
66
|
+
Optional extra: `pip install "reflex-silverpoint-react[timeline]"`. See [Timeline](#timeline).
|
|
67
|
+
- `sp_surface`, `sp_glyph`: the building blocks, for components of your own.
|
|
68
|
+
|
|
42
69
|
### New in 0.6
|
|
43
70
|
|
|
44
71
|
- **27 new charts**, the second catalog of silverpoint 0.6:
|
|
@@ -87,7 +114,7 @@ stylesheets it needs (`@silverpoint/grounds/styles.css` and the self-hosted EB G
|
|
|
87
114
|
`@silverpoint/fonts/fonts.css`); the UI components also import `@silverpoint/grounds/ui.css`. No
|
|
88
115
|
Tailwind, no CDN.
|
|
89
116
|
|
|
90
|
-
Requires Reflex 0.
|
|
117
|
+
Requires Reflex 0.10.0 or later (React 19) and Python 3.11 or later.
|
|
91
118
|
|
|
92
119
|
## Quickstart
|
|
93
120
|
|
|
@@ -350,6 +377,132 @@ rx.el.form(
|
|
|
350
377
|
- Text inputs controlled from state make a round trip per keystroke; for long text, prefer
|
|
351
378
|
`default_value` and read the value on submit.
|
|
352
379
|
|
|
380
|
+
## Palettes
|
|
381
|
+
|
|
382
|
+
silverpoint never writes a colour into its drawing: every stroke and fill is painted by CSS through
|
|
383
|
+
the ground's `--sp-` custom properties. A palette sets them, so it re-colours without re-rendering.
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
from reflex_silverpoint_react import PALETTES, Palette, bar_chart, check_palette, silverpoint_palette, sp_button
|
|
387
|
+
|
|
388
|
+
bar_chart(title="Orders", palette="sanguine") # a preset
|
|
389
|
+
sp_button("Save", variant="primary", palette={"ink": "#2C6355"}) # a dict of fields
|
|
390
|
+
bar_chart(title="Orders", palette=State.palette) # a state var holding a dict
|
|
391
|
+
|
|
392
|
+
MINE = Palette(substrate="#F2E8DC", ink="#8A3A24", ink_secondary="#6A4A3A", text="#4A2216")
|
|
393
|
+
assert not check_palette(MINE) # [] when every field meets its contrast threshold
|
|
394
|
+
|
|
395
|
+
silverpoint_palette(dashboard(...), sp_card(...), palette="indigo") # a whole section
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Fields: `substrate`, `ink`, `ink_secondary`, `heighten`, `rule`, `grid`, `text`, `text_muted` and
|
|
399
|
+
`focus` (the UI focus ring). Unset fields keep the ground's own. An element's own `palette` always
|
|
400
|
+
wins over its section's. A palette is **monochrome by design**: tone is built from hatch density
|
|
401
|
+
(Art. 6), so a chart has two inks (`ink` for the main series, `ink_secondary` for the second), never
|
|
402
|
+
a colour per series. `precision` mode and the system's high-contrast modes still apply on top.
|
|
403
|
+
`silverpoint_provider` takes no palette (it renders no element): use `silverpoint_palette`.
|
|
404
|
+
|
|
405
|
+
## Composed components
|
|
406
|
+
|
|
407
|
+
Components built in Reflex on silverpoint's markup contract: `@silverpoint/grounds/ui.css` draws its
|
|
408
|
+
hand-inked frames, hatched tones and heightening on any element that follows it, so these are drawn
|
|
409
|
+
with exactly the same pieces as the `Sp` components. They are **Reflex-only** (silverpoint's React,
|
|
410
|
+
Vue and Angular adapters do not have them) and, unlike the `Sp` components, they do not read
|
|
411
|
+
`silverpoint_provider`: pass `ground`, `substrate`, `mode` and `palette` explicitly.
|
|
412
|
+
|
|
413
|
+
```python
|
|
414
|
+
from reflex_silverpoint_react import sort_rows, sp_pagination, sp_table
|
|
415
|
+
|
|
416
|
+
sp_table(
|
|
417
|
+
[
|
|
418
|
+
{"key": "team", "title": "Team", "sortable": True},
|
|
419
|
+
{"key": "load", "title": "Load", "align": "end", "sortable": True},
|
|
420
|
+
],
|
|
421
|
+
State.rows,
|
|
422
|
+
caption="On-call teams",
|
|
423
|
+
sort_key=State.sort_key,
|
|
424
|
+
sort_order=State.sort_order,
|
|
425
|
+
on_sort=State.sort, # receives the key; sort with sort_rows(rows, key, order)
|
|
426
|
+
striped=True,
|
|
427
|
+
)
|
|
428
|
+
sp_pagination(total=240, current=State.page, on_change=State.set_page, show_total=True)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
| Level A (native) | |
|
|
432
|
+
|---|---|
|
|
433
|
+
| `sp_table` | Card-framed table: small-caps header, tabular figures, hatched striping, sortable headers with `aria-sort` |
|
|
434
|
+
| `sp_pagination` | Previous/next, first/last, a window around the current page (heightened); `on_change(page)` |
|
|
435
|
+
| `sp_breadcrumb` | `<nav>` of links; the last item is the current page |
|
|
436
|
+
| `sp_avatar`, `sp_avatar_group` | Portrait or initials in a drawn round (or square) frame |
|
|
437
|
+
| `sp_statistic` | Small-caps title, large tabular figure, prefix/suffix, trend arrow |
|
|
438
|
+
| `sp_descriptions` | Label–value grid (`<dl>`), optionally card-framed |
|
|
439
|
+
| `sp_timeline_list` | Vertical list: `done` (hatched), `current` (heightened), `pending`, `error` |
|
|
440
|
+
| `sp_collapse`, `sp_collapse_item` | Native `<details>`; `accordion=True` keeps one open |
|
|
441
|
+
| `sp_empty`, `sp_result` | Empty state; outcome with a drawn round mark |
|
|
442
|
+
| `sp_textarea`, `sp_input_number` | On the `SpInput` contract; `on_change` receives the value (text or number) |
|
|
443
|
+
|
|
444
|
+
| Level B (Radix primitives) | |
|
|
445
|
+
|---|---|
|
|
446
|
+
| `sp_modal`, `sp_drawer` | Dialog on a card frame over a hatched backdrop; drawer from any edge |
|
|
447
|
+
| `sp_popover`, `sp_tooltip` | Anchored content; tooltip on hover or keyboard focus |
|
|
448
|
+
| `sp_select` | Single choice with typeahead; the chosen option ticked, the highlighted one heightened |
|
|
449
|
+
| `sp_dropdown_menu` | Commands with shortcuts, separators and labels; `on_select(key)` |
|
|
450
|
+
| `sp_toast`, `sp_toaster` | Notices that stack in a corner; `error`/`warning` are announced assertively |
|
|
451
|
+
|
|
452
|
+
Behaviour (focus trapping, keyboard, dismissal, positioning, ARIA) is Radix's, at the versions
|
|
453
|
+
Reflex already installs. Overlays render in a portal at the end of `<body>`, outside any
|
|
454
|
+
`silverpoint_palette` section, so give them `palette` directly. A string `trigger` becomes
|
|
455
|
+
`sp_trigger(...)`, the drawn button that can forward Radix's props (`sp_button` cannot).
|
|
456
|
+
|
|
457
|
+
```python
|
|
458
|
+
sp_modal(
|
|
459
|
+
rx.el.p("Apply the new ground?"),
|
|
460
|
+
trigger="Open",
|
|
461
|
+
title="Apply changes",
|
|
462
|
+
footer=sp_trigger("Apply", variant="primary", on_click=State.confirm),
|
|
463
|
+
open=State.modal_open,
|
|
464
|
+
on_open_change=State.set_modal_open,
|
|
465
|
+
)
|
|
466
|
+
sp_select(["North", "East", "South", "West"], value=State.region, on_change=State.set_region)
|
|
467
|
+
sp_toaster(sp_toast("Saved", State.text, kind="success", open=State.toast_open, on_open_change=State.set_toast_open))
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+

|
|
471
|
+
|
|
472
|
+
## Timeline
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
pip install "reflex-silverpoint-react[timeline]" # adds reflex-knightlab-timeline
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
```python
|
|
479
|
+
from reflex_silverpoint_react import sp_timeline
|
|
480
|
+
|
|
481
|
+
sp_timeline(
|
|
482
|
+
DATA, # TimelineJS data: title, events, eras (or a TimelineData)
|
|
483
|
+
height=560,
|
|
484
|
+
ground="silverpoint",
|
|
485
|
+
substrate="cream",
|
|
486
|
+
mode="ink",
|
|
487
|
+
palette="sepia",
|
|
488
|
+
inked_frames=True, # the ground's hand-drawn frames and tone tiles
|
|
489
|
+
on_change=State.on_change, # the unique_id of the slide shown
|
|
490
|
+
)
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
It works in two layers. The **skin** replaces TimelineJS's colours, type and rules with the
|
|
494
|
+
ground's `--sp-` properties: substrate, inks, EB Garamond, hairline rules, eras hatched by density,
|
|
495
|
+
the current marker heightened. The **hand** reads the ground's own frame and tone masks from hidden
|
|
496
|
+
probes and lays them on the markers, eras and menubar, so they are drawn with the same pieces as
|
|
497
|
+
the `Sp` components; `inked_frames=False` keeps the skin only, and `precision`, `cyanotype` and
|
|
498
|
+
forced colours fall back to exact rules by themselves. Note that TimelineJS requests its icon font
|
|
499
|
+
from a relative path (`/css/icons/tl-icons.*`); the Reflex dev server answers it with HTML, so the
|
|
500
|
+
browser logs font-decoding warnings. They come from TimelineJS, not from this package.
|
|
501
|
+
|
|
502
|
+

|
|
503
|
+
|
|
504
|
+

|
|
505
|
+
|
|
353
506
|
## Interaction
|
|
354
507
|
|
|
355
508
|
```python
|
|
@@ -411,7 +564,7 @@ The exported SVG carries its own ground colours, so it renders the same outside
|
|
|
411
564
|
## Demo app
|
|
412
565
|
|
|
413
566
|
```bash
|
|
414
|
-
uv venv && uv pip install -e .
|
|
567
|
+
uv venv && uv pip install -e ".[timeline]"
|
|
415
568
|
cd silverpoint_react_demo
|
|
416
569
|
uv run reflex run
|
|
417
570
|
```
|
|
@@ -419,24 +572,45 @@ uv run reflex run
|
|
|
419
572
|
Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 60 charts, ground
|
|
420
573
|
controls, demo datasets vs data from Python state with a re-roll), **Playground** (one chart, every
|
|
421
574
|
rendering choice and the Python that reproduces it), **Interaction** (events, custom readout, a
|
|
422
|
-
volvelle that turns on click, a treemap and a sunburst that drill down together, live
|
|
575
|
+
volvelle that turns on click, a treemap and a sunburst that drill down together, live
|
|
576
|
+
KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
|
|
423
577
|
linked operations dashboard fed from Python state with ground, substrate, mode and column controls, a
|
|
424
578
|
KPI strip, and `dashboard_link` on its own), **UI components** (`/ui`: the components controlled from
|
|
425
579
|
Python state with a native form submit, and the three reference panels of the upstream example apps
|
|
426
580
|
in silverpoint ink, precision and cyanotype), one **reference page per chart** (`/chart/<slug>`) and
|
|
427
|
-
one per UI component (`/ui/<slug>`: every declared state on both grounds, usage and props). The
|
|
581
|
+
one per UI component (`/ui/<slug>`: every declared state on both grounds, usage and props). The
|
|
582
|
+
Gallery and Playground also get a ground control, for `cyanotype`, and a palette control.
|
|
583
|
+
New in 0.7: **More components** (`/components`: the 20 composed components wired to Python, with
|
|
584
|
+
ground, substrate, mode and palette controls and an event log), **Palettes** (`/palettes`: the
|
|
585
|
+
presets, a palette builder with colour pickers and `check_palette`, a coloured section) and
|
|
586
|
+
**Timeline** (`/timeline`: the Knight Lab timeline on every ground, mode and palette).
|
|
428
587
|
|
|
429
588
|

|
|
430
589
|
|
|
431
590
|
## Development
|
|
432
591
|
|
|
433
592
|
```bash
|
|
434
|
-
uv
|
|
593
|
+
uv sync --extra dev
|
|
435
594
|
uv run pytest
|
|
436
595
|
uv run ruff check .
|
|
437
|
-
|
|
596
|
+
# Reflex 0.10 removed `reflex component build`: regenerate the .pyi stubs with the generator
|
|
597
|
+
# Reflex itself uses (plus this package's fixes), then build the sdist and wheel.
|
|
598
|
+
uv run python scripts/make_stubs.py
|
|
599
|
+
uv build
|
|
438
600
|
```
|
|
439
601
|
|
|
602
|
+
Before committing, run the hooks of [`.pre-commit-config.yaml`](.pre-commit-config.yaml) (ruff check
|
|
603
|
+
and format — including the Python blocks of this README — file hygiene and `uv lock --check`):
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
pre-commit install
|
|
607
|
+
pre-commit run --all-files
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
Changes per version are in [CHANGELOG.md](CHANGELOG.md); the guide for coding agents is
|
|
611
|
+
[AGENTS.md](AGENTS.md). Releases are published to PyPI by pushing a `vX.Y.Z` tag on `main` that
|
|
612
|
+
matches `version` in `pyproject.toml`.
|
|
613
|
+
|
|
440
614
|
## License
|
|
441
615
|
|
|
442
616
|
MIT. silverpoint is MIT; the EB Garamond typeface is under the SIL Open Font License.
|
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: reflex-silverpoint-react
|
|
3
|
-
Version: 0.6.0
|
|
4
|
-
Summary: The 60 silverpoint charts, the linked Dashboard and the 17 UI components (Renaissance silverpoint drawing style) for Reflex, wrapping @silverpoint/react
|
|
5
|
-
Author-email: Ernesto Crespo <ecrespo@gmail.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/ecrespo/reflex-silverpoint-react
|
|
8
|
-
Project-URL: Source, https://github.com/ecrespo/reflex-silverpoint-react
|
|
9
|
-
Project-URL: Issues, https://github.com/ecrespo/reflex-silverpoint-react/issues
|
|
10
|
-
Project-URL: Upstream, https://github.com/ecrespo/silverpoint
|
|
11
|
-
Keywords: reflex,reflex-custom-components,charts,silverpoint,data-visualization,svg,ui-components
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
Requires-Dist: reflex>=0.9.12
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: build; extra == "dev"
|
|
22
|
-
Requires-Dist: twine; extra == "dev"
|
|
23
|
-
Requires-Dist: pytest; extra == "dev"
|
|
24
|
-
Requires-Dist: ruff; extra == "dev"
|
|
25
|
-
Dynamic: license-file
|
|
26
|
-
|
|
27
1
|
# reflex-silverpoint-react
|
|
28
2
|
|
|
29
3
|
A [Reflex](https://reflex.dev) custom component for **[silverpoint](https://github.com/ecrespo/silverpoint)**:
|
|
@@ -39,6 +13,30 @@ components** (buttons, inputs, tabs, cards, alerts…), the `SilverpointProvider
|
|
|
39
13
|
(`silverpoint` and `cyanotype`), the interaction events, custom readouts and the imperative handle
|
|
40
14
|
(SVG export and geometry) as Python.
|
|
41
15
|
|
|
16
|
+
On top of that it adds, in Reflex: **palettes** for every chart and component, **20 composed
|
|
17
|
+
components** built on silverpoint's own frames and tones (tables, overlays, toasts…), and the
|
|
18
|
+
**Knight Lab timeline** drawn in silverpoint.
|
|
19
|
+
|
|
20
|
+
### New in 0.7
|
|
21
|
+
|
|
22
|
+
- **Reflex 0.10.0**, and therefore **Python 3.11 or later** (Python 3.10 is no longer supported).
|
|
23
|
+
Reflex 0.10 removed `reflex component build`: stubs are regenerated with `scripts/make_stubs.py`.
|
|
24
|
+
- **Palettes** — `palette=` on every chart, UI component, dashboard and composed component,
|
|
25
|
+
`silverpoint_palette(...)` for a whole section, six presets named after drawing media
|
|
26
|
+
(`silverpoint`, `sanguine`, `sepia`, `iron_gall`, `verdigris`, `indigo`) and `check_palette()`
|
|
27
|
+
against the contrast thresholds of the data model. See [Palettes](#palettes).
|
|
28
|
+
- **Composed components, level A** (native markup): `sp_table` (+ `sort_rows`), `sp_pagination`,
|
|
29
|
+
`sp_breadcrumb`, `sp_avatar` (+ `sp_avatar_group`), `sp_statistic`, `sp_descriptions`,
|
|
30
|
+
`sp_timeline_list`, `sp_collapse` (+ `sp_collapse_item`), `sp_empty`, `sp_result`, `sp_textarea`
|
|
31
|
+
and `sp_input_number`.
|
|
32
|
+
- **Composed components, level B** (overlays on Radix primitives): `sp_modal`, `sp_drawer`,
|
|
33
|
+
`sp_popover`, `sp_tooltip`, `sp_select`, `sp_dropdown_menu` and `sp_toast` (+ `sp_toaster`), with
|
|
34
|
+
`sp_trigger` as their drawn button. See [Composed components](#composed-components).
|
|
35
|
+
- **`sp_timeline`** — Knight Lab TimelineJS drawn in silverpoint: a skin on the ground's colours and
|
|
36
|
+
type, plus the ground's own hand-inked frames and tone tiles on its markers, eras and buttons.
|
|
37
|
+
Optional extra: `pip install "reflex-silverpoint-react[timeline]"`. See [Timeline](#timeline).
|
|
38
|
+
- `sp_surface`, `sp_glyph`: the building blocks, for components of your own.
|
|
39
|
+
|
|
42
40
|
### New in 0.6
|
|
43
41
|
|
|
44
42
|
- **27 new charts**, the second catalog of silverpoint 0.6:
|
|
@@ -87,7 +85,7 @@ stylesheets it needs (`@silverpoint/grounds/styles.css` and the self-hosted EB G
|
|
|
87
85
|
`@silverpoint/fonts/fonts.css`); the UI components also import `@silverpoint/grounds/ui.css`. No
|
|
88
86
|
Tailwind, no CDN.
|
|
89
87
|
|
|
90
|
-
Requires Reflex 0.
|
|
88
|
+
Requires Reflex 0.10.0 or later (React 19) and Python 3.11 or later.
|
|
91
89
|
|
|
92
90
|
## Quickstart
|
|
93
91
|
|
|
@@ -350,6 +348,132 @@ rx.el.form(
|
|
|
350
348
|
- Text inputs controlled from state make a round trip per keystroke; for long text, prefer
|
|
351
349
|
`default_value` and read the value on submit.
|
|
352
350
|
|
|
351
|
+
## Palettes
|
|
352
|
+
|
|
353
|
+
silverpoint never writes a colour into its drawing: every stroke and fill is painted by CSS through
|
|
354
|
+
the ground's `--sp-` custom properties. A palette sets them, so it re-colours without re-rendering.
|
|
355
|
+
|
|
356
|
+
```python
|
|
357
|
+
from reflex_silverpoint_react import PALETTES, Palette, bar_chart, check_palette, silverpoint_palette, sp_button
|
|
358
|
+
|
|
359
|
+
bar_chart(title="Orders", palette="sanguine") # a preset
|
|
360
|
+
sp_button("Save", variant="primary", palette={"ink": "#2C6355"}) # a dict of fields
|
|
361
|
+
bar_chart(title="Orders", palette=State.palette) # a state var holding a dict
|
|
362
|
+
|
|
363
|
+
MINE = Palette(substrate="#F2E8DC", ink="#8A3A24", ink_secondary="#6A4A3A", text="#4A2216")
|
|
364
|
+
assert not check_palette(MINE) # [] when every field meets its contrast threshold
|
|
365
|
+
|
|
366
|
+
silverpoint_palette(dashboard(...), sp_card(...), palette="indigo") # a whole section
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Fields: `substrate`, `ink`, `ink_secondary`, `heighten`, `rule`, `grid`, `text`, `text_muted` and
|
|
370
|
+
`focus` (the UI focus ring). Unset fields keep the ground's own. An element's own `palette` always
|
|
371
|
+
wins over its section's. A palette is **monochrome by design**: tone is built from hatch density
|
|
372
|
+
(Art. 6), so a chart has two inks (`ink` for the main series, `ink_secondary` for the second), never
|
|
373
|
+
a colour per series. `precision` mode and the system's high-contrast modes still apply on top.
|
|
374
|
+
`silverpoint_provider` takes no palette (it renders no element): use `silverpoint_palette`.
|
|
375
|
+
|
|
376
|
+
## Composed components
|
|
377
|
+
|
|
378
|
+
Components built in Reflex on silverpoint's markup contract: `@silverpoint/grounds/ui.css` draws its
|
|
379
|
+
hand-inked frames, hatched tones and heightening on any element that follows it, so these are drawn
|
|
380
|
+
with exactly the same pieces as the `Sp` components. They are **Reflex-only** (silverpoint's React,
|
|
381
|
+
Vue and Angular adapters do not have them) and, unlike the `Sp` components, they do not read
|
|
382
|
+
`silverpoint_provider`: pass `ground`, `substrate`, `mode` and `palette` explicitly.
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
from reflex_silverpoint_react import sort_rows, sp_pagination, sp_table
|
|
386
|
+
|
|
387
|
+
sp_table(
|
|
388
|
+
[
|
|
389
|
+
{"key": "team", "title": "Team", "sortable": True},
|
|
390
|
+
{"key": "load", "title": "Load", "align": "end", "sortable": True},
|
|
391
|
+
],
|
|
392
|
+
State.rows,
|
|
393
|
+
caption="On-call teams",
|
|
394
|
+
sort_key=State.sort_key,
|
|
395
|
+
sort_order=State.sort_order,
|
|
396
|
+
on_sort=State.sort, # receives the key; sort with sort_rows(rows, key, order)
|
|
397
|
+
striped=True,
|
|
398
|
+
)
|
|
399
|
+
sp_pagination(total=240, current=State.page, on_change=State.set_page, show_total=True)
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
| Level A (native) | |
|
|
403
|
+
|---|---|
|
|
404
|
+
| `sp_table` | Card-framed table: small-caps header, tabular figures, hatched striping, sortable headers with `aria-sort` |
|
|
405
|
+
| `sp_pagination` | Previous/next, first/last, a window around the current page (heightened); `on_change(page)` |
|
|
406
|
+
| `sp_breadcrumb` | `<nav>` of links; the last item is the current page |
|
|
407
|
+
| `sp_avatar`, `sp_avatar_group` | Portrait or initials in a drawn round (or square) frame |
|
|
408
|
+
| `sp_statistic` | Small-caps title, large tabular figure, prefix/suffix, trend arrow |
|
|
409
|
+
| `sp_descriptions` | Label–value grid (`<dl>`), optionally card-framed |
|
|
410
|
+
| `sp_timeline_list` | Vertical list: `done` (hatched), `current` (heightened), `pending`, `error` |
|
|
411
|
+
| `sp_collapse`, `sp_collapse_item` | Native `<details>`; `accordion=True` keeps one open |
|
|
412
|
+
| `sp_empty`, `sp_result` | Empty state; outcome with a drawn round mark |
|
|
413
|
+
| `sp_textarea`, `sp_input_number` | On the `SpInput` contract; `on_change` receives the value (text or number) |
|
|
414
|
+
|
|
415
|
+
| Level B (Radix primitives) | |
|
|
416
|
+
|---|---|
|
|
417
|
+
| `sp_modal`, `sp_drawer` | Dialog on a card frame over a hatched backdrop; drawer from any edge |
|
|
418
|
+
| `sp_popover`, `sp_tooltip` | Anchored content; tooltip on hover or keyboard focus |
|
|
419
|
+
| `sp_select` | Single choice with typeahead; the chosen option ticked, the highlighted one heightened |
|
|
420
|
+
| `sp_dropdown_menu` | Commands with shortcuts, separators and labels; `on_select(key)` |
|
|
421
|
+
| `sp_toast`, `sp_toaster` | Notices that stack in a corner; `error`/`warning` are announced assertively |
|
|
422
|
+
|
|
423
|
+
Behaviour (focus trapping, keyboard, dismissal, positioning, ARIA) is Radix's, at the versions
|
|
424
|
+
Reflex already installs. Overlays render in a portal at the end of `<body>`, outside any
|
|
425
|
+
`silverpoint_palette` section, so give them `palette` directly. A string `trigger` becomes
|
|
426
|
+
`sp_trigger(...)`, the drawn button that can forward Radix's props (`sp_button` cannot).
|
|
427
|
+
|
|
428
|
+
```python
|
|
429
|
+
sp_modal(
|
|
430
|
+
rx.el.p("Apply the new ground?"),
|
|
431
|
+
trigger="Open",
|
|
432
|
+
title="Apply changes",
|
|
433
|
+
footer=sp_trigger("Apply", variant="primary", on_click=State.confirm),
|
|
434
|
+
open=State.modal_open,
|
|
435
|
+
on_open_change=State.set_modal_open,
|
|
436
|
+
)
|
|
437
|
+
sp_select(["North", "East", "South", "West"], value=State.region, on_change=State.set_region)
|
|
438
|
+
sp_toaster(sp_toast("Saved", State.text, kind="success", open=State.toast_open, on_open_change=State.set_toast_open))
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+

|
|
442
|
+
|
|
443
|
+
## Timeline
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
pip install "reflex-silverpoint-react[timeline]" # adds reflex-knightlab-timeline
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
```python
|
|
450
|
+
from reflex_silverpoint_react import sp_timeline
|
|
451
|
+
|
|
452
|
+
sp_timeline(
|
|
453
|
+
DATA, # TimelineJS data: title, events, eras (or a TimelineData)
|
|
454
|
+
height=560,
|
|
455
|
+
ground="silverpoint",
|
|
456
|
+
substrate="cream",
|
|
457
|
+
mode="ink",
|
|
458
|
+
palette="sepia",
|
|
459
|
+
inked_frames=True, # the ground's hand-drawn frames and tone tiles
|
|
460
|
+
on_change=State.on_change, # the unique_id of the slide shown
|
|
461
|
+
)
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
It works in two layers. The **skin** replaces TimelineJS's colours, type and rules with the
|
|
465
|
+
ground's `--sp-` properties: substrate, inks, EB Garamond, hairline rules, eras hatched by density,
|
|
466
|
+
the current marker heightened. The **hand** reads the ground's own frame and tone masks from hidden
|
|
467
|
+
probes and lays them on the markers, eras and menubar, so they are drawn with the same pieces as
|
|
468
|
+
the `Sp` components; `inked_frames=False` keeps the skin only, and `precision`, `cyanotype` and
|
|
469
|
+
forced colours fall back to exact rules by themselves. Note that TimelineJS requests its icon font
|
|
470
|
+
from a relative path (`/css/icons/tl-icons.*`); the Reflex dev server answers it with HTML, so the
|
|
471
|
+
browser logs font-decoding warnings. They come from TimelineJS, not from this package.
|
|
472
|
+
|
|
473
|
+

|
|
474
|
+
|
|
475
|
+

|
|
476
|
+
|
|
353
477
|
## Interaction
|
|
354
478
|
|
|
355
479
|
```python
|
|
@@ -411,7 +535,7 @@ The exported SVG carries its own ground colours, so it renders the same outside
|
|
|
411
535
|
## Demo app
|
|
412
536
|
|
|
413
537
|
```bash
|
|
414
|
-
uv venv && uv pip install -e .
|
|
538
|
+
uv venv && uv pip install -e ".[timeline]"
|
|
415
539
|
cd silverpoint_react_demo
|
|
416
540
|
uv run reflex run
|
|
417
541
|
```
|
|
@@ -419,24 +543,45 @@ uv run reflex run
|
|
|
419
543
|
Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 60 charts, ground
|
|
420
544
|
controls, demo datasets vs data from Python state with a re-roll), **Playground** (one chart, every
|
|
421
545
|
rendering choice and the Python that reproduces it), **Interaction** (events, custom readout, a
|
|
422
|
-
volvelle that turns on click, a treemap and a sunburst that drill down together, live
|
|
546
|
+
volvelle that turns on click, a treemap and a sunburst that drill down together, live
|
|
547
|
+
KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
|
|
423
548
|
linked operations dashboard fed from Python state with ground, substrate, mode and column controls, a
|
|
424
549
|
KPI strip, and `dashboard_link` on its own), **UI components** (`/ui`: the components controlled from
|
|
425
550
|
Python state with a native form submit, and the three reference panels of the upstream example apps
|
|
426
551
|
in silverpoint ink, precision and cyanotype), one **reference page per chart** (`/chart/<slug>`) and
|
|
427
|
-
one per UI component (`/ui/<slug>`: every declared state on both grounds, usage and props). The
|
|
552
|
+
one per UI component (`/ui/<slug>`: every declared state on both grounds, usage and props). The
|
|
553
|
+
Gallery and Playground also get a ground control, for `cyanotype`, and a palette control.
|
|
554
|
+
New in 0.7: **More components** (`/components`: the 20 composed components wired to Python, with
|
|
555
|
+
ground, substrate, mode and palette controls and an event log), **Palettes** (`/palettes`: the
|
|
556
|
+
presets, a palette builder with colour pickers and `check_palette`, a coloured section) and
|
|
557
|
+
**Timeline** (`/timeline`: the Knight Lab timeline on every ground, mode and palette).
|
|
428
558
|
|
|
429
559
|

|
|
430
560
|
|
|
431
561
|
## Development
|
|
432
562
|
|
|
433
563
|
```bash
|
|
434
|
-
uv
|
|
564
|
+
uv sync --extra dev
|
|
435
565
|
uv run pytest
|
|
436
566
|
uv run ruff check .
|
|
437
|
-
|
|
567
|
+
# Reflex 0.10 removed `reflex component build`: regenerate the .pyi stubs with the generator
|
|
568
|
+
# Reflex itself uses (plus this package's fixes), then build the sdist and wheel.
|
|
569
|
+
uv run python scripts/make_stubs.py
|
|
570
|
+
uv build
|
|
438
571
|
```
|
|
439
572
|
|
|
573
|
+
Before committing, run the hooks of [`.pre-commit-config.yaml`](.pre-commit-config.yaml) (ruff check
|
|
574
|
+
and format — including the Python blocks of this README — file hygiene and `uv lock --check`):
|
|
575
|
+
|
|
576
|
+
```bash
|
|
577
|
+
pre-commit install
|
|
578
|
+
pre-commit run --all-files
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Changes per version are in [CHANGELOG.md](CHANGELOG.md); the guide for coding agents is
|
|
582
|
+
[AGENTS.md](AGENTS.md). Releases are published to PyPI by pushing a `vX.Y.Z` tag on `main` that
|
|
583
|
+
matches `version` in `pyproject.toml`.
|
|
584
|
+
|
|
440
585
|
## License
|
|
441
586
|
|
|
442
587
|
MIT. silverpoint is MIT; the EB Garamond typeface is under the SIL Open Font License.
|