Skip to main content

reflex-silverpoint-react

A Reflex custom component for silverpoint: charts drawn in the manner of a Renaissance silverpoint drawing, with a fine silver line on a prepared ground, tone built from hatching, and white heightening on the live value.

The hand-drawn irregularity lives only in the ornament. The data geometry is exact, and every chart has a precision mode that turns the inking off.

It wraps @silverpoint/react 0.7.0 and exposes all 60 charts, the Dashboard (a laid-out, linkable grid of charts), the 17 UI components (buttons, inputs, tabs, cards, alerts…), the 12 composed components (table, pagination, breadcrumb, avatar…), the 7 overlays and the toaster (modal, drawer, popover, tooltip, select, dropdown menu, toast), the palettes, the Knight Lab timeline, the SilverpointProvider, both grounds (silverpoint and cyanotype), the interaction events, custom readouts and the imperative handle (SVG export and geometry) as Python.

Everything it renders is an npm component of silverpoint, under its parity contract: the same markup React, Vue and Angular render.

New in 0.7.1

  • Wraps @silverpoint/react 0.7.0 (0.7.0 wrapped 0.6.0). silverpoint 0.7 took this package's palettes, composed components, overlays and timeline into the library itself, so they are now the npm components, not Reflex-composed copies: same Python builders, the library's markup.
  • Palettes are the npm palette prop: they merge element → dashboard → provider field by field, silverpoint_provider(palette=...) works, and silverpoint_palette(...) is a provider with a palette. check_palette() measures the core's nine contrast pairs (the focus ring and the white heightening included); "ironGall" names the iron_gall preset too.
  • Composed components and overlays read silverpoint_provider, as the Sp components do. Overlays are a native <dialog> and the Popover API (no Radix); they render in place, so a section's palette reaches them.
  • Logical sides: side="start"/"end" and position="bottom-end"…; left/right still work with a DeprecationWarning. sp_drawer(size=) is extent=, sp_popover(side_offset=) is offset=; sp_modal gains label and dismissible, sp_result/sp_descriptions heading_level.
  • sp_textarea(textarea_id=) and sp_input_number(input_id=) are id= (deprecated aliases kept); sp_textarea has no on_blur. sp_collapse_item(on_toggle=) receives the new open state (a bool).
  • sp_timeline is the npm SpTimeline: TimelineJS is an npm dependency of that component, so the [timeline] extra pulls in nothing any more (it is kept so existing installs keep working).
  • sort_rows() follows the core's uiSortRows order (numbers first, then text by code point).

New in 0.7.0

  • Reflex 0.10.0, and therefore Python 3.11 or later (Python 3.10 is no longer supported). Reflex 0.10 removed reflex component build: stubs are regenerated with scripts/make_stubs.py.
  • Palettes — palette= on every chart, UI component, dashboard and composed component, silverpoint_palette(...) for a whole section, six presets named after drawing media (silverpoint, sanguine, sepia, iron_gall, verdigris, indigo) and check_palette() against the contrast thresholds of the data model. See Palettes.
  • Composed components, level A (native markup): sp_table (+ sort_rows), sp_pagination, sp_breadcrumb, sp_avatar (+ sp_avatar_group), sp_statistic, sp_descriptions, sp_timeline_list, sp_collapse (+ sp_collapse_item), sp_empty, sp_result, sp_textarea and sp_input_number.
  • Composed components, level B (overlays on Radix primitives): sp_modal, sp_drawer, sp_popover, sp_tooltip, sp_select, sp_dropdown_menu and sp_toast (+ sp_toaster), with sp_trigger as their drawn button. See Composed components.
  • sp_timeline — Knight Lab TimelineJS drawn in silverpoint: a skin on the ground's colours and type, plus the ground's own hand-inked frames and tone tiles on its markers, eras and buttons. Optional extra (until 0.7.1): pip install "reflex-silverpoint-react[timeline]". See Timeline.
  • sp_surface, sp_glyph: the building blocks, for components of your own.

