reflex-silverpoint-react 0.7.0__tar.gz → 0.8.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.7.0 → reflex_silverpoint_react-0.8.0}/PKG-INFO +95 -36
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/README.md +93 -32
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/__init__.py +54 -3
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/assets/trigger.jsx +63 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/base.py +40 -12
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/base.pyi +6 -3
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/catalog.py +12 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/charts.pyi +1 -1
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/composed.py +633 -0
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/composed.pyi +684 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/dashboard.py +5 -3
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/dashboard.pyi +1 -1
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/overlays.py +784 -0
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/overlays.pyi +674 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/palette.py +85 -70
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/surfaces.py +235 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/surfaces.pyi +30 -106
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react/timeline.py +172 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/timeline.pyi +43 -15
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/ui.py +3 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/ui.pyi +1 -1
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react.egg-info/PKG-INFO +95 -36
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react.egg-info/SOURCES.txt +6 -4
- reflex_silverpoint_react-0.8.0/custom_components/reflex_silverpoint_react.egg-info/requires.txt +9 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/pyproject.toml +8 -7
- reflex_silverpoint_react-0.8.0/tests/test_agent_catalog.py +162 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/tests/test_components.py +4 -4
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/tests/test_demo_data.py +23 -0
- reflex_silverpoint_react-0.8.0/tests/test_plugin.py +42 -0
- reflex_silverpoint_react-0.8.0/tests/test_skill.py +170 -0
- reflex_silverpoint_react-0.8.0/tests/test_v07.py +324 -0
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/surface.jsx +0 -219
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/surfaces.css +0 -375
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/timeline.css +0 -225
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/assets/timeline.jsx +0 -64
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/composed.py +0 -702
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/overlays.py +0 -835
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/surfaces.py +0 -329
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react/timeline.py +0 -157
- reflex_silverpoint_react-0.7.0/custom_components/reflex_silverpoint_react.egg-info/requires.txt +0 -11
- reflex_silverpoint_react-0.7.0/tests/test_v07.py +0 -234
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/LICENSE +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/charts.py +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/helpers.py +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react/ui_catalog.py +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react.egg-info/dependency_links.txt +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/custom_components/reflex_silverpoint_react.egg-info/top_level.txt +0 -0
- {reflex_silverpoint_react-0.7.0 → reflex_silverpoint_react-0.8.0}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reflex-silverpoint-react
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: The 60 silverpoint charts, the Dashboard,
|
|
3
|
+
Version: 0.8.0
|
|
4
|
+
Summary: The 60 silverpoint charts, the Dashboard, 38 UI, composed and overlay components, palettes and a Knight Lab timeline (Renaissance silverpoint drawing style) for Reflex, wrapping @silverpoint/react 0.8
|
|
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
|
|
@@ -18,13 +18,11 @@ Description-Content-Type: text/markdown
|
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: reflex>=0.10.0
|
|
20
20
|
Provides-Extra: timeline
|
|
21
|
-
Requires-Dist: reflex-knightlab-timeline>=0.1.2; extra == "timeline"
|
|
22
21
|
Provides-Extra: dev
|
|
23
22
|
Requires-Dist: build; extra == "dev"
|
|
24
23
|
Requires-Dist: twine; extra == "dev"
|
|
25
24
|
Requires-Dist: pytest; extra == "dev"
|
|
26
25
|
Requires-Dist: ruff; extra == "dev"
|
|
27
|
-
Requires-Dist: reflex-knightlab-timeline>=0.1.2; extra == "dev"
|
|
28
26
|
Dynamic: license-file
|
|
29
27
|
|
|
30
28
|
# reflex-silverpoint-react
|
|
@@ -36,17 +34,48 @@ prepared ground, tone built from hatching, and white heightening on the live val
|
|
|
36
34
|
The hand-drawn irregularity lives only in the ornament. The data geometry is exact, and every chart
|
|
37
35
|
has a `precision` mode that turns the inking off.
|
|
38
36
|
|
|
39
|
-
It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) 0.
|
|
37
|
+
It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) **0.8.0** and exposes
|
|
40
38
|
**all 60 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the **17 UI
|
|
41
|
-
components** (buttons, inputs, tabs, cards, alerts…), the
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
components** (buttons, inputs, tabs, cards, alerts…), the **12 composed components** (table,
|
|
40
|
+
pagination, breadcrumb, avatar…), the **7 overlays** and the toaster (modal, drawer, popover,
|
|
41
|
+
tooltip, select, dropdown menu, toast), the **palettes**, the **Knight Lab timeline**, the
|
|
42
|
+
`SilverpointProvider`, both grounds (`silverpoint` and `cyanotype`), the interaction events, custom
|
|
43
|
+
readouts and the imperative handle (SVG export and geometry) as Python.
|
|
44
|
+
|
|
45
|
+
Everything it renders is an npm component of silverpoint, under its parity contract: the same
|
|
46
|
+
markup React, Vue and Angular render.
|
|
47
|
+
|
|
48
|
+
### New in 0.8.0
|
|
49
|
+
|
|
50
|
+
- Wraps **`@silverpoint/react` 0.8.0**. silverpoint 0.8 adds agent access and changes no API this
|
|
51
|
+
package wraps, so the Python builders are unchanged.
|
|
52
|
+
- **Agent access:** the `reflex-silverpoint` skill, a Claude plugin with the hosted silverpoint MCP
|
|
53
|
+
server, and `reflex-catalog.json`, the Reflex catalog silverpoint's agent catalog joins. See
|
|
54
|
+
[Use with AI](#use-with-ai).
|
|
55
|
+
|
|
56
|
+
### New in 0.7.1
|
|
57
|
+
|
|
58
|
+
- Wraps **`@silverpoint/react` 0.7.0** (0.7.0 wrapped 0.6.0). silverpoint 0.7 took this package's
|
|
59
|
+
palettes, composed components, overlays and timeline into the library itself, so they are now the
|
|
60
|
+
npm components, not Reflex-composed copies: same Python builders, the library's markup.
|
|
61
|
+
- **Palettes** are the npm `palette` prop: they merge element → dashboard → provider field by field,
|
|
62
|
+
`silverpoint_provider(palette=...)` works, and `silverpoint_palette(...)` is a provider with a
|
|
63
|
+
palette. `check_palette()` measures the core's nine contrast pairs (the focus ring and the white
|
|
64
|
+
heightening included); `"ironGall"` names the `iron_gall` preset too.
|
|
65
|
+
- **Composed components and overlays read `silverpoint_provider`**, as the `Sp` components do.
|
|
66
|
+
Overlays are a native `<dialog>` and the Popover API (no Radix); they render in place, so a
|
|
67
|
+
section's palette reaches them.
|
|
68
|
+
- **Logical sides**: `side="start"`/`"end"` and `position="bottom-end"`…; `left`/`right` still work
|
|
69
|
+
with a `DeprecationWarning`. `sp_drawer(size=)` is `extent=`, `sp_popover(side_offset=)` is
|
|
70
|
+
`offset=`; `sp_modal` gains `label` and `dismissible`, `sp_result`/`sp_descriptions`
|
|
71
|
+
`heading_level`.
|
|
72
|
+
- `sp_textarea(textarea_id=)` and `sp_input_number(input_id=)` are `id=` (deprecated aliases kept);
|
|
73
|
+
`sp_textarea` has no `on_blur`. `sp_collapse_item(on_toggle=)` receives the new open state (a bool).
|
|
74
|
+
- **`sp_timeline`** is the npm `SpTimeline`: TimelineJS is an npm dependency of that component, so the
|
|
75
|
+
`[timeline]` extra pulls in nothing any more (it is kept so existing installs keep working).
|
|
76
|
+
- `sort_rows()` follows the core's `uiSortRows` order (numbers first, then text by code point).
|
|
77
|
+
|
|
78
|
+
### New in 0.7.0
|
|
50
79
|
|
|
51
80
|
- **Reflex 0.10.0**, and therefore **Python 3.11 or later** (Python 3.10 is no longer supported).
|
|
52
81
|
Reflex 0.10 removed `reflex component build`: stubs are regenerated with `scripts/make_stubs.py`.
|
|
@@ -63,7 +92,7 @@ components** built on silverpoint's own frames and tones (tables, overlays, toas
|
|
|
63
92
|
`sp_trigger` as their drawn button. See [Composed components](#composed-components).
|
|
64
93
|
- **`sp_timeline`** — Knight Lab TimelineJS drawn in silverpoint: a skin on the ground's colours and
|
|
65
94
|
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).
|
|
95
|
+
Optional extra (until 0.7.1): `pip install "reflex-silverpoint-react[timeline]"`. See [Timeline](#timeline).
|
|
67
96
|
- `sp_surface`, `sp_glyph`: the building blocks, for components of your own.
|
|
68
97
|
|
|
69
98
|
### New in 0.6
|
|
@@ -396,19 +425,19 @@ silverpoint_palette(dashboard(...), sp_card(...), palette="indigo") # a whole s
|
|
|
396
425
|
```
|
|
397
426
|
|
|
398
427
|
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.
|
|
400
|
-
wins over its section's. A palette is
|
|
401
|
-
(Art. 6), so a chart has two inks (`ink`
|
|
402
|
-
|
|
403
|
-
|
|
428
|
+
`focus` (the UI focus ring). Unset fields keep the ground's own. Palettes merge field by field,
|
|
429
|
+
element → dashboard → provider, so an element's own `palette` wins over its section's. A palette is
|
|
430
|
+
**monochrome by design**: tone is built from hatch density (Art. 6), so a chart has two inks (`ink`
|
|
431
|
+
for the main series, `ink_secondary` for the second), never a colour per series. `precision` mode and
|
|
432
|
+
the system's high-contrast modes still apply on top. `silverpoint_palette(...)` is
|
|
433
|
+
`silverpoint_provider(palette=...)` around the section.
|
|
404
434
|
|
|
405
435
|
## Composed components
|
|
406
436
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
`silverpoint_provider`: pass `ground`, `substrate`, `mode` and `palette` explicitly.
|
|
437
|
+
silverpoint 0.7's composed components and overlays, the npm components of `@silverpoint/react/ui`:
|
|
438
|
+
native markup drawn by the core with the ground's hand-inked frames, hatched tones and
|
|
439
|
+
heightening, exactly as the `Sp` components are. Like them they read `silverpoint_provider` (and
|
|
440
|
+
the dashboard they sit in); a prop on the component always wins.
|
|
412
441
|
|
|
413
442
|
```python
|
|
414
443
|
from reflex_silverpoint_react import sort_rows, sp_pagination, sp_table
|
|
@@ -428,7 +457,7 @@ sp_table(
|
|
|
428
457
|
sp_pagination(total=240, current=State.page, on_change=State.set_page, show_total=True)
|
|
429
458
|
```
|
|
430
459
|
|
|
431
|
-
|
|
|
460
|
+
| Composed (native markup) | |
|
|
432
461
|
|---|---|
|
|
433
462
|
| `sp_table` | Card-framed table: small-caps header, tabular figures, hatched striping, sortable headers with `aria-sort` |
|
|
434
463
|
| `sp_pagination` | Previous/next, first/last, a window around the current page (heightened); `on_change(page)` |
|
|
@@ -441,7 +470,7 @@ sp_pagination(total=240, current=State.page, on_change=State.set_page, show_tota
|
|
|
441
470
|
| `sp_empty`, `sp_result` | Empty state; outcome with a drawn round mark |
|
|
442
471
|
| `sp_textarea`, `sp_input_number` | On the `SpInput` contract; `on_change` receives the value (text or number) |
|
|
443
472
|
|
|
444
|
-
|
|
|
473
|
+
| Overlays (`<dialog>`, Popover API) | |
|
|
445
474
|
|---|---|
|
|
446
475
|
| `sp_modal`, `sp_drawer` | Dialog on a card frame over a hatched backdrop; drawer from any edge |
|
|
447
476
|
| `sp_popover`, `sp_tooltip` | Anchored content; tooltip on hover or keyboard focus |
|
|
@@ -449,10 +478,15 @@ sp_pagination(total=240, current=State.page, on_change=State.set_page, show_tota
|
|
|
449
478
|
| `sp_dropdown_menu` | Commands with shortcuts, separators and labels; `on_select(key)` |
|
|
450
479
|
| `sp_toast`, `sp_toaster` | Notices that stack in a corner; `error`/`warning` are announced assertively |
|
|
451
480
|
|
|
452
|
-
Behaviour (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
481
|
+
Behaviour is the platform's: `showModal()` for the modal and the drawer (focus stays inside, Escape
|
|
482
|
+
and the backdrop close it unless `dismissible=False`), the Popover API for the rest (light
|
|
483
|
+
dismiss), keyboard and placement from `@silverpoint/core` (APG listbox and menu, typeahead, flip and
|
|
484
|
+
shift). Overlays render in place (the top layer, no portal), so a section's palette reaches them.
|
|
485
|
+
Sides are logical (`start`/`end`) and mirror in right-to-left text. An overlay clones its `trigger`
|
|
486
|
+
with its ARIA and a toggling click, so the trigger must keep the props it is given: a native
|
|
487
|
+
`rx.el.button`, or `sp_trigger(...)`, the drawn button strings become (`sp_button` drops them in
|
|
488
|
+
silverpoint 0.7.0). `sp_trigger` does not read the provider: give it `ground`, `substrate`, `mode`
|
|
489
|
+
and `palette`.
|
|
456
490
|
|
|
457
491
|
```python
|
|
458
492
|
sp_modal(
|
|
@@ -471,15 +505,15 @@ sp_toaster(sp_toast("Saved", State.text, kind="success", open=State.toast_open,
|
|
|
471
505
|
|
|
472
506
|
## Timeline
|
|
473
507
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
508
|
+
The npm `SpTimeline` of `@silverpoint/react/timeline`. TimelineJS (`@knight-lab/timelinejs` 3.9.13)
|
|
509
|
+
is an npm dependency of this component: Reflex installs it when a page uses `sp_timeline`, and no
|
|
510
|
+
Python extra is needed. If it cannot be loaded, the component warns `SP025` and renders `fallback`.
|
|
477
511
|
|
|
478
512
|
```python
|
|
479
513
|
from reflex_silverpoint_react import sp_timeline
|
|
480
514
|
|
|
481
515
|
sp_timeline(
|
|
482
|
-
DATA, # TimelineJS data: title, events, eras (or
|
|
516
|
+
DATA, # TimelineJS data: title, events, eras (or any object with to_dict())
|
|
483
517
|
height=560,
|
|
484
518
|
ground="silverpoint",
|
|
485
519
|
substrate="cream",
|
|
@@ -561,10 +595,35 @@ The exported SVG carries its own ground colours, so it renders the same outside
|
|
|
561
595
|
- Accessors are field names (strings). The JavaScript API also accepts functions; from Python, shape
|
|
562
596
|
your rows instead.
|
|
563
597
|
|
|
598
|
+
## Use with AI
|
|
599
|
+
|
|
600
|
+
An assistant writes better `reflex-silverpoint-react` code with the **`reflex-silverpoint` skill**
|
|
601
|
+
([`skills/reflex-silverpoint/`](skills/reflex-silverpoint/SKILL.md)): the builders and their
|
|
602
|
+
snake_case props, State patterns, event payloads, the provider and palettes, composed components and
|
|
603
|
+
overlays, the dashboard and the timeline. Its tables are generated from the package, and every Python
|
|
604
|
+
example in it is imported and rendered by the tests.
|
|
605
|
+
|
|
606
|
+
In Claude Code, the plugin installs the skill together with the hosted silverpoint MCP server
|
|
607
|
+
(`https://silverpointweb.vercel.app/mcp`), which recommends charts, checks props and draws a chart
|
|
608
|
+
as SVG before you write the code:
|
|
609
|
+
|
|
610
|
+
```text
|
|
611
|
+
/plugin marketplace add ecrespo/reflex-silverpoint-react
|
|
612
|
+
/plugin install reflex-silverpoint@reflex-silverpoint
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
The MCP server alone: `claude mcp add --transport http silverpoint https://silverpointweb.vercel.app/mcp`.
|
|
616
|
+
|
|
617
|
+
[`reflex-catalog.json`](reflex-catalog.json) is this package's catalog for agents: every chart and
|
|
618
|
+
component builder with its props (Python name, JS name and type), the deprecated arguments it still
|
|
619
|
+
accepts, the helpers, the package version and the silverpoint version it wraps. silverpoint's agent
|
|
620
|
+
catalog joins it, so its MCP tools answer with the Reflex names too. `scripts/export_catalog.py`
|
|
621
|
+
writes it, CI fails when it is stale, and each GitHub release carries it.
|
|
622
|
+
|
|
564
623
|
## Demo app
|
|
565
624
|
|
|
566
625
|
```bash
|
|
567
|
-
uv venv && uv pip install -e
|
|
626
|
+
uv venv && uv pip install -e .
|
|
568
627
|
cd silverpoint_react_demo
|
|
569
628
|
uv run reflex run
|
|
570
629
|
```
|
|
@@ -7,17 +7,48 @@ 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.
|
|
10
|
+
It wraps [`@silverpoint/react`](https://www.npmjs.com/package/@silverpoint/react) **0.8.0** and exposes
|
|
11
11
|
**all 60 charts**, the **`Dashboard`** (a laid-out, linkable grid of charts), the **17 UI
|
|
12
|
-
components** (buttons, inputs, tabs, cards, alerts…), the
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
components** (buttons, inputs, tabs, cards, alerts…), the **12 composed components** (table,
|
|
13
|
+
pagination, breadcrumb, avatar…), the **7 overlays** and the toaster (modal, drawer, popover,
|
|
14
|
+
tooltip, select, dropdown menu, toast), the **palettes**, the **Knight Lab timeline**, the
|
|
15
|
+
`SilverpointProvider`, both grounds (`silverpoint` and `cyanotype`), the interaction events, custom
|
|
16
|
+
readouts and the imperative handle (SVG export and geometry) as Python.
|
|
17
|
+
|
|
18
|
+
Everything it renders is an npm component of silverpoint, under its parity contract: the same
|
|
19
|
+
markup React, Vue and Angular render.
|
|
20
|
+
|
|
21
|
+
### New in 0.8.0
|
|
22
|
+
|
|
23
|
+
- Wraps **`@silverpoint/react` 0.8.0**. silverpoint 0.8 adds agent access and changes no API this
|
|
24
|
+
package wraps, so the Python builders are unchanged.
|
|
25
|
+
- **Agent access:** the `reflex-silverpoint` skill, a Claude plugin with the hosted silverpoint MCP
|
|
26
|
+
server, and `reflex-catalog.json`, the Reflex catalog silverpoint's agent catalog joins. See
|
|
27
|
+
[Use with AI](#use-with-ai).
|
|
28
|
+
|
|
29
|
+
### New in 0.7.1
|
|
30
|
+
|
|
31
|
+
- Wraps **`@silverpoint/react` 0.7.0** (0.7.0 wrapped 0.6.0). silverpoint 0.7 took this package's
|
|
32
|
+
palettes, composed components, overlays and timeline into the library itself, so they are now the
|
|
33
|
+
npm components, not Reflex-composed copies: same Python builders, the library's markup.
|
|
34
|
+
- **Palettes** are the npm `palette` prop: they merge element → dashboard → provider field by field,
|
|
35
|
+
`silverpoint_provider(palette=...)` works, and `silverpoint_palette(...)` is a provider with a
|
|
36
|
+
palette. `check_palette()` measures the core's nine contrast pairs (the focus ring and the white
|
|
37
|
+
heightening included); `"ironGall"` names the `iron_gall` preset too.
|
|
38
|
+
- **Composed components and overlays read `silverpoint_provider`**, as the `Sp` components do.
|
|
39
|
+
Overlays are a native `<dialog>` and the Popover API (no Radix); they render in place, so a
|
|
40
|
+
section's palette reaches them.
|
|
41
|
+
- **Logical sides**: `side="start"`/`"end"` and `position="bottom-end"`…; `left`/`right` still work
|
|
42
|
+
with a `DeprecationWarning`. `sp_drawer(size=)` is `extent=`, `sp_popover(side_offset=)` is
|
|
43
|
+
`offset=`; `sp_modal` gains `label` and `dismissible`, `sp_result`/`sp_descriptions`
|
|
44
|
+
`heading_level`.
|
|
45
|
+
- `sp_textarea(textarea_id=)` and `sp_input_number(input_id=)` are `id=` (deprecated aliases kept);
|
|
46
|
+
`sp_textarea` has no `on_blur`. `sp_collapse_item(on_toggle=)` receives the new open state (a bool).
|
|
47
|
+
- **`sp_timeline`** is the npm `SpTimeline`: TimelineJS is an npm dependency of that component, so the
|
|
48
|
+
`[timeline]` extra pulls in nothing any more (it is kept so existing installs keep working).
|
|
49
|
+
- `sort_rows()` follows the core's `uiSortRows` order (numbers first, then text by code point).
|
|
50
|
+
|
|
51
|
+
### New in 0.7.0
|
|
21
52
|
|
|
22
53
|
- **Reflex 0.10.0**, and therefore **Python 3.11 or later** (Python 3.10 is no longer supported).
|
|
23
54
|
Reflex 0.10 removed `reflex component build`: stubs are regenerated with `scripts/make_stubs.py`.
|
|
@@ -34,7 +65,7 @@ components** built on silverpoint's own frames and tones (tables, overlays, toas
|
|
|
34
65
|
`sp_trigger` as their drawn button. See [Composed components](#composed-components).
|
|
35
66
|
- **`sp_timeline`** — Knight Lab TimelineJS drawn in silverpoint: a skin on the ground's colours and
|
|
36
67
|
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).
|
|
68
|
+
Optional extra (until 0.7.1): `pip install "reflex-silverpoint-react[timeline]"`. See [Timeline](#timeline).
|
|
38
69
|
- `sp_surface`, `sp_glyph`: the building blocks, for components of your own.
|
|
39
70
|
|
|
40
71
|
### New in 0.6
|
|
@@ -367,19 +398,19 @@ silverpoint_palette(dashboard(...), sp_card(...), palette="indigo") # a whole s
|
|
|
367
398
|
```
|
|
368
399
|
|
|
369
400
|
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.
|
|
371
|
-
wins over its section's. A palette is
|
|
372
|
-
(Art. 6), so a chart has two inks (`ink`
|
|
373
|
-
|
|
374
|
-
|
|
401
|
+
`focus` (the UI focus ring). Unset fields keep the ground's own. Palettes merge field by field,
|
|
402
|
+
element → dashboard → provider, so an element's own `palette` wins over its section's. A palette is
|
|
403
|
+
**monochrome by design**: tone is built from hatch density (Art. 6), so a chart has two inks (`ink`
|
|
404
|
+
for the main series, `ink_secondary` for the second), never a colour per series. `precision` mode and
|
|
405
|
+
the system's high-contrast modes still apply on top. `silverpoint_palette(...)` is
|
|
406
|
+
`silverpoint_provider(palette=...)` around the section.
|
|
375
407
|
|
|
376
408
|
## Composed components
|
|
377
409
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
`silverpoint_provider`: pass `ground`, `substrate`, `mode` and `palette` explicitly.
|
|
410
|
+
silverpoint 0.7's composed components and overlays, the npm components of `@silverpoint/react/ui`:
|
|
411
|
+
native markup drawn by the core with the ground's hand-inked frames, hatched tones and
|
|
412
|
+
heightening, exactly as the `Sp` components are. Like them they read `silverpoint_provider` (and
|
|
413
|
+
the dashboard they sit in); a prop on the component always wins.
|
|
383
414
|
|
|
384
415
|
```python
|
|
385
416
|
from reflex_silverpoint_react import sort_rows, sp_pagination, sp_table
|
|
@@ -399,7 +430,7 @@ sp_table(
|
|
|
399
430
|
sp_pagination(total=240, current=State.page, on_change=State.set_page, show_total=True)
|
|
400
431
|
```
|
|
401
432
|
|
|
402
|
-
|
|
|
433
|
+
| Composed (native markup) | |
|
|
403
434
|
|---|---|
|
|
404
435
|
| `sp_table` | Card-framed table: small-caps header, tabular figures, hatched striping, sortable headers with `aria-sort` |
|
|
405
436
|
| `sp_pagination` | Previous/next, first/last, a window around the current page (heightened); `on_change(page)` |
|
|
@@ -412,7 +443,7 @@ sp_pagination(total=240, current=State.page, on_change=State.set_page, show_tota
|
|
|
412
443
|
| `sp_empty`, `sp_result` | Empty state; outcome with a drawn round mark |
|
|
413
444
|
| `sp_textarea`, `sp_input_number` | On the `SpInput` contract; `on_change` receives the value (text or number) |
|
|
414
445
|
|
|
415
|
-
|
|
|
446
|
+
| Overlays (`<dialog>`, Popover API) | |
|
|
416
447
|
|---|---|
|
|
417
448
|
| `sp_modal`, `sp_drawer` | Dialog on a card frame over a hatched backdrop; drawer from any edge |
|
|
418
449
|
| `sp_popover`, `sp_tooltip` | Anchored content; tooltip on hover or keyboard focus |
|
|
@@ -420,10 +451,15 @@ sp_pagination(total=240, current=State.page, on_change=State.set_page, show_tota
|
|
|
420
451
|
| `sp_dropdown_menu` | Commands with shortcuts, separators and labels; `on_select(key)` |
|
|
421
452
|
| `sp_toast`, `sp_toaster` | Notices that stack in a corner; `error`/`warning` are announced assertively |
|
|
422
453
|
|
|
423
|
-
Behaviour (
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
454
|
+
Behaviour is the platform's: `showModal()` for the modal and the drawer (focus stays inside, Escape
|
|
455
|
+
and the backdrop close it unless `dismissible=False`), the Popover API for the rest (light
|
|
456
|
+
dismiss), keyboard and placement from `@silverpoint/core` (APG listbox and menu, typeahead, flip and
|
|
457
|
+
shift). Overlays render in place (the top layer, no portal), so a section's palette reaches them.
|
|
458
|
+
Sides are logical (`start`/`end`) and mirror in right-to-left text. An overlay clones its `trigger`
|
|
459
|
+
with its ARIA and a toggling click, so the trigger must keep the props it is given: a native
|
|
460
|
+
`rx.el.button`, or `sp_trigger(...)`, the drawn button strings become (`sp_button` drops them in
|
|
461
|
+
silverpoint 0.7.0). `sp_trigger` does not read the provider: give it `ground`, `substrate`, `mode`
|
|
462
|
+
and `palette`.
|
|
427
463
|
|
|
428
464
|
```python
|
|
429
465
|
sp_modal(
|
|
@@ -442,15 +478,15 @@ sp_toaster(sp_toast("Saved", State.text, kind="success", open=State.toast_open,
|
|
|
442
478
|
|
|
443
479
|
## Timeline
|
|
444
480
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
481
|
+
The npm `SpTimeline` of `@silverpoint/react/timeline`. TimelineJS (`@knight-lab/timelinejs` 3.9.13)
|
|
482
|
+
is an npm dependency of this component: Reflex installs it when a page uses `sp_timeline`, and no
|
|
483
|
+
Python extra is needed. If it cannot be loaded, the component warns `SP025` and renders `fallback`.
|
|
448
484
|
|
|
449
485
|
```python
|
|
450
486
|
from reflex_silverpoint_react import sp_timeline
|
|
451
487
|
|
|
452
488
|
sp_timeline(
|
|
453
|
-
DATA, # TimelineJS data: title, events, eras (or
|
|
489
|
+
DATA, # TimelineJS data: title, events, eras (or any object with to_dict())
|
|
454
490
|
height=560,
|
|
455
491
|
ground="silverpoint",
|
|
456
492
|
substrate="cream",
|
|
@@ -532,10 +568,35 @@ The exported SVG carries its own ground colours, so it renders the same outside
|
|
|
532
568
|
- Accessors are field names (strings). The JavaScript API also accepts functions; from Python, shape
|
|
533
569
|
your rows instead.
|
|
534
570
|
|
|
571
|
+
## Use with AI
|
|
572
|
+
|
|
573
|
+
An assistant writes better `reflex-silverpoint-react` code with the **`reflex-silverpoint` skill**
|
|
574
|
+
([`skills/reflex-silverpoint/`](skills/reflex-silverpoint/SKILL.md)): the builders and their
|
|
575
|
+
snake_case props, State patterns, event payloads, the provider and palettes, composed components and
|
|
576
|
+
overlays, the dashboard and the timeline. Its tables are generated from the package, and every Python
|
|
577
|
+
example in it is imported and rendered by the tests.
|
|
578
|
+
|
|
579
|
+
In Claude Code, the plugin installs the skill together with the hosted silverpoint MCP server
|
|
580
|
+
(`https://silverpointweb.vercel.app/mcp`), which recommends charts, checks props and draws a chart
|
|
581
|
+
as SVG before you write the code:
|
|
582
|
+
|
|
583
|
+
```text
|
|
584
|
+
/plugin marketplace add ecrespo/reflex-silverpoint-react
|
|
585
|
+
/plugin install reflex-silverpoint@reflex-silverpoint
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
The MCP server alone: `claude mcp add --transport http silverpoint https://silverpointweb.vercel.app/mcp`.
|
|
589
|
+
|
|
590
|
+
[`reflex-catalog.json`](reflex-catalog.json) is this package's catalog for agents: every chart and
|
|
591
|
+
component builder with its props (Python name, JS name and type), the deprecated arguments it still
|
|
592
|
+
accepts, the helpers, the package version and the silverpoint version it wraps. silverpoint's agent
|
|
593
|
+
catalog joins it, so its MCP tools answer with the Reflex names too. `scripts/export_catalog.py`
|
|
594
|
+
writes it, CI fails when it is stale, and each GitHub release carries it.
|
|
595
|
+
|
|
535
596
|
## Demo app
|
|
536
597
|
|
|
537
598
|
```bash
|
|
538
|
-
uv venv && uv pip install -e
|
|
599
|
+
uv venv && uv pip install -e .
|
|
539
600
|
cd silverpoint_react_demo
|
|
540
601
|
uv run reflex run
|
|
541
602
|
```
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""reflex-silverpoint-react: silverpoint charts and UI components for Reflex.
|
|
2
2
|
|
|
3
3
|
Charts and interface components drawn in the manner of a Renaissance silverpoint drawing,
|
|
4
|
-
wrapping ``@silverpoint/react
|
|
4
|
+
wrapping ``@silverpoint/react`` 0.8.0: the 60 charts, the dashboard, the 38 UI, composed and overlay
|
|
5
|
+
components, the palettes and the Knight Lab timeline.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from .base import (
|
|
@@ -11,6 +12,7 @@ from .base import (
|
|
|
11
12
|
GroundName,
|
|
12
13
|
SilverpointChart,
|
|
13
14
|
SilverpointProvider,
|
|
15
|
+
silverpoint_palette,
|
|
14
16
|
silverpoint_provider,
|
|
15
17
|
)
|
|
16
18
|
from .catalog import CHARTS, COMMON_PROPS, FAMILIES, ChartInfo, PropDoc, chart_by_name, chart_by_slug
|
|
@@ -138,6 +140,18 @@ from .charts import (
|
|
|
138
140
|
wind_rose,
|
|
139
141
|
)
|
|
140
142
|
from .composed import (
|
|
143
|
+
SpAvatar,
|
|
144
|
+
SpAvatarGroup,
|
|
145
|
+
SpBreadcrumb,
|
|
146
|
+
SpCollapse,
|
|
147
|
+
SpCollapseItem,
|
|
148
|
+
SpDescriptions,
|
|
149
|
+
SpEmpty,
|
|
150
|
+
SpResult,
|
|
151
|
+
SpStatistic,
|
|
152
|
+
SpTable,
|
|
153
|
+
SpTextarea,
|
|
154
|
+
SpTimelineList,
|
|
141
155
|
sort_rows,
|
|
142
156
|
sp_avatar,
|
|
143
157
|
sp_avatar_group,
|
|
@@ -165,6 +179,15 @@ from .dashboard import (
|
|
|
165
179
|
)
|
|
166
180
|
from .helpers import chart_ref, download_svg, get_geometry, get_svg, tooltip_template
|
|
167
181
|
from .overlays import (
|
|
182
|
+
SpDrawer,
|
|
183
|
+
SpDropdownMenu,
|
|
184
|
+
SpModal,
|
|
185
|
+
SpPopover,
|
|
186
|
+
SpSelect,
|
|
187
|
+
SpToast,
|
|
188
|
+
SpToaster,
|
|
189
|
+
SpTooltip,
|
|
190
|
+
SpTrigger,
|
|
168
191
|
sp_drawer,
|
|
169
192
|
sp_dropdown_menu,
|
|
170
193
|
sp_modal,
|
|
@@ -176,13 +199,15 @@ from .overlays import (
|
|
|
176
199
|
sp_trigger,
|
|
177
200
|
)
|
|
178
201
|
from .palette import (
|
|
202
|
+
PALETTE_JS_FIELDS,
|
|
203
|
+
PALETTE_PAIRS,
|
|
179
204
|
PALETTE_PROPERTIES,
|
|
180
205
|
PALETTES,
|
|
181
206
|
Palette,
|
|
182
207
|
check_palette,
|
|
183
208
|
contrast_ratio,
|
|
184
209
|
palette_css,
|
|
185
|
-
|
|
210
|
+
palette_prop,
|
|
186
211
|
)
|
|
187
212
|
from .surfaces import (
|
|
188
213
|
SpGlyph,
|
|
@@ -194,7 +219,7 @@ from .surfaces import (
|
|
|
194
219
|
sp_pagination,
|
|
195
220
|
sp_surface,
|
|
196
221
|
)
|
|
197
|
-
from .timeline import sp_timeline, timeline_available
|
|
222
|
+
from .timeline import TIMELINEJS_VERSION, SpTimeline, sp_timeline, timeline_available
|
|
198
223
|
from .ui import (
|
|
199
224
|
SILVERPOINT_UI_STYLESHEET,
|
|
200
225
|
SilverpointUi,
|
|
@@ -254,11 +279,14 @@ __all__ = [
|
|
|
254
279
|
"DASHBOARD_DEFAULTS",
|
|
255
280
|
"FAMILIES",
|
|
256
281
|
"PALETTES",
|
|
282
|
+
"PALETTE_JS_FIELDS",
|
|
283
|
+
"PALETTE_PAIRS",
|
|
257
284
|
"PALETTE_PROPERTIES",
|
|
258
285
|
"SILVERPOINT_LIBRARY",
|
|
259
286
|
"SILVERPOINT_STYLESHEETS",
|
|
260
287
|
"SILVERPOINT_UI_STYLESHEET",
|
|
261
288
|
"SILVERPOINT_VERSION",
|
|
289
|
+
"TIMELINEJS_VERSION",
|
|
262
290
|
"UI_COMMON_PROPS",
|
|
263
291
|
"UI_COMPONENTS",
|
|
264
292
|
"UI_DEMOS",
|
|
@@ -321,27 +349,49 @@ __all__ = [
|
|
|
321
349
|
"SilverpointUi",
|
|
322
350
|
"SlopeChart",
|
|
323
351
|
"SpAlert",
|
|
352
|
+
"SpAvatar",
|
|
353
|
+
"SpAvatarGroup",
|
|
324
354
|
"SpBadge",
|
|
355
|
+
"SpBreadcrumb",
|
|
325
356
|
"SpButton",
|
|
326
357
|
"SpCard",
|
|
327
358
|
"SpCheckbox",
|
|
359
|
+
"SpCollapse",
|
|
360
|
+
"SpCollapseItem",
|
|
361
|
+
"SpDescriptions",
|
|
328
362
|
"SpDivider",
|
|
363
|
+
"SpDrawer",
|
|
364
|
+
"SpDropdownMenu",
|
|
365
|
+
"SpEmpty",
|
|
329
366
|
"SpGlyph",
|
|
330
367
|
"SpInput",
|
|
331
368
|
"SpInputNumber",
|
|
369
|
+
"SpModal",
|
|
332
370
|
"SpPagination",
|
|
371
|
+
"SpPopover",
|
|
333
372
|
"SpProgress",
|
|
334
373
|
"SpRadioGroup",
|
|
335
374
|
"SpRate",
|
|
375
|
+
"SpResult",
|
|
336
376
|
"SpSegmented",
|
|
377
|
+
"SpSelect",
|
|
337
378
|
"SpSkeleton",
|
|
338
379
|
"SpSlider",
|
|
380
|
+
"SpStatistic",
|
|
339
381
|
"SpSteps",
|
|
340
382
|
"SpSurface",
|
|
341
383
|
"SpSwitch",
|
|
342
384
|
"SpTabPanel",
|
|
385
|
+
"SpTable",
|
|
343
386
|
"SpTabs",
|
|
344
387
|
"SpTag",
|
|
388
|
+
"SpTextarea",
|
|
389
|
+
"SpTimeline",
|
|
390
|
+
"SpTimelineList",
|
|
391
|
+
"SpToast",
|
|
392
|
+
"SpToaster",
|
|
393
|
+
"SpTooltip",
|
|
394
|
+
"SpTrigger",
|
|
345
395
|
"SparklineRows",
|
|
346
396
|
"SquarifiedTreemap",
|
|
347
397
|
"StackedBarChart",
|
|
@@ -405,6 +455,7 @@ __all__ = [
|
|
|
405
455
|
"network_node",
|
|
406
456
|
"orbit_chart",
|
|
407
457
|
"palette_css",
|
|
458
|
+
"palette_prop",
|
|
408
459
|
"parallel_coordinates_chart",
|
|
409
460
|
"polar_bar_chart",
|
|
410
461
|
"polar_line_chart",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* reflex-silverpoint-react — sp_trigger: a native <button> drawn as SpButton, that keeps every prop.
|
|
2
|
+
*
|
|
3
|
+
* An overlay of @silverpoint/react clones its trigger with aria-haspopup, aria-expanded,
|
|
4
|
+
* aria-controls, onPointerDown and onClick (useTrigger, REQ-500). SpButton 0.7.0 keeps only its own
|
|
5
|
+
* props, so those would be lost on it; this button renders the very tree @silverpoint/core's
|
|
6
|
+
* uiButtonView builds (resolveUi resolves ground, substrate, mode, size, frame variant and palette)
|
|
7
|
+
* and adds everything else it is given to the native element.
|
|
8
|
+
*/
|
|
9
|
+
const SP_TRIGGER_ATTRS = { class: "className", for: "htmlFor", readonly: "readOnly", tabindex: "tabIndex" };
|
|
10
|
+
|
|
11
|
+
function spTriggerStyle(text) {
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const declaration of (text || "").split(";")) {
|
|
14
|
+
const colon = declaration.indexOf(":");
|
|
15
|
+
if (colon > 0) out[declaration.slice(0, colon).trim()] = declaration.slice(colon + 1).trim();
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function spTriggerNode(node, content, extra) {
|
|
21
|
+
if ("text" in node) return node.text;
|
|
22
|
+
if ("slot" in node) return node.slot === "content" ? content : null;
|
|
23
|
+
const props = {};
|
|
24
|
+
for (const [name, value] of Object.entries(node.attrs)) {
|
|
25
|
+
if (value === undefined) continue;
|
|
26
|
+
props[SP_TRIGGER_ATTRS[name] || name] = name === "style" ? spTriggerStyle(value) : value;
|
|
27
|
+
}
|
|
28
|
+
if (extra) {
|
|
29
|
+
const { style, ...rest } = extra;
|
|
30
|
+
Object.assign(props, rest);
|
|
31
|
+
if (style) props.style = { ...(props.style || {}), ...style };
|
|
32
|
+
}
|
|
33
|
+
return createElement(node.tag, props, ...node.children.map((child) => spTriggerNode(child, content)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function useSpTriggerForced() {
|
|
37
|
+
const [forced, setForced] = useState(false);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (typeof matchMedia !== "function") return undefined;
|
|
40
|
+
const query = matchMedia(FORCED_PRECISION_QUERY);
|
|
41
|
+
const update = () => setForced(query.matches);
|
|
42
|
+
update();
|
|
43
|
+
query.addEventListener?.("change", update);
|
|
44
|
+
return () => query.removeEventListener?.("change", update);
|
|
45
|
+
}, []);
|
|
46
|
+
return forced;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const SilverpointTrigger = forwardRef(function SilverpointTrigger(
|
|
50
|
+
{ ground, substrate, mode, size, seed, palette, variant, chevron, disabled, label, children, className, id, ...rest },
|
|
51
|
+
ref,
|
|
52
|
+
) {
|
|
53
|
+
const forcedPrecision = useSpTriggerForced();
|
|
54
|
+
const props = { ground, substrate, mode, size, seed, palette, variant, disabled, label, className, id, type: "button" };
|
|
55
|
+
const resolved = resolveUi(props, { forcedPrecision });
|
|
56
|
+
const text = typeof children === "string" || typeof children === "number" ? String(children) : children == null ? undefined : "·";
|
|
57
|
+
const view = uiButtonView(props, resolved, { text });
|
|
58
|
+
// The chevron sits beside the label, as SpButton's own danger cross does.
|
|
59
|
+
const tree = chevron
|
|
60
|
+
? { ...view, children: [...view.children, { tag: "svg", attrs: { part: "sp-mark", "data-glyph": "chevronDown", viewBox: "0 0 16 16", "aria-hidden": "true" }, children: [{ tag: "path", attrs: { d: UI_GLYPHS.chevronDown }, children: [] }] }] }
|
|
61
|
+
: view;
|
|
62
|
+
return spTriggerNode(tree, children, { ...rest, ref });
|
|
63
|
+
});
|