reflex-silverpoint-react 0.2.0__tar.gz → 0.6.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 (27) hide show
  1. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/PKG-INFO +173 -13
  2. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/README.md +170 -10
  3. reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/__init__.py +403 -0
  4. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/base.py +8 -7
  5. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/base.pyi +6 -6
  6. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/catalog.py +468 -1
  7. reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/charts.py +1283 -0
  8. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/charts.pyi +3636 -66
  9. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/dashboard.pyi +2 -2
  10. reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/ui.py +573 -0
  11. reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/ui.pyi +1687 -0
  12. reflex_silverpoint_react-0.6.0/custom_components/reflex_silverpoint_react/ui_catalog.py +330 -0
  13. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react.egg-info/PKG-INFO +173 -13
  14. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react.egg-info/SOURCES.txt +5 -1
  15. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/pyproject.toml +3 -3
  16. reflex_silverpoint_react-0.6.0/tests/test_components.py +332 -0
  17. reflex_silverpoint_react-0.6.0/tests/test_demo_data.py +85 -0
  18. reflex_silverpoint_react-0.2.0/custom_components/reflex_silverpoint_react/__init__.py +0 -192
  19. reflex_silverpoint_react-0.2.0/custom_components/reflex_silverpoint_react/charts.py +0 -645
  20. reflex_silverpoint_react-0.2.0/tests/test_components.py +0 -141
  21. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/LICENSE +0 -0
  22. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/dashboard.py +0 -0
  23. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react/helpers.py +0 -0
  24. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react.egg-info/dependency_links.txt +0 -0
  25. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react.egg-info/requires.txt +0 -0
  26. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/custom_components/reflex_silverpoint_react.egg-info/top_level.txt +0 -0
  27. {reflex_silverpoint_react-0.2.0 → reflex_silverpoint_react-0.6.0}/setup.cfg +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex-silverpoint-react
3
- Version: 0.2.0
4
- Summary: The 33 silverpoint charts and the linked Dashboard (Renaissance silverpoint drawing style) for Reflex, wrapping @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
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
11
+ Keywords: reflex,reflex-custom-components,charts,silverpoint,data-visualization,svg,ui-components
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Programming Language :: Python :: 3
@@ -33,10 +33,36 @@ prepared ground, tone built from hatching, and white heightening on the live val
33
33
  The hand-drawn irregularity lives only in the ornament. The data geometry is exact, and every chart
34
34
  has a `precision` mode that turns the inking off.
35
35
 