New in 0.6

  • 27 new charts, the second catalog of silverpoint 0.6:
    • distributions & comparisons: 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;
    • hierarchies & dimensions: waffle_chart, marimekko_chart, squarified_treemap, sunburst_chart, tree_chart, parallel_coordinates_chart, polar_line_chart, polar_scatter_chart;
    • fields & networks: density_bin_chart, contour_chart, delaunay_chart, vector_field_chart, network_chart (with the network_node helper).
  • Drill-down on squarified_treemap and sunburst_chart: root_id plus the on_root_change event. See Drill-down.

New in 0.3

  • 17 UI components, drawn as the charts are: sp_button, sp_input, sp_checkbox, sp_switch, sp_radio_group, sp_slider, sp_rate, sp_segmented, sp_tabs (with sp_tab_panel), sp_steps, sp_card, sp_tag, sp_badge, sp_divider, sp_progress, sp_alert and sp_skeleton. Native controls underneath, controlled from Python. See UI components.
  • UI_COMPONENTS and UI_DEMOS: the catalog's 17 components, their 45 reference states, and ui_demo(slug, state) to render any of them.
  • substrate="prussian" is accepted everywhere (the cyanotype ground's substrate).

New in 0.2

  • dashboard, dashboard_cell and dashboard_link: a titled grid of cards laid out from a data-only layout, charts sized to their cells, and charts linked on a datum field.
  • The cyanotype ground: a white line on Prussian blue. Tone is the weight of an exact line, so nothing is hatched. Use ground="cyanotype" on a chart, the provider or a dashboard.

The gallery of the demo app

Installation

pip install reflex-silverpoint-react
# or
uv add reflex-silverpoint-react

Nothing else to do on the JavaScript side: Reflex installs @silverpoint/react, @silverpoint/core, @silverpoint/grounds and @silverpoint/fonts, and every chart imports the two stylesheets it needs (@silverpoint/grounds/styles.css and the self-hosted EB Garamond of @silverpoint/fonts/fonts.css); the UI components also import @silverpoint/grounds/ui.css. No Tailwind, no CDN.

Requires Reflex 0.10.0 or later (React 19) and Python 3.11 or later.

Quickstart

import reflex as rx
from reflex_silverpoint_react import line_chart

DATA = [
    {"hour": "00", "hits": 18},
    {"hour": "04", "hits": 11},
    {"hour": "08", "hits": 42},
    {"hour": "12", "hits": 64},
    {"hour": "16", "hits": 57},
    {"hour": "20", "hits": 30},
]


def index() -> rx.Component:
    return rx.box(
        line_chart(data=DATA, x_key="hour", value_key="hits", title="Hits per hour"),
        width="480px",
    )


app = rx.App()
app.add_page(index)

The chart takes the width of its container; height is the height of the drawing area (160 px by default). Omit data and a chart draws its own demo dataset.

Props are the React props in snake_case: xKey → x_key, hatchFill → hatch_fill, footerRight → footer_right, centerLabel → center_label, and so on. data and every prop can be a Reflex state var.

The 60 charts

Family Charts
Lines line_chart, step_chart, sparkline_rows, kpi_card
Bars bar_chart, stacked_bar_chart, composed_chart, waterfall_chart, funnel_chart, bullet_chart, pyramid_chart, candlestick_chart
Areas area_chart, range_band_chart, stream_chart
Points & grids scatter_chart, bubble_chart, heatmap_chart, treemap_chart, activity_grid
Flows sankey_chart, chord_ring
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
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
Hierarchies & dimensions (0.6) waffle_chart, marimekko_chart, squarified_treemap, sunburst_chart, tree_chart, parallel_coordinates_chart, polar_line_chart, polar_scatter_chart
Fields & networks (0.6) density_bin_chart, contour_chart, delaunay_chart, vector_field_chart, network_chart

Every factory has a class of the same name in PascalCase (LineChart, WindRose…). reflex_silverpoint_react.CHARTS is the whole catalog with each chart's family and the reference of its own props (COMMON_PROPS holds the shared ones), handy for galleries and documentation.

With your own data, ridgeline_chart needs group_key, diverging_bar_chart needs levels (the level columns, most negative first) and parallel_coordinates_chart needs dimensions (the columns, in axis order). The demo datasets ignore them.

network_chart lays its nodes out by force, the same on the server and in every browser for a given seed. Pass nodes to name and group them, built with network_node. A node with an x and a y is drawn there, and when every node has both no layout runs:

from reflex_silverpoint_react import network_chart, network_node

network_chart(
    data=State.links,  # [{"source": "a", "target": "b", "weight": 3}, ...]
    source_key="source",
    target_key="target",
    value_key="weight",
    nodes=[network_node("a", label="Archive", group="storage"), network_node("b", label="Billing")],
)

Drill-down

squarified_treemap and sunburst_chart drill down under your control. The chart keeps no root of its own: a click, Enter or Space on a node sends its id to on_root_change (the parent's id from the centre or the frame, None at the top), and you pass it back as root_id:

class Budget(rx.State):
    root: str | None = None

    @rx.event
    def drill(self, node_id: str | None):
        self.root = node_id


squarified_treemap(
    data=rows,  # one row per node: {"id": ..., "parent": ... or None, "name": ..., "amount": ...}
    id_key="id",
    parent_key="parent",
    label_key="name",
    value_key="amount",
    root_id=Budget.root,
    on_root_change=Budget.drill,
)

Props every chart shares

Prop Default
data demo dataset The rows to draw: a list of dicts. Without it, the accessor props (*_key, keys, names) are ignored.
ground / substrate / mode "silverpoint" / "cream" / "ink" Style. Grounds: silverpoint and cyanotype. The silverpoint substrates are cream, green, blue and ochre; cyanotype has one, prussian, whatever substrate a chart names. mode="precision" turns the inking off.
seed, id derived, stable The hand drawing is deterministic: same props, same strokes.
height, width 160, container width Size of the drawing area in px.
chrome "card" "bare" draws only the plot.
title, badge, value, unit, footer_left, footer_right — The card's text.
label, description, data_table from title, —, "hidden" Accessibility.
locale, number_format environment Number formatting (number_format is a dict of Intl.NumberFormatOptions).
hatch_fill "tile" "per-shape" gives richer hatching at a much greater weight.
tooltip built-in readout A custom readout; see tooltip_template.
on_active_change, on_select — Events; see below.

One ground for the whole app

from reflex_silverpoint_react import bar_chart, donut_chart, silverpoint_provider

silverpoint_provider(
    bar_chart(data=sales, x_key="month", value_key="units", title="Units sold", unit="units"),
    donut_chart(data=channels, name_key="channel", value_key="share", title="Sales by channel", center_label="%"),
    ground="silverpoint",
    substrate="green",
    locale="en-GB",
)

A prop on a chart always wins over the provider. The provider's props can be state vars, so one select can re-ground a whole dashboard.

Dashboards

dashboard lays charts out in a titled grid. The layout is plain data: the number of columns, each cell's column and row spans (per breakpoint if you like), the row height and the gap. The breakpoints are the dashboard's own width: sm below 640 px, md up to 1024 px, and lg above. The defaults are 1, 2 and 4 columns. Each chart is sized to its cell, and ground, substrate, mode and locale pass to every chart inside.

from reflex_silverpoint_react import (
    bar_chart,
    dashboard,
    dashboard_cell,
    dashboard_cell_layout,
    dashboard_layout,
    kpi_card,
    line_chart,
)

dashboard(
    dashboard_cell(kpi_card(title="Revenue", metric="thousands", delta=6.4), cell="revenue"),
    dashboard_cell(line_chart(data=State.ops, x_key="hour", value_key="hits", title="Traffic"), cell="traffic"),
    dashboard_cell(bar_chart(data=State.ops, x_key="hour", value_key="errors", title="Errors"), cell="errors"),
    id="ops",  # required
    title="Operations",  # or label=... for no visible heading
    description="Service health over the last day.",
    layout=dashboard_layout(
        ["revenue", dashboard_cell_layout("traffic", col_span={"md": 2, "lg": 3}, row_span=2), "errors"],
        columns={"sm": 1, "md": 2, "lg": 4},
        row_height=240,
        gap=16,
    ),
    link="hour",  # link the charts on the rows' "hour" field
    on_link_change=State.on_link,  # {"key": "hour", "value": "18"}, or None when it clears
)
  • dashboard_cell(chart, cell="id") puts a chart in a named layout cell. Children without one follow the named cells, in source order, with span 1.
  • With link, pointing at or focusing an item in one chart marks every item in the other charts that has the same value in that field. dashboard_link(..., link="hour") does the same for charts you lay out yourself, outside a dashboard grid.
  • heading_level (2-6) sets the title's heading level. ssr_width is the width the grid is laid out for before the browser measures it.
  • dashboard_layout and dashboard_cell_layout write the camelCase keys the component reads. You can also pass a plain dict.
  • The layout values and the charts' props can be state vars.

UI components

New in silverpoint 0.3: seventeen interface components with frames hand-drawn by each ground's own inker and tone laid as hatching (silverpoint) or as the weight of an exact white line (cyanotype). Each is a native control underneath (a <button>, an <input>, a <fieldset> of radios), so forms submit natively and the keyboard follows the WAI-ARIA patterns. They are imported from @silverpoint/react/ui.

The UI components in the demo app

Group Components
Actions sp_button
Data entry sp_input, sp_checkbox, sp_radio_group, sp_switch, sp_slider, sp_rate, sp_segmented
Navigation sp_tabs + sp_tab_panel, sp_steps
Data display sp_card, sp_tag, sp_badge, sp_divider
Feedback sp_progress, sp_alert, sp_skeleton
from reflex_silverpoint_react import sp_button, sp_input, sp_switch, sp_tab_panel, sp_tabs, ui_item


class State(rx.State):
    city: str = "Caracas"
    precision: bool = False
    view: str = "traffic"

    @rx.event
    def set_city(self, value: str):  # on_change gets the value, not an event
        self.city = value

    @rx.event
    def set_precision(self, value: bool):
        self.precision = value

    @rx.event
    def set_view(self, value: str):
        self.view = value

    @rx.event
    def save(self, form: dict):
        print(form)  # {"city": "Caracas", ...}: the native inputs submit under their name


rx.el.form(
    sp_input(
        label="City",
        name="city",
        value=State.city,
        on_change=State.set_city,
        invalid=State.city == "",
        message="Required: pick a city",
    ),
    sp_switch(label="Precision", checked=State.precision, on_change=State.set_precision),
    sp_tabs(
        sp_tab_panel(line_chart(...), value="traffic"),
        sp_tab_panel(bar_chart(...), value="errors"),
        items=[ui_item("traffic", "Traffic"), ui_item("errors", "Errors")],
        value=State.view,
        on_change=State.set_view,
    ),
    sp_button("Save", type="submit", variant="primary"),
    on_submit=State.save,
)
  • Shared props: id, ground, substrate, mode, seed, size (sm/md/lg) and class_name. Like charts, they fall back to the dashboard, then to silverpoint_provider.
  • Values: value components are controlled (value= / checked= with on_change) or uncontrolled (default_value= / default_checked=). on_change receives the new value itself (a string, a bool or a number), never a DOM event.
  • Items: ui_item(key, label, disabled=False) for tabs, segmented and radio groups; step_item(key, title, description=None, status=None) for steps.
  • Slots: children are a button's or tag's text, a card's or alert's body; sp_card also takes extra and footer, and sp_input takes prefix and suffix (components or text).
  • Close events: sp_tag(closable=True, on_close=...) and sp_alert(closable=True, on_close=...).
  • UI_COMPONENTS is the catalog (group, declared states, props reference) and UI_DEMOS the 45 reference states upstream ships; ui_demo("radio-group", "selected", ground="cyanotype") renders one, uncontrolled.
  • Text inputs controlled from state make a round trip per keystroke; for long text, prefer default_value and read the value on submit.

Palettes

silverpoint never writes a colour into its drawing: every stroke and fill is painted by CSS through the ground's --sp- custom properties. A palette sets them, so it re-colours without re-rendering.

from reflex_silverpoint_react import PALETTES, Palette, bar_chart, check_palette, silverpoint_palette, sp_button

bar_chart(title="Orders", palette="sanguine")  # a preset
sp_button("Save", variant="primary", palette={"ink": "#2C6355"})  # a dict of fields
bar_chart(title="Orders", palette=State.palette)  # a state var holding a dict

MINE = Palette(substrate="#F2E8DC", ink="#8A3A24", ink_secondary="#6A4A3A", text="#4A2216")
assert not check_palette(MINE)  # [] when every field meets its contrast threshold

silverpoint_palette(dashboard(...), sp_card(...), palette="indigo")  # a whole section

Fields: substrate, ink, ink_secondary, heighten, rule, grid, text, text_muted and focus (the UI focus ring). Unset fields keep the ground's own. Palettes merge field by field, element → dashboard → provider, so an element's own palette wins over its section's. A palette is monochrome by design: tone is built from hatch density (Art. 6), so a chart has two inks (ink for the main series, ink_secondary for the second), never a colour per series. precision mode and the system's high-contrast modes still apply on top. silverpoint_palette(...) is silverpoint_provider(palette=...) around the section.

Composed components

silverpoint 0.7's composed components and overlays, the npm components of @silverpoint/react/ui: native markup drawn by the core with the ground's hand-inked frames, hatched tones and heightening, exactly as the Sp components are. Like them they read silverpoint_provider (and the dashboard they sit in); a prop on the component always wins.

from reflex_silverpoint_react import sort_rows, sp_pagination, sp_table

sp_table(
    [
        {"key": "team", "title": "Team", "sortable": True},
        {"key": "load", "title": "Load", "align": "end", "sortable": True},
    ],
    State.rows,
    caption="On-call teams",
    sort_key=State.sort_key,
    sort_order=State.sort_order,
    on_sort=State.sort,  # receives the key; sort with sort_rows(rows, key, order)
    striped=True,
)
sp_pagination(total=240, current=State.page, on_change=State.set_page, show_total=True)
Composed (native markup)
sp_table Card-framed table: small-caps header, tabular figures, hatched striping, sortable headers with aria-sort
sp_pagination Previous/next, first/last, a window around the current page (heightened); on_change(page)
sp_breadcrumb <nav> of links; the last item is the current page
sp_avatar, sp_avatar_group Portrait or initials in a drawn round (or square) frame
sp_statistic Small-caps title, large tabular figure, prefix/suffix, trend arrow
sp_descriptions Label–value grid (<dl>), optionally card-framed
sp_timeline_list Vertical list: done (hatched), current (heightened), pending, error
sp_collapse, sp_collapse_item Native <details>; accordion=True keeps one open
sp_empty, sp_result Empty state; outcome with a drawn round mark
sp_textarea, sp_input_number On the SpInput contract; on_change receives the value (text or number)
Overlays (<dialog>, Popover API)
sp_modal, sp_drawer Dialog on a card frame over a hatched backdrop; drawer from any edge
sp_popover, sp_tooltip Anchored content; tooltip on hover or keyboard focus
sp_select Single choice with typeahead; the chosen option ticked, the highlighted one heightened
sp_dropdown_menu Commands with shortcuts, separators and labels; on_select(key)
sp_toast, sp_toaster Notices that stack in a corner; error/warning are announced assertively

Behaviour is the platform's: showModal() for the modal and the drawer (focus stays inside, Escape and the backdrop close it unless dismissible=False), the Popover API for the rest (light dismiss), keyboard and placement from @silverpoint/core (APG listbox and menu, typeahead, flip and shift). Overlays render in place (the top layer, no portal), so a section's palette reaches them. Sides are logical (start/end) and mirror in right-to-left text. An overlay clones its trigger with its ARIA and a toggling click, so the trigger must keep the props it is given: a native rx.el.button, or sp_trigger(...), the drawn button strings become (sp_button drops them in silverpoint 0.7.0). sp_trigger does not read the provider: give it ground, substrate, mode and palette.

sp_modal(
    rx.el.p("Apply the new ground?"),
    trigger="Open",
    title="Apply changes",
    footer=sp_trigger("Apply", variant="primary", on_click=State.confirm),
    open=State.modal_open,
    on_open_change=State.set_modal_open,
)
sp_select(["North", "East", "South", "West"], value=State.region, on_change=State.set_region)
sp_toaster(sp_toast("Saved", State.text, kind="success", open=State.toast_open, on_open_change=State.set_toast_open))

Composed components

Timeline

The npm SpTimeline of @silverpoint/react/timeline. TimelineJS (@knight-lab/timelinejs 3.9.13) is an npm dependency of this component: Reflex installs it when a page uses sp_timeline, and no Python extra is needed. If it cannot be loaded, the component warns SP025 and renders fallback.

from reflex_silverpoint_react import sp_timeline

sp_timeline(
    DATA,  # TimelineJS data: title, events, eras (or any object with to_dict())
    height=560,
    ground="silverpoint",
    substrate="cream",
    mode="ink",
    palette="sepia",
    inked_frames=True,  # the ground's hand-drawn frames and tone tiles
    on_change=State.on_change,  # the unique_id of the slide shown
)

It works in two layers. The skin replaces TimelineJS's colours, type and rules with the ground's --sp- properties: substrate, inks, EB Garamond, hairline rules, eras hatched by density, the current marker heightened. The hand reads the ground's own frame and tone masks from hidden probes and lays them on the markers, eras and menubar, so they are drawn with the same pieces as the Sp components; inked_frames=False keeps the skin only, and precision, cyanotype and forced colours fall back to exact rules by themselves. Note that TimelineJS requests its icon font from a relative path (/css/icons/tl-icons.*); the Reflex dev server answers it with HTML, so the browser logs font-decoding warnings. They come from TimelineJS, not from this package.

The Knight Lab timeline in silverpoint

The palettes page

Interaction

class State(rx.State):
    active: str = "—"

    @rx.event
    def on_active(self, item: dict | None):
        self.active = "—" if item is None else f"{item['datum']['hour']}: {item['value']}"

    @rx.event
    def on_select(self, item: dict):
        print("selected", item["datum"])


line_chart(
    data=DATA,
    x_key="hour",
    value_key="hits",
    on_active_change=State.on_active,
    on_select=State.on_select,
    tooltip=tooltip_template("{datum.hour} h · {value} hits"),
)
  • on_active_change receives the item under the pointer or keyboard focus, and None when it leaves. on_select fires on click, Enter or Space. The item is {"seriesKey", "index", "datum", "value", "point": {"x", "y"}}.
  • tooltip_template(text) builds the tooltip render function from a format string. Placeholders: {heading}, {text} (the built-in readout's two lines), {announcement}, {value}, {index}, {series} and {datum.<field>}. {{ and }} print literal braces.

Export: the imperative handle

Give a chart an id and its ChartHandle is reachable from Python:

from reflex_silverpoint_react import download_svg, get_geometry, get_svg

line_chart(id="hits", data=DATA, x_key="hour", value_key="hits")

rx.button("Download SVG", on_click=download_svg("hits", "hits.svg"))  # in the browser
rx.button("SVG to Python", on_click=get_svg("hits", State.receive_svg))  # handler gets a str
rx.button("Geometry", on_click=get_geometry("hits", State.receive_geometry))  # handler gets a dict

The exported SVG carries its own ground colours, so it renders the same outside the app.

Notes

  • volvelle_chart: index_ring and index_value apply to your own rings, so pass data when you use them (the demo dataset keeps its own index).
  • gauge_arc and meter_chart take percent (0-100) instead of data.
  • Charts switch to precision by themselves under prefers-contrast: more or forced-colors: active; no prop overrides that.
  • Accessors are field names (strings). The JavaScript API also accepts functions; from Python, shape your rows instead.

Demo app

uv venv && uv pip install -e .
cd silverpoint_react_demo
uv run reflex run

Pages: Start (quickstart, provider, ink vs precision), Gallery (the 60 charts, ground controls, demo datasets vs data from Python state with a re-roll), Playground (one chart, every rendering choice and the Python that reproduces it), Interaction (events, custom readout, a volvelle that turns on click, a treemap and a sunburst that drill down together, live KPI/gauge/meter, SVG and geometry export), Dashboard (a linked operations dashboard fed from Python state with ground, substrate, mode and column controls, a KPI strip, and dashboard_link on its own), UI components (/ui: the components controlled from Python state with a native form submit, and the three reference panels of the upstream example apps in silverpoint ink, precision and cyanotype), one reference page per chart (/chart/<slug>) and 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, and a palette control. New in 0.7: More components (/components: the 20 composed components wired to Python, with ground, substrate, mode and palette controls and an event log), Palettes (/palettes: the presets, a palette builder with colour pickers and check_palette, a coloured section) and Timeline (/timeline: the Knight Lab timeline on every ground, mode and palette).

Interaction page

Development

uv sync --extra dev
uv run pytest
uv run ruff check .
# Reflex 0.10 removed `reflex component build`: regenerate the .pyi stubs with the generator
# Reflex itself uses (plus this package's fixes), then build the sdist and wheel.
uv run python scripts/make_stubs.py
uv build

Before committing, run the hooks of .pre-commit-config.yaml (ruff check and format — including the Python blocks of this README — file hygiene and uv lock --check):

pre-commit install
pre-commit run --all-files

Changes per version are in CHANGELOG.md; the guide for coding agents is AGENTS.md. Releases are published to PyPI by pushing a vX.Y.Z tag on main that matches version in pyproject.toml.

License

MIT. silverpoint is MIT; the EB Garamond typeface is under the SIL Open Font License.

Metadata

Release files for reflex-silverpoint-react 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reflex-silverpoint-react 0.7.1
File Size Uploaded Provenance
reflex_silverpoint_react-0.7.1.tar.gz 103.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for reflex-silverpoint-react 0.7.1
File Interpreter ABI Platform
reflex_silverpoint_react-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 197.0 kB

Release files / reflex_silverpoint_react-0.7.1.tar.gz

Download URL reflex_silverpoint_react-0.7.1.tar.gz
Size 103.8 kB
Tags Source
SHA-256 checksum
How to use checksums
371a71b3196f06ccc8ea1cd5ddf2c9fcbe7c70cfc05999aee89323fc5dd04475
BLAKE2b-256 checksum
How to use checksums
106aa0a9a57657b302bc3fb2e1cb6f290539686e8d6b8174372b61b699496147
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / reflex_silverpoint_react-0.7.1-py3-none-any.whl

Download URL reflex_silverpoint_react-0.7.1-py3-none-any.whl
Size 93.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48149f07488480d57b7bf1e97357e32ad167fffb5e870adb9a007de04b99b317
BLAKE2b-256 checksum
How to use checksums
240817f39cf6c7ea20c40fe1ddb738c500284b382ac8eb037e6386c43bf744d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for reflex-silverpoint-react 0.7.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for reflex_silverpoint_react-0.7.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page