@silverpoint/mcp 0.7.0 → 0.8.0
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.
- package/README.md +27 -9
- package/agent-catalog.json +198 -100
- package/dist/bin.js +1 -1
- package/dist/{chunk-3FJJQMGW.js → chunk-NUDC553W.js} +208 -110
- package/dist/http.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
|
@@ -10,11 +10,11 @@ import { LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js';
|
|
|
10
10
|
// agent-catalog.json
|
|
11
11
|
var agent_catalog_default = {
|
|
12
12
|
schema: 1,
|
|
13
|
-
version: "0.
|
|
13
|
+
version: "0.8.0",
|
|
14
14
|
reflex: {
|
|
15
15
|
version: "0.7.1",
|
|
16
16
|
wraps: "0.7.0",
|
|
17
|
-
stale:
|
|
17
|
+
stale: true
|
|
18
18
|
},
|
|
19
19
|
frameworks: [
|
|
20
20
|
"react",
|
|
@@ -408,7 +408,8 @@ var agent_catalog_default = {
|
|
|
408
408
|
hits: 11,
|
|
409
409
|
baseline: 15
|
|
410
410
|
}
|
|
411
|
-
]
|
|
411
|
+
],
|
|
412
|
+
stale: "0.7.0"
|
|
412
413
|
},
|
|
413
414
|
{
|
|
414
415
|
slug: "bullet-chart",
|
|
@@ -497,7 +498,8 @@ var agent_catalog_default = {
|
|
|
497
498
|
actual: 86,
|
|
498
499
|
target: 75
|
|
499
500
|
}
|
|
500
|
-
]
|
|
501
|
+
],
|
|
502
|
+
stale: "0.7.0"
|
|
501
503
|
},
|
|
502
504
|
{
|
|
503
505
|
slug: "pyramid-chart",
|
|
@@ -581,7 +583,8 @@ var agent_catalog_default = {
|
|
|
581
583
|
label: "Specialists",
|
|
582
584
|
width: 70
|
|
583
585
|
}
|
|
584
|
-
]
|
|
586
|
+
],
|
|
587
|
+
stale: "0.7.0"
|
|
585
588
|
},
|
|
586
589
|
{
|
|
587
590
|
slug: "heatmap-chart",
|
|
@@ -688,7 +691,8 @@ var agent_catalog_default = {
|
|
|
688
691
|
47
|
|
689
692
|
]
|
|
690
693
|
}
|
|
691
|
-
]
|
|
694
|
+
],
|
|
695
|
+
stale: "0.7.0"
|
|
692
696
|
},
|
|
693
697
|
{
|
|
694
698
|
slug: "treemap-chart",
|
|
@@ -778,7 +782,8 @@ var agent_catalog_default = {
|
|
|
778
782
|
cols: 2,
|
|
779
783
|
rows: 2
|
|
780
784
|
}
|
|
781
|
-
]
|
|
785
|
+
],
|
|
786
|
+
stale: "0.7.0"
|
|
782
787
|
},
|
|
783
788
|
{
|
|
784
789
|
slug: "sankey-chart",
|
|
@@ -866,7 +871,8 @@ var agent_catalog_default = {
|
|
|
866
871
|
target: "Visit",
|
|
867
872
|
value: 15
|
|
868
873
|
}
|
|
869
|
-
]
|
|
874
|
+
],
|
|
875
|
+
stale: "0.7.0"
|
|
870
876
|
},
|
|
871
877
|
{
|
|
872
878
|
slug: "activity-grid",
|
|
@@ -962,7 +968,8 @@ var agent_catalog_default = {
|
|
|
962
968
|
count: 4,
|
|
963
969
|
level: 2
|
|
964
970
|
}
|
|
965
|
-
]
|
|
971
|
+
],
|
|
972
|
+
stale: "0.7.0"
|
|
966
973
|
},
|
|
967
974
|
{
|
|
968
975
|
slug: "step-chart",
|
|
@@ -1041,7 +1048,8 @@ var agent_catalog_default = {
|
|
|
1041
1048
|
x: "Mar",
|
|
1042
1049
|
value: 18
|
|
1043
1050
|
}
|
|
1044
|
-
]
|
|
1051
|
+
],
|
|
1052
|
+
stale: "0.7.0"
|
|
1045
1053
|
},
|
|
1046
1054
|
{
|
|
1047
1055
|
slug: "sparkline-rows",
|
|
@@ -1176,7 +1184,8 @@ var agent_catalog_default = {
|
|
|
1176
1184
|
84
|
|
1177
1185
|
]
|
|
1178
1186
|
}
|
|
1179
|
-
]
|
|
1187
|
+
],
|
|
1188
|
+
stale: "0.7.0"
|
|
1180
1189
|
},
|
|
1181
1190
|
{
|
|
1182
1191
|
slug: "kpi-card",
|
|
@@ -1252,7 +1261,8 @@ var agent_catalog_default = {
|
|
|
1252
1261
|
{
|
|
1253
1262
|
value: 121
|
|
1254
1263
|
}
|
|
1255
|
-
]
|
|
1264
|
+
],
|
|
1265
|
+
stale: "0.7.0"
|
|
1256
1266
|
},
|
|
1257
1267
|
{
|
|
1258
1268
|
slug: "bar-chart",
|
|
@@ -1351,7 +1361,8 @@ var agent_catalog_default = {
|
|
|
1351
1361
|
value: 51,
|
|
1352
1362
|
previous: 49
|
|
1353
1363
|
}
|
|
1354
|
-
]
|
|
1364
|
+
],
|
|
1365
|
+
stale: "0.7.0"
|
|
1355
1366
|
},
|
|
1356
1367
|
{
|
|
1357
1368
|
slug: "stacked-bar-chart",
|
|
@@ -1439,7 +1450,8 @@ var agent_catalog_default = {
|
|
|
1439
1450
|
pro: 26,
|
|
1440
1451
|
team: 11
|
|
1441
1452
|
}
|
|
1442
|
-
]
|
|
1453
|
+
],
|
|
1454
|
+
stale: "0.7.0"
|
|
1443
1455
|
},
|
|
1444
1456
|
{
|
|
1445
1457
|
slug: "composed-chart",
|
|
@@ -1540,7 +1552,8 @@ var agent_catalog_default = {
|
|
|
1540
1552
|
revenue: 39,
|
|
1541
1553
|
margin: 17
|
|
1542
1554
|
}
|
|
1543
|
-
]
|
|
1555
|
+
],
|
|
1556
|
+
stale: "0.7.0"
|
|
1544
1557
|
},
|
|
1545
1558
|
{
|
|
1546
1559
|
slug: "waterfall-chart",
|
|
@@ -1625,7 +1638,8 @@ var agent_catalog_default = {
|
|
|
1625
1638
|
step: "Services",
|
|
1626
1639
|
delta: 22
|
|
1627
1640
|
}
|
|
1628
|
-
]
|
|
1641
|
+
],
|
|
1642
|
+
stale: "0.7.0"
|
|
1629
1643
|
},
|
|
1630
1644
|
{
|
|
1631
1645
|
slug: "funnel-chart",
|
|
@@ -1696,7 +1710,8 @@ var agent_catalog_default = {
|
|
|
1696
1710
|
stage: "Cart",
|
|
1697
1711
|
value: 2900
|
|
1698
1712
|
}
|
|
1699
|
-
]
|
|
1713
|
+
],
|
|
1714
|
+
stale: "0.7.0"
|
|
1700
1715
|
},
|
|
1701
1716
|
{
|
|
1702
1717
|
slug: "candlestick-chart",
|
|
@@ -1825,7 +1840,8 @@ var agent_catalog_default = {
|
|
|
1825
1840
|
low: 97,
|
|
1826
1841
|
close: 99
|
|
1827
1842
|
}
|
|
1828
|
-
]
|
|
1843
|
+
],
|
|
1844
|
+
stale: "0.7.0"
|
|
1829
1845
|
},
|
|
1830
1846
|
{
|
|
1831
1847
|
slug: "area-chart",
|
|
@@ -1904,7 +1920,8 @@ var agent_catalog_default = {
|
|
|
1904
1920
|
x: "Wed",
|
|
1905
1921
|
value: 41
|
|
1906
1922
|
}
|
|
1907
|
-
]
|
|
1923
|
+
],
|
|
1924
|
+
stale: "0.7.0"
|
|
1908
1925
|
},
|
|
1909
1926
|
{
|
|
1910
1927
|
slug: "range-band-chart",
|
|
@@ -1992,7 +2009,8 @@ var agent_catalog_default = {
|
|
|
1992
2009
|
low: 14,
|
|
1993
2010
|
high: 24
|
|
1994
2011
|
}
|
|
1995
|
-
]
|
|
2012
|
+
],
|
|
2013
|
+
stale: "0.7.0"
|
|
1996
2014
|
},
|
|
1997
2015
|
{
|
|
1998
2016
|
slug: "stream-chart",
|
|
@@ -2078,7 +2096,8 @@ var agent_catalog_default = {
|
|
|
2078
2096
|
organic: 35,
|
|
2079
2097
|
paid: 16
|
|
2080
2098
|
}
|
|
2081
|
-
]
|
|
2099
|
+
],
|
|
2100
|
+
stale: "0.7.0"
|
|
2082
2101
|
},
|
|
2083
2102
|
{
|
|
2084
2103
|
slug: "scatter-chart",
|
|
@@ -2171,7 +2190,8 @@ var agent_catalog_default = {
|
|
|
2171
2190
|
y: 54,
|
|
2172
2191
|
size: 3
|
|
2173
2192
|
}
|
|
2174
|
-
]
|
|
2193
|
+
],
|
|
2194
|
+
stale: "0.7.0"
|
|
2175
2195
|
},
|
|
2176
2196
|
{
|
|
2177
2197
|
slug: "bubble-chart",
|
|
@@ -2264,7 +2284,8 @@ var agent_catalog_default = {
|
|
|
2264
2284
|
y: 12,
|
|
2265
2285
|
size: 65
|
|
2266
2286
|
}
|
|
2267
|
-
]
|
|
2287
|
+
],
|
|
2288
|
+
stale: "0.7.0"
|
|
2268
2289
|
},
|
|
2269
2290
|
{
|
|
2270
2291
|
slug: "donut-chart",
|
|
@@ -2356,7 +2377,8 @@ var agent_catalog_default = {
|
|
|
2356
2377
|
name: "Savings",
|
|
2357
2378
|
value: 15
|
|
2358
2379
|
}
|
|
2359
|
-
]
|
|
2380
|
+
],
|
|
2381
|
+
stale: "0.7.0"
|
|
2360
2382
|
},
|
|
2361
2383
|
{
|
|
2362
2384
|
slug: "radar-chart",
|
|
@@ -2433,7 +2455,8 @@ var agent_catalog_default = {
|
|
|
2433
2455
|
subject: "Comfort",
|
|
2434
2456
|
value: 7
|
|
2435
2457
|
}
|
|
2436
|
-
]
|
|
2458
|
+
],
|
|
2459
|
+
stale: "0.7.0"
|
|
2437
2460
|
},
|
|
2438
2461
|
{
|
|
2439
2462
|
slug: "polar-bar-chart",
|
|
@@ -2504,7 +2527,8 @@ var agent_catalog_default = {
|
|
|
2504
2527
|
name: "Mar",
|
|
2505
2528
|
value: 41
|
|
2506
2529
|
}
|
|
2507
|
-
]
|
|
2530
|
+
],
|
|
2531
|
+
stale: "0.7.0"
|
|
2508
2532
|
},
|
|
2509
2533
|
{
|
|
2510
2534
|
slug: "radial-arc-group",
|
|
@@ -2573,7 +2597,8 @@ var agent_catalog_default = {
|
|
|
2573
2597
|
name: "Online",
|
|
2574
2598
|
value: 47
|
|
2575
2599
|
}
|
|
2576
|
-
]
|
|
2600
|
+
],
|
|
2601
|
+
stale: "0.7.0"
|
|
2577
2602
|
},
|
|
2578
2603
|
{
|
|
2579
2604
|
slug: "radial-rings",
|
|
@@ -2641,7 +2666,8 @@ var agent_catalog_default = {
|
|
|
2641
2666
|
name: "Stand",
|
|
2642
2667
|
value: 100
|
|
2643
2668
|
}
|
|
2644
|
-
]
|
|
2669
|
+
],
|
|
2670
|
+
stale: "0.7.0"
|
|
2645
2671
|
},
|
|
2646
2672
|
{
|
|
2647
2673
|
slug: "gauge-arc",
|
|
@@ -2689,7 +2715,8 @@ var agent_catalog_default = {
|
|
|
2689
2715
|
optional: true,
|
|
2690
2716
|
doc: "Printed in place of the percent."
|
|
2691
2717
|
}
|
|
2692
|
-
]
|
|
2718
|
+
],
|
|
2719
|
+
stale: "0.7.0"
|
|
2693
2720
|
},
|
|
2694
2721
|
{
|
|
2695
2722
|
slug: "meter-chart",
|
|
@@ -2737,7 +2764,8 @@ var agent_catalog_default = {
|
|
|
2737
2764
|
optional: true,
|
|
2738
2765
|
doc: "Printed in place of the percent."
|
|
2739
2766
|
}
|
|
2740
|
-
]
|
|
2767
|
+
],
|
|
2768
|
+
stale: "0.7.0"
|
|
2741
2769
|
},
|
|
2742
2770
|
{
|
|
2743
2771
|
slug: "coxcomb-chart",
|
|
@@ -2816,7 +2844,8 @@ var agent_catalog_default = {
|
|
|
2816
2844
|
name: "Wed",
|
|
2817
2845
|
value: 31
|
|
2818
2846
|
}
|
|
2819
|
-
]
|
|
2847
|
+
],
|
|
2848
|
+
stale: "0.7.0"
|
|
2820
2849
|
},
|
|
2821
2850
|
{
|
|
2822
2851
|
slug: "wind-rose",
|
|
@@ -2902,7 +2931,8 @@ var agent_catalog_default = {
|
|
|
2902
2931
|
bearing: 180,
|
|
2903
2932
|
speed: 9
|
|
2904
2933
|
}
|
|
2905
|
-
]
|
|
2934
|
+
],
|
|
2935
|
+
stale: "0.7.0"
|
|
2906
2936
|
},
|
|
2907
2937
|
{
|
|
2908
2938
|
slug: "volvelle-chart",
|
|
@@ -2984,7 +3014,8 @@ var agent_catalog_default = {
|
|
|
2984
3014
|
"Eridanus"
|
|
2985
3015
|
]
|
|
2986
3016
|
}
|
|
2987
|
-
]
|
|
3017
|
+
],
|
|
3018
|
+
stale: "0.7.0"
|
|
2988
3019
|
},
|
|
2989
3020
|
{
|
|
2990
3021
|
slug: "chord-ring",
|
|
@@ -3080,7 +3111,8 @@ var agent_catalog_default = {
|
|
|
3080
3111
|
target: "Shop",
|
|
3081
3112
|
value: 16
|
|
3082
3113
|
}
|
|
3083
|
-
]
|
|
3114
|
+
],
|
|
3115
|
+
stale: "0.7.0"
|
|
3084
3116
|
},
|
|
3085
3117
|
{
|
|
3086
3118
|
slug: "orbit-chart",
|
|
@@ -3208,7 +3240,8 @@ var agent_catalog_default = {
|
|
|
3208
3240
|
}
|
|
3209
3241
|
]
|
|
3210
3242
|
}
|
|
3211
|
-
]
|
|
3243
|
+
],
|
|
3244
|
+
stale: "0.7.0"
|
|
3212
3245
|
},
|
|
3213
3246
|
{
|
|
3214
3247
|
slug: "histogram-chart",
|
|
@@ -3291,7 +3324,8 @@ var agent_catalog_default = {
|
|
|
3291
3324
|
device: "phone",
|
|
3292
3325
|
minutes: 3
|
|
3293
3326
|
}
|
|
3294
|
-
]
|
|
3327
|
+
],
|
|
3328
|
+
stale: "0.7.0"
|
|
3295
3329
|
},
|
|
3296
3330
|
{
|
|
3297
3331
|
slug: "ecdf-chart",
|
|
@@ -3375,7 +3409,8 @@ var agent_catalog_default = {
|
|
|
3375
3409
|
device: "phone",
|
|
3376
3410
|
minutes: 3
|
|
3377
3411
|
}
|
|
3378
|
-
]
|
|
3412
|
+
],
|
|
3413
|
+
stale: "0.7.0"
|
|
3379
3414
|
},
|
|
3380
3415
|
{
|
|
3381
3416
|
slug: "box-plot-chart",
|
|
@@ -3471,7 +3506,8 @@ var agent_catalog_default = {
|
|
|
3471
3506
|
service: "Search",
|
|
3472
3507
|
ms: 158
|
|
3473
3508
|
}
|
|
3474
|
-
]
|
|
3509
|
+
],
|
|
3510
|
+
stale: "0.7.0"
|
|
3475
3511
|
},
|
|
3476
3512
|
{
|
|
3477
3513
|
slug: "violin-chart",
|
|
@@ -3566,7 +3602,8 @@ var agent_catalog_default = {
|
|
|
3566
3602
|
service: "Search",
|
|
3567
3603
|
ms: 158
|
|
3568
3604
|
}
|
|
3569
|
-
]
|
|
3605
|
+
],
|
|
3606
|
+
stale: "0.7.0"
|
|
3570
3607
|
},
|
|
3571
3608
|
{
|
|
3572
3609
|
slug: "ridgeline-chart",
|
|
@@ -3655,7 +3692,8 @@ var agent_catalog_default = {
|
|
|
3655
3692
|
service: "Search",
|
|
3656
3693
|
ms: 158
|
|
3657
3694
|
}
|
|
3658
|
-
]
|
|
3695
|
+
],
|
|
3696
|
+
stale: "0.7.0"
|
|
3659
3697
|
},
|
|
3660
3698
|
{
|
|
3661
3699
|
slug: "beeswarm-chart",
|
|
@@ -3752,7 +3790,8 @@ var agent_catalog_default = {
|
|
|
3752
3790
|
device: "phone",
|
|
3753
3791
|
minutes: 3
|
|
3754
3792
|
}
|
|
3755
|
-
]
|
|
3793
|
+
],
|
|
3794
|
+
stale: "0.7.0"
|
|
3756
3795
|
},
|
|
3757
3796
|
{
|
|
3758
3797
|
slug: "lollipop-chart",
|
|
@@ -3841,7 +3880,8 @@ var agent_catalog_default = {
|
|
|
3841
3880
|
branch: "Old Mill",
|
|
3842
3881
|
loans: 6096
|
|
3843
3882
|
}
|
|
3844
|
-
]
|
|
3883
|
+
],
|
|
3884
|
+
stale: "0.7.0"
|
|
3845
3885
|
},
|
|
3846
3886
|
{
|
|
3847
3887
|
slug: "dumbbell-chart",
|
|
@@ -3961,7 +4001,8 @@ var agent_catalog_default = {
|
|
|
3961
4001
|
y2024: 33,
|
|
3962
4002
|
y2025: 47
|
|
3963
4003
|
}
|
|
3964
|
-
]
|
|
4004
|
+
],
|
|
4005
|
+
stale: "0.7.0"
|
|
3965
4006
|
},
|
|
3966
4007
|
{
|
|
3967
4008
|
slug: "slope-chart",
|
|
@@ -4066,7 +4107,8 @@ var agent_catalog_default = {
|
|
|
4066
4107
|
y2024: 33,
|
|
4067
4108
|
y2025: 47
|
|
4068
4109
|
}
|
|
4069
|
-
]
|
|
4110
|
+
],
|
|
4111
|
+
stale: "0.7.0"
|
|
4070
4112
|
},
|
|
4071
4113
|
{
|
|
4072
4114
|
slug: "bump-chart",
|
|
@@ -4174,7 +4216,8 @@ var agent_catalog_default = {
|
|
|
4174
4216
|
team: "Lynx",
|
|
4175
4217
|
points: 52
|
|
4176
4218
|
}
|
|
4177
|
-
]
|
|
4219
|
+
],
|
|
4220
|
+
stale: "0.7.0"
|
|
4178
4221
|
},
|
|
4179
4222
|
{
|
|
4180
4223
|
slug: "error-bar-chart",
|
|
@@ -4300,7 +4343,8 @@ var agent_catalog_default = {
|
|
|
4300
4343
|
low: 0.35,
|
|
4301
4344
|
high: 2.79
|
|
4302
4345
|
}
|
|
4303
|
-
]
|
|
4346
|
+
],
|
|
4347
|
+
stale: "0.7.0"
|
|
4304
4348
|
},
|
|
4305
4349
|
{
|
|
4306
4350
|
slug: "interval-chart",
|
|
@@ -4418,7 +4462,8 @@ var agent_catalog_default = {
|
|
|
4418
4462
|
from: "2026-03-09",
|
|
4419
4463
|
to: "2026-03-31"
|
|
4420
4464
|
}
|
|
4421
|
-
]
|
|
4465
|
+
],
|
|
4466
|
+
stale: "0.7.0"
|
|
4422
4467
|
},
|
|
4423
4468
|
{
|
|
4424
4469
|
slug: "diverging-bar-chart",
|
|
@@ -4525,7 +4570,8 @@ var agent_catalog_default = {
|
|
|
4525
4570
|
Agree: 31,
|
|
4526
4571
|
"Strongly agree": 41
|
|
4527
4572
|
}
|
|
4528
|
-
]
|
|
4573
|
+
],
|
|
4574
|
+
stale: "0.7.0"
|
|
4529
4575
|
},
|
|
4530
4576
|
{
|
|
4531
4577
|
slug: "connected-scatter-chart",
|
|
@@ -4625,7 +4671,8 @@ var agent_catalog_default = {
|
|
|
4625
4671
|
fare: 1.72,
|
|
4626
4672
|
riders: 42.7
|
|
4627
4673
|
}
|
|
4628
|
-
]
|
|
4674
|
+
],
|
|
4675
|
+
stale: "0.7.0"
|
|
4629
4676
|
},
|
|
4630
4677
|
{
|
|
4631
4678
|
slug: "waffle-chart",
|
|
@@ -4716,7 +4763,8 @@ var agent_catalog_default = {
|
|
|
4716
4763
|
use: "Appliances",
|
|
4717
4764
|
kwh: 158
|
|
4718
4765
|
}
|
|
4719
|
-
]
|
|
4766
|
+
],
|
|
4767
|
+
stale: "0.7.0"
|
|
4720
4768
|
},
|
|
4721
4769
|
{
|
|
4722
4770
|
slug: "marimekko-chart",
|
|
@@ -4809,7 +4857,8 @@ var agent_catalog_default = {
|
|
|
4809
4857
|
channel: "Wholesale",
|
|
4810
4858
|
sales: 37
|
|
4811
4859
|
}
|
|
4812
|
-
]
|
|
4860
|
+
],
|
|
4861
|
+
stale: "0.7.0"
|
|
4813
4862
|
},
|
|
4814
4863
|
{
|
|
4815
4864
|
slug: "squarified-treemap",
|
|
@@ -4931,7 +4980,8 @@ var agent_catalog_default = {
|
|
|
4931
4980
|
name: "Roads"
|
|
4932
4981
|
}
|
|
4933
4982
|
],
|
|
4934
|
-
drillable: true
|
|
4983
|
+
drillable: true,
|
|
4984
|
+
stale: "0.7.0"
|
|
4935
4985
|
},
|
|
4936
4986
|
{
|
|
4937
4987
|
slug: "sunburst-chart",
|
|
@@ -5053,7 +5103,8 @@ var agent_catalog_default = {
|
|
|
5053
5103
|
name: "Roads"
|
|
5054
5104
|
}
|
|
5055
5105
|
],
|
|
5056
|
-
drillable: true
|
|
5106
|
+
drillable: true,
|
|
5107
|
+
stale: "0.7.0"
|
|
5057
5108
|
},
|
|
5058
5109
|
{
|
|
5059
5110
|
slug: "tree-chart",
|
|
@@ -5165,7 +5216,8 @@ var agent_catalog_default = {
|
|
|
5165
5216
|
parent: "works",
|
|
5166
5217
|
name: "Roads"
|
|
5167
5218
|
}
|
|
5168
|
-
]
|
|
5219
|
+
],
|
|
5220
|
+
stale: "0.7.0"
|
|
5169
5221
|
},
|
|
5170
5222
|
{
|
|
5171
5223
|
slug: "parallel-coordinates-chart",
|
|
@@ -5263,7 +5315,8 @@ var agent_catalog_default = {
|
|
|
5263
5315
|
range: 62,
|
|
5264
5316
|
rating: 2.9
|
|
5265
5317
|
}
|
|
5266
|
-
]
|
|
5318
|
+
],
|
|
5319
|
+
stale: "0.7.0"
|
|
5267
5320
|
},
|
|
5268
5321
|
{
|
|
5269
5322
|
slug: "polar-line-chart",
|
|
@@ -5354,7 +5407,8 @@ var agent_catalog_default = {
|
|
|
5354
5407
|
month: 2,
|
|
5355
5408
|
rain: 54
|
|
5356
5409
|
}
|
|
5357
|
-
]
|
|
5410
|
+
],
|
|
5411
|
+
stale: "0.7.0"
|
|
5358
5412
|
},
|
|
5359
5413
|
{
|
|
5360
5414
|
slug: "polar-scatter-chart",
|
|
@@ -5450,7 +5504,8 @@ var agent_catalog_default = {
|
|
|
5450
5504
|
bearing: 229.3,
|
|
5451
5505
|
distance: 19.6
|
|
5452
5506
|
}
|
|
5453
|
-
]
|
|
5507
|
+
],
|
|
5508
|
+
stale: "0.7.0"
|
|
5454
5509
|
},
|
|
5455
5510
|
{
|
|
5456
5511
|
slug: "density-bin-chart",
|
|
@@ -5540,7 +5595,8 @@ var agent_catalog_default = {
|
|
|
5540
5595
|
x: 39.92,
|
|
5541
5596
|
y: 61.68
|
|
5542
5597
|
}
|
|
5543
|
-
]
|
|
5598
|
+
],
|
|
5599
|
+
stale: "0.7.0"
|
|
5544
5600
|
},
|
|
5545
5601
|
{
|
|
5546
5602
|
slug: "contour-chart",
|
|
@@ -5651,7 +5707,8 @@ var agent_catalog_default = {
|
|
|
5651
5707
|
x: 39.92,
|
|
5652
5708
|
y: 61.68
|
|
5653
5709
|
}
|
|
5654
|
-
]
|
|
5710
|
+
],
|
|
5711
|
+
stale: "0.7.0"
|
|
5655
5712
|
},
|
|
5656
5713
|
{
|
|
5657
5714
|
slug: "delaunay-chart",
|
|
@@ -5750,7 +5807,8 @@ var agent_catalog_default = {
|
|
|
5750
5807
|
x: 90.6,
|
|
5751
5808
|
y: 39.1
|
|
5752
5809
|
}
|
|
5753
|
-
]
|
|
5810
|
+
],
|
|
5811
|
+
stale: "0.7.0"
|
|
5754
5812
|
},
|
|
5755
5813
|
{
|
|
5756
5814
|
slug: "vector-field-chart",
|
|
@@ -5867,7 +5925,8 @@ var agent_catalog_default = {
|
|
|
5867
5925
|
u: 1.097,
|
|
5868
5926
|
v: -1.266
|
|
5869
5927
|
}
|
|
5870
|
-
]
|
|
5928
|
+
],
|
|
5929
|
+
stale: "0.7.0"
|
|
5871
5930
|
},
|
|
5872
5931
|
{
|
|
5873
5932
|
slug: "network-chart",
|
|
@@ -5975,7 +6034,8 @@ var agent_catalog_default = {
|
|
|
5975
6034
|
target: "p07",
|
|
5976
6035
|
weight: 5
|
|
5977
6036
|
}
|
|
5978
|
-
]
|
|
6037
|
+
],
|
|
6038
|
+
stale: "0.7.0"
|
|
5979
6039
|
}
|
|
5980
6040
|
],
|
|
5981
6041
|
components: [
|
|
@@ -6070,7 +6130,8 @@ var agent_catalog_default = {
|
|
|
6070
6130
|
],
|
|
6071
6131
|
demo: {
|
|
6072
6132
|
content: "Default"
|
|
6073
|
-
}
|
|
6133
|
+
},
|
|
6134
|
+
stale: "0.7.0"
|
|
6074
6135
|
},
|
|
6075
6136
|
{
|
|
6076
6137
|
slug: "input",
|
|
@@ -6190,7 +6251,8 @@ var agent_catalog_default = {
|
|
|
6190
6251
|
type: "search",
|
|
6191
6252
|
name: "q",
|
|
6192
6253
|
value: ""
|
|
6193
|
-
}
|
|
6254
|
+
},
|
|
6255
|
+
stale: "0.7.0"
|
|
6194
6256
|
},
|
|
6195
6257
|
{
|
|
6196
6258
|
slug: "checkbox",
|
|
@@ -6270,7 +6332,8 @@ var agent_catalog_default = {
|
|
|
6270
6332
|
label: "Legend",
|
|
6271
6333
|
name: "legend",
|
|
6272
6334
|
value: false
|
|
6273
|
-
}
|
|
6335
|
+
},
|
|
6336
|
+
stale: "0.7.0"
|
|
6274
6337
|
},
|
|
6275
6338
|
{
|
|
6276
6339
|
slug: "radio-group",
|
|
@@ -6360,7 +6423,8 @@ var agent_catalog_default = {
|
|
|
6360
6423
|
],
|
|
6361
6424
|
value: "silverpoint",
|
|
6362
6425
|
orientation: "horizontal"
|
|
6363
|
-
}
|
|
6426
|
+
},
|
|
6427
|
+
stale: "0.7.0"
|
|
6364
6428
|
},
|
|
6365
6429
|
{
|
|
6366
6430
|
slug: "switch",
|
|
@@ -6432,7 +6496,8 @@ var agent_catalog_default = {
|
|
|
6432
6496
|
label: "Linked hover",
|
|
6433
6497
|
name: "linked",
|
|
6434
6498
|
value: false
|
|
6435
|
-
}
|
|
6499
|
+
},
|
|
6500
|
+
stale: "0.7.0"
|
|
6436
6501
|
},
|
|
6437
6502
|
{
|
|
6438
6503
|
slug: "slider",
|
|
@@ -6541,7 +6606,8 @@ var agent_catalog_default = {
|
|
|
6541
6606
|
75,
|
|
6542
6607
|
100
|
|
6543
6608
|
]
|
|
6544
|
-
}
|
|
6609
|
+
},
|
|
6610
|
+
stale: "0.7.0"
|
|
6545
6611
|
},
|
|
6546
6612
|
{
|
|
6547
6613
|
slug: "rate",
|
|
@@ -6628,7 +6694,8 @@ var agent_catalog_default = {
|
|
|
6628
6694
|
name: "quality",
|
|
6629
6695
|
value: 3,
|
|
6630
6696
|
count: 5
|
|
6631
|
-
}
|
|
6697
|
+
},
|
|
6698
|
+
stale: "0.7.0"
|
|
6632
6699
|
},
|
|
6633
6700
|
{
|
|
6634
6701
|
slug: "segmented",
|
|
@@ -6724,7 +6791,8 @@ var agent_catalog_default = {
|
|
|
6724
6791
|
}
|
|
6725
6792
|
],
|
|
6726
6793
|
value: "day"
|
|
6727
|
-
}
|
|
6794
|
+
},
|
|
6795
|
+
stale: "0.7.0"
|
|
6728
6796
|
},
|
|
6729
6797
|
{
|
|
6730
6798
|
slug: "tabs",
|
|
@@ -6827,7 +6895,8 @@ var agent_catalog_default = {
|
|
|
6827
6895
|
}
|
|
6828
6896
|
],
|
|
6829
6897
|
value: "overview"
|
|
6830
|
-
}
|
|
6898
|
+
},
|
|
6899
|
+
stale: "0.7.0"
|
|
6831
6900
|
},
|
|
6832
6901
|
{
|
|
6833
6902
|
slug: "steps",
|
|
@@ -6912,7 +6981,8 @@ var agent_catalog_default = {
|
|
|
6912
6981
|
}
|
|
6913
6982
|
],
|
|
6914
6983
|
current: 2
|
|
6915
|
-
}
|
|
6984
|
+
},
|
|
6985
|
+
stale: "0.7.0"
|
|
6916
6986
|
},
|
|
6917
6987
|
{
|
|
6918
6988
|
slug: "card",
|
|
@@ -6976,7 +7046,8 @@ var agent_catalog_default = {
|
|
|
6976
7046
|
],
|
|
6977
7047
|
demo: {
|
|
6978
7048
|
content: "Hits per hour rose through the afternoon and eased at night."
|
|
6979
|
-
}
|
|
7049
|
+
},
|
|
7050
|
+
stale: "0.7.0"
|
|
6980
7051
|
},
|
|
6981
7052
|
{
|
|
6982
7053
|
slug: "tag",
|
|
@@ -7048,7 +7119,8 @@ var agent_catalog_default = {
|
|
|
7048
7119
|
demo: {
|
|
7049
7120
|
content: "draft",
|
|
7050
7121
|
tone: 1
|
|
7051
|
-
}
|
|
7122
|
+
},
|
|
7123
|
+
stale: "0.7.0"
|
|
7052
7124
|
},
|
|
7053
7125
|
{
|
|
7054
7126
|
slug: "badge",
|
|
@@ -7122,7 +7194,8 @@ var agent_catalog_default = {
|
|
|
7122
7194
|
demo: {
|
|
7123
7195
|
content: "Inbox",
|
|
7124
7196
|
count: 12
|
|
7125
|
-
}
|
|
7197
|
+
},
|
|
7198
|
+
stale: "0.7.0"
|
|
7126
7199
|
},
|
|
7127
7200
|
{
|
|
7128
7201
|
slug: "divider",
|
|
@@ -7180,7 +7253,8 @@ var agent_catalog_default = {
|
|
|
7180
7253
|
"plain",
|
|
7181
7254
|
"text"
|
|
7182
7255
|
],
|
|
7183
|
-
demo: {}
|
|
7256
|
+
demo: {},
|
|
7257
|
+
stale: "0.7.0"
|
|
7184
7258
|
},
|
|
7185
7259
|
{
|
|
7186
7260
|
slug: "progress",
|
|
@@ -7249,7 +7323,8 @@ var agent_catalog_default = {
|
|
|
7249
7323
|
demo: {
|
|
7250
7324
|
label: "Upload",
|
|
7251
7325
|
value: 40
|
|
7252
|
-
}
|
|
7326
|
+
},
|
|
7327
|
+
stale: "0.7.0"
|
|
7253
7328
|
},
|
|
7254
7329
|
{
|
|
7255
7330
|
slug: "alert",
|
|
@@ -7332,7 +7407,8 @@ var agent_catalog_default = {
|
|
|
7332
7407
|
kind: "info",
|
|
7333
7408
|
title: "New ground available",
|
|
7334
7409
|
content: "cyanotype ships in 0.2.0."
|
|
7335
|
-
}
|
|
7410
|
+
},
|
|
7411
|
+
stale: "0.7.0"
|
|
7336
7412
|
},
|
|
7337
7413
|
{
|
|
7338
7414
|
slug: "skeleton",
|
|
@@ -7392,7 +7468,8 @@ var agent_catalog_default = {
|
|
|
7392
7468
|
],
|
|
7393
7469
|
demo: {
|
|
7394
7470
|
lines: 3
|
|
7395
|
-
}
|
|
7471
|
+
},
|
|
7472
|
+
stale: "0.7.0"
|
|
7396
7473
|
},
|
|
7397
7474
|
{
|
|
7398
7475
|
slug: "surface",
|
|
@@ -7464,7 +7541,8 @@ var agent_catalog_default = {
|
|
|
7464
7541
|
demo: {
|
|
7465
7542
|
frame: "card",
|
|
7466
7543
|
content: "A surface takes the ground: its substrate, its ink and a hand-drawn frame."
|
|
7467
|
-
}
|
|
7544
|
+
},
|
|
7545
|
+
stale: "0.7.0"
|
|
7468
7546
|
},
|
|
7469
7547
|
{
|
|
7470
7548
|
slug: "glyph",
|
|
@@ -7507,7 +7585,8 @@ var agent_catalog_default = {
|
|
|
7507
7585
|
],
|
|
7508
7586
|
demo: {
|
|
7509
7587
|
glyph: "tick"
|
|
7510
|
-
}
|
|
7588
|
+
},
|
|
7589
|
+
stale: "0.7.0"
|
|
7511
7590
|
},
|
|
7512
7591
|
{
|
|
7513
7592
|
slug: "table",
|
|
@@ -7680,7 +7759,8 @@ var agent_catalog_default = {
|
|
|
7680
7759
|
}
|
|
7681
7760
|
],
|
|
7682
7761
|
rowKey: "order"
|
|
7683
|
-
}
|
|
7762
|
+
},
|
|
7763
|
+
stale: "0.7.0"
|
|
7684
7764
|
},
|
|
7685
7765
|
{
|
|
7686
7766
|
slug: "pagination",
|
|
@@ -7806,7 +7886,8 @@ var agent_catalog_default = {
|
|
|
7806
7886
|
total: 200,
|
|
7807
7887
|
pageSize: 10,
|
|
7808
7888
|
current: 10
|
|
7809
|
-
}
|
|
7889
|
+
},
|
|
7890
|
+
stale: "0.7.0"
|
|
7810
7891
|
},
|
|
7811
7892
|
{
|
|
7812
7893
|
slug: "breadcrumb",
|
|
@@ -7872,7 +7953,8 @@ var agent_catalog_default = {
|
|
|
7872
7953
|
label: "Order 1042"
|
|
7873
7954
|
}
|
|
7874
7955
|
]
|
|
7875
|
-
}
|
|
7956
|
+
},
|
|
7957
|
+
stale: "0.7.0"
|
|
7876
7958
|
},
|
|
7877
7959
|
{
|
|
7878
7960
|
slug: "avatar",
|
|
@@ -7953,7 +8035,8 @@ var agent_catalog_default = {
|
|
|
7953
8035
|
],
|
|
7954
8036
|
demo: {
|
|
7955
8037
|
name: "Ada Lovelace"
|
|
7956
|
-
}
|
|
8038
|
+
},
|
|
8039
|
+
stale: "0.7.0"
|
|
7957
8040
|
},
|
|
7958
8041
|
{
|
|
7959
8042
|
slug: "statistic",
|
|
@@ -8033,7 +8116,8 @@ var agent_catalog_default = {
|
|
|
8033
8116
|
demo: {
|
|
8034
8117
|
title: "Orders",
|
|
8035
8118
|
value: 1284
|
|
8036
|
-
}
|
|
8119
|
+
},
|
|
8120
|
+
stale: "0.7.0"
|
|
8037
8121
|
},
|
|
8038
8122
|
{
|
|
8039
8123
|
slug: "descriptions",
|
|
@@ -8131,7 +8215,8 @@ var agent_catalog_default = {
|
|
|
8131
8215
|
}
|
|
8132
8216
|
],
|
|
8133
8217
|
columns: 2
|
|
8134
|
-
}
|
|
8218
|
+
},
|
|
8219
|
+
stale: "0.7.0"
|
|
8135
8220
|
},
|
|
8136
8221
|
{
|
|
8137
8222
|
slug: "timeline-list",
|
|
@@ -8207,7 +8292,8 @@ var agent_catalog_default = {
|
|
|
8207
8292
|
status: "pending"
|
|
8208
8293
|
}
|
|
8209
8294
|
]
|
|
8210
|
-
}
|
|
8295
|
+
},
|
|
8296
|
+
stale: "0.7.0"
|
|
8211
8297
|
},
|
|
8212
8298
|
{
|
|
8213
8299
|
slug: "collapse",
|
|
@@ -8283,7 +8369,8 @@ var agent_catalog_default = {
|
|
|
8283
8369
|
content: "From hatching, level by level, never from transparency."
|
|
8284
8370
|
}
|
|
8285
8371
|
]
|
|
8286
|
-
}
|
|
8372
|
+
},
|
|
8373
|
+
stale: "0.7.0"
|
|
8287
8374
|
},
|
|
8288
8375
|
{
|
|
8289
8376
|
slug: "empty",
|
|
@@ -8333,7 +8420,8 @@ var agent_catalog_default = {
|
|
|
8333
8420
|
],
|
|
8334
8421
|
demo: {
|
|
8335
8422
|
description: "No orders yet"
|
|
8336
|
-
}
|
|
8423
|
+
},
|
|
8424
|
+
stale: "0.7.0"
|
|
8337
8425
|
},
|
|
8338
8426
|
{
|
|
8339
8427
|
slug: "result",
|
|
@@ -8408,7 +8496,8 @@ var agent_catalog_default = {
|
|
|
8408
8496
|
status: "success",
|
|
8409
8497
|
title: "Order placed",
|
|
8410
8498
|
subtitle: "Order 1042 is on its way to the workshop."
|
|
8411
|
-
}
|
|
8499
|
+
},
|
|
8500
|
+
stale: "0.7.0"
|
|
8412
8501
|
},
|
|
8413
8502
|
{
|
|
8414
8503
|
slug: "textarea",
|
|
@@ -8532,7 +8621,8 @@ var agent_catalog_default = {
|
|
|
8532
8621
|
value: "Leave it at the door.",
|
|
8533
8622
|
maxLength: 120,
|
|
8534
8623
|
showCount: true
|
|
8535
|
-
}
|
|
8624
|
+
},
|
|
8625
|
+
stale: "0.7.0"
|
|
8536
8626
|
},
|
|
8537
8627
|
{
|
|
8538
8628
|
slug: "input-number",
|
|
@@ -8676,7 +8766,8 @@ var agent_catalog_default = {
|
|
|
8676
8766
|
value: 3,
|
|
8677
8767
|
min: 1,
|
|
8678
8768
|
max: 10
|
|
8679
|
-
}
|
|
8769
|
+
},
|
|
8770
|
+
stale: "0.7.0"
|
|
8680
8771
|
},
|
|
8681
8772
|
{
|
|
8682
8773
|
slug: "modal",
|
|
@@ -8790,7 +8881,8 @@ var agent_catalog_default = {
|
|
|
8790
8881
|
title: "Edit order",
|
|
8791
8882
|
description: "Order 1042, placed on 14 October.",
|
|
8792
8883
|
content: "Changes reach the workshop before the order is packed."
|
|
8793
|
-
}
|
|
8884
|
+
},
|
|
8885
|
+
stale: "0.7.0"
|
|
8794
8886
|
},
|
|
8795
8887
|
{
|
|
8796
8888
|
slug: "drawer",
|
|
@@ -8875,7 +8967,8 @@ var agent_catalog_default = {
|
|
|
8875
8967
|
trigger: "Filters",
|
|
8876
8968
|
title: "Filters",
|
|
8877
8969
|
content: "Narrow the orders by status, customer or amount."
|
|
8878
|
-
}
|
|
8970
|
+
},
|
|
8971
|
+
stale: "0.7.0"
|
|
8879
8972
|
},
|
|
8880
8973
|
{
|
|
8881
8974
|
slug: "popover",
|
|
@@ -8994,7 +9087,8 @@ var agent_catalog_default = {
|
|
|
8994
9087
|
trigger: "Details",
|
|
8995
9088
|
title: "Order 1042",
|
|
8996
9089
|
content: "Two prints, one framed; shipped on 16 October."
|
|
8997
|
-
}
|
|
9090
|
+
},
|
|
9091
|
+
stale: "0.7.0"
|
|
8998
9092
|
},
|
|
8999
9093
|
{
|
|
9000
9094
|
slug: "tooltip",
|
|
@@ -9086,7 +9180,8 @@ var agent_catalog_default = {
|
|
|
9086
9180
|
open: true,
|
|
9087
9181
|
trigger: "Copy id",
|
|
9088
9182
|
text: "Copy the order id"
|
|
9089
|
-
}
|
|
9183
|
+
},
|
|
9184
|
+
stale: "0.7.0"
|
|
9090
9185
|
},
|
|
9091
9186
|
{
|
|
9092
9187
|
slug: "select",
|
|
@@ -9214,7 +9309,8 @@ var agent_catalog_default = {
|
|
|
9214
9309
|
}
|
|
9215
9310
|
],
|
|
9216
9311
|
value: null
|
|
9217
|
-
}
|
|
9312
|
+
},
|
|
9313
|
+
stale: "0.7.0"
|
|
9218
9314
|
},
|
|
9219
9315
|
{
|
|
9220
9316
|
slug: "dropdown-menu",
|
|
@@ -9334,7 +9430,8 @@ var agent_catalog_default = {
|
|
|
9334
9430
|
],
|
|
9335
9431
|
open: true,
|
|
9336
9432
|
active: "edit"
|
|
9337
|
-
}
|
|
9433
|
+
},
|
|
9434
|
+
stale: "0.7.0"
|
|
9338
9435
|
},
|
|
9339
9436
|
{
|
|
9340
9437
|
slug: "toast",
|
|
@@ -9426,7 +9523,8 @@ var agent_catalog_default = {
|
|
|
9426
9523
|
title: "Order saved",
|
|
9427
9524
|
description: "Order 1042 was updated.",
|
|
9428
9525
|
open: true
|
|
9429
|
-
}
|
|
9526
|
+
},
|
|
9527
|
+
stale: "0.7.0"
|
|
9430
9528
|
}
|
|
9431
9529
|
],
|
|
9432
9530
|
dashboard: {
|
|
@@ -11412,16 +11510,16 @@ function generateCode(catalog2, input) {
|
|
|
11412
11510
|
|
|
11413
11511
|
// src/guides.generated.ts
|
|
11414
11512
|
var GUIDES = {
|
|
11415
|
-
"choosing-charts": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Choosing a chart\n\n*Describes silverpoint 0.7.0.*\n\nChoose a chart in two steps. First name the shape of the rows, then name what the reader is asked to\nsee. The recommender (`recommend_chart` on the MCP server) reads the table below. It is a reviewed\ntable, not a model, and a pair that is missing from it falls back on the charts that declare both.\n\n## Data shapes\n\n| Shape | The rows hold | For example |\n|---|---|---|\n| `series` | one row per point along an ordered x (time, sequence) | hits per hour |\n| `categories` | one row per category with one or more values | revenue by region |\n| `parts` | shares of one whole | traffic by channel |\n| `matrix` | a value per pair of categories | errors by day and hour |\n| `hierarchy` | one row per node, with an `id` and its `parent` (`null` for the root) | a budget by department |\n| `links` | rows with a source, a target and a value | signup funnel steps |\n| `points` | two or more numeric measures per row | price against rating |\n| `distribution` | many raw observations of one measure | response times |\n| `intervals` | a start and an end per row | task schedule |\n| `events` | dated occurrences, or marks along a cycle | commits per day |\n| `single` | one figure, perhaps with a target | revenue this month |\n| `field` | a measure or a vector (`x`, `y`, `u`, `v`) over a plane | a wind field |\n\n## The charts by shape and intent\n\n| Chart | Family | Shape | Intents | Summary |\n|---|---|---|---|---|\n| `line-chart` | lines | `series` | trend, change, compare | Spline with an optional dotted baseline series. |\n| `bullet-chart` | bars | `categories` | progress, kpi, compare | One bar per target, with a marker at the target. Values in 0-100. |\n| `pyramid-chart` | bars | `categories` | rank, compare | Stacked tiers whose width encodes the value (0-100). |\n| `heatmap-chart` | points-grids | `matrix` | compare, distribution | Labelled rows of values, normalised against `scaleMax`. |\n| `treemap-chart` | points-grids | `parts` | part-to-whole | Tiles of `cols \xD7 rows` cells placed in a `columns \xD7 rows` grid. |\n| `sankey-chart` | flows | `links` | flow, part-to-whole | Flow bands between layered nodes. |\n| `activity-grid` | points-grids | `events` | schedule, trend | One cell per day, a column per week. |\n| `step-chart` | lines | `series` | trend, change | A series drawn as steps. |\n| `sparkline-rows` | lines | `series` | trend, compare, kpi | One row per series \u2014 name, sparkline, readout. |\n| `kpi-card` | lines | `single` | kpi, change | A metric, its delta, and an area sparkline of the series. |\n| `bar-chart` | bars | `categories` | compare, rank | Pill bars, as columns or rows, with an optional second series. |\n| `stacked-bar-chart` | bars | `categories` | compare, part-to-whole | One stacked segment per key. |\n| `composed-chart` | bars | `series` | compare, trend | Columns and a spline on one value scale. |\n| `waterfall-chart` | bars | `categories` | change, part-to-whole | Totals from zero and floating deltas from the running total. |\n| `funnel-chart` | bars | `categories` | progress, compare | Horizontal, centred stages. |\n| `candlestick-chart` | bars | `intervals` | change, trend | OHLC bodies and wicks. |\n| `area-chart` | areas | `series` | trend, change | A curved, toned area under its line. |\n| `range-band-chart` | areas | `intervals` | uncertainty, trend | The band between a low and a high series. |\n| `stream-chart` | areas | `series` | trend, part-to-whole, compare | Two waves, overlaid or stacked. |\n| `scatter-chart` | points-grids | `points` | correlation, distribution | Points on two linear scales, optionally sized. |\n| `bubble-chart` | points-grids | `points` | correlation, compare | Circles whose area encodes `sizeKey`. |\n| `donut-chart` | radial | `parts` | part-to-whole | Sectors \u221D value around a central readout. |\n| `radar-chart` | radial | `categories` | compare | One spoke per subject, a closed polygon of values. |\n| `polar-bar-chart` | radial | `categories` | compare, rank | 360\xB0 bars out from a hole, length \u221D value. |\n| `radial-arc-group` | radial | `categories` | compare, progress | Concentric 180\xB0 tracks, sweep \u221D value / the largest. |\n| `radial-rings` | radial | `categories` | progress | Concentric progress rings, sweep \u221D value in 0-100. |\n| `gauge-arc` | radial | `single` | kpi, progress | A 240\xB0 arc swept to a percent. |\n| `meter-chart` | radial | `single` | kpi, progress | A semicircular meter with a needle at a percent. |\n| `coxcomb-chart` | radial | `categories` | compare, part-to-whole | Equal angles, sector area \u221D value. |\n| `wind-rose` | radial | `distribution` | distribution | Observations of (bearing, speed) binned by compass sector and speed. |\n| `volvelle-chart` | radial | `categories` | schedule, compare | Concentric categorical rings read against one index. |\n| `chord-ring` | flows | `links` | flow, network | Directed flows between categories around a circle. |\n| `orbit-chart` | radial | `events` | schedule | Nested elliptical orbits with markers along them. |\n| `histogram-chart` | distributions-comparisons | `distribution` | distribution | Raw observations binned in the core. |\n| `ecdf-chart` | distributions-comparisons | `distribution` | distribution, compare | The empirical cumulative distribution as a step function. |\n| `box-plot-chart` | distributions-comparisons | `distribution` | distribution, compare | Quartiles, median, Tukey whiskers and outliers per group. |\n| `violin-chart` | distributions-comparisons | `distribution` | distribution, compare | A mirrored kernel density per group. |\n| `ridgeline-chart` | distributions-comparisons | `distribution` | distribution, compare, change | A kernel density per group on overlapping baselines. |\n| `beeswarm-chart` | distributions-comparisons | `distribution` | distribution | One point per observation, packed without overlap. |\n| `lollipop-chart` | distributions-comparisons | `categories` | compare, rank | A stem from the baseline and a head at the value. |\n| `dumbbell-chart` | distributions-comparisons | `categories` | change, compare | Two values per category joined by a segment. |\n| `slope-chart` | distributions-comparisons | `categories` | change, rank | Two period axes, one segment per category. |\n| `bump-chart` | distributions-comparisons | `series` | rank, change | The rank of each series at each x. |\n| `error-bar-chart` | distributions-comparisons | `intervals` | uncertainty, compare | A point estimate with its interval per category. |\n| `interval-chart` | distributions-comparisons | `intervals` | schedule | Floating bars from start to end on lanes. |\n| `diverging-bar-chart` | distributions-comparisons | `parts` | part-to-whole, compare | Ordered levels stacked on both sides of a neutral centre. |\n| `connected-scatter-chart` | distributions-comparisons | `points` | correlation, change | An ordered path through x-y points. |\n| `waffle-chart` | hierarchies-dimensions | `parts` | part-to-whole, progress | A unit grid filled in reading order by category. |\n| `marimekko-chart` | hierarchies-dimensions | `matrix` | part-to-whole, compare | Column width by total, segment height by share. |\n| `squarified-treemap` | hierarchies-dimensions | `hierarchy` | hierarchy, part-to-whole | Nested rectangles, area by value, drillable through `rootId` and `onRootChange`. |\n| `sunburst-chart` | hierarchies-dimensions | `hierarchy` | hierarchy, part-to-whole | A hierarchy as rings of arcs, drillable through `rootId` and `onRootChange`. |\n| `tree-chart` | hierarchies-dimensions | `hierarchy` | hierarchy | A tidy node-link tree. |\n| `parallel-coordinates-chart` | hierarchies-dimensions | `matrix` | correlation, compare | One polyline per row across parallel axes. |\n| `polar-line-chart` | hierarchies-dimensions | `series` | trend, compare | A line over angle and radius. |\n| `polar-scatter-chart` | hierarchies-dimensions | `points` | distribution, correlation | Points over angle and radius. |\n| `density-bin-chart` | fields-networks | `points` | distribution, correlation | X-y points counted in two-dimensional bins. |\n| `contour-chart` | fields-networks | `points` | distribution, correlation | Iso-lines and filled bands of a density or a grid. |\n| `delaunay-chart` | fields-networks | `points` | network, distribution | The triangulation of x-y points, or its Voronoi cells. |\n| `vector-field-chart` | fields-networks | `field` | flow | An arrow per grid point. |\n| `network-chart` | fields-networks | `links` | network, flow | A node-link graph. |\n\n## The recommender's table\n\nThe scores run from 0 to 1. An adjustment applies when the row count (`rows`) or the number of\nvalue columns (`values`) passes its bound.\n\n| Shape | Intent | Charts, best first | Adjustments |\n|---|---|---|---|\n| `series` | `trend` | `line-chart` 0.9 \u2014 A line is the plainest reading of a value over an ordered axis.<br>`area-chart` 0.8 \u2014 An area gives one series the weight of its magnitude.<br>`step-chart` 0.6 \u2014 Steps show a value that holds until it changes.<br>`stream-chart` 0.5 \u2014 Several value columns overlay or stack as waves.<br>`polar-line-chart` 0.3 \u2014 A cyclic axis (hours, months, degrees) closes the line around a circle. | values>1: `stream-chart` +0.3 \u2014 Several value fields read together as streams.<br>values>1: `area-chart` -0.2 \u2014 An area draws one series only. |\n| `series` | `change` | `line-chart` 0.8 \u2014 The slope between points is the change.<br>`step-chart` 0.75 \u2014 Steps mark when the value changed and by how much.<br>`area-chart` 0.6 \u2014 An area shows the change in magnitude.<br>`bump-chart` 0.5 \u2014 When the change that matters is in rank. | |\n| `series` | `compare` | `line-chart` 0.8 \u2014 A second series draws as a dotted baseline against the first.<br>`composed-chart` 0.75 \u2014 Columns and a line share one value scale.<br>`stream-chart` 0.6 \u2014 Several series overlaid on one axis.<br>`sparkline-rows` 0.55 \u2014 One small line per series, side by side with its readout.<br>`polar-line-chart` 0.3 \u2014 Values around a cycle compared by angle. | |\n| `series` | `rank` | `bump-chart` 0.9 \u2014 The rank of each series at each x, ranks joined across x. | |\n| `series` | `kpi` | `sparkline-rows` 0.85 \u2014 One row per series: its name, its trend and its latest readout.<br>`kpi-card` 0.75 \u2014 One metric, its delta and its trend. | |\n| `series` | `part-to-whole` | `stream-chart` 0.8 \u2014 Stacked waves show each part of a total over x. | |\n| `categories` | `compare` | `bar-chart` 0.9 \u2014 Bars compare values against one common baseline.<br>`lollipop-chart` 0.75 \u2014 A lighter mark per category, readable with many of them.<br>`radar-chart` 0.5 \u2014 Spokes compare a few subjects at once.<br>`polar-bar-chart` 0.4 \u2014 Bars around a circle, for a cyclic set of categories.<br>`coxcomb-chart` 0.35 \u2014 Equal angles, area by value: cyclic categories such as months.<br>`radial-arc-group` 0.3 \u2014 Concentric tracks, each swept by its value. | rows>12: `lollipop-chart` +0.2 \u2014 Many categories read better as lollipops.<br>rows>12: `radar-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>rows>12: `polar-bar-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>rows>12: `coxcomb-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>values>1: `bar-chart` +0.05 \u2014 A second value field draws as a second series of bars. |\n| `categories` | `rank` | `bar-chart` 0.85 \u2014 Sorted bars read as a ranking.<br>`lollipop-chart` 0.85 \u2014 Lollipops sort themselves with `sort`.<br>`pyramid-chart` 0.5 \u2014 Stacked tiers, widest at the base.<br>`polar-bar-chart` 0.4 \u2014 A ranking around a circle. | |\n| `categories` | `part-to-whole` | `stacked-bar-chart` 0.85 \u2014 Each bar stacks its parts, one segment per value column.<br>`waterfall-chart` 0.6 \u2014 Parts that add up to a running total.<br>`coxcomb-chart` 0.4 \u2014 Sectors whose area is each part. | |\n| `categories` | `change` | `dumbbell-chart` 0.9 \u2014 Two values per category joined by a segment: before and after.<br>`slope-chart` 0.85 \u2014 Two period axes, one segment per category: the slope is the change.<br>`waterfall-chart` 0.75 \u2014 Each step a delta from the running total. | |\n| `categories` | `progress` | `bullet-chart` 0.9 \u2014 Each bar against its own target.<br>`radial-rings` 0.75 \u2014 Concentric rings, each swept to its percent.<br>`funnel-chart` 0.7 \u2014 Stages that narrow, such as a conversion.<br>`radial-arc-group` 0.5 \u2014 Tracks swept relative to the largest. | |\n| `categories` | `kpi` | `bullet-chart` 0.8 \u2014 Each measure against its target, compact.<br>`radial-rings` 0.6 \u2014 A few percents at a glance. | |\n| `parts` | `part-to-whole` | `donut-chart` 0.9 \u2014 A ring reads a few shares of one whole around a central figure.<br>`waffle-chart` 0.85 \u2014 Unit cells make the shares countable.<br>`treemap-chart` 0.7 \u2014 Tiles sized by share.<br>`diverging-bar-chart` 0.4 \u2014 For ordered levels (agree\u2026 disagree) around a neutral centre.<br>`stacked-bar-chart` 0.35 \u2014 One bar stacked with the shares, to set beside other wholes. | rows>6: `donut-chart` -0.3 \u2014 A ring loses its shares past six slices.<br>rows>6: `treemap-chart` +0.1 \u2014 Tiles hold many shares better than a ring. |\n| `parts` | `compare` | `diverging-bar-chart` 0.8 \u2014 Likert-style levels on both sides of a neutral centre, row by row.<br>`waffle-chart` 0.6 \u2014 Countable cells per part. | |\n| `parts` | `progress` | `waffle-chart` 0.8 \u2014 A hundred cells filled to the share done. | |\n| `matrix` | `compare` | `heatmap-chart` 0.9 \u2014 One toned cell per row and column.<br>`marimekko-chart` 0.7 \u2014 Columns by total, segments by share.<br>`parallel-coordinates-chart` 0.6 \u2014 One polyline per row across many dimensions. | |\n| `matrix` | `part-to-whole` | `marimekko-chart` 0.9 \u2014 Each column a whole, each segment its share, column width by total. | |\n| `matrix` | `correlation` | `parallel-coordinates-chart` 0.9 \u2014 Crossing lines between axes show how dimensions move together.<br>`heatmap-chart` 0.6 \u2014 A grid of values, read for patterns. | |\n| `matrix` | `distribution` | `heatmap-chart` 0.8 \u2014 Where the high values gather in the grid. | |\n| `hierarchy` | `hierarchy` | `tree-chart` 0.85 \u2014 The structure itself, node by node.<br>`squarified-treemap` 0.8 \u2014 Nested rectangles, drillable.<br>`sunburst-chart` 0.75 \u2014 Rings of arcs, one ring per level, drillable. | |\n| `hierarchy` | `part-to-whole` | `squarified-treemap` 0.9 \u2014 Area by value, nested by level.<br>`sunburst-chart` 0.85 \u2014 Each arc its share of its parent. | |\n| `links` | `flow` | `sankey-chart` 0.9 \u2014 Bands between layered stages, width by value.<br>`chord-ring` 0.75 \u2014 Flows between categories around a circle, both ways.<br>`network-chart` 0.5 \u2014 When the links matter more than their volume. | |\n| `links` | `network` | `network-chart` 0.9 \u2014 Nodes and links laid out by a seeded force.<br>`chord-ring` 0.7 \u2014 Who connects to whom, around a circle. | |\n| `links` | `part-to-whole` | `sankey-chart` 0.8 \u2014 How a total splits and merges across stages. | |\n| `points` | `correlation` | `scatter-chart` 0.9 \u2014 Points on two linear scales.<br>`bubble-chart` 0.75 \u2014 A third variable as each point\u2019s area.<br>`density-bin-chart` 0.6 \u2014 Counts per bin when points overlap.<br>`connected-scatter-chart` 0.5 \u2014 When the points have an order.<br>`polar-scatter-chart` 0.3 \u2014 When one variable is an angle. | rows>500: `density-bin-chart` +0.35 \u2014 Hundreds of points read better as counts per bin.<br>rows>500: `scatter-chart` -0.2 \u2014 Points overplot and hide their density.<br>values>2: `bubble-chart` +0.2 \u2014 A third numeric field can size the points. |\n| `points` | `distribution` | `density-bin-chart` 0.85 \u2014 Points counted in hexagonal or square bins.<br>`contour-chart` 0.8 \u2014 Iso-lines of the density.<br>`scatter-chart` 0.6 \u2014 Every point, when there are few.<br>`polar-scatter-chart` 0.4 \u2014 Points by angle and radius. | |\n| `points` | `change` | `connected-scatter-chart` 0.9 \u2014 An ordered path through x-y points: how two values moved together. | |\n| `points` | `network` | `delaunay-chart` 0.85 \u2014 Neighbours by triangulation, or each point\u2019s Voronoi cell. | |\n| `points` | `compare` | `bubble-chart` 0.7 \u2014 Positions and sizes compared at once. | |\n| `distribution` | `distribution` | `histogram-chart` 0.9 \u2014 Observations binned in the core.<br>`box-plot-chart` 0.8 \u2014 Quartiles, median, whiskers and outliers.<br>`violin-chart` 0.75 \u2014 The density\u2019s shape, mirrored.<br>`beeswarm-chart` 0.7 \u2014 Every observation, packed without overlap.<br>`ecdf-chart` 0.65 \u2014 The cumulative share below each value.<br>`wind-rose` 0.3 \u2014 When the observations carry a bearing. | rows<30: `beeswarm-chart` +0.25 \u2014 Few observations: show each one.<br>rows<30: `histogram-chart` -0.2 \u2014 Few observations make coarse bins.<br>rows>1000: `beeswarm-chart` -0.4 \u2014 Too many observations to draw one by one. |\n| `distribution` | `compare` | `box-plot-chart` 0.9 \u2014 Quartiles side by side, one box per group.<br>`violin-chart` 0.85 \u2014 Density shapes side by side.<br>`ridgeline-chart` 0.8 \u2014 Densities on overlapping baselines, one per group.<br>`ecdf-chart` 0.75 \u2014 Cumulative curves of each group on one axis. | |\n| `distribution` | `change` | `ridgeline-chart` 0.85 \u2014 A density per period, stacked in order. | |\n| `intervals` | `uncertainty` | `error-bar-chart` 0.9 \u2014 A point estimate with its interval per category.<br>`range-band-chart` 0.85 \u2014 A band between low and high over x. | |\n| `intervals` | `trend` | `range-band-chart` 0.85 \u2014 The band between low and high over time.<br>`candlestick-chart` 0.8 \u2014 Open, high, low and close per period. | |\n| `intervals` | `change` | `candlestick-chart` 0.9 \u2014 Each period\u2019s open-to-close change and its range. | |\n| `intervals` | `schedule` | `interval-chart` 0.95 \u2014 Floating bars from start to end on lanes. | |\n| `events` | `schedule` | `activity-grid` 0.85 \u2014 One cell per day, a column per week. | |\n| `events` | `trend` | `activity-grid` 0.8 \u2014 Activity per day over weeks. | |\n| `single` | `kpi` | `kpi-card` 0.9 \u2014 The figure, its delta and its trend.<br>`gauge-arc` 0.75 \u2014 A percent on a 240\xB0 arc.<br>`meter-chart` 0.7 \u2014 A percent with a needle. | |\n| `single` | `progress` | `gauge-arc` 0.85 \u2014 An arc swept to the percent done.<br>`meter-chart` 0.8 \u2014 A needle at the percent done. | |\n| `field` | `flow` | `vector-field-chart` 0.95 \u2014 An arrow per grid point, its direction and magnitude. | |\n| `field` | `distribution` | `contour-chart` 0.85 \u2014 Iso-lines and bands of a scalar grid (`source: 'grid'`). | |\n\n## Common chart props\n\nEvery chart takes these, under the same names in React, Vue and Angular.\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `data` | `readonly Datum[]` | | Rows to draw. If omitted, the demo dataset is rendered (REQ-093): accessor props (`\u2026Key`, `keys`, `names`, `levels`, `axis`, `dimensions`, `period`, `nodes`) are ignored, every other prop applies. |\n| `ground` | `GroundRef` | `'silverpoint'` | Style ground. Defaults to the app provider's, or `silverpoint`. |\n| `substrate` | `SubstrateName` | `'cream'` | Prepared substrate within the ground (REQ-046). |\n| `mode` | `InkMode` | `'ink'` | `ink` by default; `precision` disables inking (REQ-021). |\n| `palette` | `Palette` | | Colours over the ground's, field by field, written on the root's `style` (REQ-461). Merged over the dashboard's and the provider's (REQ-462); presets are on `@silverpoint/core/palettes`. |\n| `seed` | `Seed` | | Seed. If omitted, it is derived from `id` stably (REQ-003). |\n| `id` | `string` | | Stable identifier. If omitted, it is generated deterministically. |\n| `height` | `number` | `160` | Height of the drawing area in px. Width is the container's unless pinned. |\n| `width` | `number` | | |\n| `chrome` | `'card' \\| 'bare'` | `'card'` | `card` draws the full frame; `bare` only the drawing area (REQ-095). |\n| `hatchFill` | `'tile' \\| 'per-shape'` | `'tile'` | How areas are filled (REQ-029). |\n| `title` | `string` | | |\n| `badge` | `string` | | |\n| `value` | `string \\| number` | | |\n| `unit` | `string` | | |\n| `footerLeft` | `string` | | |\n| `footerRight` | `string` | | |\n| `label` | `string` | | Accessible name. If omitted, it is derived from `title` (REQ-120). |\n| `description` | `string` | | Long description for screen readers (REQ-120). |\n| `dataTable` | `'visible' \\| 'hidden' \\| 'none'` | `'hidden'` | Tabular alternative; `hidden` leaves it for assistive technology only (REQ-121). |\n| `locale` | `string` | | |\n| `numberFormat` | `Intl.NumberFormatOptions` | | |\n| `className` | `string` | | |\n\nDefaults to know:\n\n- `height` is 160, the drawing area without the card frame.\n- `chrome` is `card`. `bare` drops the frame.\n- `dataTable` is `hidden`: the table stays in the page for screen readers only.\n- `hatchFill` is `tile`. `per-shape` traces the hatching shape by shape, which costs 10 to 40 times\n the path weight, so keep it for a hero chart or an export.\n\n## Events\n\n| React | Vue | Angular | Payload |\n|---|---|---|---|\n| `onActiveChange` | `@active-change` | `(activeChange)` | the item under the pointer or keyboard focus, or `null` |\n| `onSelect` | `@select` | `(select)` | the item clicked or chosen with Enter or Space |\n| `onRootChange` | `@root-change` | `(rootChange)` | the sunburst's or treemap's new root id, `null` for the data root |\n",
|
|
11416
|
-
"grounds-and-palettes": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Grounds and palettes\n\n*Describes silverpoint 0.
|
|
11417
|
-
"dashboard": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Dashboard\n\n*Describes silverpoint 0.
|
|
11418
|
-
"ui-components": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# UI and composed components\n\n*Describes silverpoint 0.7.0.*\n\nEvery component is named `Sp<Name>` in the three frameworks (`SpButton`, `<sp-input>`), imported\nfrom its own subpath (`@silverpoint/react/ui/button`), and drawn in the same ground as the\ncharts. Import `@silverpoint/grounds/ui.css` once, after `styles.css`.\n\n## Binding a value\n\n| | Controlled | Uncontrolled | Change |\n|---|---|---|---|\n| React | `value` (`checked` for Checkbox and Switch) | `defaultValue` (`defaultChecked`) | `onChange(value)`: the value, not the DOM event |\n| Vue | `v-model` | omit `v-model`, pass `default-value` | `update:modelValue`, then `change` on commit |\n| Angular | `[(value)]`, or `formControl` / `ngModel` | `[defaultValue]` | `(valueChange)` |\n\nValue events fire on user input only, never on a prop change, and never for a disabled component\nor item. Angular value components are `ControlValueAccessor`s, so they work in reactive and\ntemplate-driven forms.\n\n## Server rendering\n\nIn React, display components also have server entries (`@silverpoint/react/server/ui/<name>`):\n`card`, `tag`, `badge`, `divider`, `progress`, `alert`, `skeleton`, `steps`, `surface`, `glyph`,\n`table` (unsortable), `breadcrumb`, `avatar`, `statistic`, `descriptions`, `timeline-list`, `empty`\nand `result`. Every other component is a client component.\n\n## Notes\n\n- `SpButton` is an attribute component in Angular (`<button spButton>`, `<a spButton>`), so your own\n element is the control. `SpSurface` is `[spSurface]` in the same way.\n- `SpTabs` renders `SpTabPanel` children matched by `value`.\n- `SpTable` draws its rows as given: sort them yourself on `onSort` (`@sort`, `(sort)`), which also\n keeps paging with `SpPagination` correct.\n- A link's `href` (`SpButton`, `SpBreadcrumb`) keeps relative URLs and the `http`, `https`,\n `mailto` and `tel` schemes. Any other is dropped with `SP017`.\n- Named content: React takes node props, Vue slots (`prefix`, `suffix`, `extra`, `footer`), and\n Angular templates (`<ng-template spExtra>`, `spFooter`, `spPrefix`, `spSuffix`).\n\n**Contents:** [SpButton](#spbutton) \xB7 [SpInput](#spinput) \xB7 [SpCheckbox](#spcheckbox) \xB7 [SpRadioGroup](#spradiogroup) \xB7 [SpSwitch](#spswitch) \xB7 [SpSlider](#spslider) \xB7 [SpRate](#sprate) \xB7 [SpSegmented](#spsegmented) \xB7 [SpTabs](#sptabs) \xB7 [SpSteps](#spsteps) \xB7 [SpCard](#spcard) \xB7 [SpTag](#sptag) \xB7 [SpBadge](#spbadge) \xB7 [SpDivider](#spdivider) \xB7 [SpProgress](#spprogress) \xB7 [SpAlert](#spalert) \xB7 [SpSkeleton](#spskeleton) \xB7 [SpSurface](#spsurface) \xB7 [SpGlyph](#spglyph) \xB7 [SpTable](#sptable) \xB7 [SpPagination](#sppagination) \xB7 [SpBreadcrumb](#spbreadcrumb) \xB7 [SpAvatar](#spavatar) \xB7 [SpStatistic](#spstatistic) \xB7 [SpDescriptions](#spdescriptions) \xB7 [SpTimelineList](#sptimelinelist) \xB7 [SpCollapse](#spcollapse) \xB7 [SpEmpty](#spempty) \xB7 [SpResult](#spresult) \xB7 [SpTextarea](#sptextarea) \xB7 [SpInputNumber](#spinputnumber)\n\n## SpButton\n\n`button` \xB7 A button or a link styled as one; `primary` and `danger` variants. (actions)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpButton` | `SpButton` | `button[spButton]` | `sp_button` |\n| Import | `@silverpoint/react/ui/button` | `@silverpoint/vue/ui/button` | `@silverpoint/angular/ui/button` | `reflex_silverpoint_react` |\n\n**Events:** React `onClick`; Vue `click`; Angular .\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `default`, `primary`, `danger`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `variant` | `UiVariant` | `'default'` | Default `'default'`; `danger` also draws the exact \u2715 glyph (REQ-310). |\n| `type` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Default `'button'`. |\n| `disabled` | `boolean` | | Not focusable, not submitted; drawn with the disabled tone. |\n| `label` | `string` | | Accessible name of an icon-only button (REQ-319). |\n| `block` | `boolean` | | Fills the width of its container. |\n| `href` | `string` | | Renders an `<a>`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpButton } from '@silverpoint/react/ui/button';\n\nexport function ButtonView() {\n return (\n <SpButton>\n Default\n </SpButton>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpButton } from '@silverpoint/vue/ui/button';\n</script>\n\n<template>\n <SpButton>\n Default\n </SpButton>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpButton } from '@silverpoint/angular/ui/button';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-button-view',\n imports: [SpButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n spButton\n >\n Default\n </button>\n `,\n})\nexport class ButtonView {}\n```\n\n## SpInput\n\n`input` \xB7 A labelled text field with an optional message and an invalid state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpInput` | `SpInput` | `sp-input` | `sp_input` |\n| Import | `@silverpoint/react/ui/input` | `@silverpoint/vue/ui/input` | `@silverpoint/angular/ui/input` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**Content:** React `prefix`, `suffix`; Vue `prefix`, `suffix`; Angular `spPrefix`, `spSuffix`.\n\n**States:** `empty`, `filled`, `invalid`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `type` | `'text' \\| 'search' \\| 'email' \\| 'url' \\| 'tel' \\| 'password' \\| 'number'` | `'text'` | Native input type. Default `'text'`. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `name` | `string` | | Form field name; the native input submits under it (REQ-323). |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpInput } from '@silverpoint/react/ui/input';\n\nexport function InputView() {\n const [value, setValue] = useState<string>('');\n return (\n <SpInput\n label=\"Search charts\"\n placeholder=\"Search charts\u2026\"\n type=\"search\"\n name=\"q\"\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpInput } from '@silverpoint/vue/ui/input';\n\nconst value = ref<string>('');\n</script>\n\n<template>\n <SpInput\n label=\"Search charts\"\n placeholder=\"Search charts\u2026\"\n type=\"search\"\n name=\"q\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpInput } from '@silverpoint/angular/ui/input';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-input-view',\n imports: [SpInput],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-input\n [label]=\"'Search charts'\"\n [placeholder]=\"'Search charts\u2026'\"\n [type]=\"'search'\"\n [name]=\"'q'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class InputView {\n protected readonly value = signal<string>('');\n}\n```\n\n## SpCheckbox\n\n`checkbox` \xB7 A labelled checkbox, with an indeterminate state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCheckbox` | `SpCheckbox` | `sp-checkbox` | `sp_checkbox` |\n| Import | `@silverpoint/react/ui/checkbox` | `@silverpoint/vue/ui/checkbox` | `@silverpoint/angular/ui/checkbox` | `reflex_silverpoint_react` |\n\n**Value:** React `checked + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `unchecked`, `checked`, `indeterminate`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The visible text and accessible name. |\n| `name` | `string` | | Form field name; submitted as `on` when checked. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `indeterminate` | `boolean` | | Draws the exact dash and sets the native `indeterminate` state. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpCheckbox } from '@silverpoint/react/ui/checkbox';\n\nexport function CheckboxView() {\n const [value, setValue] = useState<boolean>(false);\n return (\n <SpCheckbox\n label=\"Legend\"\n name=\"legend\"\n checked={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpCheckbox } from '@silverpoint/vue/ui/checkbox';\n\nconst value = ref<boolean>(false);\n</script>\n\n<template>\n <SpCheckbox\n label=\"Legend\"\n name=\"legend\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpCheckbox } from '@silverpoint/angular/ui/checkbox';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-checkbox-view',\n imports: [SpCheckbox],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-checkbox\n [label]=\"'Legend'\"\n [name]=\"'legend'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class CheckboxView {\n protected readonly value = signal<boolean>(false);\n}\n```\n\n## SpRadioGroup\n\n`radio-group` \xB7 One choice among a few, as a fieldset of radios. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpRadioGroup` | `SpRadioGroup` | `sp-radio-group` | `sp_radio_group` |\n| Import | `@silverpoint/react/ui/radio-group` | `@silverpoint/vue/ui/radio-group` | `@silverpoint/angular/ui/radio-group` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `selected`, `disabled-item`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The choices; each a native radio. Keys are unique (REQ-325). |\n| `name` | `string` | | **Required.** Required: the native radios submit under it (REQ-323). |\n| `label` | `string` | | **Required.** The group's name, its `<legend>`. |\n| `orientation` | `UiOrientation` | `'vertical'` | Default `'vertical'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpRadioGroup } from '@silverpoint/react/ui/radio-group';\n\nexport function RadioGroupView() {\n const [value, setValue] = useState<string>('silverpoint');\n return (\n <SpRadioGroup\n label=\"Ground\"\n name=\"ground\"\n items={[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]}\n orientation=\"horizontal\"\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpRadioGroup } from '@silverpoint/vue/ui/radio-group';\n\nconst value = ref<string>('silverpoint');\n</script>\n\n<template>\n <SpRadioGroup\n label=\"Ground\"\n name=\"ground\"\n :items=\"[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]\"\n orientation=\"horizontal\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpRadioGroup } from '@silverpoint/angular/ui/radio-group';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-radio-group-view',\n imports: [SpRadioGroup],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-radio-group\n [label]=\"'Ground'\"\n [name]=\"'ground'\"\n [items]=\"[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]\"\n [orientation]=\"'horizontal'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class RadioGroupView {\n protected readonly value = signal<string>('silverpoint');\n}\n```\n\n## SpSwitch\n\n`switch` \xB7 An on/off toggle with the switch role. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSwitch` | `SpSwitch` | `sp-switch` | `sp_switch` |\n| Import | `@silverpoint/react/ui/switch` | `@silverpoint/vue/ui/switch` | `@silverpoint/angular/ui/switch` | `reflex_silverpoint_react` |\n\n**Value:** React `checked + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `off`, `on`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The visible text and accessible name. |\n| `name` | `string` | | Form field name; submitted as `on` when on. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSwitch } from '@silverpoint/react/ui/switch';\n\nexport function SwitchView() {\n const [value, setValue] = useState<boolean>(false);\n return (\n <SpSwitch\n label=\"Linked hover\"\n name=\"linked\"\n checked={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSwitch } from '@silverpoint/vue/ui/switch';\n\nconst value = ref<boolean>(false);\n</script>\n\n<template>\n <SpSwitch\n label=\"Linked hover\"\n name=\"linked\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSwitch } from '@silverpoint/angular/ui/switch';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-switch-view',\n imports: [SpSwitch],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-switch\n [label]=\"'Linked hover'\"\n [name]=\"'linked'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SwitchView {\n protected readonly value = signal<boolean>(false);\n}\n```\n\n## SpSlider\n\n`slider` \xB7 A value on a range, with optional marks. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSlider` | `SpSlider` | `sp-slider` | `sp_slider` |\n| Import | `@silverpoint/react/ui/slider` | `@silverpoint/vue/ui/slider` | `@silverpoint/angular/ui/slider` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `marks`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** Accessible name of the native range input. |\n| `min` | `number` | `0` | Default `0`. |\n| `max` | `number` | `100` | Default `100`. |\n| `step` | `number` | `1` | Default `1`. |\n| `name` | `string` | | Form field name; the native input submits under it. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `marks` | `readonly number[]` | | Values on the rail that get a labelled mark. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSlider } from '@silverpoint/react/ui/slider';\n\nexport function SliderView() {\n const [value, setValue] = useState<number>(30);\n return (\n <SpSlider\n label=\"Volume\"\n name=\"volume\"\n marks={[0, 25, 50, 75, 100]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSlider } from '@silverpoint/vue/ui/slider';\n\nconst value = ref<number>(30);\n</script>\n\n<template>\n <SpSlider\n label=\"Volume\"\n name=\"volume\"\n :marks=\"[0, 25, 50, 75, 100]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSlider } from '@silverpoint/angular/ui/slider';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-slider-view',\n imports: [SpSlider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-slider\n [label]=\"'Volume'\"\n [name]=\"'volume'\"\n [marks]=\"[0, 25, 50, 75, 100]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SliderView {\n protected readonly value = signal<number>(30);\n}\n```\n\n## SpRate\n\n`rate` \xB7 A rating from 1 to `count`, optionally read-only. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpRate` | `SpRate` | `sp-rate` | `sp_rate` |\n| Import | `@silverpoint/react/ui/rate` | `@silverpoint/vue/ui/rate` | `@silverpoint/angular/ui/rate` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `three`, `read-only`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The group's name, its `<legend>`. |\n| `count` | `number` | `5` | Default `5`, in 1..10; each mark an exact lozenge. |\n| `name` | `string` | | Form field name; the native radios submit under it. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Shows the value; the keyboard and the pointer do not change it. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpRate } from '@silverpoint/react/ui/rate';\n\nexport function RateView() {\n const [value, setValue] = useState<number>(3);\n return (\n <SpRate\n label=\"Quality\"\n name=\"quality\"\n count={5}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpRate } from '@silverpoint/vue/ui/rate';\n\nconst value = ref<number>(3);\n</script>\n\n<template>\n <SpRate\n label=\"Quality\"\n name=\"quality\"\n :count=\"5\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpRate } from '@silverpoint/angular/ui/rate';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-rate-view',\n imports: [SpRate],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-rate\n [label]=\"'Quality'\"\n [name]=\"'quality'\"\n [count]=\"5\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class RateView {\n protected readonly value = signal<number>(3);\n}\n```\n\n## SpSegmented\n\n`segmented` \xB7 One choice among a few, as joined segments. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSegmented` | `SpSegmented` | `sp-segmented` | `sp_segmented` |\n| Import | `@silverpoint/react/ui/segmented` | `@silverpoint/vue/ui/segmented` | `@silverpoint/angular/ui/segmented` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `first`, `middle`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The options; each a native radio. Keys are unique (REQ-325). |\n| `label` | `string` | | **Required.** The control's name, its `<legend>`. |\n| `name` | `string` | | Form field name; the native radios submit under it. |\n| `block` | `boolean` | | Fills the width of its container. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSegmented } from '@silverpoint/react/ui/segmented';\n\nexport function SegmentedView() {\n const [value, setValue] = useState<string>('day');\n return (\n <SpSegmented\n label=\"Period\"\n name=\"period\"\n items={[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSegmented } from '@silverpoint/vue/ui/segmented';\n\nconst value = ref<string>('day');\n</script>\n\n<template>\n <SpSegmented\n label=\"Period\"\n name=\"period\"\n :items=\"[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSegmented } from '@silverpoint/angular/ui/segmented';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-segmented-view',\n imports: [SpSegmented],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-segmented\n [label]=\"'Period'\"\n [name]=\"'period'\"\n [items]=\"[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SegmentedView {\n protected readonly value = signal<string>('day');\n}\n```\n\n## SpTabs\n\n`tabs` \xB7 Tabs and their panels (`SpTabPanel`), with automatic or manual activation. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTabs` | `SpTabs` | `sp-tabs` | `sp_tabs` |\n| Import | `@silverpoint/react/ui/tabs` | `@silverpoint/vue/ui/tabs` | `@silverpoint/angular/ui/tabs` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `first`, `disabled-tab`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The tabs; a disabled one is skipped by the arrows. Keys are unique (REQ-325). |\n| `label` | `string` | | Accessible name of the tab list. |\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `activation` | `'automatic' \\| 'manual'` | `'automatic'` | Default `'automatic'`: a tab is selected as focus reaches it. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpTabs } from '@silverpoint/react/ui/tabs';\n\nexport function TabsView() {\n const [value, setValue] = useState<string>('overview');\n return (\n <SpTabs\n label=\"Views\"\n items={[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpTabs } from '@silverpoint/vue/ui/tabs';\n\nconst value = ref<string>('overview');\n</script>\n\n<template>\n <SpTabs\n label=\"Views\"\n :items=\"[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpTabs } from '@silverpoint/angular/ui/tabs';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tabs-view',\n imports: [SpTabs],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tabs\n [label]=\"'Views'\"\n [items]=\"[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class TabsView {\n protected readonly value = signal<string>('overview');\n}\n```\n\n## SpSteps\n\n`steps` \xB7 The steps of a process, with the current one and an error state. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSteps` | `SpSteps` | `sp-steps` | `sp_steps` |\n| Import | `@silverpoint/react/ui/steps` | `@silverpoint/vue/ui/steps` | `@silverpoint/angular/ui/steps` | `reflex_silverpoint_react` |\n\n**States:** `current`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly StepItem[]` | | **Required.** The steps, in order; a status is derived from `current` unless set. |\n| `current` | `number` | | **Required.** 0-based. |\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `label` | `string` | | Accessible name of the list. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSteps } from '@silverpoint/react/ui/steps';\n\nexport function StepsView() {\n return (\n <SpSteps\n label=\"Release\"\n items={[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]}\n current={2}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSteps } from '@silverpoint/vue/ui/steps';\n</script>\n\n<template>\n <SpSteps\n label=\"Release\"\n :items=\"[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]\"\n :current=\"2\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSteps } from '@silverpoint/angular/ui/steps';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-steps-view',\n imports: [SpSteps],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-steps\n [label]=\"'Release'\"\n [items]=\"[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]\"\n [current]=\"2\"\n />\n `,\n})\nexport class StepsView {}\n```\n\n## SpCard\n\n`card` \xB7 A framed card with a title, an extra slot and a footer. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCard` | `SpCard` | `sp-card` | `sp_card` |\n| Import | `@silverpoint/react/ui/card` | `@silverpoint/vue/ui/card` | `@silverpoint/angular/ui/card` | `reflex_silverpoint_react` |\n\n**Content:** React `children`, `extra`, `footer`; Vue `default`, `extra`, `footer`; Angular `content`, `spExtra`, `spFooter`.\n\n**States:** `plain`, `titled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | Heading of the card; without it the card is a plain container. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCard } from '@silverpoint/react/ui/card';\n\nexport function CardView() {\n return (\n <SpCard>\n Hits per hour rose through the afternoon and eased at night.\n </SpCard>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCard } from '@silverpoint/vue/ui/card';\n</script>\n\n<template>\n <SpCard>\n Hits per hour rose through the afternoon and eased at night.\n </SpCard>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpCard } from '@silverpoint/angular/ui/card';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-card-view',\n imports: [SpCard],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-card>\n Hits per hour rose through the afternoon and eased at night.\n </sp-card>\n `,\n})\nexport class CardView {}\n```\n\n## SpTag\n\n`tag` \xB7 A short toned label, optionally closable. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTag` | `SpTag` | `sp-tag` | `sp_tag` |\n| Import | `@silverpoint/react/ui/tag` | `@silverpoint/vue/ui/tag` | `@silverpoint/angular/ui/tag` | `reflex_silverpoint_react` |\n\n**Events:** React `onClose`; Vue `close`; Angular `close`.\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `tone-1`, `closable`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `tone` | `UiToneLevel` | | Tonal level, default `1`. |\n| `closable` | `boolean` | | Adds a native close button; each adapter raises its close event. |\n| `closeLabel` | `string` | `Remove <text>` | Accessible name of the close button. Default `Remove <text>`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTag } from '@silverpoint/react/ui/tag';\n\nexport function TagView() {\n return (\n <SpTag\n tone={1}\n >\n draft\n </SpTag>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTag } from '@silverpoint/vue/ui/tag';\n</script>\n\n<template>\n <SpTag\n :tone=\"1\"\n >\n draft\n </SpTag>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTag } from '@silverpoint/angular/ui/tag';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tag-view',\n imports: [SpTag],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tag\n [tone]=\"1\"\n >\n draft\n </sp-tag>\n `,\n})\nexport class TagView {}\n```\n\n## SpBadge\n\n`badge` \xB7 A count or a dot over its content. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpBadge` | `SpBadge` | `sp-badge` | `sp_badge` |\n| Import | `@silverpoint/react/ui/badge` | `@silverpoint/vue/ui/badge` | `@silverpoint/angular/ui/badge` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `count`, `dot`, `overflow`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `count` | `number` | | The number shown, up to `max`. |\n| `max` | `number` | `99` | Default `99`; above it the badge reads `99+`. |\n| `dot` | `boolean` | | A dot with no number. |\n| `label` | `string` | | Accessible text of the badge, e.g. `unread messages`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBadge } from '@silverpoint/react/ui/badge';\n\nexport function BadgeView() {\n return (\n <SpBadge\n count={12}\n >\n Inbox\n </SpBadge>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBadge } from '@silverpoint/vue/ui/badge';\n</script>\n\n<template>\n <SpBadge\n :count=\"12\"\n >\n Inbox\n </SpBadge>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpBadge } from '@silverpoint/angular/ui/badge';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-badge-view',\n imports: [SpBadge],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-badge\n [count]=\"12\"\n >\n Inbox\n </sp-badge>\n `,\n})\nexport class BadgeView {}\n```\n\n## SpDivider\n\n`divider` \xB7 A rule between sections, optionally with text. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDivider` | `SpDivider` | `sp-divider` | `sp_divider` |\n| Import | `@silverpoint/react/ui/divider` | `@silverpoint/vue/ui/divider` | `@silverpoint/angular/ui/divider` | `reflex_silverpoint_react` |\n\n**States:** `plain`, `text`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `text` | `string` | | A caption set in the rule. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDivider } from '@silverpoint/react/ui/divider';\n\nexport function DividerView() {\n return (\n <SpDivider />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDivider } from '@silverpoint/vue/ui/divider';\n</script>\n\n<template>\n <SpDivider />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDivider } from '@silverpoint/angular/ui/divider';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-divider-view',\n imports: [SpDivider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-divider />\n `,\n})\nexport class DividerView {}\n```\n\n## SpProgress\n\n`progress` \xB7 Progress as a line or a circle, or indeterminate. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpProgress` | `SpProgress` | `sp-progress` | `sp_progress` |\n| Import | `@silverpoint/react/ui/progress` | `@silverpoint/vue/ui/progress` | `@silverpoint/angular/ui/progress` | `reflex_silverpoint_react` |\n\n**States:** `line`, `circle`, `indeterminate`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `value` | `number` | | 0..100; omitted, the progress is indeterminate. |\n| `shape` | `'line' \\| 'circle'` | `'line'` | Default `'line'`. |\n| `label` | `string` | | **Required.** Accessible name (REQ-318). |\n| `showValue` | `boolean` | `true` | Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpProgress } from '@silverpoint/react/ui/progress';\n\nexport function ProgressView() {\n return (\n <SpProgress\n label=\"Upload\"\n value={40}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpProgress } from '@silverpoint/vue/ui/progress';\n</script>\n\n<template>\n <SpProgress\n label=\"Upload\"\n :value=\"40\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpProgress } from '@silverpoint/angular/ui/progress';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-progress-view',\n imports: [SpProgress],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-progress\n [label]=\"'Upload'\"\n [value]=\"40\"\n />\n `,\n})\nexport class ProgressView {}\n```\n\n## SpAlert\n\n`alert` \xB7 An info, success, warning or error message, optionally closable. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpAlert` | `SpAlert` | `sp-alert` | `sp_alert` |\n| Import | `@silverpoint/react/ui/alert` | `@silverpoint/vue/ui/alert` | `@silverpoint/angular/ui/alert` | `reflex_silverpoint_react` |\n\n**Events:** React `onClose`; Vue `close`; Angular `close`.\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `info`, `success`, `warning`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `kind` | `AlertKind` | `'info'` | Default `'info'`. |\n| `title` | `string` | | Bold first line of the alert. |\n| `closable` | `boolean` | | Adds a native close button; each adapter raises its close event. |\n| `closeLabel` | `string` | `'Close'` | Accessible name of the close button. Default `'Close'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAlert } from '@silverpoint/react/ui/alert';\n\nexport function AlertView() {\n return (\n <SpAlert\n kind=\"info\"\n title=\"New ground available\"\n >\n cyanotype ships in 0.2.0.\n </SpAlert>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAlert } from '@silverpoint/vue/ui/alert';\n</script>\n\n<template>\n <SpAlert\n kind=\"info\"\n title=\"New ground available\"\n >\n cyanotype ships in 0.2.0.\n </SpAlert>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpAlert } from '@silverpoint/angular/ui/alert';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-alert-view',\n imports: [SpAlert],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-alert\n [kind]=\"'info'\"\n [title]=\"'New ground available'\"\n >\n cyanotype ships in 0.2.0.\n </sp-alert>\n `,\n})\nexport class AlertView {}\n```\n\n## SpSkeleton\n\n`skeleton` \xB7 A placeholder for content that is loading. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSkeleton` | `SpSkeleton` | `sp-skeleton` | `sp_skeleton` |\n| Import | `@silverpoint/react/ui/skeleton` | `@silverpoint/vue/ui/skeleton` | `@silverpoint/angular/ui/skeleton` | `reflex_silverpoint_react` |\n\n**States:** `paragraph`, `avatar`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `lines` | `number` | `3` | Default `3`, in 1..8. |\n| `avatar` | `boolean` | | Draws an avatar placeholder before the lines. |\n| `label` | `string` | `'Loading'` | Default `'Loading'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSkeleton } from '@silverpoint/react/ui/skeleton';\n\nexport function SkeletonView() {\n return (\n <SpSkeleton\n lines={3}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSkeleton } from '@silverpoint/vue/ui/skeleton';\n</script>\n\n<template>\n <SpSkeleton\n :lines=\"3\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSkeleton } from '@silverpoint/angular/ui/skeleton';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-skeleton-view',\n imports: [SpSkeleton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-skeleton\n [lines]=\"3\"\n />\n `,\n})\nexport class SkeletonView {}\n```\n\n## SpSurface\n\n`surface` \xB7 A framed, toned surface to build your own components on. (building-blocks)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSurface` | `SpSurface` | `[spSurface]` | `sp_surface` |\n| Import | `@silverpoint/react/ui/surface` | `@silverpoint/vue/ui/surface` | `@silverpoint/angular/ui/surface` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `frame-card`, `tone-2`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `as` | `string` | `'div'` | The element, a lowercase HTML tag name. Default `'div'`. |\n| `name` | `string` | | Adds the class `sp-<name>`, a lowercase ident. |\n| `frame` | `UiFrameKind` | | Draws a frame of that kind. |\n| `tone` | `UiToneLevel \\| string` | | Lays a tone: a level 1-4 of the ramp, or a state (`selected`, `primary`\u2026). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSurface } from '@silverpoint/react/ui/surface';\n\nexport function SurfaceView() {\n return (\n <SpSurface\n frame=\"card\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </SpSurface>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSurface } from '@silverpoint/vue/ui/surface';\n</script>\n\n<template>\n <SpSurface\n frame=\"card\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </SpSurface>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSurface } from '@silverpoint/angular/ui/surface';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-surface-view',\n imports: [SpSurface],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n spSurface\n [frame]=\"'card'\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </div>\n `,\n})\nexport class SurfaceView {}\n```\n\n## SpGlyph\n\n`glyph` \xB7 One of the exact glyphs the components draw (tick, cross, arrows, chevrons\u2026). (building-blocks)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpGlyph` | `SpGlyph` | `sp-glyph` | `sp_glyph` |\n| Import | `@silverpoint/react/ui/glyph` | `@silverpoint/vue/ui/glyph` | `@silverpoint/angular/ui/glyph` | `reflex_silverpoint_react` |\n\n**States:** `all`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `glyph` | `string` | | **Required.** A key of `UI_GLYPHS`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpGlyph } from '@silverpoint/react/ui/glyph';\n\nexport function GlyphView() {\n return (\n <SpGlyph\n glyph=\"tick\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpGlyph } from '@silverpoint/vue/ui/glyph';\n</script>\n\n<template>\n <SpGlyph\n glyph=\"tick\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpGlyph } from '@silverpoint/angular/ui/glyph';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-glyph-view',\n imports: [SpGlyph],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-glyph\n [glyph]=\"'tick'\"\n />\n `,\n})\nexport class GlyphView {}\n```\n\n## SpTable\n\n`table` \xB7 A data table with sortable columns, stripes and an empty state. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTable` | `SpTable` | `sp-table` | `sp_table` |\n| Import | `@silverpoint/react/ui/table` | `@silverpoint/vue/ui/table` | `@silverpoint/angular/ui/table` | `reflex_silverpoint_react` |\n\n**Events:** React `onSort`; Vue `sort`; Angular `sort`.\n\n**States:** `plain`, `sorted-striped`, `empty`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `columns` | `readonly TableColumn[]` | | **Required.** The columns, in order; each names the key it reads from a row. |\n| `data` | `readonly Readonly<Record<string, unknown>>[]` | | **Required.** The rows, drawn as given: the consumer sorts them (DD-040). |\n| `caption` | `string` | | The table's `<caption>`, its accessible name. |\n| `sortKey` | `string` | | A sortable column's key; another key sorts nothing, silently. |\n| `sortOrder` | `'asc' \\| 'desc'` | `'asc'` | Default `'asc'`. |\n| `striped` | `boolean` | `false` | Default `false`. |\n| `hoverable` | `boolean` | `true` | Default `true`. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n| `emptyText` | `string` | `'No data'` | Default `'No data'`. |\n| `rowKey` | `string` | | The column whose value keys each row. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTable } from '@silverpoint/react/ui/table';\n\nexport function TableView() {\n return (\n <SpTable\n caption=\"Orders\"\n columns={[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]}\n data={[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]}\n rowKey=\"order\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTable } from '@silverpoint/vue/ui/table';\n</script>\n\n<template>\n <SpTable\n caption=\"Orders\"\n :columns=\"[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]\"\n :data=\"[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]\"\n rowKey=\"order\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTable } from '@silverpoint/angular/ui/table';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-table-view',\n imports: [SpTable],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-table\n [caption]=\"'Orders'\"\n [columns]=\"[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]\"\n [data]=\"[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]\"\n [rowKey]=\"'order'\"\n />\n `,\n})\nexport class TableView {}\n```\n\n## SpPagination\n\n`pagination` \xB7 Page navigation with a current page, siblings and an optional total. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpPagination` | `SpPagination` | `sp-pagination` | `sp_pagination` |\n| Import | `@silverpoint/react/ui/pagination` | `@silverpoint/vue/ui/pagination` | `@silverpoint/angular/ui/pagination` | `reflex_silverpoint_react` |\n\n**Value:** React `current + onChange`, Vue `v-model:current`, Angular `[(current)]`.\n\n**Events:** React `onChange`; Vue ; Angular .\n\n**States:** `middle`, `total`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `total` | `number` | | **Required.** The number of items paged over. |\n| `pageSize` | `number` | `10` | Default `10`. |\n| `siblings` | `number` | `1` | Pages shown on each side of the current one. Default `1`. |\n| `showTotal` | `boolean` | `false` | Default `false`. |\n| `totalTemplate` | `string` | `'{start}\u2013{end} of {total}'` | Default `'{start}\u2013{end} of {total}'`. |\n| `label` | `string` | `'Pagination'` | Default `'Pagination'`. |\n| `previousLabel` | `string` | `'Previous page'` | Default `'Previous page'`. |\n| `nextLabel` | `string` | `'Next page'` | Default `'Next page'`. |\n| `pageLabel` | `string` | `'Page'` | Default `'Page'`. |\n| `disabled` | `boolean` | | Every page button disabled. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpPagination } from '@silverpoint/react/ui/pagination';\n\nexport function PaginationView() {\n const [value, setValue] = useState<number>(10);\n return (\n <SpPagination\n total={200}\n pageSize={10}\n current={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpPagination } from '@silverpoint/vue/ui/pagination';\n\nconst value = ref<number>(10);\n</script>\n\n<template>\n <SpPagination\n :total=\"200\"\n :pageSize=\"10\"\n v-model:current=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpPagination } from '@silverpoint/angular/ui/pagination';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-pagination-view',\n imports: [SpPagination],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-pagination\n [total]=\"200\"\n [pageSize]=\"10\"\n [(current)]=\"value\"\n />\n `,\n})\nexport class PaginationView {\n protected readonly value = signal<number>(10);\n}\n```\n\n## SpBreadcrumb\n\n`breadcrumb` \xB7 The trail of pages to the current one. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpBreadcrumb` | `SpBreadcrumb` | `sp-breadcrumb` | `sp_breadcrumb` |\n| Import | `@silverpoint/react/ui/breadcrumb` | `@silverpoint/vue/ui/breadcrumb` | `@silverpoint/angular/ui/breadcrumb` | `reflex_silverpoint_react` |\n\n**States:** `three`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly BreadcrumbItem[]` | | **Required.** The last item is the current page. |\n| `label` | `string` | `'Breadcrumb'` | Default `'Breadcrumb'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBreadcrumb } from '@silverpoint/react/ui/breadcrumb';\n\nexport function BreadcrumbView() {\n return (\n <SpBreadcrumb\n items={[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBreadcrumb } from '@silverpoint/vue/ui/breadcrumb';\n</script>\n\n<template>\n <SpBreadcrumb\n :items=\"[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpBreadcrumb } from '@silverpoint/angular/ui/breadcrumb';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-breadcrumb-view',\n imports: [SpBreadcrumb],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-breadcrumb\n [items]=\"[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]\"\n />\n `,\n})\nexport class BreadcrumbView {}\n```\n\n## SpAvatar\n\n`avatar` \xB7 A picture or initials in a round or square frame; `SpAvatarGroup` stacks several. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpAvatar` | `SpAvatar` | `sp-avatar` | `sp_avatar` |\n| Import | `@silverpoint/react/ui/avatar` | `@silverpoint/vue/ui/avatar` | `@silverpoint/angular/ui/avatar` | `reflex_silverpoint_react` |\n\n**States:** `initials`, `square`, `group`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `src` | `string` | | An image; the initials are drawn without one. |\n| `name` | `string` | | The person's name: the accessible name and the source of the initials. |\n| `initials` | `string` | | Overrides the initials derived from `name`. |\n| `alt` | `string` | | Overrides `name` as the accessible name. |\n| `shape` | `'circle' \\| 'square'` | `'circle'` | Default `'circle'`. |\n| `pixelSize` | `number` | | Side length in px; the ground's control height when omitted. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAvatar } from '@silverpoint/react/ui/avatar';\n\nexport function AvatarView() {\n return (\n <SpAvatar\n name=\"Ada Lovelace\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAvatar } from '@silverpoint/vue/ui/avatar';\n</script>\n\n<template>\n <SpAvatar\n name=\"Ada Lovelace\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpAvatar } from '@silverpoint/angular/ui/avatar';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-avatar-view',\n imports: [SpAvatar],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-avatar\n [name]=\"'Ada Lovelace'\"\n />\n `,\n})\nexport class AvatarView {}\n```\n\n## SpStatistic\n\n`statistic` \xB7 A titled figure with a prefix, a suffix and an optional trend. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpStatistic` | `SpStatistic` | `sp-statistic` | `sp_statistic` |\n| Import | `@silverpoint/react/ui/statistic` | `@silverpoint/vue/ui/statistic` | `@silverpoint/angular/ui/statistic` | `reflex_silverpoint_react` |\n\n**States:** `plain`, `trend-down`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | **Required.** The label above the value. |\n| `value` | `string \\| number` | | **Required.** Printed as given. |\n| `prefix` | `string` | | Printed before the value (`$`). |\n| `suffix` | `string` | | Printed after the value (`%`). |\n| `trend` | `'up' \\| 'down'` | | Draws the exact \u2191 or \u2193 glyph beside the delta. |\n| `delta` | `string` | | The change, as text (`+4.2%`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpStatistic } from '@silverpoint/react/ui/statistic';\n\nexport function StatisticView() {\n return (\n <SpStatistic\n title=\"Orders\"\n value={1284}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpStatistic } from '@silverpoint/vue/ui/statistic';\n</script>\n\n<template>\n <SpStatistic\n title=\"Orders\"\n :value=\"1284\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpStatistic } from '@silverpoint/angular/ui/statistic';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-statistic-view',\n imports: [SpStatistic],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-statistic\n [title]=\"'Orders'\"\n [value]=\"1284\"\n />\n `,\n})\nexport class StatisticView {}\n```\n\n## SpDescriptions\n\n`descriptions` \xB7 Label and value pairs as a description list. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDescriptions` | `SpDescriptions` | `sp-descriptions` | `sp_descriptions` |\n| Import | `@silverpoint/react/ui/descriptions` | `@silverpoint/vue/ui/descriptions` | `@silverpoint/angular/ui/descriptions` | `reflex_silverpoint_react` |\n\n**States:** `bordered`, `plain`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly DescriptionItem[]` | | **Required.** The label\u2013value pairs, a `<dl>`. Keys, when given, are unique (REQ-325). |\n| `title` | `string` | | A heading above the list, at `headingLevel`. |\n| `columns` | `number` | `3` | Default `3`, in 1..6. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDescriptions } from '@silverpoint/react/ui/descriptions';\n\nexport function DescriptionsView() {\n return (\n <SpDescriptions\n title=\"Order 1042\"\n items={[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]}\n columns={2}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDescriptions } from '@silverpoint/vue/ui/descriptions';\n</script>\n\n<template>\n <SpDescriptions\n title=\"Order 1042\"\n :items=\"[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]\"\n :columns=\"2\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDescriptions } from '@silverpoint/angular/ui/descriptions';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-descriptions-view',\n imports: [SpDescriptions],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-descriptions\n [title]=\"'Order 1042'\"\n [items]=\"[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]\"\n [columns]=\"2\"\n />\n `,\n})\nexport class DescriptionsView {}\n```\n\n## SpTimelineList\n\n`timeline-list` \xB7 Events in order, each done, current, pending or in error. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTimelineList` | `SpTimelineList` | `sp-timeline-list` | `sp_timeline_list` |\n| Import | `@silverpoint/react/ui/timeline-list` | `@silverpoint/vue/ui/timeline-list` | `@silverpoint/angular/ui/timeline-list` | `reflex_silverpoint_react` |\n\n**States:** `mixed`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly TimelineListItem[]` | | **Required.** The events, in reading order. |\n| `label` | `string` | | Accessible name of the list. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTimelineList } from '@silverpoint/react/ui/timeline-list';\n\nexport function TimelineListView() {\n return (\n <SpTimelineList\n label=\"Order history\"\n items={[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTimelineList } from '@silverpoint/vue/ui/timeline-list';\n</script>\n\n<template>\n <SpTimelineList\n label=\"Order history\"\n :items=\"[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTimelineList } from '@silverpoint/angular/ui/timeline-list';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-timeline-list-view',\n imports: [SpTimelineList],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-timeline-list\n [label]=\"'Order history'\"\n [items]=\"[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]\"\n />\n `,\n})\nexport class TimelineListView {}\n```\n\n## SpCollapse\n\n`collapse` \xB7 Disclosure panels (`SpCollapseItem`), optionally as an accordion. (disclosure)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCollapse` | `SpCollapse` | `sp-collapse` | `sp_collapse` |\n| Import | `@silverpoint/react/ui/collapse` | `@silverpoint/vue/ui/collapse` | `@silverpoint/angular/ui/collapse` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `one-open`, `accordion-disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `accordion` | `boolean` | `false` | One item open at a time, natively (`<details name>`). Default `false`. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCollapse } from '@silverpoint/react/ui/collapse';\n\nexport function CollapseView() {\n return (\n <SpCollapse />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCollapse } from '@silverpoint/vue/ui/collapse';\n</script>\n\n<template>\n <SpCollapse />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpCollapse } from '@silverpoint/angular/ui/collapse';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-collapse-view',\n imports: [SpCollapse],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-collapse />\n `,\n})\nexport class CollapseView {}\n```\n\n## SpEmpty\n\n`empty` \xB7 The empty state of a list or a table. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpEmpty` | `SpEmpty` | `sp-empty` | `sp_empty` |\n| Import | `@silverpoint/react/ui/empty` | `@silverpoint/vue/ui/empty` | `@silverpoint/angular/ui/empty` | `reflex_silverpoint_react` |\n\n**Content:** React `extra`; Vue `extra`; Angular `spExtra`.\n\n**States:** `plain`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `description` | `string` | `'No data'` | Default `'No data'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpEmpty } from '@silverpoint/react/ui/empty';\n\nexport function EmptyView() {\n return (\n <SpEmpty\n description=\"No orders yet\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpEmpty } from '@silverpoint/vue/ui/empty';\n</script>\n\n<template>\n <SpEmpty\n description=\"No orders yet\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpEmpty } from '@silverpoint/angular/ui/empty';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-empty-view',\n imports: [SpEmpty],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-empty\n [description]=\"'No orders yet'\"\n />\n `,\n})\nexport class EmptyView {}\n```\n\n## SpResult\n\n`result` \xB7 The outcome of an action: success, error, information or warning. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpResult` | `SpResult` | `sp-result` | `sp_result` |\n| Import | `@silverpoint/react/ui/result` | `@silverpoint/vue/ui/result` | `@silverpoint/angular/ui/result` | `reflex_silverpoint_react` |\n\n**Content:** React `extra`; Vue `extra`; Angular `spExtra`.\n\n**States:** `success`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `status` | `AlertKind` | `'info'` | Default `'info'`. |\n| `title` | `string` | | **Required.** The heading, at `headingLevel`. |\n| `subtitle` | `string` | | A paragraph under the title. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpResult } from '@silverpoint/react/ui/result';\n\nexport function ResultView() {\n return (\n <SpResult\n status=\"success\"\n title=\"Order placed\"\n subtitle=\"Order 1042 is on its way to the workshop.\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpResult } from '@silverpoint/vue/ui/result';\n</script>\n\n<template>\n <SpResult\n status=\"success\"\n title=\"Order placed\"\n subtitle=\"Order 1042 is on its way to the workshop.\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpResult } from '@silverpoint/angular/ui/result';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-result-view',\n imports: [SpResult],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-result\n [status]=\"'success'\"\n [title]=\"'Order placed'\"\n [subtitle]=\"'Order 1042 is on its way to the workshop.'\"\n />\n `,\n})\nexport class ResultView {}\n```\n\n## SpTextarea\n\n`textarea` \xB7 A multi-line text field with a counter and an invalid state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTextarea` | `SpTextarea` | `sp-textarea` | `sp_textarea` |\n| Import | `@silverpoint/react/ui/textarea` | `@silverpoint/vue/ui/textarea` | `@silverpoint/angular/ui/textarea` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `count`, `invalid`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `rows` | `number` | `3` | Default `3`. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `maxLength` | `number` | | The native limit; the counter shows it with `showCount`. |\n| `showCount` | `boolean` | `false` | Default `false`. |\n| `name` | `string` | | Form field name; the native textarea submits under it (REQ-323). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpTextarea } from '@silverpoint/react/ui/textarea';\n\nexport function TextareaView() {\n const [value, setValue] = useState<string>('Leave it at the door.');\n return (\n <SpTextarea\n label=\"Notes\"\n name=\"notes\"\n maxLength={120}\n showCount={true}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpTextarea } from '@silverpoint/vue/ui/textarea';\n\nconst value = ref<string>('Leave it at the door.');\n</script>\n\n<template>\n <SpTextarea\n label=\"Notes\"\n name=\"notes\"\n :maxLength=\"120\"\n :showCount=\"true\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpTextarea } from '@silverpoint/angular/ui/textarea';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-textarea-view',\n imports: [SpTextarea],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-textarea\n [label]=\"'Notes'\"\n [name]=\"'notes'\"\n [maxLength]=\"120\"\n [showCount]=\"true\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class TextareaView {\n protected readonly value = signal<string>('Leave it at the door.');\n}\n```\n\n## SpInputNumber\n\n`input-number` \xB7 A number field with steppers, bounds and precision. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpInputNumber` | `SpInputNumber` | `sp-input-number` | `sp_input_number` |\n| Import | `@silverpoint/react/ui/input-number` | `@silverpoint/vue/ui/input-number` | `@silverpoint/angular/ui/input-number` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue ; Angular .\n\n**States:** `value`, `at-min`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `min` | `number` | | The lowest value; the value is clamped to it (REQ-485). |\n| `max` | `number` | | The highest value; the value is clamped to it (REQ-485). |\n| `step` | `number` | `1` | Default `1`. |\n| `precision` | `number` | | Decimals. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `disabled` | `boolean` | | Not focusable and not submitted; the steppers are disabled too. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `name` | `string` | | Form field name; the native input submits under it (REQ-323). |\n| `decrementLabel` | `string` | `'Decrease'` | Default `'Decrease'`. |\n| `incrementLabel` | `string` | `'Increase'` | Default `'Increase'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpInputNumber } from '@silverpoint/react/ui/input-number';\n\nexport function InputNumberView() {\n const [value, setValue] = useState<number | null>(3);\n return (\n <SpInputNumber\n label=\"Quantity\"\n name=\"quantity\"\n min={1}\n max={10}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpInputNumber } from '@silverpoint/vue/ui/input-number';\n\nconst value = ref<number | null>(3);\n</script>\n\n<template>\n <SpInputNumber\n label=\"Quantity\"\n name=\"quantity\"\n :min=\"1\"\n :max=\"10\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpInputNumber } from '@silverpoint/angular/ui/input-number';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-input-number-view',\n imports: [SpInputNumber],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-input-number\n [label]=\"'Quantity'\"\n [name]=\"'quantity'\"\n [min]=\"1\"\n [max]=\"10\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class InputNumberView {\n protected readonly value = signal<number | null>(3);\n}\n```\n",
|
|
11419
|
-
"overlays": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Overlays\n\n*Describes silverpoint 0.7.0.*\n\nModal, Drawer, Popover, Tooltip, Select, DropdownMenu and Toast are built on the platform's\n`<dialog>` and Popover API. They are client components only.\n\n## The trigger is a native button\n\nGive every overlay a native `<button type=\"button\">` as its trigger:\n\n- **React:** the `trigger` prop, `trigger={<button type=\"button\">Edit</button>}`. The overlay\n clones it with its ARIA and its toggle. Do not pass `SpButton`: it drops the ARIA it is given.\n- **Vue:** the `trigger` slot, `<template #trigger><button type=\"button\">Edit</button></template>`.\n Its first element is cloned.\n- **Angular:** project the button with the `spTrigger` directive,\n `<button type=\"button\" spTrigger>Edit</button>`, and import `SpTrigger` from the overlay's own\n subpath.\n\n## Open state\n\n| | Controlled | Uncontrolled | Change |\n|---|---|---|---|\n| React | `open` | `defaultOpen` | `onOpenChange(open)` |\n| Vue | `v-model:open` | `default-open` | `update:open` |\n| Angular | `[(open)]` | `[defaultOpen]` | `(openChange)` |\n\n`onOpenChange` also fires when the platform closes it: Escape, or a click outside. A Modal with\n`dismissible={false}` ignores both.\n\n## Toasts\n\nPut one `SpToaster` near the root and render `SpToast` children inside it. A toast closes after the\ntoaster's `duration` (5000 ms) unless its own `duration` says otherwise. It pauses while hovered or\nfocused, and F8 moves focus to the toaster.\n\n## Sides\n\nSides are logical, `start` and `end`, so they mirror in right-to-left pages. Reflex's `left` and\n`right` become `start` and `end`.\n\n**Contents:** [SpModal](#spmodal) \xB7 [SpDrawer](#spdrawer) \xB7 [SpPopover](#sppopover) \xB7 [SpTooltip](#sptooltip) \xB7 [SpSelect](#spselect) \xB7 [SpDropdownMenu](#spdropdownmenu) \xB7 [SpToast](#sptoast)\n\n## SpModal\n\n`modal` \xB7 A modal dialog on the native `<dialog>`, opened by its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpModal` | `SpModal` | `sp-modal` | `sp_modal` |\n| Import | `@silverpoint/react/ui/modal` | `@silverpoint/vue/ui/modal` | `@silverpoint/angular/ui/modal` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `footer`, `trigger`; Vue `default`, `footer`, `trigger`; Angular `content`, `spFooter`, `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | The heading, `${id}--title`, that names the dialog. |\n| `description` | `string` | | A paragraph, `${id}--description`, that describes the dialog. |\n| `label` | `string` | | Accessible name without a title (REQ-501). |\n| `closable` | `boolean` | `true` | Default `true`. |\n| `closeLabel` | `string` | `'Close'` | Default `'Close'`. |\n| `width` | `string` | `'520px'` | CSS length. Default `'520px'` (from `ui.css`). |\n| `dismissible` | `boolean` | `true` | Escape and a backdrop click close it. Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpModal } from '@silverpoint/react/ui/modal';\n\nexport function ModalView() {\n return (\n <SpModal\n title=\"Edit order\"\n description=\"Order 1042, placed on 14 October.\"\n trigger={<button type=\"button\">Edit order</button>}\n >\n Changes reach the workshop before the order is packed.\n </SpModal>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpModal } from '@silverpoint/vue/ui/modal';\n</script>\n\n<template>\n <SpModal\n title=\"Edit order\"\n description=\"Order 1042, placed on 14 October.\"\n >\n <template #trigger><button type=\"button\">Edit order</button></template>\n Changes reach the workshop before the order is packed.\n </SpModal>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpModal, SpTrigger } from '@silverpoint/angular/ui/modal';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-modal-view',\n imports: [SpModal, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-modal\n [title]=\"'Edit order'\"\n [description]=\"'Order 1042, placed on 14 October.'\"\n >\n <button type=\"button\" spTrigger>Edit order</button>\n Changes reach the workshop before the order is packed.\n </sp-modal>\n `,\n})\nexport class ModalView {}\n```\n\n## SpDrawer\n\n`drawer` \xB7 A dialog sliding in from one side of the viewport. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDrawer` | `SpDrawer` | `sp-drawer` | `sp_drawer` |\n| Import | `@silverpoint/react/ui/drawer` | `@silverpoint/vue/ui/drawer` | `@silverpoint/angular/ui/drawer` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `footer`, `trigger`; Vue `default`, `footer`, `trigger`; Angular `content`, `spFooter`, `spTrigger`.\n\n**States:** `end-open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `side` | `'start' \\| 'end' \\| 'top' \\| 'bottom'` | `'end'` | Default `'end'`. |\n| `extent` | `string` | `'380px'` | CSS length across the side. Default `'380px'` (start/end) or `'320px'` (top/bottom). |\n| `modal` | `boolean` | `true` | `false` opens with `show()`. Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDrawer } from '@silverpoint/react/ui/drawer';\n\nexport function DrawerView() {\n return (\n <SpDrawer\n side=\"end\"\n trigger={<button type=\"button\">Filters</button>}\n >\n Narrow the orders by status, customer or amount.\n </SpDrawer>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDrawer } from '@silverpoint/vue/ui/drawer';\n</script>\n\n<template>\n <SpDrawer\n side=\"end\"\n >\n <template #trigger><button type=\"button\">Filters</button></template>\n Narrow the orders by status, customer or amount.\n </SpDrawer>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDrawer, SpTrigger } from '@silverpoint/angular/ui/drawer';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-drawer-view',\n imports: [SpDrawer, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-drawer\n [side]=\"'end'\"\n >\n <button type=\"button\" spTrigger>Filters</button>\n Narrow the orders by status, customer or amount.\n </sp-drawer>\n `,\n})\nexport class DrawerView {}\n```\n\n## SpPopover\n\n`popover` \xB7 Non-modal content anchored to its trigger, on the Popover API. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpPopover` | `SpPopover` | `sp-popover` | `sp_popover` |\n| Import | `@silverpoint/react/ui/popover` | `@silverpoint/vue/ui/popover` | `@silverpoint/angular/ui/popover` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `trigger`; Vue `default`, `trigger`; Angular `content`, `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | A heading that names the popover. |\n| `label` | `string` | | Accessible name without a title. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'bottom'` | Default `'bottom'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n| `offset` | `number` | `6` | Default `6`. |\n| `closable` | `boolean` | `false` | Default `false`. |\n| `closeLabel` | `string` | `'Close'` | Default `'Close'`. |\n| `width` | `string` | `'320px'` | CSS length. Default `'320px'` (from `ui.css`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpPopover } from '@silverpoint/react/ui/popover';\n\nexport function PopoverView() {\n return (\n <SpPopover\n title=\"Order 1042\"\n trigger={<button type=\"button\">Details</button>}\n >\n Two prints, one framed; shipped on 16 October.\n </SpPopover>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpPopover } from '@silverpoint/vue/ui/popover';\n</script>\n\n<template>\n <SpPopover\n title=\"Order 1042\"\n >\n <template #trigger><button type=\"button\">Details</button></template>\n Two prints, one framed; shipped on 16 October.\n </SpPopover>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpPopover, SpTrigger } from '@silverpoint/angular/ui/popover';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-popover-view',\n imports: [SpPopover, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-popover\n [title]=\"'Order 1042'\"\n >\n <button type=\"button\" spTrigger>Details</button>\n Two prints, one framed; shipped on 16 October.\n </sp-popover>\n `,\n})\nexport class PopoverView {}\n```\n\n## SpTooltip\n\n`tooltip` \xB7 A short text shown on hover or focus of its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTooltip` | `SpTooltip` | `sp-tooltip` | `sp_tooltip` |\n| Import | `@silverpoint/react/ui/tooltip` | `@silverpoint/vue/ui/tooltip` | `@silverpoint/angular/ui/tooltip` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `trigger`; Vue `trigger`; Angular `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `text` | `string` | | **Required.** The tooltip, the trigger's accessible description. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'top'` | Default `'top'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n| `offset` | `number` | `6` | Default `6`. |\n| `delay` | `number` | `300` | Default `300` ms. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTooltip } from '@silverpoint/react/ui/tooltip';\n\nexport function TooltipView() {\n return (\n <SpTooltip\n text=\"Copy the order id\"\n trigger={<button type=\"button\">Copy id</button>}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTooltip } from '@silverpoint/vue/ui/tooltip';\n</script>\n\n<template>\n <SpTooltip\n text=\"Copy the order id\"\n >\n <template #trigger><button type=\"button\">Copy id</button></template>\n </SpTooltip>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTooltip, SpTrigger } from '@silverpoint/angular/ui/tooltip';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tooltip-view',\n imports: [SpTooltip, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tooltip\n [text]=\"'Copy the order id'\"\n >\n <button type=\"button\" spTrigger>Copy id</button>\n </sp-tooltip>\n `,\n})\nexport class TooltipView {}\n```\n\n## SpSelect\n\n`select` \xB7 A select-only combobox: one option from a list. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSelect` | `SpSelect` | `sp-select` | `sp_select` |\n| Import | `@silverpoint/react/ui/select` | `@silverpoint/vue/ui/select` | `@silverpoint/angular/ui/select` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onChange`, `onOpenChange`; Vue ; Angular .\n\n**States:** `placeholder`, `open-selected`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly (string \\| UiItem)[]` | | **Required.** A string is its own key and label. |\n| `placeholder` | `string` | `'Select\u2026'` | Default `'Select\u2026'`. |\n| `label` | `string` | | **Required.** Accessible name of the combobox. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `required` | `boolean` | | Sets `aria-required` on the combobox. |\n| `name` | `string` | | Submits the key under this name, from a hidden input (REQ-323). |\n| `width` | `string` | `'180px'` | CSS length. Default `'180px'` (from `ui.css`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSelect } from '@silverpoint/react/ui/select';\n\nexport function SelectView() {\n const [value, setValue] = useState<string | undefined>(undefined);\n return (\n <SpSelect\n label=\"Status\"\n name=\"status\"\n items={[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSelect } from '@silverpoint/vue/ui/select';\n\nconst value = ref<string>();\n</script>\n\n<template>\n <SpSelect\n label=\"Status\"\n name=\"status\"\n :items=\"[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSelect } from '@silverpoint/angular/ui/select';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-select-view',\n imports: [SpSelect],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-select\n [label]=\"'Status'\"\n [name]=\"'status'\"\n [items]=\"[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SelectView {\n protected readonly value = signal<string | undefined>(undefined);\n}\n```\n\n## SpDropdownMenu\n\n`dropdown-menu` \xB7 A menu of actions opened from its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDropdownMenu` | `SpDropdownMenu` | `sp-dropdown-menu` | `sp_dropdown_menu` |\n| Import | `@silverpoint/react/ui/dropdown-menu` | `@silverpoint/vue/ui/dropdown-menu` | `@silverpoint/angular/ui/dropdown-menu` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`, `onSelect`; Vue `select`; Angular `select`.\n\n**Content:** React `trigger`; Vue `trigger`; Angular `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly MenuEntry[]` | | **Required.** Items, separators and labels, in order. Keys are unique (REQ-325). |\n| `label` | `string` | | **Required.** The menu's accessible name and the trigger's text when no trigger slot. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'bottom'` | Default `'bottom'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'start'` | Default `'start'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDropdownMenu } from '@silverpoint/react/ui/dropdown-menu';\n\nexport function DropdownMenuView() {\n return (\n <SpDropdownMenu\n label=\"Actions\"\n items={[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDropdownMenu } from '@silverpoint/vue/ui/dropdown-menu';\n</script>\n\n<template>\n <SpDropdownMenu\n label=\"Actions\"\n :items=\"[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDropdownMenu } from '@silverpoint/angular/ui/dropdown-menu';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-dropdown-menu-view',\n imports: [SpDropdownMenu],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-dropdown-menu\n [label]=\"'Actions'\"\n [items]=\"[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]\"\n />\n `,\n})\nexport class DropdownMenuView {}\n```\n\n## SpToast\n\n`toast` \xB7 A transient message in a `SpToaster`, with an optional action. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpToast` | `SpToast` | `sp-toast` | `sp_toast` |\n| Import | `@silverpoint/react/ui/toast` | `@silverpoint/vue/ui/toast` | `@silverpoint/angular/ui/toast` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `action`; Vue `action`; Angular `spAction`.\n\n**States:** `info`, `error-action`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | **Required.** The toast's first line. |\n| `description` | `string` | | A line under the title. |\n| `kind` | `AlertKind` | `'info'` | Default `'info'`. |\n| `duration` | `number` | | ms, at least 1000, or `Infinity`; the toaster's when omitted. |\n| `closeLabel` | `string` | `'Dismiss'` | Default `'Dismiss'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpToast } from '@silverpoint/react/ui/toast';\n\nexport function ToastView() {\n const [open, setOpen] = useState<boolean>(true);\n return (\n <SpToast\n kind=\"info\"\n title=\"Order saved\"\n description=\"Order 1042 was updated.\"\n open={open}\n onOpenChange={setOpen}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpToast } from '@silverpoint/vue/ui/toast';\n\nconst open = ref<boolean>(true);\n</script>\n\n<template>\n <SpToast\n kind=\"info\"\n title=\"Order saved\"\n description=\"Order 1042 was updated.\"\n v-model:open=\"open\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpToast } from '@silverpoint/angular/ui/toast';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-toast-view',\n imports: [SpToast],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-toast\n [kind]=\"'info'\"\n [title]=\"'Order saved'\"\n [description]=\"'Order 1042 was updated.'\"\n [(open)]=\"open\"\n />\n `,\n})\nexport class ToastView {\n protected readonly open = signal<boolean>(true);\n}\n```\n",
|
|
11420
|
-
"timeline": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Timeline\n\n*Describes silverpoint 0.
|
|
11421
|
-
"react": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# React\n\n*Describes silverpoint 0.
|
|
11422
|
-
"vue": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Vue\n\n*Describes silverpoint 0.
|
|
11423
|
-
"angular": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Angular\n\n*Describes silverpoint 0.
|
|
11424
|
-
"reflex": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Reflex\n\n*Describes silverpoint 0.
|
|
11513
|
+
"choosing-charts": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Choosing a chart\n\n*Describes silverpoint 0.8.0.*\n\nChoose a chart in two steps. First name the shape of the rows, then name what the reader is asked to\nsee. The recommender (`recommend_chart` on the MCP server) reads the table below. It is a reviewed\ntable, not a model, and a pair that is missing from it falls back on the charts that declare both.\n\n## Data shapes\n\n| Shape | The rows hold | For example |\n|---|---|---|\n| `series` | one row per point along an ordered x (time, sequence) | hits per hour |\n| `categories` | one row per category with one or more values | revenue by region |\n| `parts` | shares of one whole | traffic by channel |\n| `matrix` | a value per pair of categories | errors by day and hour |\n| `hierarchy` | one row per node, with an `id` and its `parent` (`null` for the root) | a budget by department |\n| `links` | rows with a source, a target and a value | signup funnel steps |\n| `points` | two or more numeric measures per row | price against rating |\n| `distribution` | many raw observations of one measure | response times |\n| `intervals` | a start and an end per row | task schedule |\n| `events` | dated occurrences, or marks along a cycle | commits per day |\n| `single` | one figure, perhaps with a target | revenue this month |\n| `field` | a measure or a vector (`x`, `y`, `u`, `v`) over a plane | a wind field |\n\n## The charts by shape and intent\n\n| Chart | Family | Shape | Intents | Summary |\n|---|---|---|---|---|\n| `line-chart` | lines | `series` | trend, change, compare | Spline with an optional dotted baseline series. |\n| `bullet-chart` | bars | `categories` | progress, kpi, compare | One bar per target, with a marker at the target. Values in 0-100. |\n| `pyramid-chart` | bars | `categories` | rank, compare | Stacked tiers whose width encodes the value (0-100). |\n| `heatmap-chart` | points-grids | `matrix` | compare, distribution | Labelled rows of values, normalised against `scaleMax`. |\n| `treemap-chart` | points-grids | `parts` | part-to-whole | Tiles of `cols \xD7 rows` cells placed in a `columns \xD7 rows` grid. |\n| `sankey-chart` | flows | `links` | flow, part-to-whole | Flow bands between layered nodes. |\n| `activity-grid` | points-grids | `events` | schedule, trend | One cell per day, a column per week. |\n| `step-chart` | lines | `series` | trend, change | A series drawn as steps. |\n| `sparkline-rows` | lines | `series` | trend, compare, kpi | One row per series \u2014 name, sparkline, readout. |\n| `kpi-card` | lines | `single` | kpi, change | A metric, its delta, and an area sparkline of the series. |\n| `bar-chart` | bars | `categories` | compare, rank | Pill bars, as columns or rows, with an optional second series. |\n| `stacked-bar-chart` | bars | `categories` | compare, part-to-whole | One stacked segment per key. |\n| `composed-chart` | bars | `series` | compare, trend | Columns and a spline on one value scale. |\n| `waterfall-chart` | bars | `categories` | change, part-to-whole | Totals from zero and floating deltas from the running total. |\n| `funnel-chart` | bars | `categories` | progress, compare | Horizontal, centred stages. |\n| `candlestick-chart` | bars | `intervals` | change, trend | OHLC bodies and wicks. |\n| `area-chart` | areas | `series` | trend, change | A curved, toned area under its line. |\n| `range-band-chart` | areas | `intervals` | uncertainty, trend | The band between a low and a high series. |\n| `stream-chart` | areas | `series` | trend, part-to-whole, compare | Two waves, overlaid or stacked. |\n| `scatter-chart` | points-grids | `points` | correlation, distribution | Points on two linear scales, optionally sized. |\n| `bubble-chart` | points-grids | `points` | correlation, compare | Circles whose area encodes `sizeKey`. |\n| `donut-chart` | radial | `parts` | part-to-whole | Sectors \u221D value around a central readout. |\n| `radar-chart` | radial | `categories` | compare | One spoke per subject, a closed polygon of values. |\n| `polar-bar-chart` | radial | `categories` | compare, rank | 360\xB0 bars out from a hole, length \u221D value. |\n| `radial-arc-group` | radial | `categories` | compare, progress | Concentric 180\xB0 tracks, sweep \u221D value / the largest. |\n| `radial-rings` | radial | `categories` | progress | Concentric progress rings, sweep \u221D value in 0-100. |\n| `gauge-arc` | radial | `single` | kpi, progress | A 240\xB0 arc swept to a percent. |\n| `meter-chart` | radial | `single` | kpi, progress | A semicircular meter with a needle at a percent. |\n| `coxcomb-chart` | radial | `categories` | compare, part-to-whole | Equal angles, sector area \u221D value. |\n| `wind-rose` | radial | `distribution` | distribution | Observations of (bearing, speed) binned by compass sector and speed. |\n| `volvelle-chart` | radial | `categories` | schedule, compare | Concentric categorical rings read against one index. |\n| `chord-ring` | flows | `links` | flow, network | Directed flows between categories around a circle. |\n| `orbit-chart` | radial | `events` | schedule | Nested elliptical orbits with markers along them. |\n| `histogram-chart` | distributions-comparisons | `distribution` | distribution | Raw observations binned in the core. |\n| `ecdf-chart` | distributions-comparisons | `distribution` | distribution, compare | The empirical cumulative distribution as a step function. |\n| `box-plot-chart` | distributions-comparisons | `distribution` | distribution, compare | Quartiles, median, Tukey whiskers and outliers per group. |\n| `violin-chart` | distributions-comparisons | `distribution` | distribution, compare | A mirrored kernel density per group. |\n| `ridgeline-chart` | distributions-comparisons | `distribution` | distribution, compare, change | A kernel density per group on overlapping baselines. |\n| `beeswarm-chart` | distributions-comparisons | `distribution` | distribution | One point per observation, packed without overlap. |\n| `lollipop-chart` | distributions-comparisons | `categories` | compare, rank | A stem from the baseline and a head at the value. |\n| `dumbbell-chart` | distributions-comparisons | `categories` | change, compare | Two values per category joined by a segment. |\n| `slope-chart` | distributions-comparisons | `categories` | change, rank | Two period axes, one segment per category. |\n| `bump-chart` | distributions-comparisons | `series` | rank, change | The rank of each series at each x. |\n| `error-bar-chart` | distributions-comparisons | `intervals` | uncertainty, compare | A point estimate with its interval per category. |\n| `interval-chart` | distributions-comparisons | `intervals` | schedule | Floating bars from start to end on lanes. |\n| `diverging-bar-chart` | distributions-comparisons | `parts` | part-to-whole, compare | Ordered levels stacked on both sides of a neutral centre. |\n| `connected-scatter-chart` | distributions-comparisons | `points` | correlation, change | An ordered path through x-y points. |\n| `waffle-chart` | hierarchies-dimensions | `parts` | part-to-whole, progress | A unit grid filled in reading order by category. |\n| `marimekko-chart` | hierarchies-dimensions | `matrix` | part-to-whole, compare | Column width by total, segment height by share. |\n| `squarified-treemap` | hierarchies-dimensions | `hierarchy` | hierarchy, part-to-whole | Nested rectangles, area by value, drillable through `rootId` and `onRootChange`. |\n| `sunburst-chart` | hierarchies-dimensions | `hierarchy` | hierarchy, part-to-whole | A hierarchy as rings of arcs, drillable through `rootId` and `onRootChange`. |\n| `tree-chart` | hierarchies-dimensions | `hierarchy` | hierarchy | A tidy node-link tree. |\n| `parallel-coordinates-chart` | hierarchies-dimensions | `matrix` | correlation, compare | One polyline per row across parallel axes. |\n| `polar-line-chart` | hierarchies-dimensions | `series` | trend, compare | A line over angle and radius. |\n| `polar-scatter-chart` | hierarchies-dimensions | `points` | distribution, correlation | Points over angle and radius. |\n| `density-bin-chart` | fields-networks | `points` | distribution, correlation | X-y points counted in two-dimensional bins. |\n| `contour-chart` | fields-networks | `points` | distribution, correlation | Iso-lines and filled bands of a density or a grid. |\n| `delaunay-chart` | fields-networks | `points` | network, distribution | The triangulation of x-y points, or its Voronoi cells. |\n| `vector-field-chart` | fields-networks | `field` | flow | An arrow per grid point. |\n| `network-chart` | fields-networks | `links` | network, flow | A node-link graph. |\n\n## The recommender's table\n\nThe scores run from 0 to 1. An adjustment applies when the row count (`rows`) or the number of\nvalue columns (`values`) passes its bound.\n\n| Shape | Intent | Charts, best first | Adjustments |\n|---|---|---|---|\n| `series` | `trend` | `line-chart` 0.9 \u2014 A line is the plainest reading of a value over an ordered axis.<br>`area-chart` 0.8 \u2014 An area gives one series the weight of its magnitude.<br>`step-chart` 0.6 \u2014 Steps show a value that holds until it changes.<br>`stream-chart` 0.5 \u2014 Several value columns overlay or stack as waves.<br>`polar-line-chart` 0.3 \u2014 A cyclic axis (hours, months, degrees) closes the line around a circle. | values>1: `stream-chart` +0.3 \u2014 Several value fields read together as streams.<br>values>1: `area-chart` -0.2 \u2014 An area draws one series only. |\n| `series` | `change` | `line-chart` 0.8 \u2014 The slope between points is the change.<br>`step-chart` 0.75 \u2014 Steps mark when the value changed and by how much.<br>`area-chart` 0.6 \u2014 An area shows the change in magnitude.<br>`bump-chart` 0.5 \u2014 When the change that matters is in rank. | |\n| `series` | `compare` | `line-chart` 0.8 \u2014 A second series draws as a dotted baseline against the first.<br>`composed-chart` 0.75 \u2014 Columns and a line share one value scale.<br>`stream-chart` 0.6 \u2014 Several series overlaid on one axis.<br>`sparkline-rows` 0.55 \u2014 One small line per series, side by side with its readout.<br>`polar-line-chart` 0.3 \u2014 Values around a cycle compared by angle. | |\n| `series` | `rank` | `bump-chart` 0.9 \u2014 The rank of each series at each x, ranks joined across x. | |\n| `series` | `kpi` | `sparkline-rows` 0.85 \u2014 One row per series: its name, its trend and its latest readout.<br>`kpi-card` 0.75 \u2014 One metric, its delta and its trend. | |\n| `series` | `part-to-whole` | `stream-chart` 0.8 \u2014 Stacked waves show each part of a total over x. | |\n| `categories` | `compare` | `bar-chart` 0.9 \u2014 Bars compare values against one common baseline.<br>`lollipop-chart` 0.75 \u2014 A lighter mark per category, readable with many of them.<br>`radar-chart` 0.5 \u2014 Spokes compare a few subjects at once.<br>`polar-bar-chart` 0.4 \u2014 Bars around a circle, for a cyclic set of categories.<br>`coxcomb-chart` 0.35 \u2014 Equal angles, area by value: cyclic categories such as months.<br>`radial-arc-group` 0.3 \u2014 Concentric tracks, each swept by its value. | rows>12: `lollipop-chart` +0.2 \u2014 Many categories read better as lollipops.<br>rows>12: `radar-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>rows>12: `polar-bar-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>rows>12: `coxcomb-chart` -0.3 \u2014 Radial layouts crowd past a dozen categories.<br>values>1: `bar-chart` +0.05 \u2014 A second value field draws as a second series of bars. |\n| `categories` | `rank` | `bar-chart` 0.85 \u2014 Sorted bars read as a ranking.<br>`lollipop-chart` 0.85 \u2014 Lollipops sort themselves with `sort`.<br>`pyramid-chart` 0.5 \u2014 Stacked tiers, widest at the base.<br>`polar-bar-chart` 0.4 \u2014 A ranking around a circle. | |\n| `categories` | `part-to-whole` | `stacked-bar-chart` 0.85 \u2014 Each bar stacks its parts, one segment per value column.<br>`waterfall-chart` 0.6 \u2014 Parts that add up to a running total.<br>`coxcomb-chart` 0.4 \u2014 Sectors whose area is each part. | |\n| `categories` | `change` | `dumbbell-chart` 0.9 \u2014 Two values per category joined by a segment: before and after.<br>`slope-chart` 0.85 \u2014 Two period axes, one segment per category: the slope is the change.<br>`waterfall-chart` 0.75 \u2014 Each step a delta from the running total. | |\n| `categories` | `progress` | `bullet-chart` 0.9 \u2014 Each bar against its own target.<br>`radial-rings` 0.75 \u2014 Concentric rings, each swept to its percent.<br>`funnel-chart` 0.7 \u2014 Stages that narrow, such as a conversion.<br>`radial-arc-group` 0.5 \u2014 Tracks swept relative to the largest. | |\n| `categories` | `kpi` | `bullet-chart` 0.8 \u2014 Each measure against its target, compact.<br>`radial-rings` 0.6 \u2014 A few percents at a glance. | |\n| `parts` | `part-to-whole` | `donut-chart` 0.9 \u2014 A ring reads a few shares of one whole around a central figure.<br>`waffle-chart` 0.85 \u2014 Unit cells make the shares countable.<br>`treemap-chart` 0.7 \u2014 Tiles sized by share.<br>`diverging-bar-chart` 0.4 \u2014 For ordered levels (agree\u2026 disagree) around a neutral centre.<br>`stacked-bar-chart` 0.35 \u2014 One bar stacked with the shares, to set beside other wholes. | rows>6: `donut-chart` -0.3 \u2014 A ring loses its shares past six slices.<br>rows>6: `treemap-chart` +0.1 \u2014 Tiles hold many shares better than a ring. |\n| `parts` | `compare` | `diverging-bar-chart` 0.8 \u2014 Likert-style levels on both sides of a neutral centre, row by row.<br>`waffle-chart` 0.6 \u2014 Countable cells per part. | |\n| `parts` | `progress` | `waffle-chart` 0.8 \u2014 A hundred cells filled to the share done. | |\n| `matrix` | `compare` | `heatmap-chart` 0.9 \u2014 One toned cell per row and column.<br>`marimekko-chart` 0.7 \u2014 Columns by total, segments by share.<br>`parallel-coordinates-chart` 0.6 \u2014 One polyline per row across many dimensions. | |\n| `matrix` | `part-to-whole` | `marimekko-chart` 0.9 \u2014 Each column a whole, each segment its share, column width by total. | |\n| `matrix` | `correlation` | `parallel-coordinates-chart` 0.9 \u2014 Crossing lines between axes show how dimensions move together.<br>`heatmap-chart` 0.6 \u2014 A grid of values, read for patterns. | |\n| `matrix` | `distribution` | `heatmap-chart` 0.8 \u2014 Where the high values gather in the grid. | |\n| `hierarchy` | `hierarchy` | `tree-chart` 0.85 \u2014 The structure itself, node by node.<br>`squarified-treemap` 0.8 \u2014 Nested rectangles, drillable.<br>`sunburst-chart` 0.75 \u2014 Rings of arcs, one ring per level, drillable. | |\n| `hierarchy` | `part-to-whole` | `squarified-treemap` 0.9 \u2014 Area by value, nested by level.<br>`sunburst-chart` 0.85 \u2014 Each arc its share of its parent. | |\n| `links` | `flow` | `sankey-chart` 0.9 \u2014 Bands between layered stages, width by value.<br>`chord-ring` 0.75 \u2014 Flows between categories around a circle, both ways.<br>`network-chart` 0.5 \u2014 When the links matter more than their volume. | |\n| `links` | `network` | `network-chart` 0.9 \u2014 Nodes and links laid out by a seeded force.<br>`chord-ring` 0.7 \u2014 Who connects to whom, around a circle. | |\n| `links` | `part-to-whole` | `sankey-chart` 0.8 \u2014 How a total splits and merges across stages. | |\n| `points` | `correlation` | `scatter-chart` 0.9 \u2014 Points on two linear scales.<br>`bubble-chart` 0.75 \u2014 A third variable as each point\u2019s area.<br>`density-bin-chart` 0.6 \u2014 Counts per bin when points overlap.<br>`connected-scatter-chart` 0.5 \u2014 When the points have an order.<br>`polar-scatter-chart` 0.3 \u2014 When one variable is an angle. | rows>500: `density-bin-chart` +0.35 \u2014 Hundreds of points read better as counts per bin.<br>rows>500: `scatter-chart` -0.2 \u2014 Points overplot and hide their density.<br>values>2: `bubble-chart` +0.2 \u2014 A third numeric field can size the points. |\n| `points` | `distribution` | `density-bin-chart` 0.85 \u2014 Points counted in hexagonal or square bins.<br>`contour-chart` 0.8 \u2014 Iso-lines of the density.<br>`scatter-chart` 0.6 \u2014 Every point, when there are few.<br>`polar-scatter-chart` 0.4 \u2014 Points by angle and radius. | |\n| `points` | `change` | `connected-scatter-chart` 0.9 \u2014 An ordered path through x-y points: how two values moved together. | |\n| `points` | `network` | `delaunay-chart` 0.85 \u2014 Neighbours by triangulation, or each point\u2019s Voronoi cell. | |\n| `points` | `compare` | `bubble-chart` 0.7 \u2014 Positions and sizes compared at once. | |\n| `distribution` | `distribution` | `histogram-chart` 0.9 \u2014 Observations binned in the core.<br>`box-plot-chart` 0.8 \u2014 Quartiles, median, whiskers and outliers.<br>`violin-chart` 0.75 \u2014 The density\u2019s shape, mirrored.<br>`beeswarm-chart` 0.7 \u2014 Every observation, packed without overlap.<br>`ecdf-chart` 0.65 \u2014 The cumulative share below each value.<br>`wind-rose` 0.3 \u2014 When the observations carry a bearing. | rows<30: `beeswarm-chart` +0.25 \u2014 Few observations: show each one.<br>rows<30: `histogram-chart` -0.2 \u2014 Few observations make coarse bins.<br>rows>1000: `beeswarm-chart` -0.4 \u2014 Too many observations to draw one by one. |\n| `distribution` | `compare` | `box-plot-chart` 0.9 \u2014 Quartiles side by side, one box per group.<br>`violin-chart` 0.85 \u2014 Density shapes side by side.<br>`ridgeline-chart` 0.8 \u2014 Densities on overlapping baselines, one per group.<br>`ecdf-chart` 0.75 \u2014 Cumulative curves of each group on one axis. | |\n| `distribution` | `change` | `ridgeline-chart` 0.85 \u2014 A density per period, stacked in order. | |\n| `intervals` | `uncertainty` | `error-bar-chart` 0.9 \u2014 A point estimate with its interval per category.<br>`range-band-chart` 0.85 \u2014 A band between low and high over x. | |\n| `intervals` | `trend` | `range-band-chart` 0.85 \u2014 The band between low and high over time.<br>`candlestick-chart` 0.8 \u2014 Open, high, low and close per period. | |\n| `intervals` | `change` | `candlestick-chart` 0.9 \u2014 Each period\u2019s open-to-close change and its range. | |\n| `intervals` | `schedule` | `interval-chart` 0.95 \u2014 Floating bars from start to end on lanes. | |\n| `events` | `schedule` | `activity-grid` 0.85 \u2014 One cell per day, a column per week. | |\n| `events` | `trend` | `activity-grid` 0.8 \u2014 Activity per day over weeks. | |\n| `single` | `kpi` | `kpi-card` 0.9 \u2014 The figure, its delta and its trend.<br>`gauge-arc` 0.75 \u2014 A percent on a 240\xB0 arc.<br>`meter-chart` 0.7 \u2014 A percent with a needle. | |\n| `single` | `progress` | `gauge-arc` 0.85 \u2014 An arc swept to the percent done.<br>`meter-chart` 0.8 \u2014 A needle at the percent done. | |\n| `field` | `flow` | `vector-field-chart` 0.95 \u2014 An arrow per grid point, its direction and magnitude. | |\n| `field` | `distribution` | `contour-chart` 0.85 \u2014 Iso-lines and bands of a scalar grid (`source: 'grid'`). | |\n\n## Common chart props\n\nEvery chart takes these, under the same names in React, Vue and Angular.\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `data` | `readonly Datum[]` | | Rows to draw. If omitted, the demo dataset is rendered (REQ-093): accessor props (`\u2026Key`, `keys`, `names`, `levels`, `axis`, `dimensions`, `period`, `nodes`) are ignored, every other prop applies. |\n| `ground` | `GroundRef` | `'silverpoint'` | Style ground. Defaults to the app provider's, or `silverpoint`. |\n| `substrate` | `SubstrateName` | `'cream'` | Prepared substrate within the ground (REQ-046). |\n| `mode` | `InkMode` | `'ink'` | `ink` by default; `precision` disables inking (REQ-021). |\n| `palette` | `Palette` | | Colours over the ground's, field by field, written on the root's `style` (REQ-461). Merged over the dashboard's and the provider's (REQ-462); presets are on `@silverpoint/core/palettes`. |\n| `seed` | `Seed` | | Seed. If omitted, it is derived from `id` stably (REQ-003). |\n| `id` | `string` | | Stable identifier. If omitted, it is generated deterministically. |\n| `height` | `number` | `160` | Height of the drawing area in px. Width is the container's unless pinned. |\n| `width` | `number` | | |\n| `chrome` | `'card' \\| 'bare'` | `'card'` | `card` draws the full frame; `bare` only the drawing area (REQ-095). |\n| `hatchFill` | `'tile' \\| 'per-shape'` | `'tile'` | How areas are filled (REQ-029). |\n| `title` | `string` | | |\n| `badge` | `string` | | |\n| `value` | `string \\| number` | | |\n| `unit` | `string` | | |\n| `footerLeft` | `string` | | |\n| `footerRight` | `string` | | |\n| `label` | `string` | | Accessible name. If omitted, it is derived from `title` (REQ-120). |\n| `description` | `string` | | Long description for screen readers (REQ-120). |\n| `dataTable` | `'visible' \\| 'hidden' \\| 'none'` | `'hidden'` | Tabular alternative; `hidden` leaves it for assistive technology only (REQ-121). |\n| `locale` | `string` | | |\n| `numberFormat` | `Intl.NumberFormatOptions` | | |\n| `className` | `string` | | |\n\nDefaults to know:\n\n- `height` is 160, the drawing area without the card frame.\n- `chrome` is `card`. `bare` drops the frame.\n- `dataTable` is `hidden`: the table stays in the page for screen readers only.\n- `hatchFill` is `tile`. `per-shape` traces the hatching shape by shape, which costs 10 to 40 times\n the path weight, so keep it for a hero chart or an export.\n\n## Events\n\n| React | Vue | Angular | Payload |\n|---|---|---|---|\n| `onActiveChange` | `@active-change` | `(activeChange)` | the item under the pointer or keyboard focus, or `null` |\n| `onSelect` | `@select` | `(select)` | the item clicked or chosen with Enter or Space |\n| `onRootChange` | `@root-change` | `(rootChange)` | the sunburst's or treemap's new root id, `null` for the data root |\n",
|
|
11514
|
+
"grounds-and-palettes": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Grounds and palettes\n\n*Describes silverpoint 0.8.0.*\n\n## Grounds\n\nA *ground* is the drawing technique. Every chart and component draws in the ground the application\nprovider sets, and a `ground` prop overrides it.\n\n| Ground | Substrates | What it draws |\n|---|---|---|\n| `silverpoint` | `cream`, `green`, `blue`, `ochre` | Metal point on prepared paper: hatched tone, a hand-inked line, cream and other prepared substrates. |\n| `cyanotype` | `prussian` | A contact print: a white, exact line on Prussian blue; tone is line weight, nothing is hatched. |\n\n- **silverpoint** (the default): tone is *hatch density*, not colour. A darker category gets\n denser hatching, so a chart reads in grey scale and in print. Highlights are white heightening\n with an ink outline.\n- **cyanotype**: tone is *line weight*, and nothing is hatched. Its only substrate, `prussian`, is\n painted whatever `substrate` says, so leave `substrate` out.\n- `mode="precision"` turns the hand-inked jitter off: the lines become exact. It is forced\n when the page declares `prefers-contrast: more` or `forced-colors: active`, and no prop can undo\n that.\n\n## Palettes\n\nA palette recolours a ground field by field. The fields you leave unset keep the ground\'s colours.\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `substrate` | `string` | | The prepared ground the drawing sits on. |\n| `ink` | `string` | | The main series and the frames of UI components. |\n| `inkSecondary` | `string` | | The second series and the hatch of tones. |\n| `heighten` | `string` | | White heightening on the live value (always outlined with `ink`). |\n| `rule` | `string` | | Rules and baselines. |\n| `grid` | `string` | | Grid lines. |\n| `text` | `string` | | Large figures and primary labels. |\n| `textMuted` | `string` | | Axis labels and secondary text. |\n| `focus` | `string` | `ink` | Focus ring of UI components; `ink` by default. |\n\nThe six presets, all checked for contrast on their substrate:\n\n| Preset | `substrate` | `ink` | `inkSecondary` | `heighten` | `rule` | `grid` | `text` | `textMuted` | `focus` |\n|---|---|---|---|---|---|---|---|---|---|\n| `silverpoint` | #EDE7DA | #5A5E65 | #685C4D | #FFFFFF | #737A82 | #737A82 | #3F4348 | #5A5E65 | |\n| `sanguine` | #F2E8DC | #8A3A24 | #6A4A3A | #FFFFFF | #9A6450 | #9A6450 | #4A2216 | #7A3E2C | |\n| `sepia` | #F0E6D2 | #6B4C2C | #5A5148 | #FFFFFF | #8A6E52 | #8A6E52 | #3B2A18 | #6B4C2C | |\n| `ironGall` | #EEEAE0 | #3C4858 | #6A4E36 | #FFFFFF | #6C7584 | #6C7584 | #232B36 | #4A5566 | |\n| `verdigris` | #E7EDE6 | #2C6355 | #65563F | #FFFFFF | #5C7B71 | #5C7B71 | #1F3D36 | #3E6A5E | |\n| `indigo` | #E9EAF1 | #3A4884 | #675641 | #FFFFFF | #68709A | #68709A | #232C52 | #4A5590 | |\n\nPass the object, never its name. That way a page that names no preset ships none:\n\n```tsx\nimport { sanguine } from \'@silverpoint/core/palettes\';\nimport { BarChart } from \'@silverpoint/react/bar-chart\';\n\nexport function Revenue() {\n return <BarChart title="Revenue by quarter" palette={sanguine} />;\n}\n```\n\nA palette of your own is a plain object, so check its contrast before you ship it, with\n`check_palette` on the MCP server or `checkPalette` from `@silverpoint/core/palettes`. A colour\nthat is not a CSS colour is dropped with `SP024`, and a pair under its contrast threshold warns\n`SP023`.\n\n## Precedence\n\n`ground`, `substrate`, `mode`, `locale` and `palette` resolve from the chart\'s prop first, then the\ndashboard, then the provider, then the library default. A palette merges field by field at each\nlevel, and a nested provider inherits what it does not set.\n\n```tsx\nimport { sepia } from \'@silverpoint/core/palettes\';\nimport { SilverpointProvider } from \'@silverpoint/react\';\nimport { LineChart } from \'@silverpoint/react/line-chart\';\n\nexport function Report() {\n return (\n <SilverpointProvider ground="silverpoint" substrate="ochre" palette={sepia}>\n <LineChart title="Visits" />\n <LineChart title="Visits, exact" mode="precision" />\n </SilverpointProvider>\n );\n}\n```\n',
|
|
11515
|
+
"dashboard": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Dashboard\n\n*Describes silverpoint 0.8.0.*\n\nA dashboard is a responsive grid of cards. The charts are its children, and the layout is a plain,\nserialisable object matched to them by cell id. There are no placement coordinates and no drag or\nresize.\n\n- **`id` is required.** The seed of every chart without an id of its own derives from it\n (`<dashboard id>--<cell id>`), so choose a stable one.\n- **`title` or `label` is required.** It is the region\'s name. React and Vue refuse a dashboard\n without one by type, and Angular warns `SP002`.\n- **The cells are in reading order.** `columns` defaults to `{ sm: 1, md: 2, lg: 4 }` and collapses\n 4 \u2192 2 \u2192 1 by container width. A `colSpan` wider than the breakpoint\'s columns is clamped, with\n `SP014`.\n- **A chart inside a cell takes the cell\'s box** unless it sets its own `width` and `height`, and it\n inherits the dashboard\'s `ground`, `substrate`, `mode`, `locale` and `palette`.\n- **`link={{ key: \'hour\' }}` highlights the same value** of that field in every chart when one is\n hovered or focused. It is client-only: React\'s server `Dashboard` refuses it.\n- **On the server,** cells are sized at `ssrWidth` (1200 by default) until they are measured.\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `Dashboard` | `SpDashboard` | `sp-dashboard` | `dashboard` |\n| Import | `@silverpoint/react/dashboard` | `@silverpoint/vue/dashboard` | `@silverpoint/angular/dashboard` | `reflex_silverpoint_react` |\n\n### Dashboard props\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | |\n| `label` | `string` | | |\n| `id` | `string` | | **Required.** Stable identifier; seeds of unnamed charts derive from it (REQ-209). Required. |\n| `layout` | `DashboardLayout` | | |\n| `description` | `string` | | Long description, exposed as the region\'s description (REQ-214). |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | Heading level of `title`. Default `2`. |\n| `ssrWidth` | `number` | `1200` | Width in px used for nominal cell boxes on the server and at hydration (REQ-207). Default `1200`. |\n| `link` | `DashboardLink` | | Linked interaction (REQ-216); client entry points only. |\n| `ground` | `GroundRef` | | Inherited by every chart inside, below the chart\'s own prop (REQ-212). |\n| `substrate` | `SubstrateName` | | |\n| `mode` | `InkMode` | | |\n| `locale` | `string` | | |\n| `palette` | `Palette` | | The section\'s colours, written on its root and merged under every chart\'s and component\'s own (REQ-462). |\n| `className` | `string` | | |\n\n## Layout\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `columns` | `PerBreakpoint<number>` | `{ sm: 1, md: 2, lg: 4 }` | Columns per breakpoint. Default `{ sm: 1, md: 2, lg: 4 }` (REQ-208). |\n| `rowHeight` | `number` | `240` | Height of one row unit, in px, card chrome included. Default `240`. |\n| `gap` | `number` | `16` | Gap between cells, in px. Default `16`. |\n| `cells` | `readonly DashboardCellLayout[]` | | Cells in reading order (REQ-203). Omitted: every child, span 1. |\n\n### Cell layout (`layout.cells[]`)\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `id` | `string` | | **Required.** Matches `DashboardCell`\'s `cell` prop; unique within the dashboard (REQ-205). |\n| `colSpan` | `PerBreakpoint<number>` | `1` | Default `1`. Clamped to the breakpoint\'s columns with `SP014` (REQ-204). |\n| `rowSpan` | `PerBreakpoint<number>` | `1` | Default `1`. |\n\n## React\n\n```tsx\nimport { Dashboard, DashboardCell, type DashboardLayout } from \'@silverpoint/react/dashboard\';\nimport { BarChart } from \'@silverpoint/react/bar-chart\';\nimport { KpiCard } from \'@silverpoint/react/kpi-card\';\nimport { LineChart } from \'@silverpoint/react/line-chart\';\n\nconst layout: DashboardLayout = {\n columns: { sm: 1, md: 2, lg: 4 },\n cells: [{ id: \'revenue\' }, { id: \'traffic\', colSpan: { md: 2, lg: 3 }, rowSpan: 2 }, { id: \'errors\' }],\n};\n\n// A type, not an interface: an interface has no index signature, so it is not a `Datum`.\ntype Row = { readonly hour: string; readonly hits: number; readonly errors: number };\n\nexport function Operations({ rows, revenue }: { rows: readonly Row[]; revenue: number }) {\n return (\n <Dashboard id="ops" title="Operations" layout={layout} link={{ key: \'hour\' }}>\n <DashboardCell cell="revenue">\n <KpiCard title="Revenue" data={[{ value: revenue }]} unit="EUR" />\n </DashboardCell>\n <DashboardCell cell="traffic">\n <LineChart title="Traffic" data={rows} xKey="hour" valueKey="hits" />\n </DashboardCell>\n <DashboardCell cell="errors">\n <BarChart title="Errors" data={rows} xKey="hour" valueKey="errors" />\n </DashboardCell>\n </Dashboard>\n );\n}\n```\n\nReact hands each cell\'s box and configuration to its chart as props, so a chart must be the cell\'s\ndirect child.\n\n## Vue\n\n```vue\n<script setup lang="ts">\nimport { SpDashboard, SpDashboardCell, type DashboardLayout } from \'@silverpoint/vue/dashboard\';\nimport { SpBarChart } from \'@silverpoint/vue/bar-chart\';\nimport { SpLineChart } from \'@silverpoint/vue/line-chart\';\n\ndefineProps<{ rows: readonly { hour: string; hits: number; errors: number }[] }>();\n\nconst layout: DashboardLayout = { cells: [{ id: \'traffic\', colSpan: { md: 2, lg: 3 } }, { id: \'errors\' }] };\n</script>\n\n<template>\n <SpDashboard id="ops" title="Operations" :layout="layout" :link="{ key: \'hour\' }">\n <SpDashboardCell cell="traffic"><SpLineChart title="Traffic" :data="rows" x-key="hour" value-key="hits" /></SpDashboardCell>\n <SpDashboardCell cell="errors"><SpBarChart title="Errors" :data="rows" x-key="hour" value-key="errors" /></SpDashboardCell>\n </SpDashboard>\n</template>\n```\n\n## Angular\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, input } from \'@angular/core\';\nimport { SpBarChart } from \'@silverpoint/angular/bar-chart\';\nimport { SpDashboard, SpDashboardCell, type DashboardLayout } from \'@silverpoint/angular/dashboard\';\nimport { SpLineChart } from \'@silverpoint/angular/line-chart\';\n\n@Component({\n selector: \'app-operations\',\n imports: [SpDashboard, SpDashboardCell, SpLineChart, SpBarChart],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-dashboard [id]="\'ops\'" [title]="\'Operations\'" [layout]="layout" [link]="{ key: \'hour\' }">\n <sp-dashboard-cell [cell]="\'traffic\'">\n <sp-line-chart [title]="\'Traffic\'" [data]="rows()" [xKey]="\'hour\'" [valueKey]="\'hits\'" />\n </sp-dashboard-cell>\n <sp-dashboard-cell [cell]="\'errors\'">\n <sp-bar-chart [title]="\'Errors\'" [data]="rows()" [xKey]="\'hour\'" [valueKey]="\'errors\'" />\n </sp-dashboard-cell>\n </sp-dashboard>\n `,\n})\nexport class Operations {\n readonly rows = input.required<readonly { hour: string; hits: number; errors: number }[]>();\n protected readonly layout: DashboardLayout = { cells: [{ id: \'traffic\', colSpan: { md: 2, lg: 3 } }, { id: \'errors\' }] };\n}\n```\n',
|
|
11516
|
+
"ui-components": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# UI and composed components\n\n*Describes silverpoint 0.8.0.*\n\nEvery component is named `Sp<Name>` in the three frameworks (`SpButton`, `<sp-input>`), imported\nfrom its own subpath (`@silverpoint/react/ui/button`), and drawn in the same ground as the\ncharts. Import `@silverpoint/grounds/ui.css` once, after `styles.css`.\n\n## Binding a value\n\n| | Controlled | Uncontrolled | Change |\n|---|---|---|---|\n| React | `value` (`checked` for Checkbox and Switch) | `defaultValue` (`defaultChecked`) | `onChange(value)`: the value, not the DOM event |\n| Vue | `v-model` | omit `v-model`, pass `default-value` | `update:modelValue`, then `change` on commit |\n| Angular | `[(value)]`, or `formControl` / `ngModel` | `[defaultValue]` | `(valueChange)` |\n\nValue events fire on user input only, never on a prop change, and never for a disabled component\nor item. Angular value components are `ControlValueAccessor`s, so they work in reactive and\ntemplate-driven forms.\n\n## Server rendering\n\nIn React, display components also have server entries (`@silverpoint/react/server/ui/<name>`):\n`card`, `tag`, `badge`, `divider`, `progress`, `alert`, `skeleton`, `steps`, `surface`, `glyph`,\n`table` (unsortable), `breadcrumb`, `avatar`, `statistic`, `descriptions`, `timeline-list`, `empty`\nand `result`. Every other component is a client component.\n\n## Notes\n\n- `SpButton` is an attribute component in Angular (`<button spButton>`, `<a spButton>`), so your own\n element is the control. `SpSurface` is `[spSurface]` in the same way.\n- `SpTabs` renders `SpTabPanel` children matched by `value`.\n- `SpTable` draws its rows as given: sort them yourself on `onSort` (`@sort`, `(sort)`), which also\n keeps paging with `SpPagination` correct.\n- A link's `href` (`SpButton`, `SpBreadcrumb`) keeps relative URLs and the `http`, `https`,\n `mailto` and `tel` schemes. Any other is dropped with `SP017`.\n- Named content: React takes node props, Vue slots (`prefix`, `suffix`, `extra`, `footer`), and\n Angular templates (`<ng-template spExtra>`, `spFooter`, `spPrefix`, `spSuffix`).\n\n**Contents:** [SpButton](#spbutton) \xB7 [SpInput](#spinput) \xB7 [SpCheckbox](#spcheckbox) \xB7 [SpRadioGroup](#spradiogroup) \xB7 [SpSwitch](#spswitch) \xB7 [SpSlider](#spslider) \xB7 [SpRate](#sprate) \xB7 [SpSegmented](#spsegmented) \xB7 [SpTabs](#sptabs) \xB7 [SpSteps](#spsteps) \xB7 [SpCard](#spcard) \xB7 [SpTag](#sptag) \xB7 [SpBadge](#spbadge) \xB7 [SpDivider](#spdivider) \xB7 [SpProgress](#spprogress) \xB7 [SpAlert](#spalert) \xB7 [SpSkeleton](#spskeleton) \xB7 [SpSurface](#spsurface) \xB7 [SpGlyph](#spglyph) \xB7 [SpTable](#sptable) \xB7 [SpPagination](#sppagination) \xB7 [SpBreadcrumb](#spbreadcrumb) \xB7 [SpAvatar](#spavatar) \xB7 [SpStatistic](#spstatistic) \xB7 [SpDescriptions](#spdescriptions) \xB7 [SpTimelineList](#sptimelinelist) \xB7 [SpCollapse](#spcollapse) \xB7 [SpEmpty](#spempty) \xB7 [SpResult](#spresult) \xB7 [SpTextarea](#sptextarea) \xB7 [SpInputNumber](#spinputnumber)\n\n## SpButton\n\n`button` \xB7 A button or a link styled as one; `primary` and `danger` variants. (actions)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpButton` | `SpButton` | `button[spButton]` | `sp_button` |\n| Import | `@silverpoint/react/ui/button` | `@silverpoint/vue/ui/button` | `@silverpoint/angular/ui/button` | `reflex_silverpoint_react` |\n\n**Events:** React `onClick`; Vue `click`; Angular .\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `default`, `primary`, `danger`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `variant` | `UiVariant` | `'default'` | Default `'default'`; `danger` also draws the exact \u2715 glyph (REQ-310). |\n| `type` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Default `'button'`. |\n| `disabled` | `boolean` | | Not focusable, not submitted; drawn with the disabled tone. |\n| `label` | `string` | | Accessible name of an icon-only button (REQ-319). |\n| `block` | `boolean` | | Fills the width of its container. |\n| `href` | `string` | | Renders an `<a>`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpButton } from '@silverpoint/react/ui/button';\n\nexport function ButtonView() {\n return (\n <SpButton>\n Default\n </SpButton>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpButton } from '@silverpoint/vue/ui/button';\n</script>\n\n<template>\n <SpButton>\n Default\n </SpButton>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpButton } from '@silverpoint/angular/ui/button';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-button-view',\n imports: [SpButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n spButton\n >\n Default\n </button>\n `,\n})\nexport class ButtonView {}\n```\n\n## SpInput\n\n`input` \xB7 A labelled text field with an optional message and an invalid state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpInput` | `SpInput` | `sp-input` | `sp_input` |\n| Import | `@silverpoint/react/ui/input` | `@silverpoint/vue/ui/input` | `@silverpoint/angular/ui/input` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**Content:** React `prefix`, `suffix`; Vue `prefix`, `suffix`; Angular `spPrefix`, `spSuffix`.\n\n**States:** `empty`, `filled`, `invalid`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `type` | `'text' \\| 'search' \\| 'email' \\| 'url' \\| 'tel' \\| 'password' \\| 'number'` | `'text'` | Native input type. Default `'text'`. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `name` | `string` | | Form field name; the native input submits under it (REQ-323). |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpInput } from '@silverpoint/react/ui/input';\n\nexport function InputView() {\n const [value, setValue] = useState<string>('');\n return (\n <SpInput\n label=\"Search charts\"\n placeholder=\"Search charts\u2026\"\n type=\"search\"\n name=\"q\"\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpInput } from '@silverpoint/vue/ui/input';\n\nconst value = ref<string>('');\n</script>\n\n<template>\n <SpInput\n label=\"Search charts\"\n placeholder=\"Search charts\u2026\"\n type=\"search\"\n name=\"q\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpInput } from '@silverpoint/angular/ui/input';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-input-view',\n imports: [SpInput],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-input\n [label]=\"'Search charts'\"\n [placeholder]=\"'Search charts\u2026'\"\n [type]=\"'search'\"\n [name]=\"'q'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class InputView {\n protected readonly value = signal<string>('');\n}\n```\n\n## SpCheckbox\n\n`checkbox` \xB7 A labelled checkbox, with an indeterminate state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCheckbox` | `SpCheckbox` | `sp-checkbox` | `sp_checkbox` |\n| Import | `@silverpoint/react/ui/checkbox` | `@silverpoint/vue/ui/checkbox` | `@silverpoint/angular/ui/checkbox` | `reflex_silverpoint_react` |\n\n**Value:** React `checked + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `unchecked`, `checked`, `indeterminate`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The visible text and accessible name. |\n| `name` | `string` | | Form field name; submitted as `on` when checked. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `indeterminate` | `boolean` | | Draws the exact dash and sets the native `indeterminate` state. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpCheckbox } from '@silverpoint/react/ui/checkbox';\n\nexport function CheckboxView() {\n const [value, setValue] = useState<boolean>(false);\n return (\n <SpCheckbox\n label=\"Legend\"\n name=\"legend\"\n checked={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpCheckbox } from '@silverpoint/vue/ui/checkbox';\n\nconst value = ref<boolean>(false);\n</script>\n\n<template>\n <SpCheckbox\n label=\"Legend\"\n name=\"legend\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpCheckbox } from '@silverpoint/angular/ui/checkbox';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-checkbox-view',\n imports: [SpCheckbox],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-checkbox\n [label]=\"'Legend'\"\n [name]=\"'legend'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class CheckboxView {\n protected readonly value = signal<boolean>(false);\n}\n```\n\n## SpRadioGroup\n\n`radio-group` \xB7 One choice among a few, as a fieldset of radios. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpRadioGroup` | `SpRadioGroup` | `sp-radio-group` | `sp_radio_group` |\n| Import | `@silverpoint/react/ui/radio-group` | `@silverpoint/vue/ui/radio-group` | `@silverpoint/angular/ui/radio-group` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `selected`, `disabled-item`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The choices; each a native radio. Keys are unique (REQ-325). |\n| `name` | `string` | | **Required.** Required: the native radios submit under it (REQ-323). |\n| `label` | `string` | | **Required.** The group's name, its `<legend>`. |\n| `orientation` | `UiOrientation` | `'vertical'` | Default `'vertical'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpRadioGroup } from '@silverpoint/react/ui/radio-group';\n\nexport function RadioGroupView() {\n const [value, setValue] = useState<string>('silverpoint');\n return (\n <SpRadioGroup\n label=\"Ground\"\n name=\"ground\"\n items={[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]}\n orientation=\"horizontal\"\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpRadioGroup } from '@silverpoint/vue/ui/radio-group';\n\nconst value = ref<string>('silverpoint');\n</script>\n\n<template>\n <SpRadioGroup\n label=\"Ground\"\n name=\"ground\"\n :items=\"[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]\"\n orientation=\"horizontal\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpRadioGroup } from '@silverpoint/angular/ui/radio-group';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-radio-group-view',\n imports: [SpRadioGroup],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-radio-group\n [label]=\"'Ground'\"\n [name]=\"'ground'\"\n [items]=\"[{ key: 'silverpoint', label: 'silverpoint' }, { key: 'cyanotype', label: 'cyanotype' }]\"\n [orientation]=\"'horizontal'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class RadioGroupView {\n protected readonly value = signal<string>('silverpoint');\n}\n```\n\n## SpSwitch\n\n`switch` \xB7 An on/off toggle with the switch role. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSwitch` | `SpSwitch` | `sp-switch` | `sp_switch` |\n| Import | `@silverpoint/react/ui/switch` | `@silverpoint/vue/ui/switch` | `@silverpoint/angular/ui/switch` | `reflex_silverpoint_react` |\n\n**Value:** React `checked + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `off`, `on`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The visible text and accessible name. |\n| `name` | `string` | | Form field name; submitted as `on` when on. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSwitch } from '@silverpoint/react/ui/switch';\n\nexport function SwitchView() {\n const [value, setValue] = useState<boolean>(false);\n return (\n <SpSwitch\n label=\"Linked hover\"\n name=\"linked\"\n checked={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSwitch } from '@silverpoint/vue/ui/switch';\n\nconst value = ref<boolean>(false);\n</script>\n\n<template>\n <SpSwitch\n label=\"Linked hover\"\n name=\"linked\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSwitch } from '@silverpoint/angular/ui/switch';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-switch-view',\n imports: [SpSwitch],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-switch\n [label]=\"'Linked hover'\"\n [name]=\"'linked'\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SwitchView {\n protected readonly value = signal<boolean>(false);\n}\n```\n\n## SpSlider\n\n`slider` \xB7 A value on a range, with optional marks. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSlider` | `SpSlider` | `sp-slider` | `sp_slider` |\n| Import | `@silverpoint/react/ui/slider` | `@silverpoint/vue/ui/slider` | `@silverpoint/angular/ui/slider` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `marks`, `disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** Accessible name of the native range input. |\n| `min` | `number` | `0` | Default `0`. |\n| `max` | `number` | `100` | Default `100`. |\n| `step` | `number` | `1` | Default `1`. |\n| `name` | `string` | | Form field name; the native input submits under it. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `marks` | `readonly number[]` | | Values on the rail that get a labelled mark. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSlider } from '@silverpoint/react/ui/slider';\n\nexport function SliderView() {\n const [value, setValue] = useState<number>(30);\n return (\n <SpSlider\n label=\"Volume\"\n name=\"volume\"\n marks={[0, 25, 50, 75, 100]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSlider } from '@silverpoint/vue/ui/slider';\n\nconst value = ref<number>(30);\n</script>\n\n<template>\n <SpSlider\n label=\"Volume\"\n name=\"volume\"\n :marks=\"[0, 25, 50, 75, 100]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSlider } from '@silverpoint/angular/ui/slider';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-slider-view',\n imports: [SpSlider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-slider\n [label]=\"'Volume'\"\n [name]=\"'volume'\"\n [marks]=\"[0, 25, 50, 75, 100]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SliderView {\n protected readonly value = signal<number>(30);\n}\n```\n\n## SpRate\n\n`rate` \xB7 A rating from 1 to `count`, optionally read-only. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpRate` | `SpRate` | `sp-rate` | `sp_rate` |\n| Import | `@silverpoint/react/ui/rate` | `@silverpoint/vue/ui/rate` | `@silverpoint/angular/ui/rate` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `three`, `read-only`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `label` | `string` | | **Required.** The group's name, its `<legend>`. |\n| `count` | `number` | `5` | Default `5`, in 1..10; each mark an exact lozenge. |\n| `name` | `string` | | Form field name; the native radios submit under it. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Shows the value; the keyboard and the pointer do not change it. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpRate } from '@silverpoint/react/ui/rate';\n\nexport function RateView() {\n const [value, setValue] = useState<number>(3);\n return (\n <SpRate\n label=\"Quality\"\n name=\"quality\"\n count={5}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpRate } from '@silverpoint/vue/ui/rate';\n\nconst value = ref<number>(3);\n</script>\n\n<template>\n <SpRate\n label=\"Quality\"\n name=\"quality\"\n :count=\"5\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpRate } from '@silverpoint/angular/ui/rate';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-rate-view',\n imports: [SpRate],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-rate\n [label]=\"'Quality'\"\n [name]=\"'quality'\"\n [count]=\"5\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class RateView {\n protected readonly value = signal<number>(3);\n}\n```\n\n## SpSegmented\n\n`segmented` \xB7 One choice among a few, as joined segments. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSegmented` | `SpSegmented` | `sp-segmented` | `sp_segmented` |\n| Import | `@silverpoint/react/ui/segmented` | `@silverpoint/vue/ui/segmented` | `@silverpoint/angular/ui/segmented` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `first`, `middle`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The options; each a native radio. Keys are unique (REQ-325). |\n| `label` | `string` | | **Required.** The control's name, its `<legend>`. |\n| `name` | `string` | | Form field name; the native radios submit under it. |\n| `block` | `boolean` | | Fills the width of its container. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSegmented } from '@silverpoint/react/ui/segmented';\n\nexport function SegmentedView() {\n const [value, setValue] = useState<string>('day');\n return (\n <SpSegmented\n label=\"Period\"\n name=\"period\"\n items={[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSegmented } from '@silverpoint/vue/ui/segmented';\n\nconst value = ref<string>('day');\n</script>\n\n<template>\n <SpSegmented\n label=\"Period\"\n name=\"period\"\n :items=\"[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSegmented } from '@silverpoint/angular/ui/segmented';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-segmented-view',\n imports: [SpSegmented],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-segmented\n [label]=\"'Period'\"\n [name]=\"'period'\"\n [items]=\"[{ key: 'day', label: 'Day' }, { key: 'week', label: 'Week' }, { key: 'month', label: 'Month' }, { key: 'year', label: 'Year' }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SegmentedView {\n protected readonly value = signal<string>('day');\n}\n```\n\n## SpTabs\n\n`tabs` \xB7 Tabs and their panels (`SpTabPanel`), with automatic or manual activation. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTabs` | `SpTabs` | `sp-tabs` | `sp_tabs` |\n| Import | `@silverpoint/react/ui/tabs` | `@silverpoint/vue/ui/tabs` | `@silverpoint/angular/ui/tabs` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `first`, `disabled-tab`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly UiItem[]` | | **Required.** The tabs; a disabled one is skipped by the arrows. Keys are unique (REQ-325). |\n| `label` | `string` | | Accessible name of the tab list. |\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `activation` | `'automatic' \\| 'manual'` | `'automatic'` | Default `'automatic'`: a tab is selected as focus reaches it. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpTabs } from '@silverpoint/react/ui/tabs';\n\nexport function TabsView() {\n const [value, setValue] = useState<string>('overview');\n return (\n <SpTabs\n label=\"Views\"\n items={[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpTabs } from '@silverpoint/vue/ui/tabs';\n\nconst value = ref<string>('overview');\n</script>\n\n<template>\n <SpTabs\n label=\"Views\"\n :items=\"[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpTabs } from '@silverpoint/angular/ui/tabs';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tabs-view',\n imports: [SpTabs],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tabs\n [label]=\"'Views'\"\n [items]=\"[{ key: 'overview', label: 'Overview' }, { key: 'traffic', label: 'Traffic' }, { key: 'errors', label: 'Errors' }, { key: 'settings', label: 'Settings' }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class TabsView {\n protected readonly value = signal<string>('overview');\n}\n```\n\n## SpSteps\n\n`steps` \xB7 The steps of a process, with the current one and an error state. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSteps` | `SpSteps` | `sp-steps` | `sp_steps` |\n| Import | `@silverpoint/react/ui/steps` | `@silverpoint/vue/ui/steps` | `@silverpoint/angular/ui/steps` | `reflex_silverpoint_react` |\n\n**States:** `current`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly StepItem[]` | | **Required.** The steps, in order; a status is derived from `current` unless set. |\n| `current` | `number` | | **Required.** 0-based. |\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `label` | `string` | | Accessible name of the list. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSteps } from '@silverpoint/react/ui/steps';\n\nexport function StepsView() {\n return (\n <SpSteps\n label=\"Release\"\n items={[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]}\n current={2}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSteps } from '@silverpoint/vue/ui/steps';\n</script>\n\n<template>\n <SpSteps\n label=\"Release\"\n :items=\"[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]\"\n :current=\"2\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSteps } from '@silverpoint/angular/ui/steps';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-steps-view',\n imports: [SpSteps],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-steps\n [label]=\"'Release'\"\n [items]=\"[{ key: 'install', title: 'Install' }, { key: 'import', title: 'Import' }, { key: 'configure', title: 'Configure' }, { key: 'publish', title: 'Publish' }]\"\n [current]=\"2\"\n />\n `,\n})\nexport class StepsView {}\n```\n\n## SpCard\n\n`card` \xB7 A framed card with a title, an extra slot and a footer. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCard` | `SpCard` | `sp-card` | `sp_card` |\n| Import | `@silverpoint/react/ui/card` | `@silverpoint/vue/ui/card` | `@silverpoint/angular/ui/card` | `reflex_silverpoint_react` |\n\n**Content:** React `children`, `extra`, `footer`; Vue `default`, `extra`, `footer`; Angular `content`, `spExtra`, `spFooter`.\n\n**States:** `plain`, `titled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | Heading of the card; without it the card is a plain container. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCard } from '@silverpoint/react/ui/card';\n\nexport function CardView() {\n return (\n <SpCard>\n Hits per hour rose through the afternoon and eased at night.\n </SpCard>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCard } from '@silverpoint/vue/ui/card';\n</script>\n\n<template>\n <SpCard>\n Hits per hour rose through the afternoon and eased at night.\n </SpCard>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpCard } from '@silverpoint/angular/ui/card';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-card-view',\n imports: [SpCard],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-card>\n Hits per hour rose through the afternoon and eased at night.\n </sp-card>\n `,\n})\nexport class CardView {}\n```\n\n## SpTag\n\n`tag` \xB7 A short toned label, optionally closable. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTag` | `SpTag` | `sp-tag` | `sp_tag` |\n| Import | `@silverpoint/react/ui/tag` | `@silverpoint/vue/ui/tag` | `@silverpoint/angular/ui/tag` | `reflex_silverpoint_react` |\n\n**Events:** React `onClose`; Vue `close`; Angular `close`.\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `tone-1`, `closable`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `tone` | `UiToneLevel` | | Tonal level, default `1`. |\n| `closable` | `boolean` | | Adds a native close button; each adapter raises its close event. |\n| `closeLabel` | `string` | `Remove <text>` | Accessible name of the close button. Default `Remove <text>`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTag } from '@silverpoint/react/ui/tag';\n\nexport function TagView() {\n return (\n <SpTag\n tone={1}\n >\n draft\n </SpTag>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTag } from '@silverpoint/vue/ui/tag';\n</script>\n\n<template>\n <SpTag\n :tone=\"1\"\n >\n draft\n </SpTag>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTag } from '@silverpoint/angular/ui/tag';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tag-view',\n imports: [SpTag],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tag\n [tone]=\"1\"\n >\n draft\n </sp-tag>\n `,\n})\nexport class TagView {}\n```\n\n## SpBadge\n\n`badge` \xB7 A count or a dot over its content. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpBadge` | `SpBadge` | `sp-badge` | `sp_badge` |\n| Import | `@silverpoint/react/ui/badge` | `@silverpoint/vue/ui/badge` | `@silverpoint/angular/ui/badge` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `count`, `dot`, `overflow`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `count` | `number` | | The number shown, up to `max`. |\n| `max` | `number` | `99` | Default `99`; above it the badge reads `99+`. |\n| `dot` | `boolean` | | A dot with no number. |\n| `label` | `string` | | Accessible text of the badge, e.g. `unread messages`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBadge } from '@silverpoint/react/ui/badge';\n\nexport function BadgeView() {\n return (\n <SpBadge\n count={12}\n >\n Inbox\n </SpBadge>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBadge } from '@silverpoint/vue/ui/badge';\n</script>\n\n<template>\n <SpBadge\n :count=\"12\"\n >\n Inbox\n </SpBadge>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpBadge } from '@silverpoint/angular/ui/badge';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-badge-view',\n imports: [SpBadge],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-badge\n [count]=\"12\"\n >\n Inbox\n </sp-badge>\n `,\n})\nexport class BadgeView {}\n```\n\n## SpDivider\n\n`divider` \xB7 A rule between sections, optionally with text. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDivider` | `SpDivider` | `sp-divider` | `sp_divider` |\n| Import | `@silverpoint/react/ui/divider` | `@silverpoint/vue/ui/divider` | `@silverpoint/angular/ui/divider` | `reflex_silverpoint_react` |\n\n**States:** `plain`, `text`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `orientation` | `UiOrientation` | `'horizontal'` | Default `'horizontal'`. |\n| `text` | `string` | | A caption set in the rule. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDivider } from '@silverpoint/react/ui/divider';\n\nexport function DividerView() {\n return (\n <SpDivider />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDivider } from '@silverpoint/vue/ui/divider';\n</script>\n\n<template>\n <SpDivider />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDivider } from '@silverpoint/angular/ui/divider';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-divider-view',\n imports: [SpDivider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-divider />\n `,\n})\nexport class DividerView {}\n```\n\n## SpProgress\n\n`progress` \xB7 Progress as a line or a circle, or indeterminate. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpProgress` | `SpProgress` | `sp-progress` | `sp_progress` |\n| Import | `@silverpoint/react/ui/progress` | `@silverpoint/vue/ui/progress` | `@silverpoint/angular/ui/progress` | `reflex_silverpoint_react` |\n\n**States:** `line`, `circle`, `indeterminate`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `value` | `number` | | 0..100; omitted, the progress is indeterminate. |\n| `shape` | `'line' \\| 'circle'` | `'line'` | Default `'line'`. |\n| `label` | `string` | | **Required.** Accessible name (REQ-318). |\n| `showValue` | `boolean` | `true` | Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpProgress } from '@silverpoint/react/ui/progress';\n\nexport function ProgressView() {\n return (\n <SpProgress\n label=\"Upload\"\n value={40}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpProgress } from '@silverpoint/vue/ui/progress';\n</script>\n\n<template>\n <SpProgress\n label=\"Upload\"\n :value=\"40\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpProgress } from '@silverpoint/angular/ui/progress';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-progress-view',\n imports: [SpProgress],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-progress\n [label]=\"'Upload'\"\n [value]=\"40\"\n />\n `,\n})\nexport class ProgressView {}\n```\n\n## SpAlert\n\n`alert` \xB7 An info, success, warning or error message, optionally closable. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpAlert` | `SpAlert` | `sp-alert` | `sp_alert` |\n| Import | `@silverpoint/react/ui/alert` | `@silverpoint/vue/ui/alert` | `@silverpoint/angular/ui/alert` | `reflex_silverpoint_react` |\n\n**Events:** React `onClose`; Vue `close`; Angular `close`.\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `info`, `success`, `warning`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `kind` | `AlertKind` | `'info'` | Default `'info'`. |\n| `title` | `string` | | Bold first line of the alert. |\n| `closable` | `boolean` | | Adds a native close button; each adapter raises its close event. |\n| `closeLabel` | `string` | `'Close'` | Accessible name of the close button. Default `'Close'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAlert } from '@silverpoint/react/ui/alert';\n\nexport function AlertView() {\n return (\n <SpAlert\n kind=\"info\"\n title=\"New ground available\"\n >\n cyanotype ships in 0.2.0.\n </SpAlert>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAlert } from '@silverpoint/vue/ui/alert';\n</script>\n\n<template>\n <SpAlert\n kind=\"info\"\n title=\"New ground available\"\n >\n cyanotype ships in 0.2.0.\n </SpAlert>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpAlert } from '@silverpoint/angular/ui/alert';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-alert-view',\n imports: [SpAlert],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-alert\n [kind]=\"'info'\"\n [title]=\"'New ground available'\"\n >\n cyanotype ships in 0.2.0.\n </sp-alert>\n `,\n})\nexport class AlertView {}\n```\n\n## SpSkeleton\n\n`skeleton` \xB7 A placeholder for content that is loading. (feedback)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSkeleton` | `SpSkeleton` | `sp-skeleton` | `sp_skeleton` |\n| Import | `@silverpoint/react/ui/skeleton` | `@silverpoint/vue/ui/skeleton` | `@silverpoint/angular/ui/skeleton` | `reflex_silverpoint_react` |\n\n**States:** `paragraph`, `avatar`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `lines` | `number` | `3` | Default `3`, in 1..8. |\n| `avatar` | `boolean` | | Draws an avatar placeholder before the lines. |\n| `label` | `string` | `'Loading'` | Default `'Loading'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSkeleton } from '@silverpoint/react/ui/skeleton';\n\nexport function SkeletonView() {\n return (\n <SpSkeleton\n lines={3}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSkeleton } from '@silverpoint/vue/ui/skeleton';\n</script>\n\n<template>\n <SpSkeleton\n :lines=\"3\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSkeleton } from '@silverpoint/angular/ui/skeleton';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-skeleton-view',\n imports: [SpSkeleton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-skeleton\n [lines]=\"3\"\n />\n `,\n})\nexport class SkeletonView {}\n```\n\n## SpSurface\n\n`surface` \xB7 A framed, toned surface to build your own components on. (building-blocks)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSurface` | `SpSurface` | `[spSurface]` | `sp_surface` |\n| Import | `@silverpoint/react/ui/surface` | `@silverpoint/vue/ui/surface` | `@silverpoint/angular/ui/surface` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `frame-card`, `tone-2`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `as` | `string` | `'div'` | The element, a lowercase HTML tag name. Default `'div'`. |\n| `name` | `string` | | Adds the class `sp-<name>`, a lowercase ident. |\n| `frame` | `UiFrameKind` | | Draws a frame of that kind. |\n| `tone` | `UiToneLevel \\| string` | | Lays a tone: a level 1-4 of the ramp, or a state (`selected`, `primary`\u2026). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSurface } from '@silverpoint/react/ui/surface';\n\nexport function SurfaceView() {\n return (\n <SpSurface\n frame=\"card\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </SpSurface>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpSurface } from '@silverpoint/vue/ui/surface';\n</script>\n\n<template>\n <SpSurface\n frame=\"card\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </SpSurface>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpSurface } from '@silverpoint/angular/ui/surface';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-surface-view',\n imports: [SpSurface],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n spSurface\n [frame]=\"'card'\"\n >\n A surface takes the ground: its substrate, its ink and a hand-drawn frame.\n </div>\n `,\n})\nexport class SurfaceView {}\n```\n\n## SpGlyph\n\n`glyph` \xB7 One of the exact glyphs the components draw (tick, cross, arrows, chevrons\u2026). (building-blocks)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpGlyph` | `SpGlyph` | `sp-glyph` | `sp_glyph` |\n| Import | `@silverpoint/react/ui/glyph` | `@silverpoint/vue/ui/glyph` | `@silverpoint/angular/ui/glyph` | `reflex_silverpoint_react` |\n\n**States:** `all`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `glyph` | `string` | | **Required.** A key of `UI_GLYPHS`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpGlyph } from '@silverpoint/react/ui/glyph';\n\nexport function GlyphView() {\n return (\n <SpGlyph\n glyph=\"tick\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpGlyph } from '@silverpoint/vue/ui/glyph';\n</script>\n\n<template>\n <SpGlyph\n glyph=\"tick\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpGlyph } from '@silverpoint/angular/ui/glyph';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-glyph-view',\n imports: [SpGlyph],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-glyph\n [glyph]=\"'tick'\"\n />\n `,\n})\nexport class GlyphView {}\n```\n\n## SpTable\n\n`table` \xB7 A data table with sortable columns, stripes and an empty state. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTable` | `SpTable` | `sp-table` | `sp_table` |\n| Import | `@silverpoint/react/ui/table` | `@silverpoint/vue/ui/table` | `@silverpoint/angular/ui/table` | `reflex_silverpoint_react` |\n\n**Events:** React `onSort`; Vue `sort`; Angular `sort`.\n\n**States:** `plain`, `sorted-striped`, `empty`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `columns` | `readonly TableColumn[]` | | **Required.** The columns, in order; each names the key it reads from a row. |\n| `data` | `readonly Readonly<Record<string, unknown>>[]` | | **Required.** The rows, drawn as given: the consumer sorts them (DD-040). |\n| `caption` | `string` | | The table's `<caption>`, its accessible name. |\n| `sortKey` | `string` | | A sortable column's key; another key sorts nothing, silently. |\n| `sortOrder` | `'asc' \\| 'desc'` | `'asc'` | Default `'asc'`. |\n| `striped` | `boolean` | `false` | Default `false`. |\n| `hoverable` | `boolean` | `true` | Default `true`. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n| `emptyText` | `string` | `'No data'` | Default `'No data'`. |\n| `rowKey` | `string` | | The column whose value keys each row. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTable } from '@silverpoint/react/ui/table';\n\nexport function TableView() {\n return (\n <SpTable\n caption=\"Orders\"\n columns={[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]}\n data={[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]}\n rowKey=\"order\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTable } from '@silverpoint/vue/ui/table';\n</script>\n\n<template>\n <SpTable\n caption=\"Orders\"\n :columns=\"[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]\"\n :data=\"[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]\"\n rowKey=\"order\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTable } from '@silverpoint/angular/ui/table';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-table-view',\n imports: [SpTable],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-table\n [caption]=\"'Orders'\"\n [columns]=\"[{ key: 'order', title: 'Order' }, { key: 'customer', title: 'Customer', sortable: true }, { key: 'status', title: 'Status' }, { key: 'amount', title: 'Amount', align: 'end', sortable: true }]\"\n [data]=\"[{ order: '1042', customer: 'Ada Lovelace', status: 'Shipped', amount: 128 }, { order: '1043', customer: 'Grace Hopper', status: 'Packed', amount: 64.5 }, { order: '1044', customer: 'Alan Turing', status: 'Paid', amount: 312 }, { order: '1045', customer: 'Emmy Noether', status: 'Placed', amount: 18.25 }, { order: '1046', customer: 'Kurt G\xF6del', status: 'Shipped', amount: 96 }]\"\n [rowKey]=\"'order'\"\n />\n `,\n})\nexport class TableView {}\n```\n\n## SpPagination\n\n`pagination` \xB7 Page navigation with a current page, siblings and an optional total. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpPagination` | `SpPagination` | `sp-pagination` | `sp_pagination` |\n| Import | `@silverpoint/react/ui/pagination` | `@silverpoint/vue/ui/pagination` | `@silverpoint/angular/ui/pagination` | `reflex_silverpoint_react` |\n\n**Value:** React `current + onChange`, Vue `v-model:current`, Angular `[(current)]`.\n\n**Events:** React `onChange`; Vue ; Angular .\n\n**States:** `middle`, `total`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `total` | `number` | | **Required.** The number of items paged over. |\n| `pageSize` | `number` | `10` | Default `10`. |\n| `siblings` | `number` | `1` | Pages shown on each side of the current one. Default `1`. |\n| `showTotal` | `boolean` | `false` | Default `false`. |\n| `totalTemplate` | `string` | `'{start}\u2013{end} of {total}'` | Default `'{start}\u2013{end} of {total}'`. |\n| `label` | `string` | `'Pagination'` | Default `'Pagination'`. |\n| `previousLabel` | `string` | `'Previous page'` | Default `'Previous page'`. |\n| `nextLabel` | `string` | `'Next page'` | Default `'Next page'`. |\n| `pageLabel` | `string` | `'Page'` | Default `'Page'`. |\n| `disabled` | `boolean` | | Every page button disabled. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpPagination } from '@silverpoint/react/ui/pagination';\n\nexport function PaginationView() {\n const [value, setValue] = useState<number>(10);\n return (\n <SpPagination\n total={200}\n pageSize={10}\n current={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpPagination } from '@silverpoint/vue/ui/pagination';\n\nconst value = ref<number>(10);\n</script>\n\n<template>\n <SpPagination\n :total=\"200\"\n :pageSize=\"10\"\n v-model:current=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpPagination } from '@silverpoint/angular/ui/pagination';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-pagination-view',\n imports: [SpPagination],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-pagination\n [total]=\"200\"\n [pageSize]=\"10\"\n [(current)]=\"value\"\n />\n `,\n})\nexport class PaginationView {\n protected readonly value = signal<number>(10);\n}\n```\n\n## SpBreadcrumb\n\n`breadcrumb` \xB7 The trail of pages to the current one. (navigation)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpBreadcrumb` | `SpBreadcrumb` | `sp-breadcrumb` | `sp_breadcrumb` |\n| Import | `@silverpoint/react/ui/breadcrumb` | `@silverpoint/vue/ui/breadcrumb` | `@silverpoint/angular/ui/breadcrumb` | `reflex_silverpoint_react` |\n\n**States:** `three`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly BreadcrumbItem[]` | | **Required.** The last item is the current page. |\n| `label` | `string` | `'Breadcrumb'` | Default `'Breadcrumb'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBreadcrumb } from '@silverpoint/react/ui/breadcrumb';\n\nexport function BreadcrumbView() {\n return (\n <SpBreadcrumb\n items={[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpBreadcrumb } from '@silverpoint/vue/ui/breadcrumb';\n</script>\n\n<template>\n <SpBreadcrumb\n :items=\"[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpBreadcrumb } from '@silverpoint/angular/ui/breadcrumb';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-breadcrumb-view',\n imports: [SpBreadcrumb],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-breadcrumb\n [items]=\"[{ key: 'home', label: 'Home', href: '/' }, { key: 'orders', label: 'Orders', href: '/orders' }, { key: '1042', label: 'Order 1042' }]\"\n />\n `,\n})\nexport class BreadcrumbView {}\n```\n\n## SpAvatar\n\n`avatar` \xB7 A picture or initials in a round or square frame; `SpAvatarGroup` stacks several. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpAvatar` | `SpAvatar` | `sp-avatar` | `sp_avatar` |\n| Import | `@silverpoint/react/ui/avatar` | `@silverpoint/vue/ui/avatar` | `@silverpoint/angular/ui/avatar` | `reflex_silverpoint_react` |\n\n**States:** `initials`, `square`, `group`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `src` | `string` | | An image; the initials are drawn without one. |\n| `name` | `string` | | The person's name: the accessible name and the source of the initials. |\n| `initials` | `string` | | Overrides the initials derived from `name`. |\n| `alt` | `string` | | Overrides `name` as the accessible name. |\n| `shape` | `'circle' \\| 'square'` | `'circle'` | Default `'circle'`. |\n| `pixelSize` | `number` | | Side length in px; the ground's control height when omitted. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAvatar } from '@silverpoint/react/ui/avatar';\n\nexport function AvatarView() {\n return (\n <SpAvatar\n name=\"Ada Lovelace\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpAvatar } from '@silverpoint/vue/ui/avatar';\n</script>\n\n<template>\n <SpAvatar\n name=\"Ada Lovelace\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpAvatar } from '@silverpoint/angular/ui/avatar';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-avatar-view',\n imports: [SpAvatar],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-avatar\n [name]=\"'Ada Lovelace'\"\n />\n `,\n})\nexport class AvatarView {}\n```\n\n## SpStatistic\n\n`statistic` \xB7 A titled figure with a prefix, a suffix and an optional trend. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpStatistic` | `SpStatistic` | `sp-statistic` | `sp_statistic` |\n| Import | `@silverpoint/react/ui/statistic` | `@silverpoint/vue/ui/statistic` | `@silverpoint/angular/ui/statistic` | `reflex_silverpoint_react` |\n\n**States:** `plain`, `trend-down`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | **Required.** The label above the value. |\n| `value` | `string \\| number` | | **Required.** Printed as given. |\n| `prefix` | `string` | | Printed before the value (`$`). |\n| `suffix` | `string` | | Printed after the value (`%`). |\n| `trend` | `'up' \\| 'down'` | | Draws the exact \u2191 or \u2193 glyph beside the delta. |\n| `delta` | `string` | | The change, as text (`+4.2%`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpStatistic } from '@silverpoint/react/ui/statistic';\n\nexport function StatisticView() {\n return (\n <SpStatistic\n title=\"Orders\"\n value={1284}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpStatistic } from '@silverpoint/vue/ui/statistic';\n</script>\n\n<template>\n <SpStatistic\n title=\"Orders\"\n :value=\"1284\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpStatistic } from '@silverpoint/angular/ui/statistic';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-statistic-view',\n imports: [SpStatistic],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-statistic\n [title]=\"'Orders'\"\n [value]=\"1284\"\n />\n `,\n})\nexport class StatisticView {}\n```\n\n## SpDescriptions\n\n`descriptions` \xB7 Label and value pairs as a description list. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDescriptions` | `SpDescriptions` | `sp-descriptions` | `sp_descriptions` |\n| Import | `@silverpoint/react/ui/descriptions` | `@silverpoint/vue/ui/descriptions` | `@silverpoint/angular/ui/descriptions` | `reflex_silverpoint_react` |\n\n**States:** `bordered`, `plain`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly DescriptionItem[]` | | **Required.** The label\u2013value pairs, a `<dl>`. Keys, when given, are unique (REQ-325). |\n| `title` | `string` | | A heading above the list, at `headingLevel`. |\n| `columns` | `number` | `3` | Default `3`, in 1..6. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDescriptions } from '@silverpoint/react/ui/descriptions';\n\nexport function DescriptionsView() {\n return (\n <SpDescriptions\n title=\"Order 1042\"\n items={[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]}\n columns={2}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDescriptions } from '@silverpoint/vue/ui/descriptions';\n</script>\n\n<template>\n <SpDescriptions\n title=\"Order 1042\"\n :items=\"[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]\"\n :columns=\"2\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDescriptions } from '@silverpoint/angular/ui/descriptions';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-descriptions-view',\n imports: [SpDescriptions],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-descriptions\n [title]=\"'Order 1042'\"\n [items]=\"[{ key: 'customer', label: 'Customer', value: 'Ada Lovelace' }, { key: 'status', label: 'Status', value: 'Shipped' }, { key: 'amount', label: 'Amount', value: '128.00' }, { key: 'placed', label: 'Placed', value: '14 October 2026' }]\"\n [columns]=\"2\"\n />\n `,\n})\nexport class DescriptionsView {}\n```\n\n## SpTimelineList\n\n`timeline-list` \xB7 Events in order, each done, current, pending or in error. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTimelineList` | `SpTimelineList` | `sp-timeline-list` | `sp_timeline_list` |\n| Import | `@silverpoint/react/ui/timeline-list` | `@silverpoint/vue/ui/timeline-list` | `@silverpoint/angular/ui/timeline-list` | `reflex_silverpoint_react` |\n\n**States:** `mixed`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly TimelineListItem[]` | | **Required.** The events, in reading order. |\n| `label` | `string` | | Accessible name of the list. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTimelineList } from '@silverpoint/react/ui/timeline-list';\n\nexport function TimelineListView() {\n return (\n <SpTimelineList\n label=\"Order history\"\n items={[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTimelineList } from '@silverpoint/vue/ui/timeline-list';\n</script>\n\n<template>\n <SpTimelineList\n label=\"Order history\"\n :items=\"[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTimelineList } from '@silverpoint/angular/ui/timeline-list';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-timeline-list-view',\n imports: [SpTimelineList],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-timeline-list\n [label]=\"'Order history'\"\n [items]=\"[{ key: 'placed', title: 'Placed', time: '14 Oct, 09:12', description: 'Two prints, one framed.' }, { key: 'paid', title: 'Payment', time: '14 Oct, 09:14', description: 'Card declined; paid on the second try.', status: 'error' }, { key: 'packed', title: 'Packed', time: '15 Oct, 16:40', status: 'current' }, { key: 'shipped', title: 'Shipped', status: 'pending' }]\"\n />\n `,\n})\nexport class TimelineListView {}\n```\n\n## SpCollapse\n\n`collapse` \xB7 Disclosure panels (`SpCollapseItem`), optionally as an accordion. (disclosure)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpCollapse` | `SpCollapse` | `sp-collapse` | `sp_collapse` |\n| Import | `@silverpoint/react/ui/collapse` | `@silverpoint/vue/ui/collapse` | `@silverpoint/angular/ui/collapse` | `reflex_silverpoint_react` |\n\n**Content:** React `children`; Vue `default`; Angular `content`.\n\n**States:** `one-open`, `accordion-disabled`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `accordion` | `boolean` | `false` | One item open at a time, natively (`<details name>`). Default `false`. |\n| `bordered` | `boolean` | `true` | Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCollapse } from '@silverpoint/react/ui/collapse';\n\nexport function CollapseView() {\n return (\n <SpCollapse />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpCollapse } from '@silverpoint/vue/ui/collapse';\n</script>\n\n<template>\n <SpCollapse />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpCollapse } from '@silverpoint/angular/ui/collapse';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-collapse-view',\n imports: [SpCollapse],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-collapse />\n `,\n})\nexport class CollapseView {}\n```\n\n## SpEmpty\n\n`empty` \xB7 The empty state of a list or a table. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpEmpty` | `SpEmpty` | `sp-empty` | `sp_empty` |\n| Import | `@silverpoint/react/ui/empty` | `@silverpoint/vue/ui/empty` | `@silverpoint/angular/ui/empty` | `reflex_silverpoint_react` |\n\n**Content:** React `extra`; Vue `extra`; Angular `spExtra`.\n\n**States:** `plain`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `description` | `string` | `'No data'` | Default `'No data'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpEmpty } from '@silverpoint/react/ui/empty';\n\nexport function EmptyView() {\n return (\n <SpEmpty\n description=\"No orders yet\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpEmpty } from '@silverpoint/vue/ui/empty';\n</script>\n\n<template>\n <SpEmpty\n description=\"No orders yet\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpEmpty } from '@silverpoint/angular/ui/empty';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-empty-view',\n imports: [SpEmpty],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-empty\n [description]=\"'No orders yet'\"\n />\n `,\n})\nexport class EmptyView {}\n```\n\n## SpResult\n\n`result` \xB7 The outcome of an action: success, error, information or warning. (data-display)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpResult` | `SpResult` | `sp-result` | `sp_result` |\n| Import | `@silverpoint/react/ui/result` | `@silverpoint/vue/ui/result` | `@silverpoint/angular/ui/result` | `reflex_silverpoint_react` |\n\n**Content:** React `extra`; Vue `extra`; Angular `spExtra`.\n\n**States:** `success`, `error`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `status` | `AlertKind` | `'info'` | Default `'info'`. |\n| `title` | `string` | | **Required.** The heading, at `headingLevel`. |\n| `subtitle` | `string` | | A paragraph under the title. |\n| `headingLevel` | `2 \\| 3 \\| 4 \\| 5 \\| 6` | `3` | Default `3`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpResult } from '@silverpoint/react/ui/result';\n\nexport function ResultView() {\n return (\n <SpResult\n status=\"success\"\n title=\"Order placed\"\n subtitle=\"Order 1042 is on its way to the workshop.\"\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpResult } from '@silverpoint/vue/ui/result';\n</script>\n\n<template>\n <SpResult\n status=\"success\"\n title=\"Order placed\"\n subtitle=\"Order 1042 is on its way to the workshop.\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpResult } from '@silverpoint/angular/ui/result';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-result-view',\n imports: [SpResult],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-result\n [status]=\"'success'\"\n [title]=\"'Order placed'\"\n [subtitle]=\"'Order 1042 is on its way to the workshop.'\"\n />\n `,\n})\nexport class ResultView {}\n```\n\n## SpTextarea\n\n`textarea` \xB7 A multi-line text field with a counter and an invalid state. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTextarea` | `SpTextarea` | `sp-textarea` | `sp_textarea` |\n| Import | `@silverpoint/react/ui/textarea` | `@silverpoint/vue/ui/textarea` | `@silverpoint/angular/ui/textarea` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue `change`; Angular .\n\n**States:** `count`, `invalid`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `rows` | `number` | `3` | Default `3`. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `maxLength` | `number` | | The native limit; the counter shows it with `showCount`. |\n| `showCount` | `boolean` | `false` | Default `false`. |\n| `name` | `string` | | Form field name; the native textarea submits under it (REQ-323). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpTextarea } from '@silverpoint/react/ui/textarea';\n\nexport function TextareaView() {\n const [value, setValue] = useState<string>('Leave it at the door.');\n return (\n <SpTextarea\n label=\"Notes\"\n name=\"notes\"\n maxLength={120}\n showCount={true}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpTextarea } from '@silverpoint/vue/ui/textarea';\n\nconst value = ref<string>('Leave it at the door.');\n</script>\n\n<template>\n <SpTextarea\n label=\"Notes\"\n name=\"notes\"\n :maxLength=\"120\"\n :showCount=\"true\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpTextarea } from '@silverpoint/angular/ui/textarea';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-textarea-view',\n imports: [SpTextarea],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-textarea\n [label]=\"'Notes'\"\n [name]=\"'notes'\"\n [maxLength]=\"120\"\n [showCount]=\"true\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class TextareaView {\n protected readonly value = signal<string>('Leave it at the door.');\n}\n```\n\n## SpInputNumber\n\n`input-number` \xB7 A number field with steppers, bounds and precision. (data-entry)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpInputNumber` | `SpInputNumber` | `sp-input-number` | `sp_input_number` |\n| Import | `@silverpoint/react/ui/input-number` | `@silverpoint/vue/ui/input-number` | `@silverpoint/angular/ui/input-number` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Events:** React `onChange`; Vue ; Angular .\n\n**States:** `value`, `at-min`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `min` | `number` | | The lowest value; the value is clamped to it (REQ-485). |\n| `max` | `number` | | The highest value; the value is clamped to it (REQ-485). |\n| `step` | `number` | `1` | Default `1`. |\n| `precision` | `number` | | Decimals. |\n| `placeholder` | `string` | | Hint shown while empty; not a substitute for the accessible name. |\n| `label` | `string` | | Accessible name, when no `<label for>` names the control. |\n| `message` | `string` | | Help or error text under the control, referenced by `aria-describedby` (REQ-334). |\n| `invalid` | `boolean` | | Sets `aria-invalid` and draws the exact \u26A0 glyph (REQ-334). |\n| `disabled` | `boolean` | | Not focusable and not submitted; the steppers are disabled too. |\n| `readOnly` | `boolean` | | Focusable and submitted, but not editable. |\n| `name` | `string` | | Form field name; the native input submits under it (REQ-323). |\n| `decrementLabel` | `string` | `'Decrease'` | Default `'Decrease'`. |\n| `incrementLabel` | `string` | `'Increase'` | Default `'Increase'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpInputNumber } from '@silverpoint/react/ui/input-number';\n\nexport function InputNumberView() {\n const [value, setValue] = useState<number | null>(3);\n return (\n <SpInputNumber\n label=\"Quantity\"\n name=\"quantity\"\n min={1}\n max={10}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpInputNumber } from '@silverpoint/vue/ui/input-number';\n\nconst value = ref<number | null>(3);\n</script>\n\n<template>\n <SpInputNumber\n label=\"Quantity\"\n name=\"quantity\"\n :min=\"1\"\n :max=\"10\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpInputNumber } from '@silverpoint/angular/ui/input-number';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-input-number-view',\n imports: [SpInputNumber],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-input-number\n [label]=\"'Quantity'\"\n [name]=\"'quantity'\"\n [min]=\"1\"\n [max]=\"10\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class InputNumberView {\n protected readonly value = signal<number | null>(3);\n}\n```\n",
|
|
11517
|
+
"overlays": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Overlays\n\n*Describes silverpoint 0.8.0.*\n\nModal, Drawer, Popover, Tooltip, Select, DropdownMenu and Toast are built on the platform's\n`<dialog>` and Popover API. They are client components only.\n\n## The trigger is a native button\n\nGive every overlay a native `<button type=\"button\">` as its trigger:\n\n- **React:** the `trigger` prop, `trigger={<button type=\"button\">Edit</button>}`. The overlay\n clones it with its ARIA and its toggle. Do not pass `SpButton`: it drops the ARIA it is given.\n- **Vue:** the `trigger` slot, `<template #trigger><button type=\"button\">Edit</button></template>`.\n Its first element is cloned.\n- **Angular:** project the button with the `spTrigger` directive,\n `<button type=\"button\" spTrigger>Edit</button>`, and import `SpTrigger` from the overlay's own\n subpath.\n\n## Open state\n\n| | Controlled | Uncontrolled | Change |\n|---|---|---|---|\n| React | `open` | `defaultOpen` | `onOpenChange(open)` |\n| Vue | `v-model:open` | `default-open` | `update:open` |\n| Angular | `[(open)]` | `[defaultOpen]` | `(openChange)` |\n\n`onOpenChange` also fires when the platform closes it: Escape, or a click outside. A Modal with\n`dismissible={false}` ignores both.\n\n## Toasts\n\nPut one `SpToaster` near the root and render `SpToast` children inside it. A toast closes after the\ntoaster's `duration` (5000 ms) unless its own `duration` says otherwise. It pauses while hovered or\nfocused, and F8 moves focus to the toaster.\n\n## Sides\n\nSides are logical, `start` and `end`, so they mirror in right-to-left pages. Reflex's `left` and\n`right` become `start` and `end`.\n\n**Contents:** [SpModal](#spmodal) \xB7 [SpDrawer](#spdrawer) \xB7 [SpPopover](#sppopover) \xB7 [SpTooltip](#sptooltip) \xB7 [SpSelect](#spselect) \xB7 [SpDropdownMenu](#spdropdownmenu) \xB7 [SpToast](#sptoast)\n\n## SpModal\n\n`modal` \xB7 A modal dialog on the native `<dialog>`, opened by its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpModal` | `SpModal` | `sp-modal` | `sp_modal` |\n| Import | `@silverpoint/react/ui/modal` | `@silverpoint/vue/ui/modal` | `@silverpoint/angular/ui/modal` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `footer`, `trigger`; Vue `default`, `footer`, `trigger`; Angular `content`, `spFooter`, `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | The heading, `${id}--title`, that names the dialog. |\n| `description` | `string` | | A paragraph, `${id}--description`, that describes the dialog. |\n| `label` | `string` | | Accessible name without a title (REQ-501). |\n| `closable` | `boolean` | `true` | Default `true`. |\n| `closeLabel` | `string` | `'Close'` | Default `'Close'`. |\n| `width` | `string` | `'520px'` | CSS length. Default `'520px'` (from `ui.css`). |\n| `dismissible` | `boolean` | `true` | Escape and a backdrop click close it. Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpModal } from '@silverpoint/react/ui/modal';\n\nexport function ModalView() {\n return (\n <SpModal\n title=\"Edit order\"\n description=\"Order 1042, placed on 14 October.\"\n trigger={<button type=\"button\">Edit order</button>}\n >\n Changes reach the workshop before the order is packed.\n </SpModal>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpModal } from '@silverpoint/vue/ui/modal';\n</script>\n\n<template>\n <SpModal\n title=\"Edit order\"\n description=\"Order 1042, placed on 14 October.\"\n >\n <template #trigger><button type=\"button\">Edit order</button></template>\n Changes reach the workshop before the order is packed.\n </SpModal>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpModal, SpTrigger } from '@silverpoint/angular/ui/modal';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-modal-view',\n imports: [SpModal, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-modal\n [title]=\"'Edit order'\"\n [description]=\"'Order 1042, placed on 14 October.'\"\n >\n <button type=\"button\" spTrigger>Edit order</button>\n Changes reach the workshop before the order is packed.\n </sp-modal>\n `,\n})\nexport class ModalView {}\n```\n\n## SpDrawer\n\n`drawer` \xB7 A dialog sliding in from one side of the viewport. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDrawer` | `SpDrawer` | `sp-drawer` | `sp_drawer` |\n| Import | `@silverpoint/react/ui/drawer` | `@silverpoint/vue/ui/drawer` | `@silverpoint/angular/ui/drawer` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `footer`, `trigger`; Vue `default`, `footer`, `trigger`; Angular `content`, `spFooter`, `spTrigger`.\n\n**States:** `end-open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `side` | `'start' \\| 'end' \\| 'top' \\| 'bottom'` | `'end'` | Default `'end'`. |\n| `extent` | `string` | `'380px'` | CSS length across the side. Default `'380px'` (start/end) or `'320px'` (top/bottom). |\n| `modal` | `boolean` | `true` | `false` opens with `show()`. Default `true`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDrawer } from '@silverpoint/react/ui/drawer';\n\nexport function DrawerView() {\n return (\n <SpDrawer\n side=\"end\"\n trigger={<button type=\"button\">Filters</button>}\n >\n Narrow the orders by status, customer or amount.\n </SpDrawer>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDrawer } from '@silverpoint/vue/ui/drawer';\n</script>\n\n<template>\n <SpDrawer\n side=\"end\"\n >\n <template #trigger><button type=\"button\">Filters</button></template>\n Narrow the orders by status, customer or amount.\n </SpDrawer>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDrawer, SpTrigger } from '@silverpoint/angular/ui/drawer';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-drawer-view',\n imports: [SpDrawer, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-drawer\n [side]=\"'end'\"\n >\n <button type=\"button\" spTrigger>Filters</button>\n Narrow the orders by status, customer or amount.\n </sp-drawer>\n `,\n})\nexport class DrawerView {}\n```\n\n## SpPopover\n\n`popover` \xB7 Non-modal content anchored to its trigger, on the Popover API. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpPopover` | `SpPopover` | `sp-popover` | `sp_popover` |\n| Import | `@silverpoint/react/ui/popover` | `@silverpoint/vue/ui/popover` | `@silverpoint/angular/ui/popover` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `children`, `trigger`; Vue `default`, `trigger`; Angular `content`, `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | A heading that names the popover. |\n| `label` | `string` | | Accessible name without a title. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'bottom'` | Default `'bottom'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n| `offset` | `number` | `6` | Default `6`. |\n| `closable` | `boolean` | `false` | Default `false`. |\n| `closeLabel` | `string` | `'Close'` | Default `'Close'`. |\n| `width` | `string` | `'320px'` | CSS length. Default `'320px'` (from `ui.css`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpPopover } from '@silverpoint/react/ui/popover';\n\nexport function PopoverView() {\n return (\n <SpPopover\n title=\"Order 1042\"\n trigger={<button type=\"button\">Details</button>}\n >\n Two prints, one framed; shipped on 16 October.\n </SpPopover>\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpPopover } from '@silverpoint/vue/ui/popover';\n</script>\n\n<template>\n <SpPopover\n title=\"Order 1042\"\n >\n <template #trigger><button type=\"button\">Details</button></template>\n Two prints, one framed; shipped on 16 October.\n </SpPopover>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpPopover, SpTrigger } from '@silverpoint/angular/ui/popover';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-popover-view',\n imports: [SpPopover, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-popover\n [title]=\"'Order 1042'\"\n >\n <button type=\"button\" spTrigger>Details</button>\n Two prints, one framed; shipped on 16 October.\n </sp-popover>\n `,\n})\nexport class PopoverView {}\n```\n\n## SpTooltip\n\n`tooltip` \xB7 A short text shown on hover or focus of its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTooltip` | `SpTooltip` | `sp-tooltip` | `sp_tooltip` |\n| Import | `@silverpoint/react/ui/tooltip` | `@silverpoint/vue/ui/tooltip` | `@silverpoint/angular/ui/tooltip` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `trigger`; Vue `trigger`; Angular `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `text` | `string` | | **Required.** The tooltip, the trigger's accessible description. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'top'` | Default `'top'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'center'` | Default `'center'`. |\n| `offset` | `number` | `6` | Default `6`. |\n| `delay` | `number` | `300` | Default `300` ms. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTooltip } from '@silverpoint/react/ui/tooltip';\n\nexport function TooltipView() {\n return (\n <SpTooltip\n text=\"Copy the order id\"\n trigger={<button type=\"button\">Copy id</button>}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpTooltip } from '@silverpoint/vue/ui/tooltip';\n</script>\n\n<template>\n <SpTooltip\n text=\"Copy the order id\"\n >\n <template #trigger><button type=\"button\">Copy id</button></template>\n </SpTooltip>\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpTooltip, SpTrigger } from '@silverpoint/angular/ui/tooltip';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-tooltip-view',\n imports: [SpTooltip, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-tooltip\n [text]=\"'Copy the order id'\"\n >\n <button type=\"button\" spTrigger>Copy id</button>\n </sp-tooltip>\n `,\n})\nexport class TooltipView {}\n```\n\n## SpSelect\n\n`select` \xB7 A select-only combobox: one option from a list. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpSelect` | `SpSelect` | `sp-select` | `sp_select` |\n| Import | `@silverpoint/react/ui/select` | `@silverpoint/vue/ui/select` | `@silverpoint/angular/ui/select` | `reflex_silverpoint_react` |\n\n**Value:** React `value + onChange`, Vue `v-model`, Angular `[(value)]`.\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onChange`, `onOpenChange`; Vue ; Angular .\n\n**States:** `placeholder`, `open-selected`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly (string \\| UiItem)[]` | | **Required.** A string is its own key and label. |\n| `placeholder` | `string` | `'Select\u2026'` | Default `'Select\u2026'`. |\n| `label` | `string` | | **Required.** Accessible name of the combobox. |\n| `disabled` | `boolean` | | Not focusable and not submitted. |\n| `required` | `boolean` | | Sets `aria-required` on the combobox. |\n| `name` | `string` | | Submits the key under this name, from a hidden input (REQ-323). |\n| `width` | `string` | `'180px'` | CSS length. Default `'180px'` (from `ui.css`). |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpSelect } from '@silverpoint/react/ui/select';\n\nexport function SelectView() {\n const [value, setValue] = useState<string | undefined>(undefined);\n return (\n <SpSelect\n label=\"Status\"\n name=\"status\"\n items={[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]}\n value={value}\n onChange={setValue}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSelect } from '@silverpoint/vue/ui/select';\n\nconst value = ref<string>();\n</script>\n\n<template>\n <SpSelect\n label=\"Status\"\n name=\"status\"\n :items=\"[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]\"\n v-model=\"value\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpSelect } from '@silverpoint/angular/ui/select';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-select-view',\n imports: [SpSelect],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-select\n [label]=\"'Status'\"\n [name]=\"'status'\"\n [items]=\"[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]\"\n [(value)]=\"value\"\n />\n `,\n})\nexport class SelectView {\n protected readonly value = signal<string | undefined>(undefined);\n}\n```\n\n## SpDropdownMenu\n\n`dropdown-menu` \xB7 A menu of actions opened from its trigger. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpDropdownMenu` | `SpDropdownMenu` | `sp-dropdown-menu` | `sp_dropdown_menu` |\n| Import | `@silverpoint/react/ui/dropdown-menu` | `@silverpoint/vue/ui/dropdown-menu` | `@silverpoint/angular/ui/dropdown-menu` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`, `onSelect`; Vue `select`; Angular `select`.\n\n**Content:** React `trigger`; Vue `trigger`; Angular `spTrigger`.\n\n**States:** `open`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `items` | `readonly MenuEntry[]` | | **Required.** Items, separators and labels, in order. Keys are unique (REQ-325). |\n| `label` | `string` | | **Required.** The menu's accessible name and the trigger's text when no trigger slot. |\n| `side` | `'top' \\| 'end' \\| 'bottom' \\| 'start'` | `'bottom'` | Default `'bottom'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | `'start'` | Default `'start'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDropdownMenu } from '@silverpoint/react/ui/dropdown-menu';\n\nexport function DropdownMenuView() {\n return (\n <SpDropdownMenu\n label=\"Actions\"\n items={[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { SpDropdownMenu } from '@silverpoint/vue/ui/dropdown-menu';\n</script>\n\n<template>\n <SpDropdownMenu\n label=\"Actions\"\n :items=\"[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpDropdownMenu } from '@silverpoint/angular/ui/dropdown-menu';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-dropdown-menu-view',\n imports: [SpDropdownMenu],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-dropdown-menu\n [label]=\"'Actions'\"\n [items]=\"[{ type: 'label', key: 'order', label: 'Order 1042' }, { key: 'edit', label: 'Edit', shortcut: 'E' }, { key: 'duplicate', label: 'Duplicate', shortcut: 'D' }, { key: 'archive', label: 'Archive', disabled: true }, { type: 'separator', key: 'end' }, { key: 'delete', label: 'Delete', danger: true }]\"\n />\n `,\n})\nexport class DropdownMenuView {}\n```\n\n## SpToast\n\n`toast` \xB7 A transient message in a `SpToaster`, with an optional action. (overlays)\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpToast` | `SpToast` | `sp-toast` | `sp_toast` |\n| Import | `@silverpoint/react/ui/toast` | `@silverpoint/vue/ui/toast` | `@silverpoint/angular/ui/toast` | `reflex_silverpoint_react` |\n\n**Open state:** React `open + onOpenChange`, Vue `v-model:open`, Angular `[(open)]`.\n\n**Events:** React `onOpenChange`; Vue ; Angular .\n\n**Content:** React `action`; Vue `action`; Angular `spAction`.\n\n**States:** `info`, `error-action`.\n\n### Props\n\nIts own props, beside the common ones (`id`, `seed`, `ground`, `substrate`, `mode`, `palette`, `size`, `className`).\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `title` | `string` | | **Required.** The toast's first line. |\n| `description` | `string` | | A line under the title. |\n| `kind` | `AlertKind` | `'info'` | Default `'info'`. |\n| `duration` | `number` | | ms, at least 1000, or `Infinity`; the toaster's when omitted. |\n| `closeLabel` | `string` | `'Dismiss'` | Default `'Dismiss'`. |\n\n### Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { useState } from 'react';\nimport { SpToast } from '@silverpoint/react/ui/toast';\n\nexport function ToastView() {\n const [open, setOpen] = useState<boolean>(true);\n return (\n <SpToast\n kind=\"info\"\n title=\"Order saved\"\n description=\"Order 1042 was updated.\"\n open={open}\n onOpenChange={setOpen}\n />\n );\n}\n```\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpToast } from '@silverpoint/vue/ui/toast';\n\nconst open = ref<boolean>(true);\n</script>\n\n<template>\n <SpToast\n kind=\"info\"\n title=\"Order saved\"\n description=\"Order 1042 was updated.\"\n v-model:open=\"open\"\n />\n</template>\n```\n\n```ts angular\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { SpToast } from '@silverpoint/angular/ui/toast';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-toast-view',\n imports: [SpToast],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-toast\n [kind]=\"'info'\"\n [title]=\"'Order saved'\"\n [description]=\"'Order 1042 was updated.'\"\n [(open)]=\"open\"\n />\n `,\n})\nexport class ToastView {\n protected readonly open = signal<boolean>(true);\n}\n```\n",
|
|
11518
|
+
"timeline": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Timeline\n\n*Describes silverpoint 0.8.0.*\n\n`SpTimeline` is a skin over TimelineJS: its slides, eras and navigation, drawn in the ground's\nframes and type. TimelineJS is an **optional peer**. Install it yourself before you import the\n`timeline` subpath, or the build cannot resolve it:\n\n```sh\nnpm install @knight-lab/timelinejs@^3.9.13\n```\n\nImport TimelineJS's stylesheet before silverpoint's:\n`@knight-lab/timelinejs/dist/css/timeline.css`, then `@silverpoint/grounds/timeline.css`.\n\n- `data` is TimelineJS's JSON: `title`, `events`, `eras`, `scale`. The component builds TimelineJS on\n a copy, so your object is never changed.\n- TimelineJS loads on the client only. If it fails to load, the `fallback` (React prop, Vue slot,\n Angular `<ng-template spFallback>`) is shown and `SP025` is warned.\n- `options` passes TimelineJS options through, except `font` and `theme`, which the ground sets.\n- `height` is a CSS length (`'600px'` by default). Anything else is dropped with `SP017`.\n- Its events are `change` (the slide's `unique_id`), `loaded`, `navNext`, `navPrevious`, `zoomIn`,\n `zoomOut` and `backToStart`: React `onChange`\u2026, Vue emits, Angular outputs.\n\n| | React | Vue | Angular | Reflex |\n|---|---|---|---|---|\n| Name | `SpTimeline` | `SpTimeline` | `sp-timeline` | `sp_timeline` |\n| Import | `@silverpoint/react/timeline` | `@silverpoint/vue/timeline` | `@silverpoint/angular/timeline` | `reflex_silverpoint_react` |\n\nOptional peer: `@knight-lab/timelinejs@^3.9.13`.\n\n| Prop | Type | Default | Notes |\n|---|---|---|---|\n| `data` | `TimelineData` | | **Required.** TimelineJS's JSON: a `title` slide, the `events`, optional `eras` and `scale`. |\n| `options` | `Readonly<Record<string, unknown>>` | | TimelineJS options; `font` and `theme` are ignored, the skin sets both. |\n| `height` | `string` | `'600px'` | A plain CSS length. Default `'600px'`. |\n| `inkedFrames` | `boolean` | `true` | Lays the ground's frames and tones on TimelineJS's pieces (REQ-512). Default `true`. |\n| `card` | `boolean` | `true` | Frames the whole timeline as a card. Default `true`. |\n| `label` | `string` | | The region's accessible name; the title's headline when omitted. |\n\n```tsx\nimport '@knight-lab/timelinejs/dist/css/timeline.css';\nimport '@silverpoint/grounds/timeline.css';\nimport { SpTimeline } from '@silverpoint/react/timeline';\n\nconst data = {\n title: { text: { headline: 'Releases' } },\n events: [\n { start_date: { year: 2026, month: 9, day: 26 }, text: { headline: '0.2.0', text: 'The dashboard.' } },\n { start_date: { year: 2026, month: 10, day: 1 }, text: { headline: '0.3.0', text: 'UI components.' } },\n ],\n};\n\nexport function Releases() {\n return <SpTimeline data={data} height=\"480px\" label=\"Release history\" fallback={<p>The timeline could not load.</p>} />;\n}\n```\n",
|
|
11519
|
+
"react": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# React\n\n*Describes silverpoint 0.8.0.*\n\n```sh\nnpm install @silverpoint/react @silverpoint/grounds @silverpoint/fonts\n```\n\nReact 18 and 19 are supported. Import the stylesheets once, in the entry file or the root layout:\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\n\nexport {};\n```\n\n## Names and imports\n\nCharts carry no prefix (`LineChart`) and components carry `Sp` (`SpModal`). Each one is imported\nfrom its own subpath: `@silverpoint/react/line-chart`, `@silverpoint/react/ui/modal`. The barrel\n`@silverpoint/react` holds the charts and `SilverpointProvider`, but a subpath keeps the bundle\nsmall.\n\n## Server Components and Next.js\n\n- `@silverpoint/react/<chart>` is a client entry (`\"use client\"`), with pointer and keyboard\n interaction. It renders on the server too and hydrates with no mismatch.\n- `@silverpoint/react/server/<chart>` renders pure SVG with no client JavaScript. On its own it needs\n `id`, `width` and `height` (`SP002`, `SP003` without them). Inside a `Dashboard`, the cell gives\n them. It takes no event handlers.\n- `@silverpoint/react/server/dashboard` is the server dashboard. It takes no `link`.\n- Display components have server entries as well (`@silverpoint/react/server/ui/card`\u2026). The\n overlays and every component with state are client-only.\n\n## Events and the handle\n\n`onActiveChange(item | null)`, `onSelect(item)` and, on the sunburst and the squarified treemap,\n`onRootChange(id | null)`. A `ref` gives `getGeometry()` and `toSVGString()`, which serialises the\nchart with its palette.\n\n## Example\n\n```tsx\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport { sanguine } from '@silverpoint/core/palettes';\nimport { LineChart } from '@silverpoint/react/line-chart';\n\nexport function LineChartView({ rows }: { rows: readonly Record<string, unknown>[] }) {\n return (\n <LineChart\n data={rows}\n xKey=\"hour\"\n valueKey=\"hits\"\n secondaryKey=\"baseline\"\n title=\"Line chart\"\n palette={sanguine}\n />\n );\n}\n```\n\nA custom readout replaces the built-in tooltip:\n\n```tsx\nimport { LineChart } from '@silverpoint/react/line-chart';\n\nexport function Hits({ rows }: { rows: readonly { hour: string; hits: number }[] }) {\n return (\n <LineChart\n title=\"Hits per hour\"\n data={rows}\n xKey=\"hour\"\n valueKey=\"hits\"\n tooltip={(active) => <span>{String(active.datum.hour)}: {active.value} hits</span>}\n />\n );\n}\n```\n",
|
|
11520
|
+
"vue": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Vue\n\n*Describes silverpoint 0.8.0.*\n\n```sh\nnpm install @silverpoint/vue @silverpoint/grounds @silverpoint/fonts\n```\n\nVue 3. Import the stylesheets once, in `main.ts`, and set the application's defaults with the\nplugin:\n\n```ts vue\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { provideSilverpoint } from '@silverpoint/vue';\nimport { createApp, h } from 'vue';\n\ncreateApp({ render: () => h('main') })\n .use(provideSilverpoint({ ground: 'silverpoint', substrate: 'cream' }))\n .mount('#app');\n```\n\n## Names and props\n\nEvery component is `Sp<Name>`: `SpLineChart`, `SpModal`. Each one is imported from its own subpath,\n`@silverpoint/vue/line-chart` or `@silverpoint/vue/ui/modal`. Props are the same camelCase names as\nin React. In a template, write them in kebab-case (`x-key`, `value-key`) and bind non-strings with\n`:` (`:data=\"rows\"`, `:height=\"240\"`).\n\n- Values: `v-model`. Open state: `v-model:open`. Pagination: `v-model:current`.\n- Events: `@active-change`, `@select`, `@root-change`, `@sort`, `@toggle`.\n- Content: slots `trigger`, `footer`, `extra`, `prefix`, `suffix`, `action`, `fallback`, `tooltip`.\n- A section of the page: `<SilverpointProvider :palette=\"sepia\">`. It renders no element of its\n own.\n- Server rendering works with `@vue/server-renderer`. Nuxt is not a validated integration.\n\n## Example\n\n```vue\n<script setup lang=\"ts\">\nimport '@silverpoint/fonts/fonts.css';\nimport '@silverpoint/grounds/styles.css';\nimport '@silverpoint/grounds/ui.css';\nimport { ref } from 'vue';\nimport { SpSelect } from '@silverpoint/vue/ui/select';\n\nconst value = ref<string>();\n</script>\n\n<template>\n <SpSelect\n label=\"Status\"\n name=\"status\"\n :items=\"[{ key: 'placed', label: 'Placed' }, { key: 'paid', label: 'Paid' }, { key: 'packed', label: 'Packed' }, { key: 'shipped', label: 'Shipped' }, { key: 'returned', label: 'Returned', disabled: true }]\"\n v-model=\"value\"\n />\n</template>\n```\n",
|
|
11521
|
+
"angular": "<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Angular\n\n*Describes silverpoint 0.8.0.*\n\n```sh\nnpm install @silverpoint/angular @silverpoint/grounds @silverpoint/fonts\n```\n\nAdd the stylesheets to the `styles` array of `angular.json`, in this order:\n`@silverpoint/fonts/fonts.css`, `@silverpoint/grounds/styles.css`, and\n`@silverpoint/grounds/ui.css` if you use components.\n\n```ts angular\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { Component } from '@angular/core';\nimport { provideSilverpoint } from '@silverpoint/angular';\n\n@Component({ selector: 'app-root', template: '' })\nclass App {}\n\nbootstrapApplication(App, { providers: [provideSilverpoint({ ground: 'silverpoint', substrate: 'cream' })] }).catch(console.error);\n```\n\n## Components\n\nEvery chart and component is a standalone component with signal inputs and `OnPush`, imported from\nits own secondary entry point: `@silverpoint/angular/line-chart`, `@silverpoint/angular/ui/modal`.\nSelectors are `sp-<name>`. The exceptions are `SpButton` (`<button spButton>`) and `SpSurface`\n(`[spSurface]`), which sit on your own element.\n\n- **Bind every input**, strings included: `[title]=\"'Traffic'\"`. `strictTemplates` checks\n bindings, while a static attribute with a misspelt name passes silently.\n- Values: `[(value)]`, or a forms directive (`formControlName`, `ngModel`): the value components\n are `ControlValueAccessor`s. Open state: `[(open)]`. Pagination: `[(current)]`.\n- Events are outputs: `(activeChange)`, `(select)`, `(rootChange)`, `(openChange)`, `(sort)`.\n- Content is projected through templates: `<ng-template spFooter>`, `spExtra`, `spAction`,\n `spFallback`, `spTooltip`. An overlay's trigger is `<button type=\"button\" spTrigger>`, with\n `SpTrigger` imported from the overlay's subpath.\n- `provideSilverpoint` returns a `Provider`, so a component's own `providers` can nest one for its\n subtree.\n- Server rendering with `@angular/ssr` is supported.\n\n## Example\n\n```ts angular\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { SpModal, SpTrigger } from '@silverpoint/angular/ui/modal';\n\n/** Add '@silverpoint/fonts/fonts.css', '@silverpoint/grounds/styles.css', '@silverpoint/grounds/ui.css' to the `styles` of angular.json. */\n@Component({\n selector: 'app-modal-view',\n imports: [SpModal, SpTrigger],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <sp-modal\n [title]=\"'Edit order'\"\n [description]=\"'Order 1042, placed on 14 October.'\"\n >\n <button type=\"button\" spTrigger>Edit order</button>\n Changes reach the workshop before the order is packed.\n </sp-modal>\n `,\n})\nexport class ModalView {}\n```\n",
|
|
11522
|
+
"reflex": '<!-- Generated by tools/agent-catalog from skills/silverpoint/templates and the agent catalog. Do not edit: run `pnpm --filter @silverpoint/agent-catalog generate`. -->\n# Reflex\n\n*Describes silverpoint 0.8.0.*\n\n`reflex-silverpoint-react` 0.7.1 wraps the React components for Reflex, so the same\ncharts and components are Python builders. For anything beyond names and a first example, use the\n`reflex-silverpoint` skill, which covers state, events and the demo app\'s patterns.\n\n```sh\npip install reflex-silverpoint-react\n```\n\n- Builders are snake_case: `line_chart`, `sankey_chart`, `sp_modal`, `sp_select`. Props are\n snake_case too (`x_key`, `value_key`), with the same meaning as in React.\n- Data comes from a `rx.State` field, as a list of dicts.\n- `palette` takes a preset\'s name (`"sanguine"`).\n- An overlay\'s `trigger` is the trigger\'s text.\n\n```python\nimport reflex as rx\nfrom reflex_silverpoint_react import line_chart\n\n\nclass State(rx.State):\n rows: list[dict] = []\n\n\ndef line_chart_view() -> rx.Component:\n return line_chart(\n data=State.rows,\n x_key="hour",\n value_key="hits",\n secondary_key="baseline",\n title="Line chart",\n )\n```\n\n```python\nimport reflex as rx\nfrom reflex_silverpoint_react import sp_modal\n\n\ndef modal_view() -> rx.Component:\n return sp_modal(\n "Changes reach the workshop before the order is packed.",\n title="Edit order",\n description="Order 1042, placed on 14 October.",\n trigger="Edit order",\n )\n```\n\n## Builders\n\n| Slug | Builder | Kind |\n|---|---|---|\n| `line-chart` | `line_chart` | chart |\n| `bullet-chart` | `bullet_chart` | chart |\n| `pyramid-chart` | `pyramid_chart` | chart |\n| `heatmap-chart` | `heatmap_chart` | chart |\n| `treemap-chart` | `treemap_chart` | chart |\n| `sankey-chart` | `sankey_chart` | chart |\n| `activity-grid` | `activity_grid` | chart |\n| `step-chart` | `step_chart` | chart |\n| `sparkline-rows` | `sparkline_rows` | chart |\n| `kpi-card` | `kpi_card` | chart |\n| `bar-chart` | `bar_chart` | chart |\n| `stacked-bar-chart` | `stacked_bar_chart` | chart |\n| `composed-chart` | `composed_chart` | chart |\n| `waterfall-chart` | `waterfall_chart` | chart |\n| `funnel-chart` | `funnel_chart` | chart |\n| `candlestick-chart` | `candlestick_chart` | chart |\n| `area-chart` | `area_chart` | chart |\n| `range-band-chart` | `range_band_chart` | chart |\n| `stream-chart` | `stream_chart` | chart |\n| `scatter-chart` | `scatter_chart` | chart |\n| `bubble-chart` | `bubble_chart` | chart |\n| `donut-chart` | `donut_chart` | chart |\n| `radar-chart` | `radar_chart` | chart |\n| `polar-bar-chart` | `polar_bar_chart` | chart |\n| `radial-arc-group` | `radial_arc_group` | chart |\n| `radial-rings` | `radial_rings` | chart |\n| `gauge-arc` | `gauge_arc` | chart |\n| `meter-chart` | `meter_chart` | chart |\n| `coxcomb-chart` | `coxcomb_chart` | chart |\n| `wind-rose` | `wind_rose` | chart |\n| `volvelle-chart` | `volvelle_chart` | chart |\n| `chord-ring` | `chord_ring` | chart |\n| `orbit-chart` | `orbit_chart` | chart |\n| `histogram-chart` | `histogram_chart` | chart |\n| `ecdf-chart` | `ecdf_chart` | chart |\n| `box-plot-chart` | `box_plot_chart` | chart |\n| `violin-chart` | `violin_chart` | chart |\n| `ridgeline-chart` | `ridgeline_chart` | chart |\n| `beeswarm-chart` | `beeswarm_chart` | chart |\n| `lollipop-chart` | `lollipop_chart` | chart |\n| `dumbbell-chart` | `dumbbell_chart` | chart |\n| `slope-chart` | `slope_chart` | chart |\n| `bump-chart` | `bump_chart` | chart |\n| `error-bar-chart` | `error_bar_chart` | chart |\n| `interval-chart` | `interval_chart` | chart |\n| `diverging-bar-chart` | `diverging_bar_chart` | chart |\n| `connected-scatter-chart` | `connected_scatter_chart` | chart |\n| `waffle-chart` | `waffle_chart` | chart |\n| `marimekko-chart` | `marimekko_chart` | chart |\n| `squarified-treemap` | `squarified_treemap` | chart |\n| `sunburst-chart` | `sunburst_chart` | chart |\n| `tree-chart` | `tree_chart` | chart |\n| `parallel-coordinates-chart` | `parallel_coordinates_chart` | chart |\n| `polar-line-chart` | `polar_line_chart` | chart |\n| `polar-scatter-chart` | `polar_scatter_chart` | chart |\n| `density-bin-chart` | `density_bin_chart` | chart |\n| `contour-chart` | `contour_chart` | chart |\n| `delaunay-chart` | `delaunay_chart` | chart |\n| `vector-field-chart` | `vector_field_chart` | chart |\n| `network-chart` | `network_chart` | chart |\n| `button` | `sp_button` | ui |\n| `input` | `sp_input` | ui |\n| `checkbox` | `sp_checkbox` | ui |\n| `radio-group` | `sp_radio_group` | ui |\n| `switch` | `sp_switch` | ui |\n| `slider` | `sp_slider` | ui |\n| `rate` | `sp_rate` | ui |\n| `segmented` | `sp_segmented` | ui |\n| `tabs` | `sp_tabs` | ui |\n| `steps` | `sp_steps` | ui |\n| `card` | `sp_card` | ui |\n| `tag` | `sp_tag` | ui |\n| `badge` | `sp_badge` | ui |\n| `divider` | `sp_divider` | ui |\n| `progress` | `sp_progress` | ui |\n| `alert` | `sp_alert` | ui |\n| `skeleton` | `sp_skeleton` | ui |\n| `surface` | `sp_surface` | composed |\n| `glyph` | `sp_glyph` | composed |\n| `table` | `sp_table` | composed |\n| `pagination` | `sp_pagination` | composed |\n| `breadcrumb` | `sp_breadcrumb` | composed |\n| `avatar` | `sp_avatar` | composed |\n| `statistic` | `sp_statistic` | composed |\n| `descriptions` | `sp_descriptions` | composed |\n| `timeline-list` | `sp_timeline_list` | composed |\n| `collapse` | `sp_collapse` | composed |\n| `empty` | `sp_empty` | composed |\n| `result` | `sp_result` | composed |\n| `textarea` | `sp_textarea` | composed |\n| `input-number` | `sp_input_number` | composed |\n| `modal` | `sp_modal` | overlay |\n| `drawer` | `sp_drawer` | overlay |\n| `popover` | `sp_popover` | overlay |\n| `tooltip` | `sp_tooltip` | overlay |\n| `select` | `sp_select` | overlay |\n| `dropdown-menu` | `sp_dropdown_menu` | overlay |\n| `toast` | `sp_toast` | overlay |\n'
|
|
11425
11523
|
};
|
|
11426
11524
|
|
|
11427
11525
|
// src/tools/entries.ts
|