36
- It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) 0.2.0 and exposes
37
- **all 33 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the
38
- `SilverpointProvider`, both grounds (`silverpoint` and `cyanotype`), the interaction events, custom
39
- readouts and the imperative handle (SVG export and geometry) as Python.
36
+ It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) 0.6.0 and exposes
37
+ **all 60 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the **17 UI
38
+ components** (buttons, inputs, tabs, cards, alerts…), the `SilverpointProvider`, both grounds
39
+ (`silverpoint` and `cyanotype`), the interaction events, custom readouts and the imperative handle
40
+ (SVG export and geometry) as Python.
41
+
42
+ ### New in 0.6
43
+
44
+ - **27 new charts**, the second catalog of silverpoint 0.6:
45
+ - distributions & comparisons: `histogram_chart`, `ecdf_chart`, `box_plot_chart`, `violin_chart`,
46
+ `ridgeline_chart`, `beeswarm_chart`, `lollipop_chart`, `dumbbell_chart`, `slope_chart`,
47
+ `bump_chart`, `error_bar_chart`, `interval_chart`, `diverging_bar_chart`, `connected_scatter_chart`;
48
+ - hierarchies & dimensions: `waffle_chart`, `marimekko_chart`, `squarified_treemap`,
49
+ `sunburst_chart`, `tree_chart`, `parallel_coordinates_chart`, `polar_line_chart`,
50
+ `polar_scatter_chart`;
51
+ - fields & networks: `density_bin_chart`, `contour_chart`, `delaunay_chart`, `vector_field_chart`,
52
+ `network_chart` (with the `network_node` helper).
53
+ - **Drill-down** on `squarified_treemap` and `sunburst_chart`: `root_id` plus the `on_root_change`
54
+ event. See [Drill-down](#drill-down).
55
+
56
+ ### New in 0.3
57
+
58
+ - **17 UI components**, drawn as the charts are: `sp_button`, `sp_input`, `sp_checkbox`,
59
+ `sp_switch`, `sp_radio_group`, `sp_slider`, `sp_rate`, `sp_segmented`, `sp_tabs` (with
60
+ `sp_tab_panel`), `sp_steps`, `sp_card`, `sp_tag`, `sp_badge`, `sp_divider`, `sp_progress`,
61
+ `sp_alert` and `sp_skeleton`. Native controls underneath, controlled from Python. See
62
+ [UI components](#ui-components).
63
+ - `UI_COMPONENTS` and `UI_DEMOS`: the catalog's 17 components, their 45 reference states, and
64
+ `ui_demo(slug, state)` to render any of them.
65
+ - `substrate="prussian"` is accepted everywhere (the `cyanotype` ground's substrate).
40
66
 
41
67
  ### New in 0.2
42
68
 
@@ -58,7 +84,8 @@ uv add reflex-silverpoint-react
58
84
  Nothing else to do on the JavaScript side: Reflex installs `@silverpoint/react`,
59
85
  `@silverpoint/core`, `@silverpoint/grounds` and `@silverpoint/fonts`, and every chart imports the two
60
86
  stylesheets it needs (`@silverpoint/grounds/styles.css` and the self-hosted EB Garamond of
61
- `@silverpoint/fonts/fonts.css`). No Tailwind, no CDN.
87
+ `@silverpoint/fonts/fonts.css`); the UI components also import `@silverpoint/grounds/ui.css`. No
88
+ Tailwind, no CDN.
62
89
 
63
90
  Requires Reflex 0.9.12 or later (React 19).
64
91
 
@@ -96,7 +123,7 @@ Props are the React props in `snake_case`: `xKey` → `x_key`, `hatchFill` → `
96
123
  `footerRight` → `footer_right`, `centerLabel` → `center_label`, and so on. `data` and every prop can
97
124
  be a Reflex state var.
98
125
 
99
- ## The 33 charts
126
+ ## The 60 charts
100
127
 
101
128
  | Family | Charts |
102
129
  |---|---|
@@ -106,11 +133,60 @@ be a Reflex state var.
106
133
  | Points & grids | `scatter_chart`, `bubble_chart`, `heatmap_chart`, `treemap_chart`, `activity_grid` |
107
134
  | Flows | `sankey_chart`, `chord_ring` |
108
135
  | Radial | `donut_chart`, `radar_chart`, `polar_bar_chart`, `radial_arc_group`, `radial_rings`, `gauge_arc`, `meter_chart`, `coxcomb_chart`, `wind_rose`, `volvelle_chart`, `orbit_chart` |
136
+ | Distributions & comparisons (0.6) | `histogram_chart`, `ecdf_chart`, `box_plot_chart`, `violin_chart`, `ridgeline_chart`, `beeswarm_chart`, `lollipop_chart`, `dumbbell_chart`, `slope_chart`, `bump_chart`, `error_bar_chart`, `interval_chart`, `diverging_bar_chart`, `connected_scatter_chart` |
137
+ | Hierarchies & dimensions (0.6) | `waffle_chart`, `marimekko_chart`, `squarified_treemap`, `sunburst_chart`, `tree_chart`, `parallel_coordinates_chart`, `polar_line_chart`, `polar_scatter_chart` |
138
+ | Fields & networks (0.6) | `density_bin_chart`, `contour_chart`, `delaunay_chart`, `vector_field_chart`, `network_chart` |
109
139
 
110
140
  Every factory has a class of the same name in `PascalCase` (`LineChart`, `WindRose`…).
111
141
  `reflex_silverpoint_react.CHARTS` is the whole catalog with each chart's family and the reference of
112
142
  its own props (`COMMON_PROPS` holds the shared ones), handy for galleries and documentation.
113
143
 
144
+ With your own `data`, `ridgeline_chart` needs `group_key`, `diverging_bar_chart` needs `levels` (the
145
+ level columns, most negative first) and `parallel_coordinates_chart` needs `dimensions` (the columns,
146
+ in axis order). The demo datasets ignore them.
147
+
148
+ `network_chart` lays its nodes out by force, the same on the server and in every browser for a given
149
+ `seed`. Pass `nodes` to name and group them, built with `network_node`. A node with an `x` and a `y`
150
+ is drawn there, and when every node has both no layout runs:
151
+
152
+ ```python
153
+ from reflex_silverpoint_react import network_chart, network_node
154
+
155
+ network_chart(
156
+ data=State.links, # [{"source": "a", "target": "b", "weight": 3}, ...]
157
+ source_key="source",
158
+ target_key="target",
159
+ value_key="weight",
160
+ nodes=[network_node("a", label="Archive", group="storage"), network_node("b", label="Billing")],
161
+ )
162
+ ```
163
+
164
+ ### Drill-down
165
+
166
+ `squarified_treemap` and `sunburst_chart` drill down under your control. The chart keeps no root of
167
+ its own: a click, Enter or Space on a node sends its id to `on_root_change` (the parent's id from the
168
+ centre or the frame, `None` at the top), and you pass it back as `root_id`:
169
+
170
+ ```python
171
+ class Budget(rx.State):
172
+ root: str | None = None
173
+
174
+ @rx.event
175
+ def drill(self, node_id: str | None):
176
+ self.root = node_id
177
+
178
+
179
+ squarified_treemap(
180
+ data=rows, # one row per node: {"id": ..., "parent": ... or None, "name": ..., "amount": ...}
181
+ id_key="id",
182
+ parent_key="parent",
183
+ label_key="name",
184
+ value_key="amount",
185
+ root_id=Budget.root,
186
+ on_root_change=Budget.drill,
187
+ )
188
+ ```
189
+
114
190
  ## Props every chart shares
115
191
 
116
192
  | Prop | Default | |
@@ -192,6 +268,88 @@ dashboard(
192
268
  can also pass a plain dict.
193
269
  - The layout values and the charts' props can be state vars.
194
270
 
271
+ ## UI components
272
+
273
+ New in silverpoint 0.3: seventeen interface components with frames hand-drawn by each ground's own
274
+ inker and tone laid as hatching (`silverpoint`) or as the weight of an exact white line
275
+ (`cyanotype`). Each is a native control underneath (a `<button>`, an `<input>`, a `<fieldset>` of
276
+ radios), so forms submit natively and the keyboard follows the WAI-ARIA patterns. They are imported
277
+ from `@silverpoint/react/ui`.
278
+
279
+ ![The UI components in the demo app](docs/ui-components.png)
280
+
281
+ | Group | Components |
282
+ |---|---|
283
+ | Actions | `sp_button` |
284
+ | Data entry | `sp_input`, `sp_checkbox`, `sp_radio_group`, `sp_switch`, `sp_slider`, `sp_rate`, `sp_segmented` |
285
+ | Navigation | `sp_tabs` + `sp_tab_panel`, `sp_steps` |
286
+ | Data display | `sp_card`, `sp_tag`, `sp_badge`, `sp_divider` |
287
+ | Feedback | `sp_progress`, `sp_alert`, `sp_skeleton` |
288
+
289
+ ```python
290
+ from reflex_silverpoint_react import sp_button, sp_input, sp_switch, sp_tab_panel, sp_tabs, ui_item
291
+
292
+
293
+ class State(rx.State):
294
+ city: str = "Caracas"
295
+ precision: bool = False
296
+ view: str = "traffic"
297
+
298
+ @rx.event
299
+ def set_city(self, value: str): # on_change gets the value, not an event
300
+ self.city = value
301
+
302
+ @rx.event
303
+ def set_precision(self, value: bool):
304
+ self.precision = value
305
+
306
+ @rx.event
307
+ def set_view(self, value: str):
308
+ self.view = value
309
+
310
+ @rx.event
311
+ def save(self, form: dict):
312
+ print(form) # {"city": "Caracas", ...}: the native inputs submit under their name
313
+
314
+
315
+ rx.el.form(
316
+ sp_input(
317
+ label="City",
318
+ name="city",
319
+ value=State.city,
320
+ on_change=State.set_city,
321
+ invalid=State.city == "",
322
+ message="Required: pick a city",
323
+ ),
324
+ sp_switch(label="Precision", checked=State.precision, on_change=State.set_precision),
325
+ sp_tabs(
326
+ sp_tab_panel(line_chart(...), value="traffic"),
327
+ sp_tab_panel(bar_chart(...), value="errors"),
328
+ items=[ui_item("traffic", "Traffic"), ui_item("errors", "Errors")],
329
+ value=State.view,
330
+ on_change=State.set_view,
331
+ ),
332
+ sp_button("Save", type="submit", variant="primary"),
333
+ on_submit=State.save,
334
+ )
335
+ ```
336
+
337
+ - **Shared props**: `id`, `ground`, `substrate`, `mode`, `seed`, `size` (`sm`/`md`/`lg`) and
338
+ `class_name`. Like charts, they fall back to the dashboard, then to `silverpoint_provider`.
339
+ - **Values**: value components are controlled (`value=` / `checked=` with `on_change`) or
340
+ uncontrolled (`default_value=` / `default_checked=`). `on_change` receives the new value itself (a
341
+ string, a bool or a number), never a DOM event.
342
+ - **Items**: `ui_item(key, label, disabled=False)` for tabs, segmented and radio groups;
343
+ `step_item(key, title, description=None, status=None)` for steps.
344
+ - **Slots**: children are a button's or tag's text, a card's or alert's body; `sp_card` also takes
345
+ `extra` and `footer`, and `sp_input` takes `prefix` and `suffix` (components or text).
346
+ - **Close events**: `sp_tag(closable=True, on_close=...)` and `sp_alert(closable=True, on_close=...)`.
347
+ - `UI_COMPONENTS` is the catalog (group, declared states, props reference) and `UI_DEMOS` the 45
348
+ reference states upstream ships; `ui_demo("radio-group", "selected", ground="cyanotype")` renders
349
+ one, uncontrolled.
350
+ - Text inputs controlled from state make a round trip per keystroke; for long text, prefer
351
+ `default_value` and read the value on submit.
352
+
195
353
  ## Interaction
196
354
 
197
355
  ```python
@@ -258,13 +416,15 @@ cd silverpoint_react_demo
258
416
  uv run reflex run
259
417
  ```
260
418
 
261
- Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 33 charts, ground
419
+ Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 60 charts, ground
262
420
  controls, demo datasets vs data from Python state with a re-roll), **Playground** (one chart, every
263
421
  rendering choice and the Python that reproduces it), **Interaction** (events, custom readout, a
264
- volvelle that turns on click, live KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
422
+ volvelle that turns on click, a treemap and a sunburst that drill down together, live KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
265
423
  linked operations dashboard fed from Python state with ground, substrate, mode and column controls, a
266
- KPI strip, and `dashboard_link` on its own) and one **reference page per chart** (`/chart/<slug>`)
267
- with its props. The Gallery and Playground also get a ground control, for `cyanotype`.
424
+ KPI strip, and `dashboard_link` on its own), **UI components** (`/ui`: the components controlled from
425
+ Python state with a native form submit, and the three reference panels of the upstream example apps
426
+ 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 Gallery and Playground also get a ground control, for `cyanotype`.
268
428
 
269
429
  ![Interaction page](docs/interaction.png)
270
430
 
@@ -7,10 +7,36 @@ prepared ground, tone built from hatching, and white heightening on the live val
7
7
  The hand-drawn irregularity lives only in the ornament. The data geometry is exact, and every chart
8
8
  has a `precision` mode that turns the inking off.
9
9
 
10
- It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) 0.2.0 and exposes
11
- **all 33 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the
12
- `SilverpointProvider`, both grounds (`silverpoint` and `cyanotype`), the interaction events, custom
13
- readouts and the imperative handle (SVG export and geometry) as Python.
10
+ It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) 0.6.0 and exposes
11
+ **all 60 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the **17 UI
12
+ components** (buttons, inputs, tabs, cards, alerts…), the `SilverpointProvider`, both grounds
13
+ (`silverpoint` and `cyanotype`), the interaction events, custom readouts and the imperative handle
14
+ (SVG export and geometry) as Python.
15
+
16
+ ### New in 0.6
17
+
18
+ - **27 new charts**, the second catalog of silverpoint 0.6:
19
+ - distributions & comparisons: `histogram_chart`, `ecdf_chart`, `box_plot_chart`, `violin_chart`,
20
+ `ridgeline_chart`, `beeswarm_chart`, `lollipop_chart`, `dumbbell_chart`, `slope_chart`,
21
+ `bump_chart`, `error_bar_chart`, `interval_chart`, `diverging_bar_chart`, `connected_scatter_chart`;
22
+ - hierarchies & dimensions: `waffle_chart`, `marimekko_chart`, `squarified_treemap`,
23
+ `sunburst_chart`, `tree_chart`, `parallel_coordinates_chart`, `polar_line_chart`,
24
+ `polar_scatter_chart`;
25
+ - fields & networks: `density_bin_chart`, `contour_chart`, `delaunay_chart`, `vector_field_chart`,
26
+ `network_chart` (with the `network_node` helper).
27
+ - **Drill-down** on `squarified_treemap` and `sunburst_chart`: `root_id` plus the `on_root_change`
28
+ event. See [Drill-down](#drill-down).
29
+
30
+ ### New in 0.3
31
+
32
+ - **17 UI components**, drawn as the charts are: `sp_button`, `sp_input`, `sp_checkbox`,
33
+ `sp_switch`, `sp_radio_group`, `sp_slider`, `sp_rate`, `sp_segmented`, `sp_tabs` (with
34
+ `sp_tab_panel`), `sp_steps`, `sp_card`, `sp_tag`, `sp_badge`, `sp_divider`, `sp_progress`,
35
+ `sp_alert` and `sp_skeleton`. Native controls underneath, controlled from Python. See
36
+ [UI components](#ui-components).
37
+ - `UI_COMPONENTS` and `UI_DEMOS`: the catalog's 17 components, their 45 reference states, and
38
+ `ui_demo(slug, state)` to render any of them.
39
+ - `substrate="prussian"` is accepted everywhere (the `cyanotype` ground's substrate).
14
40
 
15
41
  ### New in 0.2
16
42
 
@@ -32,7 +58,8 @@ uv add reflex-silverpoint-react
32
58
  Nothing else to do on the JavaScript side: Reflex installs `@silverpoint/react`,
33
59
  `@silverpoint/core`, `@silverpoint/grounds` and `@silverpoint/fonts`, and every chart imports the two
34
60
  stylesheets it needs (`@silverpoint/grounds/styles.css` and the self-hosted EB Garamond of
35
- `@silverpoint/fonts/fonts.css`). No Tailwind, no CDN.
61
+ `@silverpoint/fonts/fonts.css`); the UI components also import `@silverpoint/grounds/ui.css`. No
62
+ Tailwind, no CDN.
36
63
 
37
64
  Requires Reflex 0.9.12 or later (React 19).
38
65
 
@@ -70,7 +97,7 @@ Props are the React props in `snake_case`: `xKey` → `x_key`, `hatchFill` → `
70
97
  `footerRight` → `footer_right`, `centerLabel` → `center_label`, and so on. `data` and every prop can
71
98
  be a Reflex state var.
72
99
 
73
- ## The 33 charts
100
+ ## The 60 charts
74
101
 
75
102
  | Family | Charts |
76
103
  |---|---|
@@ -80,11 +107,60 @@ be a Reflex state var.
80
107
  | Points & grids | `scatter_chart`, `bubble_chart`, `heatmap_chart`, `treemap_chart`, `activity_grid` |
81
108
  | Flows | `sankey_chart`, `chord_ring` |
82
109
  | Radial | `donut_chart`, `radar_chart`, `polar_bar_chart`, `radial_arc_group`, `radial_rings`, `gauge_arc`, `meter_chart`, `coxcomb_chart`, `wind_rose`, `volvelle_chart`, `orbit_chart` |
110
+ | Distributions & comparisons (0.6) | `histogram_chart`, `ecdf_chart`, `box_plot_chart`, `violin_chart`, `ridgeline_chart`, `beeswarm_chart`, `lollipop_chart`, `dumbbell_chart`, `slope_chart`, `bump_chart`, `error_bar_chart`, `interval_chart`, `diverging_bar_chart`, `connected_scatter_chart` |
111
+ | Hierarchies & dimensions (0.6) | `waffle_chart`, `marimekko_chart`, `squarified_treemap`, `sunburst_chart`, `tree_chart`, `parallel_coordinates_chart`, `polar_line_chart`, `polar_scatter_chart` |
112
+ | Fields & networks (0.6) | `density_bin_chart`, `contour_chart`, `delaunay_chart`, `vector_field_chart`, `network_chart` |
83
113
 
84
114
  Every factory has a class of the same name in `PascalCase` (`LineChart`, `WindRose`…).
85
115
  `reflex_silverpoint_react.CHARTS` is the whole catalog with each chart's family and the reference of
86
116
  its own props (`COMMON_PROPS` holds the shared ones), handy for galleries and documentation.
87
117
 
118
+ With your own `data`, `ridgeline_chart` needs `group_key`, `diverging_bar_chart` needs `levels` (the
119
+ level columns, most negative first) and `parallel_coordinates_chart` needs `dimensions` (the columns,
120
+ in axis order). The demo datasets ignore them.
121
+
122
+ `network_chart` lays its nodes out by force, the same on the server and in every browser for a given
123
+ `seed`. Pass `nodes` to name and group them, built with `network_node`. A node with an `x` and a `y`
124
+ is drawn there, and when every node has both no layout runs:
125
+
126
+ ```python
127
+ from reflex_silverpoint_react import network_chart, network_node
128
+
129
+ network_chart(
130
+ data=State.links, # [{"source": "a", "target": "b", "weight": 3}, ...]
131
+ source_key="source",
132
+ target_key="target",
133
+ value_key="weight",
134
+ nodes=[network_node("a", label="Archive", group="storage"), network_node("b", label="Billing")],
135
+ )
136
+ ```
137
+
138
+ ### Drill-down
139
+
140
+ `squarified_treemap` and `sunburst_chart` drill down under your control. The chart keeps no root of
141
+ its own: a click, Enter or Space on a node sends its id to `on_root_change` (the parent's id from the
142
+ centre or the frame, `None` at the top), and you pass it back as `root_id`:
143
+
144
+ ```python
145
+ class Budget(rx.State):
146
+ root: str | None = None
147
+
148
+ @rx.event
149
+ def drill(self, node_id: str | None):
150
+ self.root = node_id
151
+
152
+
153
+ squarified_treemap(
154
+ data=rows, # one row per node: {"id": ..., "parent": ... or None, "name": ..., "amount": ...}
155
+ id_key="id",
156
+ parent_key="parent",
157
+ label_key="name",
158
+ value_key="amount",
159
+ root_id=Budget.root,
160
+ on_root_change=Budget.drill,
161
+ )
162
+ ```
163
+
88
164
  ## Props every chart shares
89
165
 
90
166
  | Prop | Default | |
@@ -166,6 +242,88 @@ dashboard(
166
242
  can also pass a plain dict.
167
243
  - The layout values and the charts' props can be state vars.
168
244
 
245
+ ## UI components
246
+
247
+ New in silverpoint 0.3: seventeen interface components with frames hand-drawn by each ground's own
248
+ inker and tone laid as hatching (`silverpoint`) or as the weight of an exact white line
249
+ (`cyanotype`). Each is a native control underneath (a `<button>`, an `<input>`, a `<fieldset>` of
250
+ radios), so forms submit natively and the keyboard follows the WAI-ARIA patterns. They are imported
251
+ from `@silverpoint/react/ui`.
252
+
253
+ ![The UI components in the demo app](docs/ui-components.png)
254
+
255
+ | Group | Components |
256
+ |---|---|
257
+ | Actions | `sp_button` |
258
+ | Data entry | `sp_input`, `sp_checkbox`, `sp_radio_group`, `sp_switch`, `sp_slider`, `sp_rate`, `sp_segmented` |
259
+ | Navigation | `sp_tabs` + `sp_tab_panel`, `sp_steps` |
260
+ | Data display | `sp_card`, `sp_tag`, `sp_badge`, `sp_divider` |
261
+ | Feedback | `sp_progress`, `sp_alert`, `sp_skeleton` |
262
+
263
+ ```python
264
+ from reflex_silverpoint_react import sp_button, sp_input, sp_switch, sp_tab_panel, sp_tabs, ui_item
265
+
266
+
267
+ class State(rx.State):
268
+ city: str = "Caracas"
269
+ precision: bool = False
270
+ view: str = "traffic"
271
+
272
+ @rx.event
273
+ def set_city(self, value: str): # on_change gets the value, not an event
274
+ self.city = value
275
+
276
+ @rx.event
277
+ def set_precision(self, value: bool):
278
+ self.precision = value
279
+
280
+ @rx.event
281
+ def set_view(self, value: str):
282
+ self.view = value
283
+
284
+ @rx.event
285
+ def save(self, form: dict):
286
+ print(form) # {"city": "Caracas", ...}: the native inputs submit under their name
287
+
288
+
289
+ rx.el.form(
290
+ sp_input(
291
+ label="City",
292
+ name="city",
293
+ value=State.city,
294
+ on_change=State.set_city,
295
+ invalid=State.city == "",
296
+ message="Required: pick a city",
297
+ ),
298
+ sp_switch(label="Precision", checked=State.precision, on_change=State.set_precision),
299
+ sp_tabs(
300
+ sp_tab_panel(line_chart(...), value="traffic"),
301
+ sp_tab_panel(bar_chart(...), value="errors"),
302
+ items=[ui_item("traffic", "Traffic"), ui_item("errors", "Errors")],
303
+ value=State.view,
304
+ on_change=State.set_view,
305
+ ),
306
+ sp_button("Save", type="submit", variant="primary"),
307
+ on_submit=State.save,
308
+ )
309
+ ```
310
+
311
+ - **Shared props**: `id`, `ground`, `substrate`, `mode`, `seed`, `size` (`sm`/`md`/`lg`) and
312
+ `class_name`. Like charts, they fall back to the dashboard, then to `silverpoint_provider`.
313
+ - **Values**: value components are controlled (`value=` / `checked=` with `on_change`) or
314
+ uncontrolled (`default_value=` / `default_checked=`). `on_change` receives the new value itself (a
315
+ string, a bool or a number), never a DOM event.
316
+ - **Items**: `ui_item(key, label, disabled=False)` for tabs, segmented and radio groups;
317
+ `step_item(key, title, description=None, status=None)` for steps.
318
+ - **Slots**: children are a button's or tag's text, a card's or alert's body; `sp_card` also takes
319
+ `extra` and `footer`, and `sp_input` takes `prefix` and `suffix` (components or text).
320
+ - **Close events**: `sp_tag(closable=True, on_close=...)` and `sp_alert(closable=True, on_close=...)`.
321
+ - `UI_COMPONENTS` is the catalog (group, declared states, props reference) and `UI_DEMOS` the 45
322
+ reference states upstream ships; `ui_demo("radio-group", "selected", ground="cyanotype")` renders
323
+ one, uncontrolled.
324
+ - Text inputs controlled from state make a round trip per keystroke; for long text, prefer
325
+ `default_value` and read the value on submit.
326
+
169
327
  ## Interaction
170
328
 
171
329
  ```python
@@ -232,13 +390,15 @@ cd silverpoint_react_demo
232
390
  uv run reflex run
233
391
  ```
234
392
 
235
- Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 33 charts, ground
393
+ Pages: **Start** (quickstart, provider, ink vs precision), **Gallery** (the 60 charts, ground
236
394
  controls, demo datasets vs data from Python state with a re-roll), **Playground** (one chart, every
237
395
  rendering choice and the Python that reproduces it), **Interaction** (events, custom readout, a
238
- volvelle that turns on click, live KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
396
+ volvelle that turns on click, a treemap and a sunburst that drill down together, live KPI/gauge/meter, SVG and geometry export), **Dashboard** (a
239
397
  linked operations dashboard fed from Python state with ground, substrate, mode and column controls, a
240
- KPI strip, and `dashboard_link` on its own) and one **reference page per chart** (`/chart/<slug>`)
241
- with its props. The Gallery and Playground also get a ground control, for `cyanotype`.
398
+ KPI strip, and `dashboard_link` on its own), **UI components** (`/ui`: the components controlled from
399
+ Python state with a native form submit, and the three reference panels of the upstream example apps
400
+ in silverpoint ink, precision and cyanotype), one **reference page per chart** (`/chart/<slug>`) and
401
+ one per UI component (`/ui/<slug>`: every declared state on both grounds, usage and props). The Gallery and Playground also get a ground control, for `cyanotype`.
242
402
 
243
403
  ![Interaction page](docs/interaction.png)
244
404