UI components · Overlays · new in 0.7
SpModal
A dialog on a card frame over a hatched backdrop: focus trapped, Escape closes it. Group: Overlays · new in silverpoint 0.7, in React, Vue, Angular and Reflex (sp_modal).
Live
Drawn here with the Reflex version, sp_modal, on the ground you pick:
Code
The same example in each framework; pick one once and every example on the site follows it.
import { useState } from 'react';
import { SpButton } from '@silverpoint/react/ui/button';
import { SpModal } from '@silverpoint/react/ui/modal';
export function ApplyChanges() {
const [open, setOpen] = useState(false);
return (
<SpModal
title="Apply changes"
description="The geometry of the data does not move."
trigger={<button type="button">Open the modal</button>} // any element you write
footer={<SpButton variant="primary" onClick={() => setOpen(false)}>Apply</SpButton>}
open={open}
onOpenChange={setOpen}
>
<p>Apply the new ground to every chart on the page?</p>
</SpModal>
);
}<script setup lang="ts">
import { ref } from 'vue';
import { SpButton } from '@silverpoint/vue/ui/button';
import { SpModal } from '@silverpoint/vue/ui/modal';
const open = ref(false);
</script>
<template>
<SpModal v-model:open="open" title="Apply changes" description="The geometry of the data does not move.">
<template #trigger><button type="button">Open the modal</button></template>
<p>Apply the new ground to every chart on the page?</p>
<template #footer><SpButton variant="primary" @click="open = false">Apply</SpButton></template>
</SpModal>
</template>import { Component, signal } from '@angular/core';
import { SpCardFooter, SpTrigger } from '@silverpoint/angular/ui';
import { SpButton } from '@silverpoint/angular/ui/button';
import { SpModal } from '@silverpoint/angular/ui/modal';
@Component({
selector: 'app-apply-changes',
imports: [SpButton, SpCardFooter, SpModal, SpTrigger],
template: `
<sp-modal [(open)]="open" title="Apply changes" description="The geometry of the data does not move.">
<button type="button" spTrigger>Open the modal</button>
<p>Apply the new ground to every chart on the page?</p>
<ng-template spFooter>
<button spButton variant="primary" (click)="open.set(false)">Apply</button>
</ng-template>
</sp-modal>
`,
})
export class ApplyChanges {
protected readonly open = signal(false);
}sp_modal(
rx.el.p("Apply the new ground to every chart on the page?"),
trigger="Open the modal", # a string becomes sp_trigger(...)
title="Apply changes",
description="The geometry of the data does not move.",
footer=sp_trigger("Apply", variant="primary", on_click=State.confirm),
open=State.modal_open,
on_open_change=State.set_modal_open,
)Import
Import @silverpoint/grounds/ui.css once, beside styles.css; Reflex adds it for you. Every adapter also exports it from the ui barrel.
| Framework | Import |
|---|---|
| React | import { SpModal } from '@silverpoint/react/ui/modal'; |
| Vue | import { SpModal } from '@silverpoint/vue/ui/modal'; |
| Angular | import { SpModal } from '@silverpoint/angular/ui/modal'; · sp-modal |
| Reflex | from reflex_silverpoint_react import sp_modal |
Events, values and slots
Each framework's own way. A change carries the new value itself (a key, a page, a number, a bool), never a DOM event.
| React | Vue | Angular | Reflex | |
|---|---|---|---|---|
| Trigger | trigger={<button …/>} | #trigger slot | a projected element with spTrigger | trigger= (a string or sp_trigger) |
| Open state | open + onOpenChange, or defaultOpen | v-model:open, or default-open | [(open)], or [defaultOpen] | open + on_open_change, or default_open |
| Footer | footer | #footer slot | <ng-template spFooter> | footer= |
Props
| React / Angular | Vue | Type | Description |
|---|---|---|---|
title | title | string | The heading, ${id}--title, that names the dialog. |
description | description | string | A paragraph, ${id}--description, that describes the dialog. |
label | label | string | Accessible name without a title. |
closable | closable | boolean | Default true. |
closeLabel | close-label | string | Default 'Close'. |
width | width | string | CSS length. Default '520px' (from ui.css). |
dismissible | dismissible | boolean | Escape and a backdrop click close it. Default true. |
In Reflex the names are snake_case; the Reflex column of Composed components shows the builder's arguments.
Common props
Every UI component also takes these, falling back to the dashboard it sits in, then to the provider. In Reflex they read silverpoint_provider too; only sp_trigger does not: pass them to it.
| React / Angular | Vue | Reflex | Type | Description |
|---|---|---|---|---|
id | id | id | str | The frame variant and every related id derive from it. |
ground | ground | ground | Literal['silverpoint', 'cyanotype'] | str | dict[str, Any] | Style ground: "silverpoint" or "cyanotype", or a ground object. Defaults to the dashboard's, then the provider's, or silverpoint. |
substrate | substrate | substrate | Literal['cream', 'green', 'blue', 'ochre', 'prussian'] | Prepared substrate within the ground. |
mode | mode | mode | Literal['ink', 'precision'] | ink by default; precision disables inking. |
seed | seed | seed | str | int | Seed of the frame's hand; overrides id for the frame variant only. |
size | size | size | Literal['sm', 'md', 'lg'] | Control size: sm, md (default) or lg. |
palette | palette | palette | dict[str, str] | Colours over the ground's (set with palette=), merged over the dashboard's and the provider's. |
className | class-name | class_name | str | Added to the component's root element, after its own classes. |
palette | palette | palette | Palette | Colours over the ground's, merged over the dashboard's and the provider's. |
Report it
Found something wrong with SpModal? Open an issue on GitHub — the form comes pre-filled with the component and the version.