canonrs-core 0.1.0

CanonRS core types, traits and primitives
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
[
  {
    "id": "accordion",
    "label": "Accordion",
    "category": "Navigation",
    "description": "Expandable accordion sections",
    "keywords": "",
    "pain": "Accordion allows invalid multi-open logic without enforced selection mode",
    "promise": "Selection mode enforced via type, preventing invalid open states",
    "why": "AccordionSelection defines whether single or multiple items can be open. The primitive encodes state and behavior in data-rs attributes, ensuring consistent disclosure logic. VisibilityState guarantees SSR-safe open/closed state without runtime drift.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"accordion\">\n    <button on:click=move |_| toggle(1)>\"Item 1\"</button>\n    {if open == 1 { view! { <div>\"Content\"</div> } } else { view! {} }}\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Accordion selection=AccordionSelection::Single>\n    <AccordionItem>\n      <AccordionTrigger>\"Item 1\"</AccordionTrigger>\n      <AccordionContent>\"Content\"</AccordionContent>\n    </AccordionItem>\n  </Accordion>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "faq sections",
      "settings panels"
    ],
    "related": [
      "collapsible"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "accordion",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Accordion Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{VisibilityState, DisabledState};\nuse crate::infra::uid::generate;\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Default, Debug)]\npub enum AccordionSelection {\n    #[default]\n    Single,\n    Multiple,\n}\nimpl AccordionSelection {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Single => \"single\", Self::Multiple => \"multiple\" }\n    }\n}\n\n#[component]\npub fn AccordionPrimitive(\n    children: Children,\n    #[prop(default = AccordionSelection::Single)] selection: AccordionSelection,\n    #[prop(into, default = \"true\".to_string())] collapsible: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid = generate(\"ac\");\n    view! {\n        <div\n            data-rs-accordion=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"nav\"\n            data-rs-selection=selection.as_str()\n            data-rs-collapsible=collapsible\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn AccordionItemPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = generate(\"ac-item\");\n    view! {\n        <div\n            data-rs-accordion-item=\"\"\n            data-rs-uid=uid\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            role=\"group\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn AccordionTriggerPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h3 data-rs-accordion-heading=\"\">\n            <button\n                type=\"button\"\n                data-rs-accordion-trigger=\"\"\n                data-rs-uid=generate(\"ac-trigger\")\n                data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n                aria-expanded=state.aria_expanded()\n                aria-disabled=disabled.aria_disabled()\n                class=class\n            >\n                {children()}\n                <svg data-rs-accordion-icon=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n                    <path d=\"m6 9 6 6 6-6\"/>\n                </svg>\n            </button>\n        </h3>\n    }\n}\n\n#[component]\npub fn AccordionContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = generate(\"ac-content\");\n    view! {\n        <div\n            data-rs-accordion-content=\"\"\n            data-rs-uid=uid\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::meta::{VisibilityState, DisabledState};\nuse canonrs_core::primitives::{\n    AccordionPrimitive, AccordionItemPrimitive,\n    AccordionTriggerPrimitive, AccordionContentPrimitive,\n    AccordionSelection,\n};\n\n#[component]\npub fn Accordion(\n    children: Children,\n    #[prop(default = AccordionSelection::Single)] selection: AccordionSelection,\n    #[prop(into, default = \"true\".to_string())] collapsible: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AccordionPrimitive selection=selection collapsible=collapsible class=class node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </AccordionPrimitive>\n    }\n}\n\n#[component]\npub fn AccordionItem(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AccordionItemPrimitive state=state disabled=disabled class=class>\n            {children()}\n        </AccordionItemPrimitive>\n    }\n}\n\n#[component]\npub fn AccordionTrigger(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AccordionTriggerPrimitive disabled=disabled class=class>\n            {children()}\n        </AccordionTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn AccordionContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AccordionContentPrimitive class=class>\n            {children()}\n        </AccordionContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Accordion Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v4.0.0: interaction delegated to canonrs-interactions-nav\n\nuse leptos::prelude::*;\nuse super::accordion_ui::{\n    Accordion as AccordionUi,\n    AccordionItem as AccordionItemUi,\n    AccordionTrigger as AccordionTriggerUi,\n    AccordionContent as AccordionContentUi\n};\npub use canonrs_core::meta::{VisibilityState, DisabledState};\npub use canonrs_core::primitives::AccordionSelection;\n\n#[component]\npub fn Accordion(\n    children: Children,\n    #[prop(default = AccordionSelection::Single)] selection: AccordionSelection,\n    #[prop(into, default = \"true\".to_string())] collapsible: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AccordionUi selection=selection collapsible=collapsible class=class>{children()}</AccordionUi> }\n}\n\n#[component]\npub fn AccordionItem(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AccordionItemUi state=state disabled=disabled class=class>{children()}</AccordionItemUi> }\n}\n\n#[component]\npub fn AccordionTrigger(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AccordionTriggerUi disabled=disabled class=class>{children()}</AccordionTriggerUi> }\n}\n\n#[component]\npub fn AccordionContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AccordionContentUi class=class>{children()}</AccordionContentUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{AccordionSelection}; \n\npub const ACCORDION_API: ComponentApi = ComponentApi {\n    id: \"accordion\",\n    description: \"Expandable accordion sections\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selection\", kind: PropType::Enum(&[\"single\", \"multiple\"]), required: false, default: Some(\"single\"), description: \"Prop value\" },\n        PropDef { name: \"collapsible\", kind: PropType::String, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ACCORDIONITEM_API: ComponentApi = ComponentApi {\n    id: \"accordion-item\",\n    description: \"Expandable accordion sections\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"closed\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ACCORDIONTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"accordion-trigger\",\n    description: \"Expandable accordion sections\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ACCORDIONCONTENT_API: ComponentApi = ComponentApi {\n    id: \"accordion-content\",\n    description: \"Expandable accordion sections\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::accordion_boundary::{Accordion, AccordionItem, AccordionTrigger, AccordionContent, AccordionSelection, DisabledState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn AccordionShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Accordion>\n                <AccordionItem>\n                    <AccordionTrigger>\"What is CanonRS?\"</AccordionTrigger>\n                    <AccordionContent>\"CanonRS is a design system built in Rust and Leptos with a 3-layer architecture.\"</AccordionContent>\n                </AccordionItem>\n                <AccordionItem>\n                    <AccordionTrigger>\"How does it work?\"</AccordionTrigger>\n                    <AccordionContent>\"Primitives define structure. Behaviors add interactivity. UI components compose both.\"</AccordionContent>\n                </AccordionItem>\n                <AccordionItem>\n                    <AccordionTrigger>\"Is SSR supported?\"</AccordionTrigger>\n                    <AccordionContent>\"Yes. All state is defined at the primitive level via data-rs-state.\"</AccordionContent>\n                </AccordionItem>\n            </Accordion>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Open/close state governed by DOM — single or multiple selection.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Multiple selection\"</span>\n                <Accordion selection=AccordionSelection::Multiple>\n                    <AccordionItem>\n                        <AccordionTrigger>\"Section A\"</AccordionTrigger>\n                        <AccordionContent>\"Content for section A.\"</AccordionContent>\n                    </AccordionItem>\n                    <AccordionItem>\n                        <AccordionTrigger>\"Section B\"</AccordionTrigger>\n                        <AccordionContent>\"Content for section B.\"</AccordionContent>\n                    </AccordionItem>\n                </Accordion>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Non-collapsible\"</span>\n                <Accordion collapsible=\"false\".to_string()>\n                    <AccordionItem>\n                        <AccordionTrigger>\"Always one open\"</AccordionTrigger>\n                        <AccordionContent>\"This accordion always keeps one item open.\"</AccordionContent>\n                    </AccordionItem>\n                    <AccordionItem>\n                        <AccordionTrigger>\"Second item\"</AccordionTrigger>\n                        <AccordionContent>\"Click to switch — cannot close all.\"</AccordionContent>\n                    </AccordionItem>\n                </Accordion>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled item\"</span>\n                <Accordion>\n                    <AccordionItem>\n                        <AccordionTrigger>\"Active item\"</AccordionTrigger>\n                        <AccordionContent>\"This item is interactive.\"</AccordionContent>\n                    </AccordionItem>\n                    <AccordionItem disabled=DisabledState::Disabled>\n                        <AccordionTrigger disabled=DisabledState::Disabled>\"Disabled item\"</AccordionTrigger>\n                        <AccordionContent>\"This content is not reachable.\"</AccordionContent>\n                    </AccordionItem>\n                </Accordion>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "alert",
    "label": "Alert",
    "category": "Feedback",
    "description": "Alert message box",
    "keywords": "",
    "pain": "Alerts use wrong ARIA roles causing accessibility issues silently",
    "promise": "Semantic state drives ARIA role and live region — variant is visual only",
    "why": "Semantic state (error/warning/success) is derived from variant at the primitive level and drives role and aria-live. Visual styling via data-rs-variant is separate from semantic contract. Accessibility is guaranteed at compile-time.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"alert alert-error\">\"Error occurred\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Alert variant=AlertVariant::Destructive>\n    <AlertTitle>\"Error\"</AlertTitle>\n    <AlertDescription>\"Error occurred\"</AlertDescription>\n  </Alert>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "error messages",
      "status notifications"
    ],
    "related": [
      "toast",
      "banner",
      "callout",
      "inline_notice",
      "status_dot"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Alert Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Default, Debug)]\npub enum AlertVariant {\n    #[default]\n    Default, Destructive, Warning, Success,\n}\nimpl AlertVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default     => \"default\",\n            Self::Destructive => \"destructive\",\n            Self::Warning     => \"warning\",\n            Self::Success     => \"success\",\n        }\n    }\n    pub fn role(&self) -> &'static str {\n        match self {\n            Self::Destructive | Self::Warning => \"alert\",\n            _                                 => \"status\",\n        }\n    }\n    pub fn aria_live(&self) -> &'static str {\n        match self {\n            Self::Destructive | Self::Warning => \"assertive\",\n            _                                 => \"polite\",\n        }\n    }\n}\n\n#[component]\npub fn AlertPrimitive(\n    children: Children,\n    #[prop(default = AlertVariant::Default)] variant: AlertVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"al\");\n    view! {\n        <div\n            data-rs-alert=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            role=variant.role()\n            aria-live=variant.aria_live()\n            aria-atomic=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn AlertTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h5 data-rs-alert-title=\"\" class=class>\n            {children()}\n        </h5>\n    }\n}\n\n#[component]\npub fn AlertDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-alert-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn AlertCloseButtonPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-alert-close=\"\"\n            aria-label=\"Close alert\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    AlertPrimitive, AlertTitlePrimitive, AlertDescriptionPrimitive,\n    AlertCloseButtonPrimitive, AlertVariant,\n};\n\n#[component]\npub fn Alert(\n    children: Children,\n    #[prop(default = AlertVariant::Default)] variant: AlertVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertPrimitive variant=variant class=class>\n            {children()}\n        </AlertPrimitive>\n    }\n}\n\n#[component]\npub fn AlertTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertTitlePrimitive class=class>\n            {children()}\n        </AlertTitlePrimitive>\n    }\n}\n\n#[component]\npub fn AlertDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDescriptionPrimitive class=class>\n            {children()}\n        </AlertDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn AlertCloseButton(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertCloseButtonPrimitive class=class>\n            {children()}\n        </AlertCloseButtonPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Alert Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::alert_ui::{\n    Alert as AlertUi,\n    AlertTitle,\n    AlertDescription,\n    AlertCloseButton\n};\npub use canonrs_core::primitives::AlertVariant;\n\n#[component]\npub fn Alert(\n    #[prop(into, optional)] title: Option<String>,\n    #[prop(into, optional)] description: Option<String>,\n    #[prop(default = AlertVariant::Default)] variant: AlertVariant,\n    #[prop(default = false)] dismissible: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertUi variant=variant class=class>\n            {title.map(|t| view! { <AlertTitle>{t}</AlertTitle> })}\n            {description.map(|d| view! { <AlertDescription>{d}</AlertDescription> })}\n            {dismissible.then(|| view! { <AlertCloseButton>\"×\"</AlertCloseButton> })}\n        </AlertUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{AlertVariant}; \n\npub const ALERT_API: ComponentApi = ComponentApi {\n    id: \"alert\",\n    description: \"Alert message box\",\n    props: &[\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"warning\", \"success\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"dismissible\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::alert_boundary::{Alert, AlertVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn AlertShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Alert title=\"Info\" description=\"This is a default informational alert.\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Semantic state (error/warning/success) drives ARIA role and live region. Visual variant is separate from semantic contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Alert variant=AlertVariant::Success     title=\"Success\"     description=\"Your changes have been saved.\" />\n                <Alert variant=AlertVariant::Warning     title=\"Warning\"     description=\"Session expires in 5 minutes.\" />\n                <Alert variant=AlertVariant::Destructive title=\"Error\"       description=\"Failed to save changes.\" />\n                <Alert variant=AlertVariant::Default     title=\"Info\"        description=\"A new version is available.\" />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Dismissible\"</span>\n                <Alert title=\"Update available\" description=\"New version ready.\" dismissible=true />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "alert_dialog",
    "label": "Alert Dialog",
    "category": "Overlay",
    "description": "Alert dialog for critical confirmations",
    "keywords": "",
    "pain": "Destructive dialogs lack proper role and accessibility enforcement",
    "promise": "Alertdialog role and accessibility guaranteed by component contract",
    "why": "AlertDialog reuses Dialog but enforces role=\"alertdialog\" and assertive aria-live. The specialized content primitive ensures critical actions are announced correctly. This prevents misuse of generic dialogs for destructive flows.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"modal\">\n    <p>\"Delete account?\"</p>\n    <button>\"Confirm\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <AlertDialog>\n    <AlertDialogTrigger>\"Delete\"</AlertDialogTrigger>\n    <AlertDialogPortal>\n      <AlertDialogContent>\n        <AlertDialogTitle>\"Confirm\"</AlertDialogTitle>\n        <AlertDialogDescription>\"This cannot be undone\"</AlertDialogDescription>\n      </AlertDialogContent>\n    </AlertDialogPortal>\n  </AlertDialog>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "delete confirmation",
      "critical actions"
    ],
    "related": [
      "dialog",
      "drawer",
      "sheet",
      "modal",
      "confirm_dialog",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! AlertDialog Primitive - Reusa Dialog com role=alertdialog\n\npub use super::dialog::{\n    DialogPrimitive as AlertDialogPrimitive,\n    DialogTriggerPrimitive as AlertDialogTriggerPrimitive,\n    DialogPortalPrimitive as AlertDialogPortalPrimitive,\n    DialogOverlayPrimitive as AlertDialogOverlayPrimitive,\n    DialogTitlePrimitive as AlertDialogTitlePrimitive,\n    DialogDescriptionPrimitive as AlertDialogDescriptionPrimitive,\n    DialogClosePrimitive as AlertDialogClosePrimitive,\n};\n\nuse leptos::prelude::*;\n\n#[component]\npub fn AlertDialogContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] aria_labelledby: String,\n    #[prop(optional, into)] aria_describedby: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ad = crate::infra::uid::generate(\"ad\");\n    view! {\n        <div\n            data-rs-dialog-content=\"\"\n            data-rs-uid=uid_ad\n            data-rs-interaction=\"overlay\"\n            role=\"alertdialog\"\n            aria-modal=\"true\"\n            aria-live=\"assertive\"\n            aria-labelledby=aria_labelledby\n            aria-describedby=aria_describedby\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    AlertDialogPrimitive,\n    AlertDialogPortalPrimitive,\n    AlertDialogOverlayPrimitive,\n    AlertDialogContentPrimitive,\n    AlertDialogTitlePrimitive,\n    AlertDialogDescriptionPrimitive,\n};\nuse crate::ui::button::{Button, ButtonVariant};\n\n#[component]\npub fn AlertDialog(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogPrimitive class=class>\n            {children()}\n        </AlertDialogPrimitive>\n    }\n}\n\n#[component]\npub fn AlertDialogTrigger(\n    children: Children,\n    #[prop(default = ButtonVariant::Primary)] variant: ButtonVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <Button\n            variant=variant\n            class=class\n            attr:data-rs-dialog-trigger=\"\"\n            attr:aria-haspopup=\"dialog\"\n            attr:aria-expanded=\"false\"\n        >\n            {children()}\n        </Button>\n    }\n}\n\n#[component]\npub fn AlertDialogPortal(\n    children: ChildrenFn,\n) -> impl IntoView {\n    view! {\n        <AlertDialogPortalPrimitive>\n            {children()}\n        </AlertDialogPortalPrimitive>\n    }\n}\n\n#[component]\npub fn AlertDialogOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogOverlayPrimitive class=class />\n    }\n}\n\n#[component]\npub fn AlertDialogContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogContentPrimitive class=class aria_labelledby=\"alert-title\">\n            {children()}\n        </AlertDialogContentPrimitive>\n    }\n}\n\n#[component]\npub fn AlertDialogTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogTitlePrimitive class=class>\n            {children()}\n        </AlertDialogTitlePrimitive>\n    }\n}\n\n#[component]\npub fn AlertDialogDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogDescriptionPrimitive class=class>\n            {children()}\n        </AlertDialogDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn AlertDialogClose(\n    children: Children,\n    #[prop(default = ButtonVariant::Outline)] variant: ButtonVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <Button\n            variant=variant\n            class=class\n            attr:data-rs-dialog-close=\"\"\n        >\n            {children()}\n        </Button>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! AlertDialog Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v3.0.0: interaction delegated to canonrs-interactions-overlay\n\nuse leptos::prelude::*;\nuse super::alert_dialog_ui::{\n    AlertDialog as AlertDialogUi,\n    AlertDialogTrigger,\n    AlertDialogOverlay,\n    AlertDialogContent,\n    AlertDialogTitle,\n    AlertDialogDescription,\n    AlertDialogClose\n};\nuse crate::ui::button::ButtonVariant;\n\n#[component]\npub fn AlertDialog(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::from(\"Delete\"))] trigger_label: String,\n    #[prop(into, default = String::from(\"Confirm\"))] confirm_label: String,\n    #[prop(into, default = String::from(\"Cancel\"))] cancel_label: String,\n    #[prop(into, optional)] title: Option<String>,\n    #[prop(into, optional)] description: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AlertDialogUi class=class>\n            <AlertDialogTrigger variant=ButtonVariant::Destructive>\n                {trigger_label\n};\n            </AlertDialogTrigger>\n            <AlertDialogOverlay />\n            <AlertDialogContent>\n                {title.map(|t| view! { <AlertDialogTitle>{t}</AlertDialogTitle> })}\n                {description.map(|d| view! { <AlertDialogDescription>{d}</AlertDialogDescription> })}\n                {children.map(|c| c())}\n                <div data-rs-alert-dialog-actions=\"\">\n                    <AlertDialogClose variant=ButtonVariant::Outline>\n                        {cancel_label}\n                    </AlertDialogClose>\n                    <AlertDialogClose variant=ButtonVariant::Destructive>\n                        {confirm_label}\n                    </AlertDialogClose>\n                </div>\n            </AlertDialogContent>\n        </AlertDialogUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const ALERTDIALOG_API: ComponentApi = ComponentApi {\n    id: \"alert-dialog\",\n    description: \"Alert dialog for critical confirmations\",\n    props: &[\n        PropDef { name: \"trigger_label\", kind: PropType::String, required: false, default: Some(\"Delete\"), description: \"Prop value\" },\n        PropDef { name: \"confirm_label\", kind: PropType::String, required: false, default: Some(\"Confirm\"), description: \"Prop value\" },\n        PropDef { name: \"cancel_label\", kind: PropType::String, required: false, default: Some(\"Cancel\"), description: \"Prop value\" },\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::alert_dialog_boundary::AlertDialog;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn AlertDialogShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <AlertDialog\n                trigger_label=\"Delete Account\"\n                title=\"Are you absolutely sure?\"\n                description=\"This action cannot be undone. This will permanently delete your account.\"\n                confirm_label=\"Delete\"\n                cancel_label=\"Cancel\"\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Alert dialog enforces destructive action confirmation via ARIA alertdialog.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Custom trigger\"</span>\n                <AlertDialog\n                    trigger_label=\"Remove item\"\n                    title=\"Remove this item?\"\n                    description=\"This item will be permanently removed from your list.\"\n                    confirm_label=\"Remove\"\n                    cancel_label=\"Keep it\"\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "animate",
    "label": "Animate",
    "category": "Display",
    "description": "Animation wrapper component",
    "keywords": "",
    "pain": "Animations rely on fragile class names and inconsistent timing values",
    "promise": "Animation type and easing enforced through typed enums",
    "why": "AnimationName and AnimationEasing define allowed motion patterns. The primitive encodes animation parameters into data-rs attributes, avoiding class-based drift. This ensures consistent animation behavior across SSR and client.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"fade-in ease-in-out duration-300\">\"Content\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Animate animation=AnimationName::FadeIn duration=\"300ms\">\n    \"Content\"\n  </Animate>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "page transitions",
      "modal animations"
    ],
    "related": [
      "empty_state",
      "error_state"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback_state",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Animate Primitive - HTML puro + data-attributes de animacao\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum AnimationName {\n    #[default]\n    None,\n    FadeIn,\n    FadeOut,\n    SlideIn,\n    SlideOut,\n    ScaleIn,\n    ScaleOut,\n}\nimpl AnimationName {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::None     => \"none\",\n            Self::FadeIn   => \"fade-in\",\n            Self::FadeOut  => \"fade-out\",\n            Self::SlideIn  => \"slide-in\",\n            Self::SlideOut => \"slide-out\",\n            Self::ScaleIn  => \"scale-in\",\n            Self::ScaleOut => \"scale-out\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum AnimationEasing {\n    #[default]\n    EaseInOut,\n    EaseIn,\n    EaseOut,\n    Linear,\n}\nimpl AnimationEasing {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::EaseInOut => \"ease-in-out\",\n            Self::EaseIn    => \"ease-in\",\n            Self::EaseOut   => \"ease-out\",\n            Self::Linear    => \"linear\",\n        }\n    }\n}\n\n#[component]\npub fn AnimatePrimitive(\n    children: Children,\n    #[prop(default = AnimationName::None)] animation: AnimationName,\n    #[prop(default = AnimationEasing::EaseInOut)] easing: AnimationEasing,\n    #[prop(into, default = String::new())] duration: String,\n    #[prop(into, default = String::new())] delay: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_an = crate::infra::uid::generate(\"an\");\n    view! {\n        <div\n            data-rs-animate=\"\"\n            data-rs-uid=uid_an\n            data-rs-interaction=\"init\"\n            data-rs-animation=animation.as_str()\n            data-rs-easing=easing.as_str()\n            data-rs-duration=duration\n            data-rs-delay=delay\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::AnimatePrimitive;\npub use canonrs_core::primitives::{AnimationName, AnimationEasing};\n\n#[component]\npub fn Animate(\n    children: Children,\n    #[prop(default = AnimationName::FadeIn)] animation: AnimationName,\n    #[prop(default = AnimationEasing::EaseInOut)] easing: AnimationEasing,\n    #[prop(into, default = String::new())] duration: String,\n    #[prop(into, default = String::new())] delay: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AnimatePrimitive\n            animation=animation\n            easing=easing\n            duration=duration\n            delay=delay\n            class=class\n        >\n            {children()}\n        </AnimatePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Animate Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::animate_ui::{\n    Animate as AnimateUi,\n    AnimationName,\n    AnimationEasing\n};\n\n#[component]\npub fn Animate(\n    children: Children,\n    #[prop(into, default = String::from(\"fade-in\"))] animation: String,\n    #[prop(into, default = String::from(\"ease-in-out\"))] easing: String,\n    #[prop(into, default = String::from(\"300ms\"))] duration: String,\n    #[prop(into, default = String::new())] delay: String,\n    #[prop(optional)] stagger: Option<f64>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let animation_val = match animation.as_str() {\n        \"fade-out\"  => AnimationName::FadeOut,\n        \"slide-in\"  => AnimationName::SlideIn,\n        \"slide-out\" => AnimationName::SlideOut,\n        \"scale-in\"  => AnimationName::ScaleIn,\n        \"scale-out\" => AnimationName::ScaleOut,\n        _           => AnimationName::FadeIn,\n    };\n    let easing_val = match easing.as_str() {\n        \"ease-in\"  => AnimationEasing::EaseIn,\n        \"ease-out\" => AnimationEasing::EaseOut,\n        \"linear\"   => AnimationEasing::Linear,\n        _          => AnimationEasing::EaseInOut,\n    };\n    let _ = stagger; // handled by init module\n    view! {\n        <AnimateUi animation=animation_val easing=easing_val duration=duration delay=delay class=class>\n            {children()}\n        </AnimateUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const ANIMATE_API: ComponentApi = ComponentApi {\n    id: \"animate\",\n    description: \"Animation wrapper component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"animation\", kind: PropType::String, required: false, default: Some(\"fade-in\"), description: \"Prop value\" },\n        PropDef { name: \"easing\", kind: PropType::String, required: false, default: Some(\"ease-in-out\"), description: \"Prop value\" },\n        PropDef { name: \"duration\", kind: PropType::String, required: false, default: Some(\"300ms\"), description: \"Prop value\" },\n        PropDef { name: \"delay\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"stagger\", kind: PropType::Number, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::animate_boundary::Animate;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\n\n#[component]\npub fn AnimateShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg attr:data-rs-showcase-preview-hero=\"\">\n            <Animate animation=\"fade-in\" duration=\"1.2s\">\n                <div data-rs-animate-demo=\"\">\"Fade In\"</div>\n            </Animate>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Animation type and easing enforced through typed enums. Respects prefers-reduced-motion.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Animation variants\"</span>\n                <Grid cols=GridCols::Three>\n                    <Animate animation=\"fade-in\"   duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"FadeIn\"</div></Animate>\n                    <Animate animation=\"fade-out\"  duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"FadeOut\"</div></Animate>\n                    <Animate animation=\"slide-in\"  duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"SlideIn\"</div></Animate>\n                    <Animate animation=\"slide-out\" duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"SlideOut\"</div></Animate>\n                    <Animate animation=\"scale-in\"  duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"ScaleIn\"</div></Animate>\n                    <Animate animation=\"scale-out\" duration=\"1.4s\"><div data-rs-animate-demo=\"\">\"ScaleOut\"</div></Animate>\n                </Grid>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Easing\"</span>\n                <Grid cols=GridCols::Four>\n                    <Animate animation=\"slide-in\" easing=\"ease-in\"     duration=\"1.6s\"><div data-rs-animate-demo=\"\">\"EaseIn\"</div></Animate>\n                    <Animate animation=\"slide-in\" easing=\"ease-out\"    duration=\"1.6s\"><div data-rs-animate-demo=\"\">\"EaseOut\"</div></Animate>\n                    <Animate animation=\"slide-in\" easing=\"ease-in-out\" duration=\"1.6s\"><div data-rs-animate-demo=\"\">\"EaseInOut\"</div></Animate>\n                    <Animate animation=\"slide-in\" easing=\"linear\"      duration=\"1.6s\"><div data-rs-animate-demo=\"\">\"Linear\"</div></Animate>\n                </Grid>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Stagger\"</span>\n                <Animate animation=\"fade-in\" duration=\"0.6s\" stagger=100.0>\n                    <div data-rs-animate-demo=\"\">\"Item 1\"</div>\n                    <div data-rs-animate-demo=\"\">\"Item 2\"</div>\n                    <div data-rs-animate-demo=\"\">\"Item 3\"</div>\n                </Animate>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack",
      "grid"
    ]
  },
  {
    "id": "aspect_ratio",
    "label": "Aspect Ratio",
    "category": "Display",
    "description": "Aspect ratio container",
    "keywords": "",
    "pain": "Aspect ratios break on resize causing layout shift and inconsistent rendering",
    "promise": "Aspect ratio enforced structurally with no layout drift",
    "why": "AspectRatioPrimitive encodes width/height ratio in data attributes. The structure guarantees consistent layout regardless of content size. This eliminates runtime calculations and ensures SSR-safe rendering.\n",
    "before": "// ❌ Typical\nview! {\n  <div style=\"position:relative;padding-top:56.25%\">\n    <img src=\"img.png\" style=\"position:absolute;width:100%;height:100%\" />\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <AspectRatio ratio_w=16.0 ratio_h=9.0>\n    <img src=\"img.png\" />\n  </AspectRatio>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "video containers",
      "image previews"
    ],
    "related": [
      "card",
      "resizable",
      "scroll_area",
      "page_header",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! AspectRatio Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[component]\npub fn AspectRatioPrimitive(\n    children: Children,\n    #[prop(default = 16.0f32)] ratio_w: f32,\n    #[prop(default = 9.0f32)] ratio_h: f32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ar = crate::infra::uid::generate(\"ar\");\n    let ratio = format!(\"{}/{}\", ratio_w, ratio_h);\n    let ratio_style = format!(\"aspect-ratio:{}/{}\", ratio_w, ratio_h);\n    view! {\n        <div\n            data-rs-aspect-ratio=\"\"\n            data-rs-uid=uid_ar\n            data-rs-ratio=ratio\n            style=ratio_style\n            class=class\n        >\n            <div data-rs-aspect-ratio-content=\"\">\n                {children()}\n            </div>\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::AspectRatioPrimitive;\n\n#[component]\npub fn AspectRatio(\n    children: Children,\n    #[prop(default = 16.0f32)] ratio_w: f32,\n    #[prop(default = 9.0f32)] ratio_h: f32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AspectRatioPrimitive\n            ratio_w=ratio_w\n            ratio_h=ratio_h\n            class=class\n        >\n            {children()}\n        </AspectRatioPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! AspectRatio Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::aspect_ratio_ui::AspectRatio as AspectRatioUi;\n\n#[component]\npub fn AspectRatio(\n    children: Children,\n    #[prop(default = 16.0f32)] ratio_w: f32,\n    #[prop(default = 9.0f32)] ratio_h:  f32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AspectRatioUi ratio_w=ratio_w ratio_h=ratio_h class=class>\n            {children()\n};\n        </AspectRatioUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const ASPECTRATIO_API: ComponentApi = ComponentApi {\n    id: \"aspect-ratio\",\n    description: \"Aspect ratio container\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"ratio_w\", kind: PropType::Number, required: false, default: Some(\"16.0f32\"), description: \"Prop value\" },\n        PropDef { name: \"ratio_h\", kind: PropType::Number, required: false, default: Some(\"9.0f32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::aspect_ratio_boundary::AspectRatio;\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\n\n#[component]\npub fn AspectRatioShowcasePreview() -> impl IntoView {\n    view! {\n        <Grid cols=GridCols::One>\n            <AspectRatio ratio_w=16.0f32 ratio_h=9.0f32>\n                <div data-rs-aspect-demo=\"\">\"16 / 9\"</div>\n            </AspectRatio>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Aspect ratio enforced structurally with no layout drift.\"\n            </p>\n            <span data-rs-showcase-preview-label=\"\">\"Ratios\"</span>\n            <Grid cols=GridCols::Three>\n                <AspectRatio ratio_w=4.0f32  ratio_h=3.0f32><div data-rs-aspect-demo=\"\">\"4 / 3\"</div></AspectRatio>\n                <AspectRatio ratio_w=1.0f32  ratio_h=1.0f32><div data-rs-aspect-demo=\"\">\"1 / 1\"</div></AspectRatio>\n                <AspectRatio ratio_w=21.0f32 ratio_h=9.0f32><div data-rs-aspect-demo=\"\">\"21 / 9\"</div></AspectRatio>\n            </Grid>\n        </Grid>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "grid"
    ]
  },
  {
    "id": "avatar",
    "label": "Avatar",
    "category": "Display",
    "description": "User avatar image",
    "keywords": "",
    "pain": "Avatar fallback logic breaks when image fails to load",
    "promise": "Image and fallback visibility controlled by state system",
    "why": "AvatarImage and AvatarFallback use VisibilityState to control rendering. The system ensures fallback is shown when image is unavailable. This avoids manual conditional logic and guarantees consistent behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <img src=\"user.png\" on:error=move |_| show_fallback() />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Avatar>\n    <AvatarImage src=\"user.png\" alt=\"User\" />\n    <AvatarFallback>\"AB\"</AvatarFallback>\n  </Avatar>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "user profile",
      "team lists"
    ],
    "related": [
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Avatar Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[component]\npub fn AvatarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] size: String,\n    #[prop(into, default = String::new())] shape: String,\n    #[prop(into, default = String::new())] status: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"av\");\n    view! {\n        <span\n            data-rs-avatar=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"init\"\n            data-rs-size=size\n            data-rs-shape=shape\n            data-rs-status=status\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn AvatarImagePrimitive(\n    #[prop(into)] src: String,\n    #[prop(into)] alt: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"av-img\");\n    view! {\n        <img\n            data-rs-avatar-image=\"\"\n            data-rs-uid=uid\n            data-rs-state=state.as_str()\n            src=src\n            alt=alt\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn AvatarFallbackPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"av-fb\");\n    view! {\n        <span\n            data-rs-avatar-fallback=\"\"\n            data-rs-uid=uid\n            data-rs-state=state.as_str()\n            aria-hidden=state.aria_hidden()\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{AvatarPrimitive, AvatarImagePrimitive, AvatarFallbackPrimitive};\nuse canonrs_core::StatusDotVariant;\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum AvatarSize { Xs, Sm, Md, Lg, Xl }\nimpl AvatarSize {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Xs=>\"xs\", Self::Sm=>\"sm\", Self::Md=>\"md\", Self::Lg=>\"lg\", Self::Xl=>\"xl\" }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum AvatarShape { Circle, Square, Rounded }\nimpl AvatarShape {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Circle=>\"circle\", Self::Square=>\"square\", Self::Rounded=>\"rounded\" }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum AvatarStatus { Online, Offline, Busy, Away }\nimpl AvatarStatus {\n    pub fn to_variant(&self) -> StatusDotVariant {\n        match self {\n            Self::Online  => StatusDotVariant::Online,\n            Self::Offline => StatusDotVariant::Offline,\n            Self::Busy    => StatusDotVariant::Busy,\n            Self::Away    => StatusDotVariant::Away,\n        }\n    }\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Online  => \"online\",\n            Self::Offline => \"offline\",\n            Self::Busy    => \"busy\",\n            Self::Away    => \"away\",\n        }\n    }\n}\n\n#[component]\npub fn Avatar(\n    children: Children,\n    #[prop(default = AvatarSize::Md)] size: AvatarSize,\n    #[prop(default = AvatarShape::Circle)] shape: AvatarShape,\n    #[prop(optional)] status: Option<AvatarStatus>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let status_str = status.as_ref().map(|s| s.as_str().to_string()).unwrap_or_default();\n    view! {\n        <AvatarPrimitive\n            status=status_str\n            size=size.as_str().to_string()\n            shape=shape.as_str().to_string()\n            class=class\n        >\n            {children()}\n        </AvatarPrimitive>\n    }\n}\n\n#[component]\npub fn AvatarImage(\n    src: String,\n    alt: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AvatarImagePrimitive src={src} alt={alt} class={class} />\n    }\n}\n\n#[component]\npub fn AvatarFallback(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AvatarFallbackPrimitive class={class}>\n            {children()}\n        </AvatarFallbackPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Avatar Boundary — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::avatar_ui::{\n    Avatar as AvatarUi,\n    AvatarImage as AvatarImageUi,\n    AvatarFallback as AvatarFallbackUi,\n};\npub use super::avatar_ui::{AvatarSize, AvatarShape, AvatarStatus};\n\n#[component]\npub fn Avatar(\n    children: Children,\n    #[prop(default = AvatarSize::Md)] size: AvatarSize,\n    #[prop(default = AvatarShape::Circle)] shape: AvatarShape,\n    #[prop(optional)] status: Option<AvatarStatus>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <AvatarUi size=size shape=shape status=status.unwrap_or(AvatarStatus::Offline) class=class>\n            {children()}\n        </AvatarUi>\n    }\n}\n\n#[component]\npub fn AvatarImage(\n    #[prop(into)] src: String,\n    #[prop(into)] alt: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AvatarImageUi src=src alt=alt class=class /> }\n}\n\n#[component]\npub fn AvatarFallback(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <AvatarFallbackUi class=class>{children()}</AvatarFallbackUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const AVATAR_API: ComponentApi = ComponentApi {\n    id: \"avatar\",\n    description: \"User avatar image\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"size\", kind: PropType::String, required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"shape\", kind: PropType::String, required: false, default: Some(\"circle\"), description: \"Prop value\" },\n        PropDef { name: \"status\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const AVATARIMAGE_API: ComponentApi = ComponentApi {\n    id: \"avatar-image\",\n    description: \"User avatar image\",\n    props: &[\n        PropDef { name: \"src\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"alt\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const AVATARFALLBACK_API: ComponentApi = ComponentApi {\n    id: \"avatar-fallback\",\n    description: \"User avatar image\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::avatar_boundary::{Avatar, AvatarImage, AvatarFallback};\nuse super::avatar_boundary::{AvatarSize, AvatarShape, AvatarStatus};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn AvatarShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                <Avatar status=AvatarStatus::Online>\n                    <AvatarFallback>\"AB\"</AvatarFallback>\n                </Avatar>\n                <Avatar shape=AvatarShape::Circle size=AvatarSize::Lg status=AvatarStatus::Online>\n                    <AvatarImage src=\"/assets/avatar_canonrs.webp\".to_string() alt=\"User\".to_string() />\n                    <AvatarFallback>\"CD\"</AvatarFallback>\n                </Avatar>\n            </Stack>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Image and fallback visibility controlled by state system.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Avatar size=AvatarSize::Xs><AvatarFallback>\"XS\"</AvatarFallback></Avatar>\n                    <Avatar size=AvatarSize::Sm><AvatarFallback>\"SM\"</AvatarFallback></Avatar>\n                    <Avatar size=AvatarSize::Md><AvatarFallback>\"MD\"</AvatarFallback></Avatar>\n                    <Avatar size=AvatarSize::Lg><AvatarFallback>\"LG\"</AvatarFallback></Avatar>\n                    <Avatar size=AvatarSize::Xl><AvatarFallback>\"XL\"</AvatarFallback></Avatar>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Shapes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Avatar shape=AvatarShape::Circle> <AvatarFallback>\"CI\"</AvatarFallback></Avatar>\n                    <Avatar shape=AvatarShape::Rounded><AvatarFallback>\"RO\"</AvatarFallback></Avatar>\n                    <Avatar shape=AvatarShape::Square> <AvatarFallback>\"SQ\"</AvatarFallback></Avatar>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Status\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Avatar status=AvatarStatus::Online> <AvatarFallback>\"ON\"</AvatarFallback></Avatar>\n                    <Avatar status=AvatarStatus::Busy>   <AvatarFallback>\"BU\"</AvatarFallback></Avatar>\n                    <Avatar status=AvatarStatus::Away>   <AvatarFallback>\"AW\"</AvatarFallback></Avatar>\n                    <Avatar status=AvatarStatus::Offline><AvatarFallback>\"OF\"</AvatarFallback></Avatar>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "badge",
    "label": "Badge",
    "category": "Display",
    "description": "Status badge label",
    "keywords": "",
    "pain": "Badges mix interactive and static behavior without clear intent",
    "promise": "Interactivity explicitly defined and enforced by type",
    "why": "BadgeInteractivity defines whether the badge is static or interactive. The primitive encodes this into data attributes, preventing misuse. This ensures consistent semantics and avoids accidental clickable badges.\n",
    "before": "// ❌ Typical\nview! {\n  <span class=\"badge clickable\">\"New\"</span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Badge interactivity=BadgeInteractivity::Static>\n    \"New\"\n  </Badge>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "status labels",
      "notifications"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Badge Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum BadgeVariant {\n    #[default]\n    Default,\n    Primary,\n    Success,\n    Warning,\n    Destructive,\n    Outline,\n}\n\nimpl BadgeVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default     => \"default\",\n            Self::Primary     => \"primary\",\n            Self::Success     => \"success\",\n            Self::Warning     => \"warning\",\n            Self::Destructive => \"destructive\",\n            Self::Outline     => \"outline\",\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum BadgeInteractivity {\n    #[default]\n    Static,\n    Interactive,\n}\n\nimpl BadgeInteractivity {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Static      => \"static\",\n            Self::Interactive => \"interactive\",\n        }\n    }\n}\n\n#[component]\npub fn BadgePrimitive(\n    children: Children,\n    #[prop(default = BadgeVariant::Default)] variant: BadgeVariant,\n    #[prop(default = BadgeInteractivity::Static)] interactivity: BadgeInteractivity,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_bdg = crate::infra::uid::generate(\"bdg\");\n    view! {\n        <span\n            data-rs-badge=\"\"\n            data-rs-uid=uid_bdg\n            data-rs-variant=variant.as_str()\n            data-rs-interactivity=interactivity.as_str()\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{BadgePrimitive, BadgeInteractivity};\npub use canonrs_core::primitives::BadgeVariant;\n\n#[component]\npub fn Badge(\n    children: Children,\n    #[prop(default = BadgeVariant::Default)] variant: BadgeVariant,\n    #[prop(default = BadgeInteractivity::Static)] interactivity: BadgeInteractivity,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BadgePrimitive variant=variant interactivity=interactivity class=class>\n            {children()}\n        </BadgePrimitive>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::badge_ui::Badge as BadgeUi;\npub use canonrs_core::primitives::{\n    BadgeVariant,\n    BadgeInteractivity\n};\n\n#[component]\npub fn Badge(\n    children: Children,\n    #[prop(default = BadgeVariant::Default)] variant: BadgeVariant,\n    #[prop(default = BadgeInteractivity::Static)] interactivity: BadgeInteractivity,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] hidden: bool,\n) -> impl IntoView {\n    view! {\n        <BadgeUi variant=variant interactivity=interactivity class=class attr:hidden=hidden.then(|| \"\")>\n            {children()}\n        </BadgeUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{BadgeVariant, BadgeInteractivity}; \n\npub const BADGE_API: ComponentApi = ComponentApi {\n    id: \"badge\",\n    description: \"Status badge label\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"primary\", \"success\", \"warning\", \"destructive\", \"outline\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"interactivity\", kind: PropType::Enum(&[\"static\", \"interactive\"]), required: false, default: Some(\"static\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"hidden\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::badge_boundary::{Badge, BadgeVariant, BadgeInteractivity};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn BadgeShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Badge variant=BadgeVariant::Success>\"Active\"</Badge>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Interactivity explicitly defined and enforced by type.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Badge>\"Default\"</Badge>\n                    <Badge variant=BadgeVariant::Primary>\"Primary\"</Badge>\n                    <Badge variant=BadgeVariant::Success>\"Success\"</Badge>\n                    <Badge variant=BadgeVariant::Warning>\"Warning\"</Badge>\n                    <Badge variant=BadgeVariant::Destructive>\"Destructive\"</Badge>\n                    <Badge variant=BadgeVariant::Outline>\"Outline\"</Badge>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Interactivity\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Badge>\"Static\"</Badge>\n                    <Badge interactivity=BadgeInteractivity::Interactive>\"Interactive\"</Badge>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Count / status examples\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Badge variant=BadgeVariant::Primary>\"12\"</Badge>\n                    <Badge variant=BadgeVariant::Warning>\"Pending\"</Badge>\n                    <Badge variant=BadgeVariant::Destructive>\"Failed\"</Badge>\n                    <Badge variant=BadgeVariant::Outline>\"Draft\"</Badge>\n                    <Badge variant=BadgeVariant::Success>\"Published\"</Badge>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "banner",
    "label": "Banner",
    "category": "Feedback",
    "description": "Banner message",
    "keywords": "",
    "pain": "Banner messages lack consistent visibility and accessibility behavior",
    "promise": "Visibility and ARIA behavior enforced by state and variant",
    "why": "BannerVariant controls semantic role and aria-live behavior. VisibilityState ensures correct open/hidden state without runtime logic. This guarantees accessible, consistent page-level messaging.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"banner\">\"Maintenance scheduled\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Banner>\n    <BannerContent>\"Maintenance scheduled\"</BannerContent>\n  </Banner>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "system announcements",
      "warnings"
    ],
    "related": [
      "toast",
      "alert",
      "callout",
      "inline_notice",
      "status_dot"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Banner Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum BannerVariant {\n    #[default]\n    Info, Success, Warning, Error,\n}\nimpl BannerVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Info    => \"info\",\n            Self::Success => \"success\",\n            Self::Warning => \"warning\",\n            Self::Error   => \"error\",\n        }\n    }\n    pub fn role(&self) -> &'static str {\n        match self {\n            Self::Error | Self::Warning => \"alert\",\n            _                           => \"region\",\n        }\n    }\n    pub fn aria_live(&self) -> &'static str {\n        match self {\n            Self::Error | Self::Warning => \"assertive\",\n            _                           => \"polite\",\n        }\n    }\n    pub fn aria_label(&self) -> &'static str {\n        match self {\n            Self::Error   => \"Error notification\",\n            Self::Warning => \"Warning notification\",\n            Self::Success => \"Success notification\",\n            Self::Info    => \"System notification\",\n        }\n    }\n}\n\n#[component]\npub fn BannerPrimitive(\n    children: Children,\n    #[prop(default = BannerVariant::Info)] variant: BannerVariant,\n    #[prop(default = VisibilityState::Open)] visibility: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"bn\");\n    view! {\n        <div\n            data-rs-banner=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"dismiss\"\n            data-rs-variant=variant.as_str()\n            data-rs-state=visibility.as_str()\n            role=variant.role()\n            aria-live=variant.aria_live()\n            aria-label=variant.aria_label()\n            aria-atomic=\"true\"\n            hidden=visibility.hidden()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn BannerClosePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-banner-close=\"\"\n            aria-label=\"Close banner\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn BannerContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-banner-content=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn BannerActionsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-banner-actions=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    BannerPrimitive, BannerClosePrimitive,\n    BannerContentPrimitive, BannerActionsPrimitive,\n};\npub use canonrs_core::primitives::BannerVariant;\n\n#[component]\npub fn Banner(\n    children: Children,\n    #[prop(default = BannerVariant::Info)] variant: BannerVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BannerPrimitive variant=variant class=class>\n            {children()}\n        </BannerPrimitive>\n    }\n}\n\n#[component]\npub fn BannerContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BannerContentPrimitive class=class>\n            {children()}\n        </BannerContentPrimitive>\n    }\n}\n\n#[component]\npub fn BannerActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BannerActionsPrimitive class=class>\n            {children()}\n        </BannerActionsPrimitive>\n    }\n}\n\n#[component]\npub fn BannerClose(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BannerClosePrimitive class=class>\n            {children()}\n        </BannerClosePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Banner Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::banner_ui::{\n    Banner as BannerUi,\n    BannerClose,\n    BannerContent\n};\npub use canonrs_core::primitives::BannerVariant;\n\n#[component]\npub fn Banner(\n    #[prop(into, optional)] content: Option<String>,\n    #[prop(default = BannerVariant::Info)] variant: BannerVariant,\n    #[prop(default = true)] dismissible: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <BannerUi variant=variant class=class>\n            <BannerContent>{content}</BannerContent>\n            {dismissible.then(|| view! { <BannerClose>\"×\"</BannerClose> })}\n        </BannerUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{BannerVariant}; \n\npub const BANNER_API: ComponentApi = ComponentApi {\n    id: \"banner\",\n    description: \"Banner message\",\n    props: &[\n        PropDef { name: \"content\", kind: PropType::String, required: false, default: None, description: \"Content region slot\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"info\", \"success\", \"warning\", \"error\"]), required: false, default: Some(\"info\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"dismissible\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::banner_boundary::{Banner, BannerVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn BannerShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Banner content=\"System maintenance scheduled for Saturday at 2am UTC.\" dismissible=true />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Visibility and ARIA behavior enforced by state and variant.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <Banner variant=BannerVariant::Success content=\"Your account has been verified.\" dismissible=true />\n                    <Banner variant=BannerVariant::Warning content=\"Your subscription expires in 3 days.\" dismissible=true />\n                    <Banner variant=BannerVariant::Error content=\"Payment failed. Please update billing.\" dismissible=true />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container",
      "stack"
    ]
  },
  {
    "id": "breadcrumb",
    "label": "Breadcrumb",
    "category": "Navigation",
    "description": "Navigation breadcrumb trail",
    "keywords": "",
    "pain": "Breadcrumbs fail to mark current page correctly for accessibility",
    "promise": "Current page state enforced via activity state mapping",
    "why": "ActivityState defines whether a breadcrumb link is active. The primitive maps this to aria-current automatically. This ensures correct navigation semantics without manual ARIA handling.\n",
    "before": "// ❌ Typical\nview! {\n  <nav>\n    <a href=\"#\">Home</a>\n    <span>\"/\"</span>\n    <a class=\"active\">Page</a>\n  </nav>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Breadcrumb>\n    <BreadcrumbItem>\n      <BreadcrumbLink href=\"#\">\"Home\"</BreadcrumbLink>\n    </BreadcrumbItem>\n    <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n    <BreadcrumbItem>\n      <BreadcrumbPage>\"Page\"</BreadcrumbPage>\n    </BreadcrumbItem>\n  </Breadcrumb>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "navigation trails",
      "hierarchy display"
    ],
    "related": [
      "navigation_menu",
      "sidebar",
      "nav_item",
      "pagination",
      "link_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "navigation",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Breadcrumb Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::ActivityState;\n\n#[component]\npub fn BreadcrumbPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_bc = crate::infra::uid::generate(\"bc\");\n    view! {\n        <nav\n            data-rs-breadcrumb=\"\"\n            data-rs-uid=uid_bc\n            data-rs-interaction=\"nav\"\n            aria-label=\"Breadcrumb\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn BreadcrumbItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-breadcrumb-item=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn BreadcrumbLinkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let aria_current = if state == ActivityState::Active { Some(\"page\") } else { None };\n    view! {\n        <a\n            data-rs-breadcrumb-link=\"\"\n            data-rs-activity=state.as_str()\n            href=href\n            aria-current=aria_current\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn BreadcrumbSeparatorPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-breadcrumb-separator=\"\" aria-hidden=\"true\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn BreadcrumbEllipsisPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-breadcrumb-ellipsis=\"\" aria-hidden=\"true\" class=class>\n            \"...\"\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    BreadcrumbPrimitive, BreadcrumbItemPrimitive, BreadcrumbLinkPrimitive, BreadcrumbSeparatorPrimitive, BreadcrumbEllipsisPrimitive,\n};\nuse canonrs_core::meta::ActivityState;\n\n#[component]\npub fn Breadcrumb(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <BreadcrumbPrimitive class=class>{children()}</BreadcrumbPrimitive> }\n}\n#[component]\npub fn BreadcrumbItem(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <BreadcrumbItemPrimitive class=class>{children()}</BreadcrumbItemPrimitive> }\n}\n#[component]\npub fn BreadcrumbLink(children: Children, #[prop(into, default = String::new())] href: String, #[prop(default = ActivityState::Inactive)] state: ActivityState, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <BreadcrumbLinkPrimitive href=href state=state class=class>{children()}</BreadcrumbLinkPrimitive> }\n}\n#[component]\npub fn BreadcrumbPage(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <span data-rs-breadcrumb-page=\"\" class=class>{children()}</span> }\n}\n#[component]\npub fn BreadcrumbSeparator(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <BreadcrumbSeparatorPrimitive class=class>{children()}</BreadcrumbSeparatorPrimitive> }\n}\n#[component]\npub fn BreadcrumbEllipsis(#[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <BreadcrumbItemPrimitive class=String::new()><BreadcrumbEllipsisPrimitive class=class /></BreadcrumbItemPrimitive> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Breadcrumb Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::breadcrumb_ui::{\n    Breadcrumb as BreadcrumbUi,\n    BreadcrumbItem as BreadcrumbItemUi,\n    BreadcrumbLink as BreadcrumbLinkUi,\n    BreadcrumbPage as BreadcrumbPageUi,\n    BreadcrumbSeparator as BreadcrumbSeparatorUi,\n    BreadcrumbEllipsis as BreadcrumbEllipsisUi\n};\nuse canonrs_core::meta::ActivityState;\n\n\n\n#[component]\npub fn Breadcrumb(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! {\n        <BreadcrumbUi class=class.unwrap_or_default()>{children()}</BreadcrumbUi>\n    }\n}\n\n#[component]\npub fn BreadcrumbItem(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <BreadcrumbItemUi class=class.unwrap_or_default()>{children()}</BreadcrumbItemUi> }\n}\n\n#[component]\npub fn BreadcrumbLink(\n    children: Children,\n    #[prop(optional, into)] href: Option<String>,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! {\n        <BreadcrumbLinkUi href=href.unwrap_or_default() state=state class=class.unwrap_or_default()>\n            {children()}\n        </BreadcrumbLinkUi>\n    }\n}\n\n#[component]\npub fn BreadcrumbPage(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <BreadcrumbPageUi class=class.unwrap_or_default()>{children()}</BreadcrumbPageUi> }\n}\n\n#[component]\npub fn BreadcrumbSeparator(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <BreadcrumbSeparatorUi class=class.unwrap_or_default()>{children()}</BreadcrumbSeparatorUi> }\n}\n\n#[component]\npub fn BreadcrumbEllipsis(\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <BreadcrumbEllipsisUi class=class.unwrap_or_default() /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const BREADCRUMB_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const BREADCRUMBITEM_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb-item\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const BREADCRUMBLINK_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb-link\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: None, description: \"Navigation target URL\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const BREADCRUMBPAGE_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb-page\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const BREADCRUMBSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb-separator\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const BREADCRUMBELLIPSIS_API: ComponentApi = ComponentApi {\n    id: \"breadcrumb-ellipsis\",\n    description: \"Navigation breadcrumb trail\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::breadcrumb_boundary::{\n    Breadcrumb, BreadcrumbItem, BreadcrumbLink,\n    BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn BreadcrumbShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Breadcrumb>\n                <BreadcrumbItem>\n                    <BreadcrumbLink href=\"#\">\"Home\"</BreadcrumbLink>\n                </BreadcrumbItem>\n                <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n                <BreadcrumbItem>\n                    <BreadcrumbLink href=\"#\">\"Components\"</BreadcrumbLink>\n                </BreadcrumbItem>\n                <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n                <BreadcrumbItem>\n                    <BreadcrumbPage>\"Breadcrumb\"</BreadcrumbPage>\n                </BreadcrumbItem>\n            </Breadcrumb>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Current page state enforced via activity state mapping.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Custom separator\"</span>\n                <Breadcrumb>\n                    <BreadcrumbItem>\n                        <BreadcrumbLink href=\"#\">\"Home\"</BreadcrumbLink>\n                    </BreadcrumbItem>\n                    <BreadcrumbSeparator>\"›\"</BreadcrumbSeparator>\n                    <BreadcrumbItem>\n                        <BreadcrumbLink href=\"#\">\"Settings\"</BreadcrumbLink>\n                    </BreadcrumbItem>\n                    <BreadcrumbSeparator>\"›\"</BreadcrumbSeparator>\n                    <BreadcrumbItem>\n                        <BreadcrumbPage>\"Profile\"</BreadcrumbPage>\n                    </BreadcrumbItem>\n                </Breadcrumb>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With ellipsis\"</span>\n                <Breadcrumb>\n                    <BreadcrumbItem>\n                        <BreadcrumbLink href=\"#\">\"Home\"</BreadcrumbLink>\n                    </BreadcrumbItem>\n                    <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n                    <BreadcrumbItem>\n                        <BreadcrumbEllipsis />\n                    </BreadcrumbItem>\n                    <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n                    <BreadcrumbItem>\n                        <BreadcrumbLink href=\"#\">\"Components\"</BreadcrumbLink>\n                    </BreadcrumbItem>\n                    <BreadcrumbSeparator>\"/\"</BreadcrumbSeparator>\n                    <BreadcrumbItem>\n                        <BreadcrumbPage>\"Breadcrumb\"</BreadcrumbPage>\n                    </BreadcrumbItem>\n                </Breadcrumb>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "button",
    "label": "Button",
    "category": "Action",
    "description": "Action button with variant and size",
    "keywords": "button rust leptos, ssr safe button leptos, canonical button component rust, governed ui button",
    "pain": "Buttons rely on string classes causing inconsistent variants and states",
    "promise": "Variant and size enforced at compile-time via enums",
    "why": "ButtonVariant and ButtonSize define allowed visual and behavioral states. The primitive encodes these into data attributes, ensuring consistent rendering. This eliminates invalid combinations and style drift.\n",
    "before": "// ❌ Typical\nview! {\n  <button class=\"btn btn-primary btn-md\">\"Submit\"</button>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Button variant=ButtonVariant::Primary size=ButtonSize::Md>\n    \"Submit\"\n  </Button>\n}\n",
    "rules": [
      "CR-001",
      "CR-004",
      "CR-148"
    ],
    "use_cases": [
      "form submit",
      "cta actions"
    ],
    "related": [
      "button_group",
      "icon_button",
      "copy_button",
      "link"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "action",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Button Primitive - HTML puro\nuse leptos::prelude::*;\nuse crate::meta::{DisabledState, LoadingState, ToggleState, ToDataAttr};\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Default, Debug)]\npub enum ButtonVariant {\n    #[default]\n    Default, Destructive, Outline, Secondary, Ghost, Link, Primary,\n}\nimpl ButtonVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default     => \"default\",\n            Self::Destructive => \"destructive\",\n            Self::Outline     => \"outline\",\n            Self::Secondary   => \"secondary\",\n            Self::Ghost       => \"ghost\",\n            Self::Link        => \"link\",\n            Self::Primary     => \"primary\",\n        }\n    }\n}\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Default, Debug)]\npub enum ButtonSize {\n    Xs, Sm,\n    #[default]\n    Md,\n    Lg, Xl, Icon,\n}\nimpl ButtonSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Xs   => \"xs\",\n            Self::Sm   => \"sm\",\n            Self::Md   => \"md\",\n            Self::Lg   => \"lg\",\n            Self::Xl   => \"xl\",\n            Self::Icon => \"icon\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug, serde::Serialize, serde::Deserialize)]\npub enum ButtonStateHint {\n    #[default] None,\n    First, Last, Hover, Focus,\n}\nimpl ButtonStateHint {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::None  => \"\",\n            Self::First => \"first\",\n            Self::Last  => \"last\",\n            Self::Hover => \"hover\",\n            Self::Focus => \"focus\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug, serde::Serialize, serde::Deserialize)]\npub enum ButtonType {\n    #[default]\n    Button, Submit, Reset,\n}\nimpl ButtonType {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Button => \"button\",\n            Self::Submit => \"submit\",\n            Self::Reset  => \"reset\",\n        }\n    }\n}\n\n#[component]\npub fn ButtonPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(default = ButtonType::Button)] button_type: ButtonType,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = LoadingState::Idle)] loading: LoadingState,\n    #[prop(optional)] pressed: Option<ToggleState>,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"bt\");\n    view! {\n        <button\n            type=button_type.as_str()\n            data-rs-button=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            data-rs-size=size.as_str()\n            data-rs-disabled=disabled.to_data_attr().1.ne(\"enabled\").then(|| disabled.to_data_attr().1)\n            data-rs-loading=loading.to_data_attr().1.ne(\"idle\").then(|| loading.to_data_attr().1)\n            disabled=disabled.disabled()\n            aria-disabled=disabled.aria_disabled()\n            aria-busy=loading.aria_busy()\n            aria-pressed=pressed.map(|p| p.aria_pressed())\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn LinkButtonPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] target: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"bt\");\n    view! {\n        <a\n            href=href\n            target=if target.is_empty() { None } else { Some(target) }\n            data-rs-button=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            data-rs-size=size.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n",
    "ui_src": "use leptos::prelude::*;\nuse canonrs_core::primitives::{ButtonPrimitive, LinkButtonPrimitive, ButtonVariant, ButtonSize, ButtonType};\nuse canonrs_core::meta::{DisabledState, LoadingState};\n\n#[component]\npub fn Button(\n    children: Children,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = LoadingState::Idle)] loading: LoadingState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(default = ButtonType::Button)] button_type: ButtonType,\n) -> impl IntoView {\n    view! {\n        <ButtonPrimitive\n            variant=variant\n            size=size\n            disabled=disabled\n            loading=loading\n            button_type=button_type\n            aria_label=aria_label.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </ButtonPrimitive>\n    }\n}\n\n#[component]\npub fn LinkButton(\n    children: Children,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] target: String,\n) -> impl IntoView {\n    view! {\n        <LinkButtonPrimitive\n            href=href\n            target=target\n            variant=variant\n            size=size\n            disabled=disabled\n            aria_label=aria_label.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </LinkButtonPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Button Boundary — Tipo 2: Init\n//! Normaliza props (bool -> State), delega para canonrs-interactions-init\n\nuse leptos::prelude::*;\nuse super::button_ui::{Button as ButtonUi, LinkButton as LinkButtonUi};\npub use canonrs_core::primitives::{ButtonVariant, ButtonSize, ButtonType, ButtonStateHint};\nuse canonrs_core::meta::{DisabledState, LoadingState};\n\n#[component]\npub fn Button(\n    children: Children,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(default = false)] disabled: bool,\n    #[prop(default = false)] loading: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, optional)] validation: Option<String>,\n    #[prop(optional)] state_hint: Option<ButtonStateHint>,\n    #[prop(default = ButtonType::Button)] button_type: ButtonType,\n) -> impl IntoView {\n    let disabled_state = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    let loading_state  = if loading  { LoadingState::Loading  } else { LoadingState::Idle };\n    let _ = (validation, state_hint);\n    view! {\n        <ButtonUi\n            variant=variant\n            size=size\n            disabled=disabled_state\n            loading=loading_state\n            button_type=button_type\n            aria_label=aria_label.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </ButtonUi>\n    }\n}\n\n#[component]\npub fn LinkButton(\n    children: Children,\n    #[prop(default = ButtonVariant::Default)] variant: ButtonVariant,\n    #[prop(default = ButtonSize::Md)] size: ButtonSize,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] target: String,\n) -> impl IntoView {\n    let disabled_state = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    view! {\n        <LinkButtonUi\n            variant=variant\n            size=size\n            disabled=disabled_state\n            aria_label=aria_label.unwrap_or_default()\n            href=href\n            target=target\n            class=class\n        >\n            {children()}\n        </LinkButtonUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ButtonVariant, ButtonSize, ButtonType, ButtonStateHint}; \n\npub const BUTTON_API: ComponentApi = ComponentApi {\n    id: \"button\",\n    description: \"Action button with variant and size\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"outline\", \"secondary\", \"ghost\", \"link\", \"primary\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"icon\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"loading\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n        PropDef { name: \"validation\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"state_hint\", kind: PropType::Enum(&[\"first\", \"last\", \"hover\", \"focus\"]), required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"button_type\", kind: PropType::Enum(&[\"button\", \"submit\", \"reset\"]), required: false, default: Some(\"button\"), description: \"Prop value\" },\n    ],\n};\n\npub const LINKBUTTON_API: ComponentApi = ComponentApi {\n    id: \"link-button\",\n    description: \"Action button with variant and size\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"outline\", \"secondary\", \"ghost\", \"link\", \"primary\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"icon\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"target\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Target element selector for copy\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::button_boundary::{Button, ButtonVariant, ButtonSize};\nuse crate::ui::button_group::button_group_boundary::ButtonGroup;\nuse canonrs_core::ToggleState;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ButtonPreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Button variant=ButtonVariant::Primary size=ButtonSize::Lg>\"Confirm Action\"</Button>\n            <p data-rs-showcase-preview-anchor=\"\">\"Cannot drift. Cannot break. Cannot diverge.\"</p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Button variant=ButtonVariant::Primary>\"Primary\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"Secondary\"</Button>\n                    <Button variant=ButtonVariant::Outline>\"Outline\"</Button>\n                    <Button variant=ButtonVariant::Ghost>\"Ghost\"</Button>\n                    <Button variant=ButtonVariant::Destructive>\"Destructive\"</Button>\n                    <Button variant=ButtonVariant::Link>\"Link\"</Button>\n                    <Button variant=ButtonVariant::Default>\"Default\"</Button>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Button variant=ButtonVariant::Primary size=ButtonSize::Xs>\"Xs\"</Button>\n                    <Button variant=ButtonVariant::Primary size=ButtonSize::Sm>\"Sm\"</Button>\n                    <Button variant=ButtonVariant::Primary size=ButtonSize::Md>\"Md\"</Button>\n                    <Button variant=ButtonVariant::Primary size=ButtonSize::Lg>\"Lg\"</Button>\n                    <Button variant=ButtonVariant::Primary size=ButtonSize::Xl>\"Xl\"</Button>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Button variant=ButtonVariant::Primary>\"Default\"</Button>\n                    <Button variant=ButtonVariant::Primary disabled=true>\"Disabled\"</Button>\n                    <Button variant=ButtonVariant::Ghost attr:data-rs-state=\"hover\">\"Ghost Hover\"</Button>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Validation\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Button variant=ButtonVariant::Primary validation=\"error\">\"Error\"</Button>\n                    <Button variant=ButtonVariant::Primary validation=\"warning\">\"Warning\"</Button>\n                    <Button variant=ButtonVariant::Primary validation=\"success\">\"Success\"</Button>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Button Group — detached\"</span>\n                <ButtonGroup aria_label=\"Group detached\">\n                    <Button variant=ButtonVariant::Primary>\"One\"</Button>\n                    <Button variant=ButtonVariant::Primary>\"Two\"</Button>\n                    <Button variant=ButtonVariant::Primary>\"Three\"</Button>\n                </ButtonGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Button Group — attached\"</span>\n                <ButtonGroup attached=ToggleState::On aria_label=\"Group attached\">\n                    <Button variant=ButtonVariant::Primary>\"One\"</Button>\n                    <Button variant=ButtonVariant::Primary>\"Two\"</Button>\n                    <Button variant=ButtonVariant::Primary>\"Three\"</Button>\n                </ButtonGroup>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "button_group",
    "label": "Button Group",
    "category": "Action",
    "description": "Group of action buttons",
    "keywords": "",
    "pain": "Grouped buttons lose semantic grouping and accessibility context",
    "promise": "Group semantics and attachment enforced via component contract",
    "why": "ButtonGroupPrimitive defines role=\"group\" and controlled attachment state via ToggleState. This ensures grouped actions are treated as a single logical unit. The contract guarantees consistent accessibility and visual cohesion.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"btn-group\">\n    <button>\"Left\"</button>\n    <button>\"Right\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ButtonGroup>\n    <Button>\"Left\"</Button>\n    <Button>\"Right\"</Button>\n  </ButtonGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "toolbar actions",
      "segmented controls"
    ],
    "related": [
      "button",
      "icon_button",
      "copy_button",
      "link"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "action",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ButtonGroup Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::ToggleState;\n\n#[component]\npub fn ButtonGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ToggleState::Off)] attached: ToggleState,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    let uid_bg = crate::infra::uid::generate(\"bg\");\n    view! {\n        <div\n            data-rs-button-group=\"\"\n            data-rs-uid=uid_bg\n            data-rs-toggle=attached.as_str()\n            role=\"group\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::ToggleState;\nuse canonrs_core::primitives::{ButtonGroupPrimitive, ButtonPrimitive, ButtonVariant as CoreVariant};\n\n#[component]\npub fn ButtonGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ToggleState::Off)] attached: ToggleState,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <ButtonGroupPrimitive class=class attached=attached aria_label=aria_label.unwrap_or_default()>\n            {children()}\n        </ButtonGroupPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! ButtonGroup Island — Canon Rule passthrough\nuse leptos::prelude::*;\npub use canonrs_core::ToggleState;\n\n\n#[component]\npub fn ButtonGroup(\n    children: Children,\n    #[prop(default = ToggleState::Off)] attached: ToggleState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <super::button_group_ui::ButtonGroup class=class attached=attached aria_label=aria_label.unwrap_or_default()>\n            {children()}\n        </super::button_group_ui::ButtonGroup>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const BUTTONGROUP_API: ComponentApi = ComponentApi {\n    id: \"button-group\",\n    description: \"Group of action buttons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"attached\", kind: PropType::String, required: false, default: Some(\"off\"), description: \"Whether buttons are visually attached\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::button_group_boundary::{ButtonGroup, ToggleState};\nuse canonrs_core::primitives::{ButtonVariant, ButtonSize, ButtonStateHint};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse crate::ui::button::button_boundary::Button;\n\n#[component]\npub fn ButtonGroupShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <ButtonGroup attached=ToggleState::On aria_label=\"Actions\">\n                <Button variant=ButtonVariant::Secondary size=ButtonSize::Md>\"Left\"</Button>\n                <Button variant=ButtonVariant::Secondary size=ButtonSize::Md>\"Center\"</Button>\n                <Button variant=ButtonVariant::Secondary size=ButtonSize::Md>\"Right\"</Button>\n            </ButtonGroup>\n            <p data-rs-showcase-preview-anchor=\"\">\"Grouped actions. One contract.\"</p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Detached\"</span>\n                <ButtonGroup>\n                    <Button variant=ButtonVariant::Secondary>\"A\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"B\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"C\"</Button>\n                </ButtonGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Attached\"</span>\n                <ButtonGroup attached=ToggleState::On>\n                    <Button variant=ButtonVariant::Primary>\"Save\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"Cancel\"</Button>\n                </ButtonGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"First/last radius\"</span>\n                <ButtonGroup attached=ToggleState::On aria_label=\"First last demo\">\n                    <Button variant=ButtonVariant::Secondary state_hint=ButtonStateHint::First>\"First\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"Middle\"</Button>\n                    <Button variant=ButtonVariant::Secondary state_hint=ButtonStateHint::Last>\"Last\"</Button>\n                </ButtonGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Hover z-index\"</span>\n                <ButtonGroup attached=ToggleState::On aria_label=\"Hover z-index demo\">\n                    <Button variant=ButtonVariant::Secondary>\"One\"</Button>\n                    <Button variant=ButtonVariant::Secondary state_hint=ButtonStateHint::Hover>\"Hover\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"Three\"</Button>\n                </ButtonGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Focus z-index\"</span>\n                <ButtonGroup attached=ToggleState::On aria_label=\"Focus z-index demo\">\n                    <Button variant=ButtonVariant::Secondary>\"One\"</Button>\n                    <Button variant=ButtonVariant::Secondary state_hint=ButtonStateHint::Focus>\"Focus\"</Button>\n                    <Button variant=ButtonVariant::Secondary>\"Three\"</Button>\n                </ButtonGroup>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "callout",
    "label": "Callout",
    "category": "Feedback",
    "description": "Callout info box",
    "keywords": "",
    "pain": "Callouts use inconsistent roles and lack semantic intent",
    "promise": "Semantic role and urgency enforced via variant",
    "why": "CalloutVariant determines role and aria-live behavior. The primitive encodes these semantics directly into the DOM. This guarantees consistent accessibility and meaning across all callouts.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"callout warning\">\"Be careful\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Callout variant=CalloutVariant::Warning>\n    <CalloutTitle>\"Warning\"</CalloutTitle>\n    <CalloutDescription>\"Be careful\"</CalloutDescription>\n  </Callout>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "tips",
      "warnings"
    ],
    "related": [
      "toast",
      "alert",
      "banner",
      "inline_notice",
      "status_dot"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Callout Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum CalloutVariant {\n    #[default]\n    Default,\n    Info,\n    Success,\n    Warning,\n    Error,\n}\n\nimpl CalloutVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Info    => \"info\",\n            Self::Success => \"success\",\n            Self::Warning => \"warning\",\n            Self::Error   => \"error\",\n        }\n    }\n\n    pub fn role(&self) -> &'static str {\n        match self {\n            Self::Error => \"alert\",\n            _           => \"note\",\n        }\n    }\n\n    pub fn aria_live(&self) -> &'static str {\n        match self {\n            Self::Error => \"assertive\",\n            _           => \"polite\",\n        }\n    }\n}\n\n#[component]\npub fn CalloutPrimitive(\n    children: Children,\n    #[prop(default = CalloutVariant::Default)] variant: CalloutVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_clt = crate::infra::uid::generate(\"clt\");\n    view! {\n        <aside\n            data-rs-callout=\"\"\n            data-rs-uid=uid_clt\n            data-rs-variant=variant.as_str()\n            role=variant.role()\n            aria-live=variant.aria_live()\n            aria-atomic=\"true\"\n            class=class\n        >\n            {children()}\n        </aside>\n    }\n}\n\n#[component]\npub fn CalloutIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-callout-icon=\"\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CalloutTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-callout-title=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CalloutDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-callout-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    CalloutPrimitive, CalloutIconPrimitive,\n    CalloutTitlePrimitive, CalloutDescriptionPrimitive,\n};\npub use canonrs_core::primitives::CalloutVariant;\n\n#[component]\npub fn Callout(\n    children: Children,\n    #[prop(default = CalloutVariant::Default)] variant: CalloutVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CalloutPrimitive variant=variant class=class>\n            {children()}\n        </CalloutPrimitive>\n    }\n}\n\n#[component]\npub fn CalloutIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CalloutIconPrimitive class=class>\n            {children()}\n        </CalloutIconPrimitive>\n    }\n}\n\n#[component]\npub fn CalloutTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CalloutTitlePrimitive class=class>\n            {children()}\n        </CalloutTitlePrimitive>\n    }\n}\n\n#[component]\npub fn CalloutDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CalloutDescriptionPrimitive class=class>\n            {children()}\n        </CalloutDescriptionPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Callout Boundary — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::callout_ui::{Callout as CalloutUi, CalloutIcon, CalloutTitle, CalloutDescription};\npub use canonrs_core::primitives::CalloutVariant;\n\n#[component]\npub fn Callout(\n    #[prop(optional, into)] title:       Option<String>,\n    #[prop(optional, into)] description: Option<String>,\n    #[prop(optional, into)] icon:        Option<String>,\n    #[prop(default = CalloutVariant::Default)] variant: CalloutVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CalloutUi variant=variant class=class>\n            {icon.map(|i| view! { <CalloutIcon>{i}</CalloutIcon> })}\n            {title.map(|t| view! { <CalloutTitle>{t}</CalloutTitle> })}\n            {description.map(|d| view! { <CalloutDescription>{d}</CalloutDescription> })}\n        </CalloutUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{CalloutVariant}; \n\npub const CALLOUT_API: ComponentApi = ComponentApi {\n    id: \"callout\",\n    description: \"Callout info box\",\n    props: &[\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"icon\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"info\", \"success\", \"warning\", \"error\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::callout_boundary::{Callout, CalloutVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CalloutShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Callout variant=CalloutVariant::Info title=\"Information\" description=\"New features are available in the latest release.\" />\n            <p data-rs-showcase-preview-anchor=\"\">\"Semantic role and urgency enforced via variant.\"</p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <Callout variant=CalloutVariant::Success icon=\"✓\" title=\"Success\"  description=\"Your changes have been deployed.\" />\n                    <Callout variant=CalloutVariant::Warning icon=\"⚠\" title=\"Warning\"  description=\"This action cannot be undone.\" />\n                    <Callout variant=CalloutVariant::Warning icon=\"✕\" title=\"Error\"    description=\"Build failed due to type errors.\" />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "card",
    "label": "Card",
    "category": "Display",
    "description": "Card component",
    "keywords": "",
    "pain": "Content containers lack consistent structure and semantic regions",
    "promise": "Card structure enforced with defined regions and roles",
    "why": "CardPrimitive enforces a semantic region with structured subcomponents like header and content. This guarantees consistent layout composition. The contract prevents ad-hoc container misuse.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"card\">\n    <h3>\"Title\"</h3>\n    <p>\"Content\"</p>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Card>\n    <CardHeader>\n      <CardTitle>\"Title\"</CardTitle>\n    </CardHeader>\n    <CardContent>\"Content\"</CardContent>\n  </Card>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "dashboards",
      "content grouping"
    ],
    "related": [
      "resizable",
      "scroll_area",
      "aspect_ratio",
      "page_header",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Card Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum CardVariant {\n    #[default]\n    Default,\n    Outlined,\n    Elevated,\n    Ghost,\n}\nimpl CardVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default  => \"default\",\n            Self::Outlined => \"outlined\",\n            Self::Elevated => \"elevated\",\n            Self::Ghost    => \"ghost\",\n        }\n    }\n}\n\n#[component]\npub fn CardPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = CardVariant::Default)] variant: CardVariant,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    let uid_crd = crate::infra::uid::generate(\"crd\");\n    view! {\n        <div\n            data-rs-card=\"\"\n            data-rs-uid=uid_crd\n            data-rs-variant=variant.as_str()\n            role=\"region\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CardHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-card-header=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CardTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h3 data-rs-card-title=\"\" class=class>\n            {children()}\n        </h3>\n    }\n}\n\n#[component]\npub fn CardDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p data-rs-card-description=\"\" class=class>\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn CardContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-card-content=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CardFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-card-footer=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    CardPrimitive, CardVariant,\n    CardHeaderPrimitive,\n    CardTitlePrimitive,\n    CardDescriptionPrimitive,\n    CardContentPrimitive,\n    CardFooterPrimitive,\n};\n\n#[component]\npub fn Card(\n    children: Children,\n    #[prop(into, default = String::new())] variant: String,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    let base_class = format!(\"card {}\", class);\n\n    view! {\n        <CardPrimitive\n            variant=match variant.as_str() {\n                \"outlined\" => CardVariant::Outlined,\n                \"elevated\" => CardVariant::Elevated,\n                \"ghost\"    => CardVariant::Ghost,\n                _          => CardVariant::Default,\n            }\n            class={base_class}\n        >\n            {children()}\n        </CardPrimitive>\n    }\n}\n\n#[component]\npub fn CardHeader(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CardHeaderPrimitive\n            class={class}\n        >\n            {children()}\n        </CardHeaderPrimitive>\n    }\n}\n\n#[component]\npub fn CardTitle(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CardTitlePrimitive\n            class={class}\n        >\n            {children()}\n        </CardTitlePrimitive>\n    }\n}\n\n#[component]\npub fn CardDescription(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CardDescriptionPrimitive\n            class={class}\n        >\n            {children()}\n        </CardDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn CardContent(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CardContentPrimitive\n            class={class}\n        >\n            {children()}\n        </CardContentPrimitive>\n    }\n}\n\n#[component]\npub fn CardFooter(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CardFooterPrimitive\n            class={class}\n        >\n            {children()}\n        </CardFooterPrimitive>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::card_ui::{\n    Card as CardUi,\n    CardHeader as CardHeaderUi,\n    CardTitle as CardTitleUi,\n    CardDescription as CardDescriptionUi,\n    CardContent as CardContentUi,\n    CardFooter as CardFooterUi,\n};\n\n#[component]\npub fn Card(\n    children: Children,\n    #[prop(into, default = String::new())] variant: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardUi variant=variant class=class>{children()}</CardUi> }\n}\n\n#[component]\npub fn CardHeader(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardHeaderUi class=class>{children()}</CardHeaderUi> }\n}\n\n#[component]\npub fn CardTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardTitleUi class=class>{children()}</CardTitleUi> }\n}\n\n#[component]\npub fn CardDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardDescriptionUi class=class>{children()}</CardDescriptionUi> }\n}\n\n#[component]\npub fn CardContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardContentUi class=class>{children()}</CardContentUi> }\n}\n\n#[component]\npub fn CardFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CardFooterUi class=class>{children()}</CardFooterUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const CARD_API: ComponentApi = ComponentApi {\n    id: \"card\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CARDHEADER_API: ComponentApi = ComponentApi {\n    id: \"card-header\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CARDTITLE_API: ComponentApi = ComponentApi {\n    id: \"card-title\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CARDDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"card-description\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CARDCONTENT_API: ComponentApi = ComponentApi {\n    id: \"card-content\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CARDFOOTER_API: ComponentApi = ComponentApi {\n    id: \"card-footer\",\n    description: \"Card component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse canonrs_core::slot;\nuse crate::blocks::card::{CardBlock, CardVariant};\nuse super::card_boundary::{CardHeader, CardTitle, CardDescription, CardContent, CardFooter};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CardShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <CardBlock\n                header=slot!(|| view! {\n                    <CardHeader>\n                        <CardTitle>\"Getting Started\"</CardTitle>\n                        <CardDescription>\"Everything you need to build with CanonRS.\"</CardDescription>\n                    </CardHeader>\n                }.into_any())\n                content=slot!(|| view! {\n                    <CardContent><p>\"Card structure enforced with defined regions and roles.\"</p></CardContent>\n                }.into_any())\n                footer=slot!(|| view! {\n                    <CardFooter><span>\"Last updated: today\"</span></CardFooter>\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Card structure enforced with defined regions and roles.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Md>\n                    <CardBlock\n                        header=slot!(|| view! {\n                            <CardHeader><CardTitle>\"Header only\"</CardTitle></CardHeader>\n                        }.into_any())\n                    />\n                    <CardBlock\n                        content=slot!(|| view! {\n                            <CardContent><p>\"Content only — no header or footer.\"</p></CardContent>\n                        }.into_any())\n                    />\n                    <CardBlock\n                        variant=CardVariant::Outlined\n                        header=slot!(|| view! {\n                            <CardHeader>\n                                <CardTitle>\"Full card\"</CardTitle>\n                                <CardDescription>\"With all three regions.\"</CardDescription>\n                            </CardHeader>\n                        }.into_any())\n                        content=slot!(|| view! {\n                            <CardContent><p>\"Body content goes here.\"</p></CardContent>\n                        }.into_any())\n                        footer=slot!(|| view! {\n                            <CardFooter><span>\"Footer action\"</span></CardFooter>\n                        }.into_any())\n                    />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "card_block"
    ],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "carousel",
    "label": "Carousel",
    "category": "Display",
    "description": "Image carousel slider",
    "keywords": "",
    "pain": "Carousels break accessibility and state synchronization across slides",
    "promise": "Slide state and navigation semantics enforced via structured primitives",
    "why": "CarouselPrimitive defines roles and slide semantics including aria labels and state. ActivityState and VisibilityState control active and hidden slides. This ensures accessibility and predictable slideshow behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"carousel\">\n    <div class=\"slide active\">\"Slide 1\"</div>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Carousel>\n    <CarouselTrack>\n      <CarouselItem>\"Slide 1\"</CarouselItem>\n    </CarouselTrack>\n  </Carousel>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "image galleries",
      "feature sliders"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Carousel Primitive - Interactive slideshow\n\nuse leptos::prelude::*;\nuse crate::meta::{ActivityState, DisabledState, VisibilityState};\n\n#[component]\npub fn CarouselPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"cr\");\n    view! {\n        <div\n            data-rs-carousel=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"gesture\"\n            role=\"region\"\n            aria-roledescription=\"carousel\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CarouselTrackPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-carousel-track=\"\"\n            role=\"group\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CarouselItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ActivityState::Inactive)] activity: ActivityState,\n    #[prop(default = VisibilityState::Closed)] visibility: VisibilityState,\n    #[prop(optional, into)] aria_label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-carousel-item=\"\"\n            data-rs-activity=activity.as_str()\n            role=\"group\"\n            aria-roledescription=\"slide\"\n            aria-label=aria_label\n            aria-hidden=visibility.aria_hidden()\n            hidden=visibility.hidden()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CarouselPrevPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-carousel-prev=\"\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            disabled=disabled.disabled()\n            aria-disabled=disabled.aria_disabled()\n            aria-label=\"Previous slide\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn CarouselNextPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-carousel-next=\"\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            disabled=disabled.disabled()\n            aria-disabled=disabled.aria_disabled()\n            aria-label=\"Next slide\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn CarouselIndicatorsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-carousel-indicators=\"\"\n            role=\"group\"\n            aria-label=\"Slide indicators\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CarouselDotPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-carousel-dot=\"\"\n            data-rs-activity=state.as_str()\n            aria-label=aria_label\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn CarouselContentPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] children: Option<Children>,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"cc\");\n    view! {\n        <div\n            data-rs-carousel-content=\"\"\n            data-rs-uid=uid\n            class=class\n        >\n            {children.map(|c| c())}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::ToggleState;\nuse canonrs_core::meta::ActivityState;\nuse canonrs_core::primitives::{\n    CarouselPrimitive, CarouselTrackPrimitive, CarouselItemPrimitive,\n    CarouselPrevPrimitive, CarouselNextPrimitive, CarouselIndicatorsPrimitive, CarouselDotPrimitive,\n};\n\n#[component]\npub fn Carousel(children: Children, #[prop(default = 0)] initial_index: usize, #[prop(default = ToggleState::Off)] autoplay: ToggleState, #[prop(default = 5000)] interval: u32, #[prop(default = ToggleState::On)] loop_state: ToggleState, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <CarouselPrimitive class=class>\n            <CarouselTrackPrimitive>\n                {children()}\n            </CarouselTrackPrimitive>\n        </CarouselPrimitive>\n    }\n}\n#[component]\npub fn CarouselTrack(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <CarouselTrackPrimitive class=class>{children()}</CarouselTrackPrimitive> }\n}\n#[component]\npub fn CarouselItem(children: Children, #[prop(into, default = String::new())] class: String, #[prop(default = false)] active: bool) -> impl IntoView {\n    use canonrs_core::meta::VisibilityState;\n    let activity = if active { ActivityState::Active } else { ActivityState::Inactive };\n    let visibility = if active { VisibilityState::Open } else { VisibilityState::Closed };\n    view! { <CarouselItemPrimitive class=class activity=activity visibility=visibility>{children()}</CarouselItemPrimitive> }\n}\n#[component]\npub fn CarouselPrev(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <CarouselPrevPrimitive class=class>{children()}</CarouselPrevPrimitive> }\n}\n#[component]\npub fn CarouselNext(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <CarouselNextPrimitive class=class>{children()}</CarouselNextPrimitive> }\n}\n#[component]\npub fn CarouselIndicators(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <CarouselIndicatorsPrimitive class=class>{children()}</CarouselIndicatorsPrimitive> }\n}\n#[component]\npub fn CarouselDot(#[prop(into, default = String::new())] class: String, #[prop(into, default = String::new())] aria_label: String, #[prop(default = false)] active: bool) -> impl IntoView {\n    let state = if active { ActivityState::Active } else { ActivityState::Inactive };\n    view! { <CarouselDotPrimitive class=class aria_label=aria_label state=state /> }\n}\n",
    "boundary_src": "//! Carousel Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::carousel_ui::{\n    Carousel as CarouselUi,\n    CarouselTrack as CarouselTrackUi,\n    CarouselItem as CarouselItemUi,\n    CarouselPrev as CarouselPrevUi,\n    CarouselNext as CarouselNextUi,\n    CarouselIndicators as CarouselIndicatorsUi,\n    CarouselDot as CarouselDotUi\n};\nuse canonrs_core::ToggleState;\n\n#[component]\npub fn Carousel(\n    children: Children,\n    #[prop(default = 0)] initial_index: usize,\n    #[prop(default = ToggleState::Off)] autoplay: ToggleState,\n    #[prop(default = 5000)] interval: u32,\n    #[prop(default = ToggleState::On)] loop_state: ToggleState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CarouselUi initial_index=initial_index autoplay=autoplay interval=interval loop_state=loop_state class=class>\n            {children()}\n        </CarouselUi>\n    }\n}\n\n#[component]\npub fn CarouselTrack(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CarouselTrackUi class=class>{children()}</CarouselTrackUi> }\n}\n\n#[component]\npub fn CarouselItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] active: bool,\n) -> impl IntoView {\n    view! { <CarouselItemUi class=class active=active>{children()}</CarouselItemUi> }\n}\n\n#[component]\npub fn CarouselPrev(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CarouselPrevUi class=class>{children()}</CarouselPrevUi> }\n}\n\n#[component]\npub fn CarouselNext(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CarouselNextUi class=class>{children()}</CarouselNextUi> }\n}\n\n#[component]\npub fn CarouselIndicators(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CarouselIndicatorsUi class=class>{children()}</CarouselIndicatorsUi> }\n}\n\n#[component]\npub fn CarouselDot(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(default = false)] active: bool,\n) -> impl IntoView {\n    view! { <CarouselDotUi class=class aria_label=aria_label active=active /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const CAROUSEL_API: ComponentApi = ComponentApi {\n    id: \"carousel\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"initial_index\", kind: PropType::Number, required: false, default: Some(\"0\"), description: \"Prop value\" },\n        PropDef { name: \"autoplay\", kind: PropType::String, required: false, default: Some(\"off\"), description: \"Prop value\" },\n        PropDef { name: \"interval\", kind: PropType::Number, required: false, default: Some(\"5000\"), description: \"Prop value\" },\n        PropDef { name: \"loop_state\", kind: PropType::String, required: false, default: Some(\"on\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CAROUSELTRACK_API: ComponentApi = ComponentApi {\n    id: \"carousel-track\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CAROUSELITEM_API: ComponentApi = ComponentApi {\n    id: \"carousel-item\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"active\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Active/selected state\" },\n    ],\n};\n\npub const CAROUSELPREV_API: ComponentApi = ComponentApi {\n    id: \"carousel-prev\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CAROUSELNEXT_API: ComponentApi = ComponentApi {\n    id: \"carousel-next\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CAROUSELINDICATORS_API: ComponentApi = ComponentApi {\n    id: \"carousel-indicators\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CAROUSELDOT_API: ComponentApi = ComponentApi {\n    id: \"carousel-dot\",\n    description: \"Image carousel slider\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"active\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Active/selected state\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::carousel_boundary::{\n    Carousel, CarouselTrack, CarouselItem,\n    CarouselPrev, CarouselNext, CarouselIndicators, CarouselDot\n};\nuse canonrs_core::ToggleState;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CarouselShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Carousel>\n                <CarouselTrack>\n                    <CarouselItem active=true>\n                        <img src=\"/assets/canonrs-image1.webp\" alt=\"Slide 1\" style=\"width:100%;height:auto;display:block;\" />\n                    </CarouselItem>\n                    <CarouselItem>\n                        <img src=\"/assets/canonrs-image2.webp\" alt=\"Slide 2\" style=\"width:100%;height:auto;display:block;\" />\n                    </CarouselItem>\n                    <CarouselItem>\n                        <img src=\"/assets/canonrs-image3.webp\" alt=\"Slide 3\" style=\"width:100%;height:auto;display:block;\" />\n                    </CarouselItem>\n                </CarouselTrack>\n                <CarouselPrev>\"←\"</CarouselPrev>\n                <CarouselNext>\"→\"</CarouselNext>\n                <CarouselIndicators>\n                    <CarouselDot active=true aria_label=\"Slide 1\" />\n                    <CarouselDot aria_label=\"Slide 2\" />\n                    <CarouselDot aria_label=\"Slide 3\" />\n                </CarouselIndicators>\n            </Carousel>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Sequential navigation with optional autoplay and loop.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Autoplay\"</span>\n                <Carousel autoplay=ToggleState::On interval=3000u32>\n                    <CarouselTrack>\n                        <CarouselItem active=true>\n                            <img src=\"/assets/canonrs-image1.webp\" alt=\"Slide 1\" style=\"width:100%;height:auto;display:block;\" />\n                        </CarouselItem>\n                        <CarouselItem>\n                            <img src=\"/assets/canonrs-image2.webp\" alt=\"Slide 2\" style=\"width:100%;height:auto;display:block;\" />\n                        </CarouselItem>\n                        <CarouselItem>\n                            <img src=\"/assets/canonrs-image3.webp\" alt=\"Slide 3\" style=\"width:100%;height:auto;display:block;\" />\n                        </CarouselItem>\n                    </CarouselTrack>\n                    <CarouselPrev>\"←\"</CarouselPrev>\n                    <CarouselNext>\"→\"</CarouselNext>\n                    <CarouselIndicators>\n                        <CarouselDot active=true aria_label=\"Slide 1\" />\n                        <CarouselDot aria_label=\"Slide 2\" />\n                        <CarouselDot aria_label=\"Slide 3\" />\n                    </CarouselIndicators>\n                </Carousel>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "chart",
    "label": "Chart",
    "category": "Display",
    "description": "Data chart visualization",
    "keywords": "",
    "pain": "Charts mix rendering logic and data, causing inconsistent behavior",
    "promise": "Chart structure and data binding enforced via contract",
    "why": "ChartPrimitive separates rendering (canvas) from data (data-rs attributes). ChartType enforces visualization type at compile-time. This guarantees consistent rendering and interaction patterns.\n",
    "before": "// ❌ Typical\nview! {\n  <canvas id=\"chart\"></canvas>\n  <script>renderChart(data)</script>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Chart data=data chart_type=ChartType::Line />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "analytics dashboards",
      "data visualization"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Chart Primitive - Canvas + overlay enterprise architecture\n\nuse leptos::prelude::*;\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ChartGridState {\n    #[default] Visible,\n    Hidden,\n}\nimpl ChartGridState {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Visible => \"visible\", Self::Hidden => \"hidden\" }\n    }\n}\nimpl From<bool> for ChartGridState {\n    fn from(b: bool) -> Self { if b { Self::Visible } else { Self::Hidden } }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ChartLegendState {\n    #[default] Visible,\n    Hidden,\n}\nimpl ChartLegendState {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Visible => \"visible\", Self::Hidden => \"hidden\" }\n    }\n}\nimpl From<bool> for ChartLegendState {\n    fn from(b: bool) -> Self { if b { Self::Visible } else { Self::Hidden } }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ChartType {\n    #[default]\n    Bar, Line, Area, Pie, Donut, Scatter, Radar,\n}\nimpl ChartType {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Bar     => \"bar\",\n            Self::Line    => \"line\",\n            Self::Area    => \"area\",\n            Self::Pie     => \"pie\",\n            Self::Donut   => \"donut\",\n            Self::Scatter => \"scatter\",\n            Self::Radar   => \"radar\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ChartAnimation {\n    #[default]\n    Auto,\n    None,\n}\nimpl ChartAnimation {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Auto => \"auto\",\n            Self::None => \"none\",\n        }\n    }\n}\n\n#[component]\npub fn ChartPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ChartType::Bar)] chart_type: ChartType,\n    #[prop(into, default = \"320\".to_string())] height: String,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = ChartGridState::Visible)] chart_grid: ChartGridState,\n    #[prop(default = ChartLegendState::Visible)] chart_legend: ChartLegendState,\n    #[prop(default = ChartAnimation::Auto)] animation: ChartAnimation,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"ch\");\n    view! {\n        <div\n            data-rs-chart=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"data\"\n            data-rs-chart-type=chart_type.as_str()\n            data-rs-chart-height=height\n            data-rs-animation=animation.as_str()\n            data-rs-value=value\n            role=\"img\"\n            aria-label=aria_label\n            class=class\n        >\n            <canvas data-rs-chart-canvas=\"\" aria-hidden=\"true\" />\n            <div data-rs-chart-overlay=\"\" aria-hidden=\"true\">\n                <div data-rs-chart-tooltip=\"\" />\n                <div data-rs-chart-crosshair=\"\" />\n            </div>\n            <div data-rs-chart-legend=\"\" data-rs-state=chart_legend.as_str() />\n            <div data-rs-chart-grid=\"\" data-rs-state=chart_grid.as_str() />\n            {children()}\n        </div>\n    }\n}\n\n/// ChartDataPrimitive — injeta dados via data attribute\n/// O runtime lê data-rs-chart-data para renderizar o gráfico\n#[component]\npub fn ChartDataPrimitive(\n    #[prop(into, default = String::new())] data: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-chart-data=data\n            aria-hidden=\"true\"\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{ChartPrimitive, ChartDataPrimitive, ChartType, ChartAnimation};\nuse canonrs_core::{ChartGridState, ChartLegendState};\npub use canonrs_core::primitives::ChartType as ChartKind;\npub use canonrs_core::{ChartData, ChartSeries};\n\n#[component]\npub fn Chart(\n    data: ChartData,\n    #[prop(default = ChartType::Line)] chart_type: ChartType,\n    #[prop(into, default = \"320\".to_string())] height: String,\n    #[prop(default = true)] show_grid: bool,\n    #[prop(default = true)] show_legend: bool,\n    #[prop(default = true)] _show_tooltip: bool,\n    #[prop(default = true)] animate: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] _max_width: Option<u32>,\n    #[prop(into, default = String::new())] _sync_table: String,\n    #[prop(into, default = String::new())] _sync_scope: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n) -> impl IntoView {\n    let json = data.to_json();\n    let animation = if animate { ChartAnimation::Auto } else { ChartAnimation::None };\n    view! {\n        <ChartPrimitive\n            class=class\n            chart_type=chart_type\n            height=height\n            value=value\n            aria_label=aria_label.unwrap_or_default()\n            chart_grid=ChartGridState::from(show_grid)\n            chart_legend=ChartLegendState::from(show_legend)\n            animation=animation\n        >\n            <ChartDataPrimitive data=json />\n        </ChartPrimitive>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::chart_ui::Chart as ChartUi;\npub use canonrs_core::primitives::ChartType;\nuse canonrs_core::ChartData;\n\n#[component]\npub fn Chart(\n    data: ChartData,\n    #[prop(default = ChartType::Line)] chart_type: ChartType,\n    #[prop(into, default = \"320\".to_string())] height: String,\n    #[prop(default = true)] show_grid: bool,\n    #[prop(default = true)] show_legend: bool,\n    #[prop(default = true)] animate: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] aria_label: String,\n) -> impl IntoView {\n    view! {\n        <ChartUi\n            data=data\n            chart_type=chart_type\n            height=height\n            show_grid=show_grid\n            show_legend=show_legend\n            animate=animate\n            class=class\n            value=value\n            aria_label=aria_label\n        />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ChartType}; \n\npub const CHART_API: ComponentApi = ComponentApi {\n    id: \"chart\",\n    description: \"Data chart visualization\",\n    props: &[\n        PropDef { name: \"data\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"chart_type\", kind: PropType::Enum(&[\"bar\", \"line\", \"area\", \"pie\", \"donut\", \"scatter\", \"radar\"]), required: false, default: Some(\"line\"), description: \"Prop value\" },\n        PropDef { name: \"height\", kind: PropType::String, required: false, default: Some(\"320\"), description: \"Prop value\" },\n        PropDef { name: \"show_grid\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"show_legend\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"animate\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::chart_boundary::{Chart, ChartType};\nuse canonrs_core::{ChartData, ChartSeries};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\nfn monthly_data() -> ChartData {\n    ChartData {\n        labels: vec![\"Jan\".to_string(), \"Feb\".to_string(), \"Mar\".to_string(),\n                     \"Apr\".to_string(), \"May\".to_string(), \"Jun\".to_string()],\n        series: vec![\n            ChartSeries { name: \"Revenue\".to_string(),  data: vec![42.0, 58.0, 51.0, 73.0, 65.0, 89.0], color: None },\n            ChartSeries { name: \"Expenses\".to_string(), data: vec![31.0, 40.0, 38.0, 52.0, 47.0, 61.0], color: None },\n        ],\n    }\n}\n\nfn bar_data() -> ChartData {\n    ChartData {\n        labels: vec![\"Q1\".to_string(), \"Q2\".to_string(), \"Q3\".to_string(), \"Q4\".to_string()],\n        series: vec![\n            ChartSeries { name: \"Growth\".to_string(), data: vec![24.0, 38.0, 55.0, 72.0], color: None },\n        ],\n    }\n}\n\nfn area_data() -> ChartData {\n    ChartData {\n        labels: vec![\"Mon\".to_string(), \"Tue\".to_string(), \"Wed\".to_string(), \"Thu\".to_string(), \"Fri\".to_string()],\n        series: vec![\n            ChartSeries { name: \"Users\".to_string(), data: vec![120.0, 145.0, 132.0, 178.0, 195.0], color: None },\n        ],\n    }\n}\n\n#[component]\npub fn ChartShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Chart data=monthly_data() chart_type=ChartType::Line height=\"280\".to_string()\n                value=\"revenue-monthly\" aria_label=\"Monthly revenue and expenses line chart\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Chart structure and data binding enforced via contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Bar\"</span>\n                <Chart data=bar_data() chart_type=ChartType::Bar height=\"200\".to_string()\n                    value=\"growth-quarterly\" aria_label=\"Quarterly growth bar chart\" />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Area\"</span>\n                <Chart data=area_data() chart_type=ChartType::Area height=\"200\".to_string()\n                    value=\"users-weekly\" aria_label=\"Weekly active users area chart\" />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "checkbox",
    "label": "Checkbox",
    "category": "Form",
    "description": "Checkbox input",
    "keywords": "",
    "pain": "Checkbox state desyncs between UI and internal state",
    "promise": "Selection state (checked/unchecked/indeterminate) drives visual and aria-checked contract",
    "why": "CheckboxPrimitive maps ActivityState to checked and ARIA attributes. This ensures UI and accessibility stay in sync. The contract prevents mismatched boolean and DOM state.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"checkbox\" checked=state />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Checkbox checked=true>\"Remember me\"</Checkbox>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "multi-selection"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "input_otp",
      "textarea",
      "field",
      "label",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Checkbox Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Default, Debug)]\npub enum CheckboxState {\n    #[default]\n    Unchecked,\n    Checked,\n    Indeterminate,\n}\n\nimpl CheckboxState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Unchecked     => \"unchecked\",\n            Self::Checked       => \"checked\",\n            Self::Indeterminate => \"indeterminate\",\n        }\n    }\n    pub fn aria_checked(&self) -> &'static str {\n        match self {\n            Self::Unchecked     => \"false\",\n            Self::Checked       => \"true\",\n            Self::Indeterminate => \"mixed\",\n        }\n    }\n    pub fn is_checked(&self) -> bool {\n        matches!(self, Self::Checked)\n    }\n}\n\n#[component]\npub fn CheckboxPrimitive(\n    children: Children,\n    #[prop(default = CheckboxState::Unchecked)] checked: CheckboxState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_cb = crate::infra::uid::generate(\"cb\");\n    view! {\n        <label\n            data-rs-checkbox=\"\"\n            data-rs-uid=uid_cb\n            data-rs-interaction=\"init\"\n            data-rs-selection=checked.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            <input\n                type=\"checkbox\"\n                data-rs-checkbox-input=\"\"\n                checked=checked.is_checked()\n                disabled=disabled.disabled()\n                aria-checked=checked.aria_checked()\n                name={if name.is_empty() { None } else { Some(name) }}\n            />\n            {children()}\n        </label>\n    }\n}\n\n#[component]\npub fn CheckboxIndicatorPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-checkbox-indicator=\"\" aria-hidden=\"true\" class=class>\n            {children()}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{CheckboxPrimitive, CheckboxIndicatorPrimitive};\nuse canonrs_core::primitives::CheckboxState;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Checkbox(\n    children: Children,\n    #[prop(default = CheckboxState::Unchecked)] checked: CheckboxState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CheckboxPrimitive checked=checked disabled=disabled name=name class=class>\n            <CheckboxIndicatorPrimitive>\"✓\"</CheckboxIndicatorPrimitive>\n            {children()}\n        </CheckboxPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Checkbox Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::checkbox_ui::Checkbox as CheckboxUi;\npub use canonrs_core::primitives::CheckboxState;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Checkbox(\n    children: Children,\n    #[prop(default = false)] checked: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let checked_state = if checked { CheckboxState::Checked } else { CheckboxState::Unchecked };\n    let disabled_state = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    view! {\n        <CheckboxUi checked=checked_state disabled=disabled_state name=name class=class>\n            {children()}\n        </CheckboxUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{CheckboxState}; \n\npub const CHECKBOX_API: ComponentApi = ComponentApi {\n    id: \"checkbox\",\n    description: \"Checkbox input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"checked\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is checked\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::checkbox_boundary::Checkbox;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CheckboxShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Checkbox checked=true>\n                <span>\"Remember me\"</span>\n            </Checkbox>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Checked state mapped explicitly to activity state.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Checkbox><span>\"Unchecked\"</span></Checkbox>\n                    <Checkbox checked=true><span>\"Checked\"</span></Checkbox>\n                    <Checkbox disabled=true><span>\"Disabled\"</span></Checkbox>\n                    <Checkbox checked=true disabled=true><span>\"Checked + Disabled\"</span></Checkbox>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "code_block",
    "label": "Code Block",
    "category": "Display",
    "description": "Syntax-highlighted code display",
    "keywords": "",
    "pain": "Code blocks rely on client-side highlighting causing hydration mismatch",
    "promise": "SSR-safe syntax highlighting with deterministic DOM output",
    "why": "CodeBlockPrimitive supports SSR-safe rendering with precomputed HTML. The contract ensures no client mutation is required. This prevents hydration mismatch and ensures consistent output.\n",
    "before": "// ❌ Typical\nview! {\n  <pre><code>{highlight(code)}</code></pre>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <CodeBlock code=\"fn main() {}\" language=\"rust\" />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "docs",
      "code snippets"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! CodeBlock Primitive - HTML puro, SSR-safe\n\nuse leptos::prelude::*;\nuse crate::meta::ToggleState;\n\n#[component]\npub fn CodeBlockPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] language: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_cob = crate::infra::uid::generate(\"cob\");\n    view! {\n        <div\n            data-rs-code-block=\"\"\n            data-rs-uid=uid_cob\n            data-rs-interaction=\"content\"\n            data-rs-language=language\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CodeBlockHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-code-header=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CodeBlockLanguagePrimitive(\n    #[prop(into)] language: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-code-language=\"\" class=class>\n            {language}\n        </span>\n    }\n}\n\n#[component]\npub fn CodeBlockFilenamePrimitive(\n    #[prop(into)] filename: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-code-filename=\"\" class=class>\n            {filename}\n        </span>\n    }\n}\n\n#[component]\npub fn CodeBlockCopyButtonPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ToggleState::Off)] copied: ToggleState,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-code-copy-btn=\"\"\n            data-rs-toggle=copied.as_str()\n            aria-pressed=copied.aria_pressed()\n            aria-label=\"Copy code\"\n            class=class\n        >\n            <span data-rs-code-copy-label=\"\">\"Copy\"</span>\n        </button>\n    }\n}\n\n#[component]\npub fn CodeBlockPrePrimitive(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] inner_html: String,\n) -> impl IntoView {\n    if inner_html.is_empty() {\n        view! {\n            <pre data-rs-code-pre=\"\" class=class>\n                {children.map(|c| c())}\n            </pre>\n        }.into_any()\n    } else {\n        view! {\n            <pre data-rs-code-pre=\"\" class=class inner_html=inner_html></pre>\n        }.into_any()\n    }\n}\n\n#[component]\npub fn CodeBlockLinePrimitive(\n    #[prop(into)] _html: String,\n    #[prop(default = 0usize)] line_number: usize,\n    #[prop(into, default = String::new())] diff: String,\n) -> impl IntoView {\n    #[cfg(feature = \"ssr\")]\n    {\n        view! {\n            <span\n                data-rs-code-line=\"\"\n                data-rs-line-number=line_number.to_string()\n                data-rs-diff={if diff.is_empty() { None } else { Some(diff) }}\n                inner_html=_html\n            ></span>\n        }.into_any()\n    }\n    #[cfg(not(feature = \"ssr\"))]\n    {\n        view! {\n            <span\n                data-rs-code-line=\"\"\n                data-rs-line-number=line_number.to_string()\n                data-rs-diff={if diff.is_empty() { None } else { Some(diff.clone()) }}\n            ></span>\n        }.into_any()\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code, unused_variables)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    CodeBlockPrimitive, CodeBlockHeaderPrimitive, CodeBlockLanguagePrimitive,\n    CodeBlockFilenamePrimitive, CodeBlockPrePrimitive,\n};\nuse crate::ui::copy_button::copy_button_boundary::CopyButton;\n#[cfg(feature = \"ssr\")]\nuse super::highlighter::highlight;\n\n#[component]\npub fn CodeBlock(\n    #[prop(into)] code: String,\n    #[prop(into, default = \"text\".to_string())] language: String,\n    #[prop(into, optional)] filename: Option<String>,\n    #[prop(default = false)] show_line_numbers: bool,\n    #[prop(default = true)] show_copy: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    #[cfg(feature = \"ssr\")]\n    let pre_html = {\n        let result = highlight(&code, &language);\n        result.lines.into_iter().enumerate().map(|(i, html)| {\n            format!(r#\"<span data-rs-code-line=\"\" data-rs-line-number=\"{}\">{}</span>\"#, i + 1, html)\n        }).collect::<Vec<_>>().join(\"\")\n    };\n    #[cfg(not(feature = \"ssr\"))]\n    let pre_html = String::new();\n\n    let lang_display = language.clone();\n    let code_for_copy = code.clone();\n\n    view! {\n        <CodeBlockPrimitive\n            language=lang_display.clone()\n            class=class\n            attr:data-line-numbers={show_line_numbers.then(|| \"true\")}\n        >\n            <CodeBlockHeaderPrimitive>\n                <div data-code-header-left=\"\">\n                    <CodeBlockLanguagePrimitive language=lang_display />\n                    {filename.map(|f| view! {\n                        <CodeBlockFilenamePrimitive filename=f />\n                    })}\n                </div>\n                {show_copy.then(|| view! {\n                    <CopyButton text=code_for_copy />\n                })}\n            </CodeBlockHeaderPrimitive>\n            <CodeBlockPrePrimitive inner_html=pre_html />\n        </CodeBlockPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! CodeBlock Boundary — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::code_block_ui::CodeBlock as CodeBlockUi;\n\n#[component]\npub fn CodeBlock(\n    #[prop(into)] code: String,\n    #[prop(into, default = \"text\".to_string())] language: String,\n    #[prop(into, optional)] filename: Option<String>,\n    #[prop(default = false)] show_line_numbers: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CodeBlockUi\n            code=code\n            language=language\n            filename=filename.unwrap_or_default()\n            show_line_numbers=show_line_numbers\n            class=class\n        />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const CODEBLOCK_API: ComponentApi = ComponentApi {\n    id: \"code-block\",\n    description: \"Syntax-highlighted code display\",\n    props: &[\n        PropDef { name: \"code\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"language\", kind: PropType::String, required: false, default: Some(\"text\"), description: \"Prop value\" },\n        PropDef { name: \"filename\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"show_line_numbers\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::code_block_boundary::CodeBlock;\nuse crate::blocks::card::CardBlock;\nuse crate::ui::card::{CardHeader, CardTitle, CardContent};\nuse canonrs_core::slot;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CodeBlockShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <CardBlock\n                header=slot!(|| view! {\n                    <CardHeader><CardTitle>\"Rust\"</CardTitle></CardHeader>\n                }.into_any())\n                content=slot!(|| view! {\n                    <CardContent>\n                        <CodeBlock\n                            code=\"fn main() {\\n    println!(\\\"Hello, world!\\\");\\n}\".to_string()\n                            language=\"rust\".to_string()\n                        />\n                    </CardContent>\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"SSR-safe syntax highlighting with deterministic DOM output.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With filename\"</span>\n                <CardBlock\n                    content=slot!(|| view! {\n                        <CardContent>\n                            <CodeBlock\n                                code=\"const greet = (name: string) => `Hello, ${name}!`;\".to_string()\n                                language=\"typescript\".to_string()\n                                filename=\"greet.ts\".to_string()\n                            />\n                        </CardContent>\n                    }.into_any())\n                />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With line numbers\"</span>\n                <CardBlock\n                    content=slot!(|| view! {\n                        <CardContent>\n                            <CodeBlock\n                                code=\"[dependencies]\\nleptos = { version = \\\"0.8\\\" }\".to_string()\n                                language=\"toml\".to_string()\n                                show_line_numbers=true\n                            />\n                        </CardContent>\n                    }.into_any())\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "card_block"
    ],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "collapsible",
    "label": "Collapsible",
    "category": "Navigation",
    "description": "Collapsible section",
    "keywords": "",
    "pain": "Collapsible sections lose sync between trigger and content state",
    "promise": "Trigger and content state always synchronized via shared visibility state",
    "why": "CollapsiblePrimitive shares VisibilityState across trigger and content. This ensures both reflect the same open/closed state. The contract eliminates manual sync logic.\n",
    "before": "// ❌ Typical\nview! {\n  <button on:click=toggle>\"Toggle\"</button>\n  {if open { view! { <div>\"Content\"</div> } }}\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Collapsible>\n    <CollapsibleTrigger>\"Toggle\"</CollapsibleTrigger>\n    <CollapsibleContent>\"Content\"</CollapsibleContent>\n  </Collapsible>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "faq sections",
      "expandable panels"
    ],
    "related": [
      "accordion"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "accordion",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Collapsible Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{VisibilityState, DisabledState};\n\n\n#[component]\npub fn CollapsiblePrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid_col = crate::infra::uid::generate(\"col\");\n    view! {\n        <div\n            data-rs-collapsible=\"\"\n            data-rs-uid=uid_col\n            data-rs-interaction=\"init\"\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CollapsibleTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] controls: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-collapsible-trigger=\"\"\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-expanded=state.aria_expanded()\n            aria-disabled=disabled.aria_disabled()\n            aria-controls=if controls.is_empty() { None } else { Some(controls) }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn CollapsibleContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] id: String,\n) -> impl IntoView {\n    let content_id = if id.is_empty() { crate::infra::uid::generate(\"col-content\") } else { id };\n    view! {\n        <div\n            data-rs-collapsible-content=\"\"\n            data-rs-state=state.as_str()\n            role=\"region\"\n            aria-hidden=state.aria_hidden()\n            id=content_id\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    CollapsiblePrimitive, CollapsibleTriggerPrimitive, CollapsibleContentPrimitive,\n};\nuse canonrs_core::meta::{VisibilityState, DisabledState};\nuse canonrs_core::infra::uid::generate;\n\n#[component]\npub fn Collapsible(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    view! {\n        <CollapsiblePrimitive state=state disabled=disabled class=class node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </CollapsiblePrimitive>\n    }\n}\n\n#[component]\npub fn CollapsibleTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] controls: String,\n) -> impl IntoView {\n    view! {\n        <CollapsibleTriggerPrimitive class=class controls=controls>\n            {children()}\n        </CollapsibleTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn CollapsibleContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] id: String,\n) -> impl IntoView {\n    view! {\n        <CollapsibleContentPrimitive class=class id=id>\n            {children()}\n        </CollapsibleContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Collapsible Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v3.0.0: interaction delegated to canonrs-interactions-init\n\nuse leptos::prelude::*;\nuse super::collapsible_ui::{\n    Collapsible as CollapsibleUi,\n    CollapsibleTrigger as CollapsibleTriggerUi,\n    CollapsibleContent as CollapsibleContentUi\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Collapsible(\n    children: Children,\n    #[prop(default = false)] open: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let state = if open { VisibilityState::Open } else { VisibilityState::Closed };\n    view! { <CollapsibleUi state=state class=class>{children()}</CollapsibleUi> }\n}\n\n#[component]\npub fn CollapsibleTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CollapsibleTriggerUi class=class>{children()}</CollapsibleTriggerUi> }\n}\n\n#[component]\npub fn CollapsibleContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <CollapsibleContentUi class=class>{children()}</CollapsibleContentUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const COLLAPSIBLE_API: ComponentApi = ComponentApi {\n    id: \"collapsible\",\n    description: \"Collapsible section\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"open\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COLLAPSIBLETRIGGER_API: ComponentApi = ComponentApi {\n    id: \"collapsible-trigger\",\n    description: \"Collapsible section\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COLLAPSIBLECONTENT_API: ComponentApi = ComponentApi {\n    id: \"collapsible-content\",\n    description: \"Collapsible section\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::collapsible_boundary::{Collapsible, CollapsibleTrigger, CollapsibleContent};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CollapsibleShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Collapsible>\n                <CollapsibleTrigger>\"Toggle details\"</CollapsibleTrigger>\n                <CollapsibleContent>\n                    \"Hidden content revealed on toggle. State governed by signal.\"\n                </CollapsibleContent>\n            </Collapsible>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Single toggle — open/close state via signal. SSR-safe, hydration-safe.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Initially open\"</span>\n                <Collapsible open=true>\n                    <CollapsibleTrigger>\"Advanced options\"</CollapsibleTrigger>\n                    <CollapsibleContent>\n                        \"These options are visible by default because open=true was passed.\"\n                    </CollapsibleContent>\n                </Collapsible>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Nested\"</span>\n                <Collapsible>\n                    <CollapsibleTrigger>\"Parent\"</CollapsibleTrigger>\n                    <CollapsibleContent>\n                        <Collapsible>\n                            <CollapsibleTrigger>\"Child\"</CollapsibleTrigger>\n                            <CollapsibleContent>\"Nested collapsible content.\"</CollapsibleContent>\n                        </Collapsible>\n                    </CollapsibleContent>\n                </Collapsible>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "color_picker",
    "label": "Color Picker",
    "category": "Form",
    "description": "Color picker input",
    "keywords": "",
    "pain": "Color inputs lack consistent selection and accessibility behavior",
    "promise": "Color selection and state enforced via structured primitives",
    "why": "ColorPickerPrimitive uses SelectionState and VisibilityState for interaction control. The contract ensures consistent value handling and accessibility. This prevents ad-hoc color input implementations.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"color\" value=\"#000\" />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ColorPicker value=\"#000000\" />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "theme customization",
      "design tools"
    ],
    "related": [
      "select",
      "combobox",
      "radio",
      "radio_group",
      "slider"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ColorPicker Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState, VisibilityState};\n\n#[component]\npub fn ColorPickerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"cp\");\n    view! {\n        <div\n            data-rs-color-picker=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"selection\"\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-name=name\n            data-rs-value=value\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ColorPickerTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = \"#000000\".to_string())] color: String,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-color-picker-trigger=\"\"\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-color=color\n            aria-haspopup=\"dialog\"\n            aria-expanded=state.aria_expanded()\n            aria-disabled=disabled.aria_disabled()\n            aria-label=\"Open color picker\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ColorPickerInputPrimitive(\n    #[prop(into, default = \"#000000\".to_string())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <input\n            type=\"color\"\n            data-rs-color-picker-input=\"\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            disabled=disabled.disabled()\n            value=value\n            name=name\n            aria-label=\"Color picker\"\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn ColorPickerSwatchPrimitive(\n    #[prop(into, default = \"#000000\".to_string())] color: String,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-color-swatch=\"\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-color=color\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-label=aria_label\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ColorPickerPrimitive, ColorPickerTriggerPrimitive, ColorPickerInputPrimitive,\n    ColorPickerSwatchPrimitive,\n};\nuse canonrs_core::meta::{DisabledState, SelectionState, VisibilityState};\n\n#[component]\npub fn ColorPicker(#[prop(into, default = \"#000000\".to_string())] value: String, #[prop(into, default = String::new())] name: String, #[prop(default = DisabledState::Enabled)] disabled: DisabledState, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <ColorPickerPrimitive state=VisibilityState::Closed disabled=disabled name=name.clone() value=value.clone() class=class>\n            <ColorPickerTriggerPrimitive state=VisibilityState::Closed disabled=disabled color=value.clone()>\n                <ColorPickerInputPrimitive value=value name=name disabled=disabled />\n            </ColorPickerTriggerPrimitive>\n        </ColorPickerPrimitive>\n    }\n}\n#[component]\npub fn ColorPickerSwatch(#[prop(into)] color: String, #[prop(default = SelectionState::Unselected)] selected: SelectionState, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <ColorPickerSwatchPrimitive color=color selected=selected class=class /> }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ColorFormat { #[default] Hex, Rgb, Hsl, Cmyk }\nimpl ColorFormat {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Hex => \"hex\", Self::Rgb => \"rgb\", Self::Hsl => \"hsl\", Self::Cmyk => \"cmyk\" }\n    }\n}\n\n#[component]\npub fn ColorPickerDisplay(#[prop(into, default = \"#3b82f6\".to_string())] value: String, #[prop(default = ColorFormat::Hex)] format: ColorFormat, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <ColorPickerInputPrimitive value=value class=class /> }\n}\n#[component]\npub fn ColorPickerSwatches(children: Children, #[prop(into, default = \"#000000\".to_string())] value: String, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <div data-rs-color-picker-swatches=\"\" class=class>{children()}</div> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! ColorPicker Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::color_picker_ui::ColorFormat;\nuse canonrs_core::meta::{\n    DisabledState,\n    SelectionState\n};\n\n\n\n#[component]\npub fn ColorPicker(\n    #[prop(into, default = \"#000000\".to_string())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::color_picker_ui::ColorPicker value=value name=name disabled=disabled class=class />\n    }\n}\n\n#[component]\npub fn ColorPickerSwatch(\n    #[prop(into)] color: String,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <super::color_picker_ui::ColorPickerSwatch color=color selected=selected class=class /> }\n}\n\n#[component]\npub fn ColorPickerDisplay(\n    #[prop(into, default = \"#3b82f6\".to_string())] value: String,\n    #[prop(default = ColorFormat::Hex)] format: ColorFormat,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <super::color_picker_ui::ColorPickerDisplay value=value format=format class=class /> }\n}\n\n#[component]\npub fn ColorPickerSwatches(\n    #[prop(into, default = \"#3b82f6\".to_string())] value: String,\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    use super::color_picker_ui::ColorPickerSwatches as ColorPickerSwatchesUi;\n    view! {\n    <ColorPickerSwatchesUi value=value class=class>\n            {children()}\n        </ColorPickerSwatchesUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const COLORPICKER_API: ComponentApi = ComponentApi {\n    id: \"color-picker\",\n    description: \"Color picker input\",\n    props: &[\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"#000000\"), description: \"Current value\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COLORPICKERSWATCH_API: ComponentApi = ComponentApi {\n    id: \"color-picker-swatch\",\n    description: \"Color picker input\",\n    props: &[\n        PropDef { name: \"color\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"selected\", kind: PropType::String, required: false, default: Some(\"unselected\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COLORPICKERDISPLAY_API: ComponentApi = ComponentApi {\n    id: \"color-picker-display\",\n    description: \"Color picker input\",\n    props: &[\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"#3b82f6\"), description: \"Current value\" },\n        PropDef { name: \"format\", kind: PropType::String, required: false, default: Some(\"hex\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COLORPICKERSWATCHES_API: ComponentApi = ComponentApi {\n    id: \"color-picker-swatches\",\n    description: \"Color picker input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"#3b82f6\"), description: \"Current value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::color_picker_boundary::{ColorPicker, ColorPickerSwatch, ColorPickerSwatches};\nuse canonrs_core::meta::DisabledState;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ColorPickerShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <ColorPicker value=\"#3b82f6\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Color input with swatch preview — state governed by data-rs-state.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Swatches\"</span>\n                <ColorPickerSwatches value=\"#3b82f6\">\n                    <ColorPickerSwatch color=\"#3b82f6\" />\n                    <ColorPickerSwatch color=\"#ef4444\" />\n                    <ColorPickerSwatch color=\"#22c55e\" />\n                    <ColorPickerSwatch color=\"#f59e0b\" />\n                    <ColorPickerSwatch color=\"#8b5cf6\" />\n                    <ColorPickerSwatch color=\"#ec4899\" />\n                </ColorPickerSwatches>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <ColorPicker value=\"#6b7280\" disabled=DisabledState::Disabled />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "combobox",
    "label": "Combobox",
    "category": "Form",
    "description": "Searchable combo box",
    "keywords": "",
    "pain": "Searchable selects break ARIA roles and keyboard navigation",
    "promise": "Combobox roles and interaction fully enforced by structure",
    "why": "ComboboxPrimitive defines proper ARIA roles and input behavior. SelectionState and VisibilityState control dropdown interaction. This guarantees accessible and predictable combobox behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"text\" />\n  <ul><li>\"Option\"</li></ul>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Combobox>\n    <ComboboxTrigger>\"Select...\"</ComboboxTrigger>\n    <ComboboxList>\n      <ComboboxItem value=\"1\">\"Option\"</ComboboxItem>\n    </ComboboxList>\n  </Combobox>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "autocomplete",
      "search dropdown"
    ],
    "related": [
      "select",
      "radio",
      "radio_group",
      "color_picker",
      "slider"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Combobox Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState, VisibilityState};\n\n#[component]\npub fn ComboboxPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    let uid = crate::infra::uid::generate(\"cbx\");\n    view! {\n        <div\n            data-rs-combobox=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"selection\"\n            data-rs-state=state.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-name=name\n            role=\"combobox\"\n            aria-expanded=state.aria_expanded()\n            aria-haspopup=\"listbox\"\n            aria-disabled=disabled.aria_disabled()\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ComboboxInputPrimitive(\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <input\n            data-rs-combobox-input=\"\"\n            type=\"text\"\n            placeholder=placeholder\n            aria-autocomplete=\"list\"\n            autocomplete=\"off\"\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn ComboboxListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-combobox-list=\"\"\n            role=\"listbox\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ComboboxItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-combobox-item=\"\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-value=value\n            role=\"option\"\n            tabindex=\"-1\"\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ComboboxPrimitive, ComboboxInputPrimitive,\n    ComboboxListPrimitive, ComboboxItemPrimitive,\n};\nuse canonrs_core::meta::{DisabledState, SelectionState};\n\n#[component]\npub fn Combobox(\n    children: Children,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    view! {\n        <ComboboxPrimitive disabled=disabled class=class name=name node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </ComboboxPrimitive>\n    }\n}\n\n#[component]\npub fn ComboboxInput(\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ComboboxInputPrimitive placeholder=placeholder disabled=disabled class=class />\n    }\n}\n\n#[component]\npub fn ComboboxList(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ComboboxListPrimitive class=class>\n            {children()}\n        </ComboboxListPrimitive>\n    }\n}\n\n#[component]\npub fn ComboboxItem(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ComboboxItemPrimitive selected=selected disabled=disabled value=value class=class>\n            {children()}\n        </ComboboxItemPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Combobox Island — Canon Rule passthrough\nuse leptos::prelude::*;\npub use super::combobox_ui::{ComboboxInput, ComboboxList, ComboboxItem};\n\n#[component]\npub fn Combobox(\n    children: Children,\n    #[prop(into, default = String::from(\"Search...\"))] placeholder: String,\n    #[prop(default = canonrs_core::meta::DisabledState::Enabled)] disabled: canonrs_core::meta::DisabledState,\n    #[prop(optional)] node_ref: Option<leptos::prelude::NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    view! {\n        <super::combobox_ui::Combobox disabled=disabled class=class name=name node_ref=node_ref.unwrap_or_default()>\n            <ComboboxInput placeholder=placeholder />\n            <ComboboxList>\n                {children()}\n            </ComboboxList>\n        </super::combobox_ui::Combobox>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const COMBOBOX_API: ComponentApi = ComponentApi {\n    id: \"combobox\",\n    description: \"Searchable combo box\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"placeholder\", kind: PropType::String, required: false, default: Some(\"Search...\"), description: \"Placeholder text\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"node_ref\", kind: PropType::String, required: false, default: None, description: \"DOM node reference\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::combobox_boundary::{Combobox, ComboboxInput, ComboboxList, ComboboxItem};\nuse canonrs_core::meta::{DisabledState, SelectionState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ComboboxShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Combobox placeholder=\"Search framework...\">\n                <ComboboxItem value=\"leptos\">\"Leptos\"</ComboboxItem>\n                <ComboboxItem value=\"dioxus\">\"Dioxus\"</ComboboxItem>\n                <ComboboxItem value=\"yew\">\"Yew\"</ComboboxItem>\n                <ComboboxItem value=\"react\" disabled=DisabledState::Disabled>\"React (disabled)\"</ComboboxItem>\n            </Combobox>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Combobox roles and interaction fully enforced by structure.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Pre-selected\"</span>\n                <Combobox>\n                    <ComboboxInput placeholder=\"Search size...\" />\n                    <ComboboxList>\n                        <ComboboxItem value=\"xs\">\"Extra Small\"</ComboboxItem>\n                        <ComboboxItem value=\"sm\">\"Small\"</ComboboxItem>\n                        <ComboboxItem value=\"md\" selected=SelectionState::Selected>\"Medium\"</ComboboxItem>\n                        <ComboboxItem value=\"lg\">\"Large\"</ComboboxItem>\n                        <ComboboxItem value=\"xl\">\"Extra Large\"</ComboboxItem>\n                    </ComboboxList>\n                </Combobox>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <Combobox disabled=DisabledState::Disabled>\n                    <ComboboxInput placeholder=\"Disabled...\" disabled=DisabledState::Disabled />\n                    <ComboboxList>\n                        <ComboboxItem value=\"a\">\"Option A\"</ComboboxItem>\n                    </ComboboxList>\n                </Combobox>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "command",
    "label": "Command",
    "category": "Action",
    "description": "Command palette",
    "keywords": "",
    "pain": "Command palette lacks keyboard navigation and ARIA consistency",
    "promise": "Command palette semantics and selection fully enforced",
    "why": "CommandPrimitive enforces listbox semantics with structured input, grouping and items. SelectionState and ActivityState control highlight and selection behavior. This guarantees consistent keyboard navigation and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  <input placeholder=\"Search\" />\n  <div class=\"list\">\n    <div>\"Item\"</div>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Command>\n    <CommandInput placeholder=\"Search...\" />\n    <CommandList>\n      <CommandItem>\"Item\"</CommandItem>\n    </CommandList>\n  </Command>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "command palette",
      "quick navigation"
    ],
    "related": [
      "dropdown_menu",
      "context_menu",
      "menubar",
      "menu"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "menu",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Command Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState, ActivityState, VisibilityState};\n\n#[component]\npub fn CommandPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_cmd = crate::infra::uid::generate(\"cmd\");\n    let listbox_id = crate::infra::uid::generate(\"cmd-list\");\n\n    view! {\n        <div\n            data-rs-command=\"\"\n            data-rs-uid=uid_cmd\n            data-rs-interaction=\"init\"\n            data-rs-state=state.as_str()\n            data-rs-listbox-id=listbox_id.clone()\n            role=\"dialog\"\n            aria-label=\"Command palette\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandInputPrimitive(\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-command-input-wrapper=\"\" class=class>\n            <input\n                data-rs-command-input=\"\"\n                type=\"text\"\n                role=\"combobox\"\n                aria-autocomplete=\"list\"\n                aria-expanded=\"false\"\n                aria-haspopup=\"listbox\"\n                placeholder=if placeholder.is_empty() { None } else { Some(placeholder) }\n            />\n        </div>\n    }\n}\n\n#[component]\npub fn CommandListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let list_id = crate::infra::uid::generate(\"cmd-list\");\n    view! {\n        <div\n            data-rs-command-list=\"\"\n            id=list_id\n            role=\"listbox\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandEmptyPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-command-empty=\"\"\n            role=\"status\"\n            aria-live=\"polite\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-command-group=\"\"\n            role=\"group\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandGroupHeadingPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-command-group-heading=\"\"\n            role=\"presentation\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = ActivityState::Inactive)] highlighted: ActivityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-command-item=\"\"\n            data-rs-value=value\n            data-rs-activity=highlighted.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            id=crate::infra::uid::generate(\"cmd-item\")\n            role=\"option\"\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn CommandSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-command-separator=\"\"\n            role=\"separator\"\n            aria-orientation=\"horizontal\"\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    CommandPrimitive, CommandInputPrimitive, CommandListPrimitive,\n    CommandEmptyPrimitive, CommandGroupPrimitive, CommandGroupHeadingPrimitive,\n    CommandItemPrimitive, CommandSeparatorPrimitive,\n};\nuse canonrs_core::meta::SelectionState;\n\n#[component]\npub fn Command(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = canonrs_core::meta::VisibilityState::Closed)] state: canonrs_core::meta::VisibilityState,\n) -> impl IntoView {\n    view! {\n        <CommandPrimitive class=class state=state>\n            {children()}\n        </CommandPrimitive>\n    }\n}\n\n#[component]\npub fn CommandInput(\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandInputPrimitive placeholder=placeholder class=class />\n    }\n}\n\n#[component]\npub fn CommandList(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandListPrimitive class=class>\n            {children()}\n        </CommandListPrimitive>\n    }\n}\n\n#[component]\npub fn CommandEmpty(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandEmptyPrimitive class=class>\n            {children()}\n        </CommandEmptyPrimitive>\n    }\n}\n\n#[component]\npub fn CommandGroup(\n    children: Children,\n    #[prop(optional, into)] heading: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandGroupPrimitive class=class>\n            {heading.map(|h: String| view! {\n                <CommandGroupHeadingPrimitive>{h}</CommandGroupHeadingPrimitive>\n            })}\n            {children()}\n        </CommandGroupPrimitive>\n    }\n}\n\n#[component]\npub fn CommandItem(\n    children: Children,\n    #[prop(optional, into)] value: Option<String>,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandItemPrimitive value=value.unwrap_or_default() selected=selected class=class>\n            {children()}\n        </CommandItemPrimitive>\n    }\n}\n\n#[component]\npub fn CommandSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <CommandSeparatorPrimitive class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Command Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::command_ui::{\n    CommandInput,\n    CommandList,\n    CommandItem as CommandItemUi\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Command(\n    children: Children,\n    #[prop(into, default = String::from(\"Search...\"))] placeholder: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::command_ui::Command class=class state=VisibilityState::Open>\n            <CommandInput placeholder=placeholder />\n            <CommandList>{children()}</CommandList>\n        </super::command_ui::Command>\n    }\n}\n\n#[allow(unused_variables)]\n#[component]\npub fn CommandItem(\n    children: Children,\n    #[prop(into, optional)] value: Option<String>,\n    #[prop(into, optional)] group: Option<String>,\n) -> impl IntoView {\n    view! {\n        <CommandItemUi value=value.unwrap_or_default()>\n            {children()}\n        </CommandItemUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const COMMAND_API: ComponentApi = ComponentApi {\n    id: \"command\",\n    description: \"Command palette\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"placeholder\", kind: PropType::String, required: false, default: Some(\"Search...\"), description: \"Placeholder text\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const COMMANDITEM_API: ComponentApi = ComponentApi {\n    id: \"command-item\",\n    description: \"Command palette\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: None, description: \"Current value\" },\n        PropDef { name: \"group\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::command_boundary::{Command, CommandItem};\nuse crate::blocks::card::CardBlock;\nuse crate::ui::card::{CardHeader, CardTitle, CardContent};\nuse canonrs_core::slot;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CommandShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <CardBlock\n                header=slot!(|| view! {\n                    <CardHeader><CardTitle>\"Command Palette\"</CardTitle></CardHeader>\n                }.into_any())\n                content=slot!(|| view! {\n                    <CardContent>\n                        <Command placeholder=\"Search commands...\">\n                            <CommandItem value=\"calendar\" group=\"Suggestions\">\"Calendar\"</CommandItem>\n                            <CommandItem value=\"search\"   group=\"Suggestions\">\"Search\"</CommandItem>\n                            <CommandItem value=\"settings\" group=\"Suggestions\">\"Settings\"</CommandItem>\n                            <CommandItem value=\"new\"      group=\"Actions\">\"New file\"</CommandItem>\n                            <CommandItem value=\"open\"     group=\"Actions\">\"Open file\"</CommandItem>\n                            <CommandItem value=\"save\"     group=\"Actions\">\"Save\"</CommandItem>\n                        </Command>\n                    </CardContent>\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Command palette — typeahead filter governed by DOM.\"\n            </p>\n        </Stack>\n    }\n}\n",
    "block": [
      "card_block"
    ],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "confirm_dialog",
    "label": "Confirm Dialog",
    "category": "Overlay",
    "description": "Confirmation dialog",
    "keywords": "",
    "pain": "Confirmation dialogs miss ARIA roles and destructive intent signaling",
    "promise": "Confirmation semantics and intent enforced via variant and structure",
    "why": "ConfirmDialogPrimitive enforces role=\"alertdialog\" with variant-driven semantics. VisibilityState controls lifecycle and accessibility attributes. This guarantees proper focus and urgency communication.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"modal\">\"Are you sure?\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ConfirmDialog />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "delete confirmation",
      "critical actions"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "sheet",
      "modal",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ConfirmDialog Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ConfirmDialogVariant {\n    #[default]\n    Default,\n    Destructive,\n    Warning,\n}\nimpl ConfirmDialogVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default     => \"primary\",\n            Self::Destructive => \"destructive\",\n            Self::Warning     => \"warning\",\n        }\n    }\n}\n\n#[component]\npub fn ConfirmDialogPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_str = if uid.is_empty() { crate::infra::uid::generate(\"cd\") } else { uid };\n    view! {\n        <div\n            data-rs-confirm-dialog=\"\"\n            data-rs-interaction=\"overlay\"\n            data-rs-uid=uid_str\n            data-rs-variant=variant.as_str()\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ConfirmDialogOverlayPrimitive(\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-confirm-dialog-overlay=\"\"\n            data-rs-state=state.as_str()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn ConfirmDialogTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h2 data-rs-confirm-dialog-title=\"\" class=class>\n            {children()}\n        </h2>\n    }\n}\n\n#[component]\npub fn ConfirmDialogDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-confirm-dialog-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ConfirmDialogCancelPrimitive(\n    children: Children,\n    #[prop(into, default = \"Cancel\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-confirm-dialog-cancel=\"\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ConfirmDialogConfirmPrimitive(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = \"Confirm\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-confirm-dialog-confirm=\"\"\n            data-rs-variant=variant.as_str()\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ConfirmDialogTriggerPrimitive(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-confirm-dialog-trigger=\"\"\n            data-rs-variant=variant.as_str()\n            data-rs-target=target\n            data-rs-value=value\n            data-rs-label=label\n            aria-haspopup=\"alertdialog\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ConfirmDialogPortalPrimitive(children: ChildrenFn) -> impl IntoView {\n    view! {\n        <div data-rs-confirm-dialog-portal=\"\">\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ConfirmDialogContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-confirm-dialog-content=\"\"\n            data-rs-state=state.as_str()\n            role=\"alertdialog\"\n            aria-modal=\"true\"\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ConfirmDialogFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-confirm-dialog-footer=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ConfirmDialogPortalPrimitive,\n    ConfirmDialogPrimitive, ConfirmDialogTriggerPrimitive,\n    ConfirmDialogOverlayPrimitive, ConfirmDialogContentPrimitive,\n    ConfirmDialogTitlePrimitive, ConfirmDialogDescriptionPrimitive,\n    ConfirmDialogFooterPrimitive, ConfirmDialogCancelPrimitive,\n    ConfirmDialogConfirmPrimitive, ConfirmDialogVariant,\n};\n\n#[component]\npub fn ConfirmDialog(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(default = canonrs_core::meta::VisibilityState::Closed)] state: canonrs_core::meta::VisibilityState,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ConfirmDialogPrimitive variant=variant state=state uid=uid class=class>\n            {children()}\n        </ConfirmDialogPrimitive>\n    }\n}\n\n#[component]\npub fn ConfirmDialogTrigger(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogTriggerPrimitive variant=variant target=target value=value label=label class=class>{children()}</ConfirmDialogTriggerPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogPortal(children: ChildrenFn) -> impl IntoView {\n    view! { <ConfirmDialogPortalPrimitive>{children()}</ConfirmDialogPortalPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogOverlayPrimitive class=class /> }\n}\n\n#[component]\npub fn ConfirmDialogContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogContentPrimitive class=class>{children()}</ConfirmDialogContentPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogTitlePrimitive class=class>{children()}</ConfirmDialogTitlePrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogDescriptionPrimitive class=class>{children()}</ConfirmDialogDescriptionPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogFooterPrimitive class=class>{children()}</ConfirmDialogFooterPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogCancel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogCancelPrimitive class=class>{children()}</ConfirmDialogCancelPrimitive> }\n}\n\n#[component]\npub fn ConfirmDialogConfirm(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ConfirmDialogConfirmPrimitive variant=variant class=class>{children()}</ConfirmDialogConfirmPrimitive> }\n}\n\n",
    "boundary_src": "//! ConfirmDialog Island — Canon Rule #340 passthrough\nuse leptos::prelude::*;\nuse super::confirm_dialog_ui::{\n    ConfirmDialog as ConfirmDialogUi,\n    ConfirmDialogTrigger as ConfirmDialogTriggerUi,\n    ConfirmDialogPortal as ConfirmDialogPortalUi,\n    ConfirmDialogOverlay as ConfirmDialogOverlayUi,\n    ConfirmDialogContent as ConfirmDialogContentUi,\n    ConfirmDialogTitle as ConfirmDialogTitleUi,\n    ConfirmDialogDescription as ConfirmDialogDescriptionUi,\n    ConfirmDialogFooter as ConfirmDialogFooterUi,\n    ConfirmDialogCancel as ConfirmDialogCancelUi,\n    ConfirmDialogConfirm as ConfirmDialogConfirmUi,\n};\npub use canonrs_core::primitives::ConfirmDialogVariant;\n\n#[component]\npub fn ConfirmDialog(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogUi variant=variant uid=uid class=class.unwrap_or_default()>{children()}</ConfirmDialogUi> }\n}\n\n#[component]\npub fn ConfirmDialogTrigger(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogTriggerUi variant=variant target=target value=value label=label class=class.unwrap_or_default()>{children()}</ConfirmDialogTriggerUi> }\n}\n\n#[component]\npub fn ConfirmDialogPortal(children: ChildrenFn) -> impl IntoView {\n    view! { <ConfirmDialogPortalUi>{children()}</ConfirmDialogPortalUi> }\n}\n\n#[component]\npub fn ConfirmDialogOverlay(\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogOverlayUi class=class.unwrap_or_default() /> }\n}\n\n#[component]\npub fn ConfirmDialogContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogContentUi class=class.unwrap_or_default()>{children()}</ConfirmDialogContentUi> }\n}\n\n#[component]\npub fn ConfirmDialogTitle(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogTitleUi class=class.unwrap_or_default()>{children()}</ConfirmDialogTitleUi> }\n}\n\n#[component]\npub fn ConfirmDialogDescription(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogDescriptionUi class=class.unwrap_or_default()>{children()}</ConfirmDialogDescriptionUi> }\n}\n\n#[component]\npub fn ConfirmDialogFooter(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogFooterUi class=class.unwrap_or_default()>{children()}</ConfirmDialogFooterUi> }\n}\n\n#[component]\npub fn ConfirmDialogCancel(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogCancelUi class=class.unwrap_or_default()>{children()}</ConfirmDialogCancelUi> }\n}\n\n#[component]\npub fn ConfirmDialogConfirm(\n    children: Children,\n    #[prop(default = ConfirmDialogVariant::Default)] variant: ConfirmDialogVariant,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ConfirmDialogConfirmUi variant=variant class=class.unwrap_or_default()>{children()}</ConfirmDialogConfirmUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ConfirmDialogVariant}; \n\npub const CONFIRMDIALOG_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"warning\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"uid\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-trigger\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"warning\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"target\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Target element selector for copy\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label text\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGPORTAL_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-portal\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\npub const CONFIRMDIALOGCONTENT_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-content\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGTITLE_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-title\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-description\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGFOOTER_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-footer\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGCANCEL_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-cancel\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONFIRMDIALOGCONFIRM_API: ComponentApi = ComponentApi {\n    id: \"confirm-dialog-confirm\",\n    description: \"Confirmation dialog\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"destructive\", \"warning\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::confirm_dialog_boundary::{ConfirmDialog, ConfirmDialogTrigger, ConfirmDialogPortal, ConfirmDialogOverlay, ConfirmDialogContent, ConfirmDialogTitle, ConfirmDialogDescription, ConfirmDialogFooter, ConfirmDialogCancel, ConfirmDialogConfirm, ConfirmDialogVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ConfirmDialogShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <ConfirmDialog>\n                <ConfirmDialogTrigger>\"Delete item\"</ConfirmDialogTrigger>\n                <ConfirmDialogPortal>\n                    <ConfirmDialogOverlay />\n                    <ConfirmDialogContent>\n                        <ConfirmDialogTitle>\"Are you sure?\"</ConfirmDialogTitle>\n                        <ConfirmDialogDescription>\"This action cannot be undone.\"</ConfirmDialogDescription>\n                        <ConfirmDialogFooter>\n                            <ConfirmDialogCancel>\"Cancel\"</ConfirmDialogCancel>\n                            <ConfirmDialogConfirm variant=ConfirmDialogVariant::Destructive>\"Delete\"</ConfirmDialogConfirm>\n                        </ConfirmDialogFooter>\n                    </ConfirmDialogContent>\n                </ConfirmDialogPortal>\n            </ConfirmDialog>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Confirm dialog enforces action confirmation with variant-aware actions.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Warning variant\"</span>\n                <ConfirmDialog variant=ConfirmDialogVariant::Warning>\n                    <ConfirmDialogTrigger variant=ConfirmDialogVariant::Warning>\"Archive project\"</ConfirmDialogTrigger>\n                    <ConfirmDialogPortal>\n                        <ConfirmDialogOverlay />\n                        <ConfirmDialogContent>\n                            <ConfirmDialogTitle>\"Archive this project?\"</ConfirmDialogTitle>\n                            <ConfirmDialogDescription>\"The project will be archived and hidden from your dashboard.\"</ConfirmDialogDescription>\n                            <ConfirmDialogFooter>\n                                <ConfirmDialogCancel>\"Cancel\"</ConfirmDialogCancel>\n                                <ConfirmDialogConfirm variant=ConfirmDialogVariant::Warning>\"Archive\"</ConfirmDialogConfirm>\n                            </ConfirmDialogFooter>\n                        </ConfirmDialogContent>\n                    </ConfirmDialogPortal>\n                </ConfirmDialog>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "context_menu",
    "label": "Context Menu",
    "category": "Action",
    "description": "Right-click context menu",
    "keywords": "",
    "pain": "Right-click menus lack consistent trigger and focus behavior",
    "promise": "Context menu interaction and roles enforced structurally",
    "why": "ContextMenuPrimitive defines trigger/content separation with ARIA roles. ActivityState and DisabledState ensure correct focus and navigation. This guarantees predictable contextual actions.\n",
    "before": "// ❌ Typical\nview! {\n  <div on:contextmenu=show_menu>\n    <div class=\"menu\">\"Item\"</div>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ContextMenu>\n    <ContextMenuTrigger>\n      <span>\"Right-click\"</span>\n    </ContextMenuTrigger>\n    <ContextMenuContent>\n      <ContextMenuItem>\"Item\"</ContextMenuItem>\n    </ContextMenuContent>\n  </ContextMenu>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "file actions",
      "contextual tools"
    ],
    "related": [
      "dropdown_menu",
      "menubar",
      "menu",
      "command"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "menu",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ContextMenu Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{VisibilityState, DisabledState, ActivityState};\n\n\n#[component]\npub fn ContextMenuPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_cm = crate::infra::uid::generate(\"cm\");\n    view! {\n        <div\n            data-rs-context-menu=\"\"\n            data-rs-uid=uid_cm\n            data-rs-interaction=\"overlay\"\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ContextMenuTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-context-menu-trigger=\"\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ContextMenuContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-context-menu-content=\"\"\n            data-rs-state=state.as_str()\n            role=\"menu\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ContextMenuItemPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = ActivityState::Inactive)] highlighted: ActivityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-context-menu-item=\"\"\n            role=\"menuitem\"\n            data-rs-activity=highlighted.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ContextMenuSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-context-menu-separator=\"\"\n            role=\"separator\"\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn ContextMenuGroupPrimitive(\n    children: Children,\n    #[prop(into, optional)] label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-context-menu-group=\"\"\n            role=\"group\"\n            aria-label=label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ContextMenuLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-context-menu-label=\"\"\n            role=\"presentation\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::meta::VisibilityState;\nuse canonrs_core::primitives::{\n    ContextMenuPrimitive, ContextMenuTriggerPrimitive, ContextMenuContentPrimitive,\n    ContextMenuItemPrimitive, ContextMenuSeparatorPrimitive,\n};\n\n#[component]\npub fn ContextMenu(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ContextMenuPrimitive class=class>\n            {children()}\n        </ContextMenuPrimitive>\n    }\n}\n\n#[component]\npub fn ContextMenuTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ContextMenuTriggerPrimitive class=class>\n            {children()}\n        </ContextMenuTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn ContextMenuContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ContextMenuContentPrimitive state=VisibilityState::Closed class=class>\n            {children()}\n        </ContextMenuContentPrimitive>\n    }\n}\n\n#[component]\npub fn ContextMenuItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ContextMenuItemPrimitive class=class>\n            {children()}\n        </ContextMenuItemPrimitive>\n    }\n}\n\n#[component]\npub fn ContextMenuSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ContextMenuSeparatorPrimitive class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! ContextMenu Island — passthrough only\n\nuse leptos::prelude::*;\nuse super::context_menu_ui::{\n    ContextMenu as ContextMenuUi,\n    ContextMenuTrigger as ContextMenuTriggerUi,\n    ContextMenuContent as ContextMenuContentUi,\n    ContextMenuItem as ContextMenuItemUi\n};\n\n#[component]\npub fn ContextMenu(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ContextMenuUi class=class.unwrap_or_default()>{children()}</ContextMenuUi> }\n}\n\n#[component]\npub fn ContextMenuTrigger(children: Children) -> impl IntoView {\n    view! { <ContextMenuTriggerUi>{children()}</ContextMenuTriggerUi> }\n}\n\n#[component]\npub fn ContextMenuContent(children: Children) -> impl IntoView {\n    view! { <ContextMenuContentUi>{children()}</ContextMenuContentUi> }\n}\n\n#[component]\npub fn ContextMenuItem(children: Children) -> impl IntoView {\n    view! { <ContextMenuItemUi>{children()}</ContextMenuItemUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const CONTEXTMENU_API: ComponentApi = ComponentApi {\n    id: \"context-menu\",\n    description: \"Right-click context menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const CONTEXTMENUTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"context-menu-trigger\",\n    description: \"Right-click context menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\npub const CONTEXTMENUITEM_API: ComponentApi = ComponentApi {\n    id: \"context-menu-item\",\n    description: \"Right-click context menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::context_menu_boundary::{\n    ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ContextMenuShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <ContextMenu>\n                <ContextMenuTrigger>\n                    <div data-rs-context-menu-target=\"\">\"Right-click here\"</div>\n                </ContextMenuTrigger>\n                <ContextMenuContent>\n                    <ContextMenuItem>\"Edit\"</ContextMenuItem>\n                    <ContextMenuItem>\"Duplicate\"</ContextMenuItem>\n                    <ContextMenuItem>\"Delete\"</ContextMenuItem>\n                </ContextMenuContent>\n            </ContextMenu>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Context menu appears at cursor position on right-click.\"\n            </p>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "copy_button",
    "label": "Copy Button",
    "category": "Action",
    "description": "Clipboard copy button",
    "keywords": "",
    "pain": "Copy buttons require manual state handling and feedback UI",
    "promise": "Copy state lifecycle fully encoded in DOM state machine",
    "why": "CopyButton encodes idle, copied, and error states via data-rs-state. Behavior layer handles transitions without JS wiring. This guarantees consistent feedback and eliminates manual state management.\n",
    "before": "// ❌ Typical\nview! {\n  <button on:click=copy>\"Copy\"</button>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <CopyButton id=\"copy\" text=\"value\" />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "code snippets",
      "share links"
    ],
    "related": [
      "button",
      "button_group",
      "icon_button",
      "link"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "action",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! CopyButton Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[component]\npub fn CopyButtonPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] id: String,\n    #[prop(optional, into)] text: Option<String>,\n    #[prop(optional, into)] target: Option<String>,\n    #[prop(default = 2000)] reset_delay: u32,\n    #[prop(into, default = \"Copy to clipboard\".to_string())] aria_label: String,\n) -> impl IntoView {\n    let uid_cpb = crate::infra::uid::generate(\"cpb\");\n    view! {\n        <button\n            class=class\n            id=id\n            data-rs-copy-button=\"\"\n            data-rs-uid=uid_cpb\n            data-rs-interaction=\"content\"\n            data-rs-copy-text=text\n            data-rs-copy-target=target\n            data-rs-reset-delay=reset_delay.to_string()\n            data-rs-activity=\"idle\"\n            aria-label=aria_label\n        >\n            <span data-rs-copy-content=\"\">\n                <svg data-rs-copy-icon=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n                    <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/>\n                    <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/>\n                </svg>\n                <span data-rs-copy-label=\"\">\"Copy\"</span>\n            </span>\n\n            <span data-rs-copied-content=\"\">\n                <svg data-rs-copied-icon=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n                    <path d=\"M20 6 9 17l-5-5\"/>\n                </svg>\n                <span data-rs-copied-label=\"\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\"Copied!\"</span>\n            </span>\n\n            <span data-rs-error-content=\"\">\n                <svg data-rs-error-icon=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n                    <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n                    <path d=\"m15 9-6 6M9 9l6 6\"/>\n                </svg>\n                <span data-rs-error-label=\"\" role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\">\"Failed\"</span>\n            </span>\n        </button>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! CopyButton UI - SSR wrapper\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::CopyButtonPrimitive;\n\n#[component]\npub fn CopyButton(\n    #[prop(optional, into)] text: Option<String>,\n    #[prop(optional, into)] target: Option<String>,\n    #[prop(default = 2000)] reset_delay: u32,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] id: Option<String>,\n    #[prop(into, default = \"Copy to clipboard\".to_string())] aria_label: String,\n) -> impl IntoView {\n    view! {\n        <CopyButtonPrimitive\n            class=class\n            id=id.unwrap_or_default()\n            text=text.unwrap_or_default()\n            target=target.unwrap_or_default()\n            reset_delay=reset_delay\n            aria_label=aria_label\n        />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! CopyButton Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::copy_button_ui::CopyButton as CopyButtonUi;\n\n#[component]\npub fn CopyButton(\n    #[prop(optional, into)] text: Option<String>,\n    #[prop(optional, into)] target: Option<String>,\n    #[prop(default = 2000u32)] reset_delay: u32,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] id: Option<String>,\n    #[prop(into, default = \"Copy to clipboard\".to_string())] aria_label: String,\n) -> impl IntoView {\n    view! {\n        <CopyButtonUi\n            text=text.unwrap_or_default()\n            target=target.unwrap_or_default()\n            reset_delay=reset_delay\n            class=class\n            id=id.unwrap_or_default()\n            aria_label=aria_label\n        />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const COPYBUTTON_API: ComponentApi = ComponentApi {\n    id: \"copy-button\",\n    description: \"Clipboard copy button\",\n    props: &[\n        PropDef { name: \"text\", kind: PropType::String, required: false, default: None, description: \"Text to copy to clipboard\" },\n        PropDef { name: \"target\", kind: PropType::String, required: false, default: None, description: \"Target element selector for copy\" },\n        PropDef { name: \"reset_delay\", kind: PropType::Number, required: false, default: Some(\"2000u32\"), description: \"Delay in ms before resetting copy state\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"Copy to clipboard\"), description: \"Accessible label for screen readers\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::copy_button_boundary::CopyButton;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn CopyButtonShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <CopyButton text=\"cargo add canonrs\" aria_label=\"Copy to clipboard\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Click to copy — state machine: idle → copied → idle\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With target selector\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <code id=\"snippet-1\">\"npm install canonrs\"</code>\n                    <CopyButton target=\"snippet-1\" aria_label=\"Copy npm command\" />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Error state (no text — click to trigger)\"</span>\n                <CopyButton aria_label=\"Copy empty — triggers error\" />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "data_table",
    "label": "Data Table",
    "category": "Data",
    "description": "Sortable data table component",
    "keywords": "",
    "pain": "Tables mix rendering, sorting and state with no structure",
    "promise": "Table structure and sorting semantics enforced at component level",
    "why": "DataTablePrimitive separates head, body and cells with explicit sort metadata. SelectionState and density are encoded as attributes. This guarantees consistent behavior across all tables.\n",
    "before": "// ❌ Typical\nview! {\n  <table>\n    <tr><td>\"A\"</td></tr>\n  </table>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <DataTableCore data=data columns=columns />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "admin dashboards",
      "data grids"
    ],
    "related": [
      "table",
      "virtual_list",
      "empty_table",
      "tree",
      "list_item"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "data",
    "primitive_src": "#![allow(unused_variables)]\n//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! DataTable Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::primitives::table::SortDirection;\nuse crate::meta::SelectionState;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum DataTableDensity {\n    Compact,\n    #[default]\n    Comfortable,\n    Spacious,\n}\n\nimpl DataTableDensity {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Compact     => \"compact\",\n            Self::Comfortable => \"comfortable\",\n            Self::Spacious    => \"spacious\",\n        }\n    }\n}\n\n\n\n\n\n\n\n\n\n\n#[component]\npub fn DataTablePrimitive(\n    children: Children,\n    #[prop(default = DataTableDensity::Comfortable)] density: DataTableDensity,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    let uid_dt = crate::infra::uid::generate(\"dt\");\n    view! {\n        <div\n            data-rs-datatable=\"\"\n            data-rs-uid=uid_dt\n            data-rs-interaction=\"data\"\n            data-rs-density=density.as_str()\n            data-rs-name=name\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableBulkBarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-datatable-bulk-bar=\"\" hidden class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableToolbarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-datatable-toolbar=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableScrollPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-datatable-scroll=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableTablePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] resizable: bool,\n) -> impl IntoView {\n    view! {\n        <table\n            data-rs-datatable-table=\"\"\n            data-rs-resizable=if resizable { Some(\"true\") } else { None }\n            class=class\n        >\n            {children()}\n        </table>\n    }\n}\n\n#[component]\npub fn DataTableExpandHeadCellPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <th data-rs-datatable-head-cell=\"\" data-rs-col-expand=\"\" scope=\"col\" class=class></th>\n    }\n}\n\n#[component]\npub fn DataTableExpandCellPrimitive(\n    children: Children,\n    row_id: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <td data-rs-datatable-cell=\"\" data-rs-col-expand=\"\" class=class>\n            {children()}\n        </td>\n    }\n}\n\n#[component]\npub fn DataTableExpandBtnPrimitive(\n    row_id: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-datatable-expand-btn=\"\"\n            data-rs-row-id=row_id\n            aria-expanded=\"false\"\n        >\n            \"▶\"\n        </button>\n    }\n}\n\n#[component]\npub fn DataTableExpandRowPrimitive(\n    children: Children,\n    row_id: String,\n    colspan: String,\n) -> impl IntoView {\n    view! {\n        <tr data-rs-datatable-expand-row=\"\" data-rs-row-id=row_id hidden=true>\n            <td data-rs-datatable-cell=\"\" colspan=colspan>\n                <div data-rs-datatable-expand-content=\"\">\n                    {children()}\n                </div>\n            </td>\n        </tr>\n    }\n}\n\n#[component]\npub fn DataTableColgroupPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! {\n        <colgroup data-rs-datatable-colgroup=\"\">\n            {children()}\n        </colgroup>\n    }\n}\n\n#[component]\npub fn DataTableColPrimitive(\n    #[prop(into, default = String::new())] col_index: String,\n    #[prop(into, default = String::new())] width: String,\n) -> impl IntoView {\n    view! {\n        <col\n            data-rs-datatable-col=\"\"\n            data-rs-col-index=col_index\n            style=if width.is_empty() { String::new() } else { format!(\"width:{}\", width) }\n        />\n    }\n}\n\n#[component]\npub fn DataTableHeadPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <thead data-rs-datatable-head=\"\" data-rs-resize-container=\"\" class=class>\n            {children()}\n        </thead>\n    }\n}\n\n#[component]\npub fn DataTableHeadRowPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <tr data-rs-datatable-head-row=\"\" class=class>\n            {children()}\n        </tr>\n    }\n}\n\n#[component]\npub fn DataTableHeadCellPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] sort_key: String,\n    #[prop(default = SortDirection::None)] sort_direction: SortDirection,\n    #[prop(into, default = String::new())] col_index: String,\n    #[prop(into, default = String::new())] style: String,\n    #[prop(default = false)] resizable: bool,\n) -> impl IntoView {\n    view! {\n        <th\n            data-rs-datatable-head-cell=\"\"\n            scope=\"col\"\n            role=\"columnheader\"\n            aria-sort=sort_direction.aria_sort()\n            data-rs-sort=sort_direction.as_str()\n            data-rs-sort-key=sort_key\n            data-rs-col-index=col_index\n            data-rs-resizable=if resizable { Some(\"true\") } else { None }\n            style=style\n            class=class\n        >\n            {children()}\n            {resizable.then(|| view! {\n                <span data-rs-datatable-resize-handle=\"\" aria-hidden=\"true\"></span>\n            })}\n        </th>\n    }\n}\n\n#[component]\npub fn DataTableBodyPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <tbody data-rs-datatable-body=\"\" class=class>\n            {children()}\n        </tbody>\n    }\n}\n\n#[component]\npub fn DataTableRowPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] row_id: String,\n    #[prop(into, default = String::new())] row_label: String,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(optional)] row_index: Option<usize>,\n) -> impl IntoView {\n    let is_selected = selected == SelectionState::Selected;\n    let aria_rowindex = row_index.map(|i| (i + 1).to_string()).unwrap_or_default();\n    let row_index_str = row_index.map(|i| i.to_string()).unwrap_or_default();\n    view! {\n        <tr\n            data-rs-datatable-row=\"\"\n            data-rs-selection=if is_selected { \"selected\" } else { \"unselected\" }\n            data-rs-row-id=row_id\n            data-rs-row-label=row_label\n            aria-selected=if is_selected { \"true\" } else { \"false\" }\n            aria-rowindex=aria_rowindex\n            data-rs-row-index=row_index_str\n            class=class\n        >\n            {children()}\n        </tr>\n    }\n}\n\n#[component]\npub fn DataTableCellPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] col_index: String,\n    #[prop(into, default = String::new())] style: String,\n) -> impl IntoView {\n    view! {\n        <td\n            data-rs-datatable-cell=\"\"\n            data-rs-col-index=col_index\n            style=style\n            class=class\n        >\n            {children()}\n        </td>\n    }\n}\n\n#[component]\npub fn DataTableFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <tfoot data-rs-datatable-footer=\"\" class=class>\n            {children()}\n        </tfoot>\n    }\n}\n\n#[component]\npub fn DataTablePaginationPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-datatable-pagination=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableEmptyPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-datatable-empty=\"\"\n            data-rs-activity=\"empty\"\n            role=\"status\"\n            aria-live=\"polite\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DataTableLoadingPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-datatable-loading=\"\"\n            data-rs-loading=\"loading\"\n            role=\"status\"\n            aria-live=\"polite\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n//! DataTable Full - HTML estático, comportamento delegado ao behavior JS\n\nuse leptos::prelude::*;\nuse crate::ui::scroll_area::scroll_area_boundary::ScrollArea;\nuse std::sync::Arc;\nuse canonrs_core::primitives::{\n    DataTableBulkBarPrimitive,\n    DataTablePrimitive, DataTableToolbarPrimitive,\n    DataTableTablePrimitive, DataTableHeadPrimitive, DataTableHeadRowPrimitive,\n    DataTableHeadCellPrimitive, DataTableBodyPrimitive, DataTableRowPrimitive,\n    DataTableCellPrimitive, DataTableEmptyPrimitive,\n    DataTableColgroupPrimitive, DataTableColPrimitive,\n    DataTableExpandHeadCellPrimitive, DataTableExpandCellPrimitive,\n    DataTableExpandBtnPrimitive, DataTableExpandRowPrimitive,\n    DataTableDensity, SortDirection,\n};\nuse crate::ui::dropdown_menu::{\n    DropdownMenu, DropdownMenuItem, DropdownMenuCheckboxItem,\n};\nuse super::types::{RowIdFn, RowLabelFn, ExpandRenderFn};\nuse crate::ui::context_menu::context_menu_boundary::{\n    ContextMenuContent, ContextMenuItem,\n};\n\n#[derive(Clone)]\npub struct DataTableColumn<T> {\n    pub key: String,\n    pub label: String,\n    pub render: Arc<dyn Fn(&T) -> String + Send + Sync>,\n}\n\nimpl<T> DataTableColumn<T> {\n    pub fn new(key: impl Into<String>, label: impl Into<String>, render: impl Fn(&T) -> String + Send + Sync + 'static) -> Self {\n        Self { key: key.into(), label: label.into(), render: Arc::new(render) }\n    }\n}\n\n#[derive(Clone)]\npub struct BulkAction {\n    pub id: &'static str,\n    pub label: &'static str,\n    pub danger: bool,\n}\n\nimpl BulkAction {\n    pub fn new(id: &'static str, label: &'static str) -> Self {\n        Self { id, label, danger: false }\n    }\n    pub fn danger(mut self) -> Self { self.danger = true; self }\n}\n\n#[derive(Clone)]\npub struct RowAction {\n    pub id: &'static str,\n    pub label: &'static str,\n    pub danger: bool,\n    pub inline: bool,\n}\n\nimpl RowAction {\n    pub fn new(id: &'static str, label: &'static str) -> Self {\n        Self { id, label, danger: false, inline: false }\n    }\n    pub fn danger(mut self) -> Self { self.danger = true; self }\n    pub fn inline(mut self) -> Self { self.inline = true; self }\n}\n\n#[component]\npub fn DataTableStatic<T>(\n    data: Vec<T>,\n    columns: Vec<DataTableColumn<T>>,\n    #[prop(default = DataTableDensity::default())] density: DataTableDensity,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = 10)] page_size: usize,\n    #[prop(default = false)] selectable: bool,\n    #[prop(into, default = String::new())] sync_chart: String,\n    #[prop(into, default = String::new())] sync_scope: String,\n    #[prop(default = false)] show_density: bool,\n    #[prop(default = false)] resizable: bool,\n    #[prop(default = ExpandRenderFn::default())] expand_render: ExpandRenderFn<T>,\n    #[prop(default = vec![])] row_actions: Vec<RowAction>,\n    #[prop(default = vec![])] bulk_actions: Vec<BulkAction>,\n    #[prop(default = RowIdFn::default())] row_id_fn: RowIdFn<T>,\n    #[prop(default = RowLabelFn::default())] row_label_fn: RowLabelFn<T>,\n) -> impl IntoView\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    let total = data.len();\n    let total_pages = ((total as f64) / (page_size as f64)).ceil().max(1.0) as usize;\n    let has_expand = expand_render.0.is_some();\n    let col_count = columns.len()\n        + if selectable { 1 } else { 0 }\n        + if has_expand { 1 } else { 0 }\n        + if !row_actions.is_empty() { 1 } else { 0 };\n    let visible_data = StoredValue::new(data.into_iter().enumerate().collect::<Vec<_>>());\n    let cols = StoredValue::new(columns.clone());\n    let expand_render = StoredValue::new(expand_render.0);\n    let row_actions = StoredValue::new(row_actions);\n    let bulk_actions = StoredValue::new(bulk_actions);\n    let row_id_fn = StoredValue::new(row_id_fn.0);\n    let row_label_fn = StoredValue::new(row_label_fn.0);\n    let initial_density = density.as_str();\n\n    view! {\n        <DataTablePrimitive\n            density=density\n            class=class\n            attr:data-rs-page-size=page_size.to_string()\n            attr:data-rs-current-page=\"1\"\n            attr:data-rs-total-pages=total_pages.to_string()\n            attr:data-rs-selectable={selectable.then(|| \"true\")}\n            attr:data-rs-chart-sync=sync_chart.clone()\n            attr:data-rs-chart-sync-scope=sync_scope.clone()\n        >\n            <DataTableBulkBarPrimitive>\n                <span data-rs-datatable-bulk-count=\"\">\"0 selected\"</span>\n                <div data-rs-datatable-bulk-actions=\"\">\n                    {bulk_actions.get_value().into_iter().map(|action| {\n                        view! {\n                            <button\n                                type=\"button\"\n                                data-rs-datatable-bulk-action=action.id\n                                class={if action.danger { \"danger\".to_string() } else { String::new() }}\n                            >\n                                {action.label}\n                            </button>\n                        }\n                    }).collect::<Vec<_>>()}\n                </div>\n                <button type=\"button\" data-rs-datatable-bulk-clear=\"\">\"✕ Clear\"</button>\n            </DataTableBulkBarPrimitive>\n            <DataTableToolbarPrimitive>\n                <input type=\"text\" data-rs-datatable-filter=\"\" placeholder=\"Search...\" />\n                <div data-rs-datatable-density-toggle=\"\" hidden=(!show_density)>\n                    <button type=\"button\" data-rs-density-btn=\"compact\"\n                        data-active={if initial_density == \"compact\" { \"true\" } else { \"false\" }}>\n                        \"Compact\"\n                    </button>\n                    <button type=\"button\" data-rs-density-btn=\"comfortable\"\n                        data-active={if initial_density == \"comfortable\" { \"true\" } else { \"false\" }}>\n                        \"Comfortable\"\n                    </button>\n                    <button type=\"button\" data-rs-density-btn=\"spacious\"\n                        data-active={if initial_density == \"spacious\" { \"true\" } else { \"false\" }}>\n                        \"Spacious\"\n                    </button>\n                </div>\n                <DropdownMenu trigger_label=\"Columns\">\n                    {columns.iter().enumerate().map(|(idx, col)| {\n                        let label = col.label.clone();\n                        view! {\n                            <DropdownMenuCheckboxItem attr:data-rs-col-index=idx.to_string()>\n                                {label}\n                            </DropdownMenuCheckboxItem>\n                        }\n                    }).collect::<Vec<_>>()}\n                </DropdownMenu>\n            </DataTableToolbarPrimitive>\n\n            <ScrollArea orientation=canonrs_core::primitives::ScrollOrientation::Horizontal auto_hide=false>\n            <DataTableTablePrimitive resizable=resizable>\n                <DataTableColgroupPrimitive>\n                    <col data-rs-datatable-col=\"\" data-rs-col-expand=\"\" class=if has_expand { \"\" } else { \"rs-col-hidden\" } />\n                    <col data-rs-datatable-col=\"\" data-rs-col-select=\"\" class=if selectable { \"\" } else { \"rs-col-hidden\" } />\n                    {cols.get_value().into_iter().enumerate().map(|(idx, _)| {\n                        view! { <DataTableColPrimitive col_index=idx.to_string() /> }\n                    }).collect::<Vec<_>>()}\n                    <col data-rs-datatable-col=\"\" data-rs-col-actions=\"\" class=if !row_actions.get_value().is_empty() { \"\" } else { \"rs-col-hidden\" } />\n                </DataTableColgroupPrimitive>\n                <DataTableHeadPrimitive>\n                    <DataTableHeadRowPrimitive>\n                        <DataTableExpandHeadCellPrimitive class=if has_expand { \"\" } else { \"rs-col-hidden\" } />\n                        <th data-rs-datatable-head-cell=\"\" scope=\"col\" data-rs-col-select=\"\" class=if selectable { \"\" } else { \"rs-col-hidden\" }>\n                            <input type=\"checkbox\" data-rs-datatable-select-all=\"\" />\n                        </th>\n                        {cols.get_value().into_iter().enumerate().map(|(idx, col)| {\n                            let key = col.key.clone();\n                            let label = col.label.clone();\n                            view! {\n                                <DataTableHeadCellPrimitive\n                                    sort_key=key\n                                    sort_direction=SortDirection::None\n                                    col_index=idx.to_string()\n                                    resizable=resizable\n                                >\n                                    <span data-rs-datatable-head-label=\"\">{label}</span>\n                                    <span data-rs-datatable-sort-icon=\"\" aria-hidden=\"true\">\"↕\"</span>\n                                </DataTableHeadCellPrimitive>\n                            }\n                        }).collect::<Vec<_>>()}\n                    </DataTableHeadRowPrimitive>\n                </DataTableHeadPrimitive>\n\n                <DataTableBodyPrimitive>\n                    {visible_data.get_value().into_iter().map(|(idx, row)| {\n                        let row_cols = cols.get_value();\n                        let expand_content: Option<AnyView> = expand_render.get_value().as_ref().map(|f| f(&row));\n                        let has_expand_row = expand_content.is_some();\n                        let has_actions = !row_actions.get_value().is_empty();\n                        let ctx_actions = row_actions.get_value();\n                        let row_label = row_label_fn.get_value().as_ref().map(|f| f(&row)).unwrap_or_default();\n                        let real_id = row_id_fn.get_value().as_ref().map(|f| f(&row)).unwrap_or_else(|| idx.to_string());\n                        let real_id = StoredValue::new(real_id);\n                        let ctx_row_id = real_id;\n\n                        let main_row = view! {\n                            <DataTableRowPrimitive row_id=real_id.get_value() row_label=row_label row_index=idx>\n                                {\n                                    let rid = real_id.get_value();\n                                    view! {\n                                        <DataTableExpandCellPrimitive row_id=rid.clone() class=if has_expand { \"\" } else { \"rs-col-hidden\" }>\n                                            {if has_expand { Some(view! { <DataTableExpandBtnPrimitive row_id=rid /> }) } else { None }}\n                                        </DataTableExpandCellPrimitive>\n                                    }\n                                }\n                                <td data-rs-datatable-cell=\"\" data-rs-col-select=\"\" class=if selectable { \"\" } else { \"rs-col-hidden\" }>\n                                    <input type=\"checkbox\" data-rs-datatable-select-row=\"\" value=idx.to_string() />\n                                </td>\n                                {row_cols.into_iter().enumerate().map(|(col_idx, col)| {\n                                    let value = (col.render)(&row);\n                                    view! {\n                                        <DataTableCellPrimitive col_index=col_idx.to_string()>\n                                            {value}\n                                        </DataTableCellPrimitive>\n                                    }\n                                }).collect::<Vec<_>>()}\n                                {\n                                    let actions = row_actions.get_value();\n                                    let has_actions_cell = !actions.is_empty();\n                                    let row_id = ctx_row_id.get_value();\n                                    let inline_actions: Vec<RowAction> = actions.iter().filter(|a| a.inline).cloned().collect();\n                                    let menu_actions: Vec<RowAction> = actions.iter().filter(|a| !a.inline).cloned().collect();\n                                    let has_menu = !menu_actions.is_empty();\n                                    let inline_views = inline_actions.into_iter().map(|action| {\n                                        let rid = row_id.clone();\n                                        view! {\n                                            <button type=\"button\"\n                                                data-rs-datatable-action=action.id\n                                                data-rs-row-id=rid\n                                                data-rs-datatable-inline-action=\"\"\n                                                class={if action.danger { \"danger\".to_string() } else { String::new() }}\n                                            >\n                                                {action.label}\n                                            </button>\n                                        }\n                                    }).collect::<Vec<_>>();\n                                    let menu_views = menu_actions.into_iter().map(|action| {\n                                        let rid = row_id.clone();\n                                        view! {\n                                            <DropdownMenuItem\n                                                class={if action.danger { \"danger\".to_string() } else { String::new() }}\n                                            >\n                                                <span data-rs-datatable-action=action.id data-rs-row-id=rid>\n                                                    {action.label}\n                                                </span>\n                                            </DropdownMenuItem>\n                                        }\n                                    }).collect::<Vec<_>>();\n                                    view! {\n                                        <td data-rs-datatable-cell=\"\" data-rs-col-actions=\"\" class=if has_actions_cell { \"\" } else { \"rs-col-hidden\" }>\n                                            <div data-rs-datatable-actions-cell=\"\">\n                                                <div data-rs-datatable-inline-actions=\"\">{inline_views}</div>\n                                                <div data-rs-datatable-menu-actions=\"\" hidden=(!has_menu)>\n                                                    <DropdownMenu>{menu_views}</DropdownMenu>\n                                                </div>\n                                            </div>\n                                        </td>\n                                    }\n                                }\n                            </DataTableRowPrimitive>\n                        };\n\n                        view! {\n                            <>\n                                {main_row}\n                                {expand_content.map(|content| {\n                                    let rid = real_id.get_value();\n                                    view! {\n                                        <DataTableExpandRowPrimitive row_id=rid colspan=col_count.to_string()>\n                                            {content}\n                                        </DataTableExpandRowPrimitive>\n                                    }\n                                })}\n                            </>\n                        }\n                    }).collect::<Vec<_>>()}\n                </DataTableBodyPrimitive>\n            </DataTableTablePrimitive></ScrollArea>\n\n            <div data-rs-datatable-context-menus=\"\">\n                {visible_data.get_value().into_iter().map(|(idx, row)| {\n                    let has_actions = !row_actions.get_value().is_empty();\n                    let ctx_actions = row_actions.get_value();\n                    let real_id2 = row_id_fn.get_value().as_ref().map(|f| f(&row)).unwrap_or_else(|| idx.to_string());\n                    let ctx_row_id2 = real_id2.clone();\n                    view! {\n                        <div data-rs-datatable-row-context=\"\" data-rs-context-menu=\"\"\n                            data-rs-row-id=ctx_row_id2 hidden=(!has_actions)>\n                            <ContextMenuContent>\n                                {ctx_actions.into_iter().map(|action| {\n                                    let rid2 = real_id2.clone();\n                                    view! {\n                                        <ContextMenuItem>\n                                            <span data-rs-datatable-action=action.id data-rs-row-id=rid2>\n                                                {action.label}\n                                            </span>\n                                        </ContextMenuItem>\n                                    }\n                                }).collect::<Vec<_>>()}\n                            </ContextMenuContent>\n                        </div>\n                    }\n                }).collect::<Vec<_>>()}\n            </div>\n\n            <DataTableEmptyPrimitive class=\"hidden\".to_string()>\n                \"No results found.\"\n            </DataTableEmptyPrimitive>\n            <div data-rs-datatable-pagination=\"\">\n                <button type=\"button\" data-rs-action=\"prev\" data-rs-datatable-pagination-btn=\"\" disabled=true>\n                    \"Previous\"\n                </button>\n                <span data-rs-pagination-info=\"\">{format!(\"1 of {}\", total_pages)}</span>\n                <button type=\"button\" data-rs-action=\"next\" data-rs-datatable-pagination-btn=\"\" disabled={total_pages <= 1}>\n                    \"Next\"\n                </button>\n            </div>\n        </DataTablePrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! DataTable Island — Canon Rule #340 (zero-logic passthrough)\n\nuse leptos::prelude::*;\npub use canonrs_core::primitives::DataTableDensity;\npub use super::data_table_ui::{\n    DataTableColumn,\n    RowAction,\n    BulkAction\n};\nuse super::data_table_ui::DataTableStatic;\nuse super::types::{ExpandRenderFn, RowIdFn, RowLabelFn};\n\n#[component]\npub fn DataTable<T>(\n    data: Vec<T>,\n    columns: Vec<DataTableColumn<T>>,\n    #[prop(default = DataTableDensity::default())] density: DataTableDensity,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = 10)] page_size: usize,\n    #[prop(default = false)] selectable: bool,\n    #[prop(default = false)] show_density: bool,\n    #[prop(default = false)] resizable: bool,\n    #[prop(default = vec![])] row_actions: Vec<RowAction>,\n    #[prop(default = vec![])] bulk_actions: Vec<BulkAction>,\n    #[prop(optional)] expand_render: Option<std::sync::Arc<dyn Fn(&T) -> leptos::prelude::AnyView + Send + Sync>>,\n    #[prop(optional)] row_id_fn: Option<std::sync::Arc<dyn Fn(&T) -> String + Send + Sync>>,\n    #[prop(optional)] row_label_fn: Option<std::sync::Arc<dyn Fn(&T) -> String + Send + Sync>>,\n) -> impl IntoView\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    match (expand_render, row_id_fn, row_label_fn) {\n        (Some(er), Some(ri), Some(rl)) => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n                expand_render=ExpandRenderFn(Some(er)) row_id_fn=RowIdFn(Some(ri)) row_label_fn=RowLabelFn(Some(rl))\n            />\n        }.into_any(),\n        (Some(er), None, None) => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n                expand_render=ExpandRenderFn(Some(er))\n            />\n        }.into_any(),\n        (Some(er), Some(ri), None) => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n                expand_render=ExpandRenderFn(Some(er)) row_id_fn=RowIdFn(Some(ri))\n            />\n        }.into_any(),\n        (None, Some(ri), Some(rl)) => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n                row_id_fn=RowIdFn(Some(ri)) row_label_fn=RowLabelFn(Some(rl))\n            />\n        }.into_any(),\n        (None, Some(ri), None) => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n                row_id_fn=RowIdFn(Some(ri))\n            />\n        }.into_any(),\n        _ => view! {\n            <DataTableStatic\n                data=data columns=columns density=density class=class\n                page_size=page_size selectable=selectable show_density=show_density resizable=resizable\n                row_actions=row_actions bulk_actions=bulk_actions\n            />\n        }.into_any(),\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{DataTableDensity}; \n\npub const DATATABLE<T>_API: ComponentApi = ComponentApi {\n    id: \"data-table<-t>\",\n    description: \"Sortable data table component\",\n    props: &[\n        PropDef { name: \"data\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"columns\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"density\", kind: PropType::Enum(&[\"compact\", \"comfortable\", \"spacious\"]), required: false, default: Some(\"default\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"page_size\", kind: PropType::Number, required: false, default: Some(\"10\"), description: \"Prop value\" },\n        PropDef { name: \"selectable\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"show_density\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"resizable\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \")] row_actions\", kind: PropType::String, required: false, default: Some(\"vec![]\"), description: \"Prop value\" },\n        PropDef { name: \")] bulk_actions\", kind: PropType::String, required: false, default: Some(\"vec![]\"), description: \"Prop value\" },\n        PropDef { name: \"expand_render\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::data_table_boundary::DataTable;\nuse super::data_table_boundary::{DataTableColumn, RowAction, BulkAction};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols, GridGap};\n\nfn sample_data() -> Vec<Vec<String>> {\n    vec![\n        vec![\"Alice\".to_string(),   \"Engineer\".to_string(), \"Active\".to_string(),   \"98\".to_string()],\n        vec![\"Bob\".to_string(),     \"Designer\".to_string(), \"Active\".to_string(),   \"87\".to_string()],\n        vec![\"Carol\".to_string(),   \"Manager\".to_string(),  \"Away\".to_string(),     \"76\".to_string()],\n        vec![\"Dave\".to_string(),    \"Engineer\".to_string(), \"Inactive\".to_string(), \"65\".to_string()],\n        vec![\"Eve\".to_string(),     \"Designer\".to_string(), \"Active\".to_string(),   \"91\".to_string()],\n        vec![\"Frank\".to_string(),   \"DevOps\".to_string(),   \"Active\".to_string(),   \"82\".to_string()],\n        vec![\"Grace\".to_string(),   \"QA\".to_string(),       \"Active\".to_string(),   \"79\".to_string()],\n        vec![\"Henry\".to_string(),   \"Manager\".to_string(),  \"Away\".to_string(),     \"88\".to_string()],\n        vec![\"Iris\".to_string(),    \"Engineer\".to_string(), \"Active\".to_string(),   \"95\".to_string()],\n        vec![\"Jack\".to_string(),    \"Designer\".to_string(), \"Inactive\".to_string(), \"71\".to_string()],\n        vec![\"Karen\".to_string(),   \"DevOps\".to_string(),   \"Active\".to_string(),   \"84\".to_string()],\n        vec![\"Leo\".to_string(),     \"QA\".to_string(),       \"Active\".to_string(),   \"77\".to_string()],\n    ]\n}\n\nfn sample_columns() -> Vec<DataTableColumn<Vec<String>>> {\n    vec![\n        DataTableColumn::new(\"name\",   \"Name\",   |r: &Vec<String>| r[0].clone()),\n        DataTableColumn::new(\"role\",   \"Role\",   |r: &Vec<String>| r[1].clone()),\n        DataTableColumn::new(\"status\", \"Status\", |r: &Vec<String>| r[2].clone()),\n        DataTableColumn::new(\"score\",  \"Score\",  |r: &Vec<String>| r[3].clone()),\n    ]\n}\n\nfn expand_data() -> Vec<Vec<String>> {\n    vec![\n        vec![\"Alice\".to_string(),   \"Engineer\".to_string(), \"Active\".to_string(),   \"alice@example.com|alice.j@work.com\".to_string()],\n        vec![\"Bob\".to_string(),     \"Designer\".to_string(), \"Active\".to_string(),   \"bob@example.com|bob.s@work.com\".to_string()],\n        vec![\"Carol\".to_string(),   \"Manager\".to_string(),  \"Away\".to_string(),     \"carol@example.com|carol.w@work.com\".to_string()],\n        vec![\"Dave\".to_string(),    \"Engineer\".to_string(), \"Inactive\".to_string(), \"dave@example.com|dave.b@work.com\".to_string()],\n        vec![\"Eve\".to_string(),     \"Designer\".to_string(), \"Active\".to_string(),   \"eve@example.com|eve.d@work.com\".to_string()],\n        vec![\"Frank\".to_string(),   \"DevOps\".to_string(),   \"Active\".to_string(),   \"frank@example.com|frank.m@work.com\".to_string()],\n    ]\n}\n\nfn expand_columns() -> Vec<DataTableColumn<Vec<String>>> {\n    vec![\n        DataTableColumn::new(\"name\",   \"Name\",   |r: &Vec<String>| r[0].clone()),\n        DataTableColumn::new(\"role\",   \"Role\",   |r: &Vec<String>| r[1].clone()),\n        DataTableColumn::new(\"status\", \"Status\", |r: &Vec<String>| r[2].clone()),\n        DataTableColumn::new(\"email\",  \"Email\",  |r: &Vec<String>| r[3].split('|').next().unwrap_or(\"\").to_string()),\n    ]\n}\n\n#[component]\npub fn DataTableStaticShowcasePreview() -> impl IntoView {\n    view! {\n        <DataTable\n            data=sample_data()\n            columns=sample_columns()\n            page_size=5\n            show_density=true\n            selectable=true\n            row_actions=vec![\n                RowAction::new(\"edit\",   \"Edit\").inline(),\n                RowAction::new(\"delete\", \"Delete\").danger(),\n            ]\n            bulk_actions=vec![\n                BulkAction::new(\"export\", \"Export\"),\n                BulkAction::new(\"delete\", \"Delete\").danger(),\n            ]\n        />\n    }\n}\n\n#[component]\npub fn DataTableShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Xl>\n            <Grid cols=GridCols::Two gap=GridGap::Lg>\n\n                // 1. Data Operations — sort, filter, pagination\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Data Operations — Sort · Search · Paginate\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                    />\n                </Stack>\n\n                // 2. Visual Density\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Visual Density — Compact · Comfortable · Spacious\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                        show_density=true\n                    />\n                </Stack>\n\n                // 3. Selection Domain — row selection, bulk actions, keyboard nav\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Selection — Row · Bulk · Keyboard\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                        selectable=true\n                        bulk_actions=vec![\n                            BulkAction::new(\"export\", \"Export\"),\n                            BulkAction::new(\"delete\", \"Delete\").danger(),\n                        ]\n                    />\n                </Stack>\n\n                // 4. Action Dispatch — inline actions, menu actions, context menu\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Actions — Inline · Menu · Context\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                        row_actions=vec![\n                            RowAction::new(\"edit\",   \"Edit\").inline(),\n                            RowAction::new(\"delete\", \"Delete\").danger(),\n                            RowAction::new(\"archive\", \"Archive\"),\n                        ]\n                    />\n                </Stack>\n\n                // 5. Expandable Structure\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Expand Row — Structural Composition\"</span>\n                    <DataTable\n                        data=expand_data()\n                        columns=expand_columns()\n                        page_size=5\n                        expand_render=std::sync::Arc::new(|r: &Vec<String>| {\n                            let emails: Vec<String> = r[3].split('|').map(|s| s.to_string()).collect();\n                            view! {\n                                <div style=\"padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs);\">\n                                    <strong>\"Contact emails:\"</strong>\n                                    {emails.into_iter().map(|e| view! {\n                                        <span style=\"color:var(--theme-action-primary-bg);\">{e}</span>\n                                    }).collect::<Vec<_>>()}\n                                </div>\n                            }.into_any()\n                        })\n                    />\n                </Stack>\n\n                // 6. Column Layout — resize, reorder, pin, toggle\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Column Layout — Resize · Reorder · Toggle\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                        resizable=true\n                    />\n                </Stack>\n\n                // 7. Editing Domain — inline edit lifecycle: state transition, commit, rollback\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Editing — Inline Edit · Commit · Rollback\"</span>\n                    <DataTable\n                        data=sample_data()\n                        columns=sample_columns()\n                        page_size=5\n                        row_actions=vec![\n                            RowAction::new(\"edit\",   \"✎ Edit\").inline(),\n                        ]\n                    />\n                </Stack>\n\n                // 8. Full Orchestration — all capabilities composed\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <span data-rs-showcase-label=\"\">\"Full Orchestration\"</span>\n                    <DataTable\n                        data=expand_data()\n                        columns=expand_columns()\n                        page_size=3\n                        show_density=true\n                        selectable=true\n                        resizable=true\n                        row_actions=vec![\n                            RowAction::new(\"edit\",   \"Edit\").inline(),\n                            RowAction::new(\"delete\", \"Delete\").danger(),\n                            RowAction::new(\"archive\", \"Archive\"),\n                        ]\n                        bulk_actions=vec![\n                            BulkAction::new(\"export\", \"Export\"),\n                            BulkAction::new(\"delete\", \"Delete\").danger(),\n                        ]\n                        expand_render=std::sync::Arc::new(|r: &Vec<String>| {\n                            let emails: Vec<String> = r[3].split('|').map(|s| s.to_string()).collect();\n                            view! {\n                                <div style=\"padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-xs);\">\n                                    <strong>\"Contact emails:\"</strong>\n                                    {emails.into_iter().map(|e| view! {\n                                        <span style=\"color:var(--theme-action-primary-bg);\">{e}</span>\n                                    }).collect::<Vec<_>>()}\n                                </div>\n                            }.into_any()\n                        })\n                    />\n                </Stack>\n\n            </Grid>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"DataTable — Data Ops · Density · Selection · Actions · Expand · Column Layout · Editing · Full Orchestration\"\n            </p>\n        </Stack>\n    }\n}\n",
    "block": [
      "data_table_block"
    ],
    "blocks_primitives": [
      "container"
    ]
  },
  {
    "id": "dialog",
    "label": "Dialog",
    "category": "Overlay",
    "description": "Modal dialog component",
    "keywords": "",
    "pain": "Dialogs break focus trap and accessibility roles",
    "promise": "Dialog accessibility and lifecycle enforced via primitives",
    "why": "DialogPrimitive defines overlay, portal and content with ARIA compliance. VisibilityState guarantees correct open/close synchronization. This ensures safe modal behavior across SSR and client.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"modal\">\"Content\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Dialog>\n    <DialogTrigger>\"Open\"</DialogTrigger>\n    <DialogPortal>\n      <DialogOverlay />\n      <DialogContent>\n        <DialogTitle>\"Title\"</DialogTitle>\n      </DialogContent>\n    </DialogPortal>\n  </Dialog>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "modals",
      "forms"
    ],
    "related": [
      "alert_dialog",
      "drawer",
      "sheet",
      "modal",
      "confirm_dialog",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Dialog Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[component]\npub fn DialogPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_str = if uid.is_empty() { crate::infra::uid::generate(\"dlg\") } else { uid };\n    view! {\n        <div\n            data-rs-dialog=\"\"\n            data-rs-interaction=\"overlay\"\n            data-rs-uid=uid_str\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DialogTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-dialog-trigger=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"primary\"\n            data-rs-target=target\n            aria-haspopup=\"dialog\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn DialogPortalPrimitive(children: ChildrenFn) -> impl IntoView {\n    view! {\n        <div data-rs-dialog-portal=\"\">\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DialogOverlayPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dialog-overlay=\"\"\n            data-rs-state=\"closed\"\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn DialogContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dialog-content=\"\"\n            data-rs-state=\"closed\"\n            role=\"dialog\"\n            aria-modal=\"true\"\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DialogTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h2 data-rs-dialog-title=\"\" class=class>\n            {children()}\n        </h2>\n    }\n}\n\n#[component]\npub fn DialogDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p data-rs-dialog-description=\"\" class=class>\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn DialogClosePrimitive(\n    children: Children,\n    #[prop(into, default = \"Close dialog\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-dialog-close=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"ghost\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn DialogFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-dialog-footer=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    DialogPrimitive, DialogTriggerPrimitive, DialogPortalPrimitive,\n    DialogOverlayPrimitive, DialogContentPrimitive, DialogTitlePrimitive,\n    DialogDescriptionPrimitive, DialogClosePrimitive, DialogFooterPrimitive,\n};\n\n#[component]\npub fn Dialog(\n    children: Children,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DialogPrimitive uid=uid class=class>\n            {children()}\n        </DialogPrimitive>\n    }\n}\n\n#[component]\npub fn DialogTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogTriggerPrimitive target=target class=class>{children()}</DialogTriggerPrimitive> }\n}\n\n#[component]\npub fn DialogPortal(children: ChildrenFn) -> impl IntoView {\n    view! { <DialogPortalPrimitive>{children()}</DialogPortalPrimitive> }\n}\n\n#[component]\npub fn DialogOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogOverlayPrimitive class=class /> }\n}\n\n#[component]\npub fn DialogContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogContentPrimitive class=class>{children()}</DialogContentPrimitive> }\n}\n\n#[component]\npub fn DialogTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogTitlePrimitive class=class>{children()}</DialogTitlePrimitive> }\n}\n\n#[component]\npub fn DialogDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogDescriptionPrimitive class=class>{children()}</DialogDescriptionPrimitive> }\n}\n\n#[component]\npub fn DialogClose(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogClosePrimitive class=class>{children()}</DialogClosePrimitive> }\n}\n\n#[component]\npub fn DialogFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DialogFooterPrimitive class=class>{children()}</DialogFooterPrimitive> }\n}\n\n",
    "boundary_src": "//! Dialog Island — Canon Rule #340 passthrough\nuse leptos::prelude::*;\nuse super::dialog_ui::{\n    Dialog as DialogUi,\n    DialogTrigger as DialogTriggerUi,\n    DialogPortal as DialogPortalUi,\n    DialogOverlay as DialogOverlayUi,\n    DialogContent as DialogContentUi,\n    DialogTitle as DialogTitleUi,\n    DialogDescription as DialogDescriptionUi,\n    DialogClose as DialogCloseUi,\n    DialogFooter as DialogFooterUi,\n};\n\n#[component]\npub fn Dialog(\n    children: Children,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogUi uid=uid class=class.unwrap_or_default()>{children()}</DialogUi> }\n}\n\n#[component]\npub fn DialogTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] target: String,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogTriggerUi target=target class=class.unwrap_or_default()>{children()}</DialogTriggerUi> }\n}\n\n#[component]\npub fn DialogPortal(children: ChildrenFn) -> impl IntoView {\n    view! { <DialogPortalUi>{children()}</DialogPortalUi> }\n}\n\n#[component]\npub fn DialogOverlay(\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogOverlayUi class=class.unwrap_or_default() /> }\n}\n\n#[component]\npub fn DialogContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogContentUi class=class.unwrap_or_default()>{children()}</DialogContentUi> }\n}\n\n#[component]\npub fn DialogTitle(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogTitleUi class=class.unwrap_or_default()>{children()}</DialogTitleUi> }\n}\n\n#[component]\npub fn DialogDescription(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogDescriptionUi class=class.unwrap_or_default()>{children()}</DialogDescriptionUi> }\n}\n\n#[component]\npub fn DialogClose(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogCloseUi class=class.unwrap_or_default()>{children()}</DialogCloseUi> }\n}\n\n#[component]\npub fn DialogFooter(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <DialogFooterUi class=class.unwrap_or_default()>{children()}</DialogFooterUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const DIALOG_API: ComponentApi = ComponentApi {\n    id: \"dialog\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"uid\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"dialog-trigger\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"target\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Target element selector for copy\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGPORTAL_API: ComponentApi = ComponentApi {\n    id: \"dialog-portal\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\npub const DIALOGCONTENT_API: ComponentApi = ComponentApi {\n    id: \"dialog-content\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGTITLE_API: ComponentApi = ComponentApi {\n    id: \"dialog-title\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"dialog-description\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGCLOSE_API: ComponentApi = ComponentApi {\n    id: \"dialog-close\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DIALOGFOOTER_API: ComponentApi = ComponentApi {\n    id: \"dialog-footer\",\n    description: \"Modal dialog component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::dialog_boundary::{\n    Dialog, DialogTrigger, DialogPortal, DialogOverlay,\n    DialogContent, DialogTitle, DialogDescription,\n    DialogClose, DialogFooter,\n};\nuse crate::ui::button::button_boundary::{Button, ButtonVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn DialogShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Dialog>\n                <DialogTrigger>\"Open Dialog\"</DialogTrigger>\n                <DialogPortal>\n                    <DialogOverlay />\n                    <DialogContent>\n                        <DialogTitle>\"Confirm action\"</DialogTitle>\n                        <DialogDescription>\"Are you sure? This action cannot be undone.\"</DialogDescription>\n                        <DialogFooter>\n                            <DialogClose>\"Cancel\"</DialogClose>\n                            <Button variant=ButtonVariant::Primary>\"Confirm\"</Button>\n                        </DialogFooter>\n                    </DialogContent>\n                </DialogPortal>\n            </Dialog>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Dialog accessibility and lifecycle enforced via primitives.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Form dialog\"</span>\n                <Dialog>\n                    <DialogTrigger>\"Edit profile\"</DialogTrigger>\n                    <DialogPortal>\n                        <DialogOverlay />\n                        <DialogContent>\n                            <DialogTitle>\"Edit profile\"</DialogTitle>\n                            <DialogDescription>\"Update your profile information below.\"</DialogDescription>\n                            <DialogFooter>\n                                <DialogClose>\"Cancel\"</DialogClose>\n                                <Button variant=ButtonVariant::Primary>\"Save changes\"</Button>\n                            </DialogFooter>\n                        </DialogContent>\n                    </DialogPortal>\n                </Dialog>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "doc_progress",
    "label": "Doc Progress",
    "category": "Display",
    "description": "Document progress indicator",
    "keywords": "",
    "pain": "Scroll progress indicators require manual scroll tracking logic",
    "promise": "Progress tracking injected automatically via behavior layer",
    "why": "DocProgressPrimitive exposes progress via data attributes and ARIA. Portal variant allows injection anywhere in layout. This guarantees consistent scroll tracking without custom JS.\n",
    "before": "// ❌ Typical\nwindow.onscroll = () => updateProgress();\n",
    "after": "// ✅ CanonRS\nview! {\n  <DocProgress />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "docs reading",
      "long articles"
    ],
    "related": [
      "progress",
      "spinner",
      "skeleton",
      "pulse",
      "loading_overlay"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! DocProgress Primitive\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum DocProgressPosition {\n    Top,\n    #[default]\n    Bottom,\n}\n\nimpl DocProgressPosition {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            DocProgressPosition::Top    => \"top\",\n            DocProgressPosition::Bottom => \"bottom\",\n        }\n    }\n}\n\n#[component]\npub fn DocProgressPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = 0u8)] progress: u8,\n) -> impl IntoView {\n    let uid_dp_1 = crate::infra::uid::generate(\"dp\");\n    let progress_str = progress.to_string();\n    view! {\n        <div\n            data-rs-doc-progress=\"\"\n            data-rs-uid=uid_dp_1\n            data-rs-interaction=\"init\"\n            data-rs-progress=progress_str.clone()\n            role=\"progressbar\"\n            aria-valuemin=\"0\"\n            aria-valuemax=\"100\"\n            aria-valuenow=progress_str\n            aria-label=\"Reading progress\"\n            class=class\n        >\n            <div data-rs-doc-progress-bar=\"\" />\n        </div>\n    }\n}\n\n#[component]\npub fn DocProgressPortal(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] scroll_target: String,\n    #[prop(default = DocProgressPosition::Top)] position: DocProgressPosition,\n) -> impl IntoView {\n    let uid_dp_1 = crate::infra::uid::generate(\"dp\");\n    view! {\n        <div\n            data-rs-doc-progress-portal=\"\"\n            data-rs-uid=uid_dp_1\n            data-rs-interaction=\"init\"\n            data-rs-scroll-target=scroll_target\n            data-rs-position=position.as_str()\n            aria-hidden=\"true\"\n            class=class\n        >\n            <div data-rs-doc-progress-bar=\"\" />\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::doc_progress::{DocProgressPrimitive, DocProgressPortal, DocProgressPosition};\n\npub use canonrs_core::primitives::doc_progress::DocProgressPosition as DocProgressSlotPosition;\n\n#[component]\npub fn DocProgress(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DocProgressPrimitive class=class progress=0u8 />\n    }\n}\n\n#[component]\npub fn DocProgressSlot(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] scroll_target: String,\n    #[prop(default = DocProgressPosition::Top)] position: DocProgressPosition,\n) -> impl IntoView {\n    view! {\n        <DocProgressPortal class=class scroll_target=scroll_target position=position />\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! DocProgress Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::doc_progress_ui::{\n    DocProgress as DocProgressUi,\n    DocProgressSlot as DocProgressSlotUi,\n    DocProgressSlotPosition\n};\n\n#[component]\npub fn DocProgress(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DocProgressUi class=class /> }\n}\n\n#[component]\npub fn DocProgressSlot(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] scroll_target: String,\n    #[prop(into, default = String::from(\"top\"))] position: String,\n) -> impl IntoView {\n    let pos = match position.as_str() {\n        \"bottom\" => DocProgressSlotPosition::Bottom,\n        _        => DocProgressSlotPosition::Top,\n    };\n    view! { <DocProgressSlotUi class=class scroll_target=scroll_target position=pos /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const DOCPROGRESS_API: ComponentApi = ComponentApi {\n    id: \"doc-progress\",\n    description: \"Document progress indicator\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DOCPROGRESSSLOT_API: ComponentApi = ComponentApi {\n    id: \"doc-progress-slot\",\n    description: \"Document progress indicator\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"scroll_target\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Scroll target element id\" },\n        PropDef { name: \"position\", kind: PropType::String, required: false, default: Some(\"top\"), description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::doc_progress_boundary::DocProgressSlot;\nuse crate::ui::scroll_area::scroll_area_boundary::ScrollArea;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::container::{ContainerPrimitive as Container, ContainerSize};\n\n#[component]\npub fn DocProgressShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Progress tracking injected automatically via behavior layer.\"\n            </p>\n            <Container size=ContainerSize::Md>\n            <div data-rs-doc-progress-demo=\"\" style=\"position:relative; height: 320px; border: var(--border-thin) solid var(--theme-surface-border); border-radius: var(--radius-md); overflow: hidden;\">\n                <DocProgressSlot scroll_target=\"doc-progress-viewport\" position=\"top\" />\n                <ScrollArea viewport_id=\"doc-progress-viewport\">\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xl>\n                        <section>\n                            <h2>\"Introduction\"</h2>\n                            <p>\"This document tracks your reading progress as you scroll through the content. The progress bar updates in real time based on scroll position, giving readers a clear visual indicator of how far they have come.\"</p>\n                            <p>\"The implementation uses a behavior layer that observes scroll events and maps them to a percentage value. This value is stored as a data attribute on the root element, keeping the DOM as the single source of truth.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"Getting Started\"</h2>\n                            <p>\"DocProgress uses a behavior layer that observes scroll position and computes a reading percentage. The component is SSR-safe and hydration-safe — the initial state is rendered on the server and the behavior layer takes over on the client.\"</p>\n                            <p>\"To use DocProgress, simply add it to your layout. No configuration is required for basic usage. The component will automatically track the scroll position of the window or a custom scroll container.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"Installation\"</h2>\n                            <p>\"Add the DocProgress component to your layout and the behavior handles the rest. The component exposes two variants: a standalone fixed bar that sits at the top of the viewport, and a portal variant that can be embedded inside a custom header or container.\"</p>\n                            <p>\"The portal variant is useful when you want the progress bar to appear inside a sticky header or a custom scrollable area rather than at the top of the page.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"Configuration\"</h2>\n                            <p>\"Tokens control height, color and transition speed. The following tokens are available: doc-progress-height, doc-progress-bg, doc-progress-bar-bg, doc-progress-z-index, and doc-progress-transition.\"</p>\n                            <p>\"All tokens follow the CanonRS token system and can be overridden at any level of the component tree. This makes it easy to customize the appearance of the progress bar without touching the component source code.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"Advanced Usage\"</h2>\n                            <p>\"Use DocProgressSlot to embed the bar inside a custom header. This is useful when you want the progress bar to appear inside a sticky navigation bar or a custom layout component.\"</p>\n                            <p>\"The scroll_target attribute allows you to specify a custom scroll container. This is useful when the scrollable content is not the window but a specific element on the page, such as a modal or a side panel.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"API Reference\"</h2>\n                            <p>\"DocProgress — standalone fixed bar that tracks window scroll. DocProgressSlot — portal for custom placement inside headers or containers. Both components share the same behavior layer and token system.\"</p>\n                            <p>\"The aria-valuenow attribute is updated in real time to reflect the current progress percentage. Screen readers can announce the progress to users who rely on assistive technology.\"</p>\n                        </section>\n                        <section>\n                            <h2>\"Accessibility\"</h2>\n                            <p>\"The progress bar uses role=progressbar with aria-valuemin, aria-valuemax, aria-valuenow, and aria-valuetext attributes. The aria-valuetext attribute provides a human-readable description of the progress value for screen readers.\"</p>\n                        </section>\n                    </Stack>\n                </ScrollArea>\n            </div>\n            </Container>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container",
      "stack"
    ]
  },
  {
    "id": "drawer",
    "label": "Drawer",
    "category": "Overlay",
    "description": "Slide-out drawer component",
    "keywords": "",
    "pain": "Slide panels lack consistent direction and accessibility semantics",
    "promise": "Drawer direction and visibility enforced via typed contract",
    "why": "DrawerPrimitive encodes side and visibility with DrawerSide and VisibilityState. ARIA attributes ensure accessibility compliance. This guarantees predictable slide behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"drawer left\">\"Content\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Drawer>\n    <DrawerOverlay />\n    <DrawerContent aria_labelledby=\"title\" />\n  </Drawer>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "mobile navigation",
      "side panels"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "sheet",
      "modal",
      "confirm_dialog",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Drawer Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum DrawerSide {\n    #[default]\n    Right,\n    Left,\n    Top,\n    Bottom,\n}\nimpl DrawerSide {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Right  => \"right\",\n            Self::Left   => \"left\",\n            Self::Top    => \"top\",\n            Self::Bottom => \"bottom\",\n        }\n    }\n}\n\n\n#[component]\npub fn DrawerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DrawerSide::Right)] side: DrawerSide,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_dr = crate::infra::uid::generate(\"dr\");\n    view! {\n        <div\n            data-rs-drawer=\"\"\n            data-rs-interaction=\"overlay\"\n            data-rs-uid=uid_dr\n            data-rs-state=state.as_str()\n            data-rs-side=side.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DrawerTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(optional, into)] aria_controls: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-drawer-trigger=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"primary\"\n            data-rs-state=state.as_str()\n            aria-haspopup=\"dialog\"\n            aria-expanded=state.aria_expanded()\n            aria-controls=aria_controls\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn DrawerOverlayPrimitive(\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-drawer-overlay=\"\"\n            data-rs-state=state.as_str()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn DrawerContentPrimitive(\n    children: Children,\n    #[prop(optional, into)] aria_labelledby: Option<String>,\n    #[prop(optional, into)] aria_describedby: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-drawer-content=\"\"\n            role=\"dialog\"\n            aria-modal=\"true\"\n            aria-labelledby=aria_labelledby\n            aria-describedby=aria_describedby\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DrawerPortalPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-drawer-portal=\"\" class=class>{children()}</div> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    DrawerPrimitive, DrawerTriggerPrimitive, DrawerOverlayPrimitive,\n    DrawerContentPrimitive, DrawerPortalPrimitive, DrawerSide,\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Drawer(\n    children: Children,\n    #[prop(default = DrawerSide::Right)] side: DrawerSide,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DrawerPrimitive side=side state=state class=class>{children()}</DrawerPrimitive> }\n}\n\n#[component]\npub fn DrawerTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DrawerTriggerPrimitive class=class>{children()}</DrawerTriggerPrimitive> }\n}\n\n#[component]\npub fn DrawerOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DrawerOverlayPrimitive class=class /> }\n}\n\n#[component]\npub fn DrawerContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] aria_labelledby: String,\n) -> impl IntoView {\n    view! {\n        <DrawerContentPrimitive aria_labelledby=aria_labelledby class=class>\n            {children()}\n        </DrawerContentPrimitive>\n    }\n}\n\n#[component]\npub fn DrawerPortal(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DrawerPortalPrimitive class=class>{children()}</DrawerPortalPrimitive> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Drawer Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v3.0.0: interaction delegated to canonrs-interactions-overlay\n\nuse leptos::prelude::*;\nuse super::drawer_ui::{\n    Drawer as DrawerUi,\n    DrawerTrigger,\n    DrawerOverlay,\n    DrawerContent,\n    DrawerPortal\n};\npub use canonrs_core::primitives::DrawerSide;\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Drawer(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::from(\"Open\"))] trigger_label: String,\n    #[prop(into, default = String::from(\"Close\"))] close_label: String,\n    #[prop(into, optional)] title: Option<String>,\n    #[prop(into, optional)] description: Option<String>,\n    #[prop(default = DrawerSide::Right)] side: DrawerSide,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DrawerUi side=side state=VisibilityState::Closed class=class>\n            <DrawerTrigger>{trigger_label}</DrawerTrigger>\n            <DrawerPortal>\n            <DrawerOverlay />\n            <DrawerContent aria_labelledby=\"drawer-title\">\n                {title.map(|t| view! { <h2 id=\"drawer-title\" data-rs-drawer-title=\"\">{t}</h2> })}\n                {description.map(|d| view! { <p data-rs-drawer-description=\"\">{d}</p> })}\n                {children.map(|c| c())}\n                <button type=\"button\" data-rs-drawer-close=\"\">{close_label}</button>\n            </DrawerContent>\n            </DrawerPortal>\n        </DrawerUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{DrawerSide}; \n\npub const DRAWER_API: ComponentApi = ComponentApi {\n    id: \"drawer\",\n    description: \"Slide-out drawer component\",\n    props: &[\n        PropDef { name: \"trigger_label\", kind: PropType::String, required: false, default: Some(\"Open\"), description: \"Prop value\" },\n        PropDef { name: \"close_label\", kind: PropType::String, required: false, default: Some(\"Close\"), description: \"Prop value\" },\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"side\", kind: PropType::Enum(&[\"right\", \"left\", \"top\", \"bottom\"]), required: false, default: Some(\"right\"), description: \"Tooltip or popover side\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::drawer_boundary::{Drawer, DrawerSide};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn DrawerShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Drawer\n                trigger_label=\"Open Drawer\"\n                title=\"Drawer Title\"\n                description=\"Slides in from the side. State governed via DOM.\"\n                close_label=\"Close\"\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Drawer visibility and overlay fully governed via shared state.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Left side\"</span>\n                <Drawer\n                    trigger_label=\"Open left\"\n                    title=\"Left Drawer\"\n                    close_label=\"Close\"\n                    side=DrawerSide::Left\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "dropdown_menu",
    "label": "Dropdown Menu",
    "category": "Action",
    "description": "Dropdown menu",
    "keywords": "",
    "pain": "Dropdown menus break keyboard navigation and selection state",
    "promise": "Menu interaction and state fully encoded via primitives",
    "why": "DropdownMenuPrimitive defines trigger/content with ARIA roles. ToggleState and ActivityState manage selection and highlight. This guarantees consistent menu behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"dropdown\">\n    <button>\"Open\"</button>\n    <div class=\"menu\">\"Item\"</div>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <DropdownMenu>\n    <DropdownMenuTrigger>\"Open\"</DropdownMenuTrigger>\n    <DropdownMenuContent>\n      <DropdownMenuItem>\"Item\"</DropdownMenuItem>\n    </DropdownMenuContent>\n  </DropdownMenu>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "actions menu",
      "user menu"
    ],
    "related": [
      "context_menu",
      "menubar",
      "menu",
      "command"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "menu",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! DropdownMenu Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{DisabledState, ToggleState, VisibilityState};\n\n\n\n#[component]\npub fn DropdownMenuPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid_dm = crate::infra::uid::generate(\"dm\");\n    view! {\n        <div\n            data-rs-dropdown-menu=\"\"\n            data-rs-uid=uid_dm\n            data-rs-interaction=\"overlay\"\n            data-rs-state=state.as_str()\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DropdownMenuTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    let aria_disabled = if disabled == DisabledState::Disabled { \"true\" } else { \"false\" };\n    view! {\n        <button\n            type=\"button\"\n            data-rs-dropdown-menu-trigger=\"\"\n            aria-haspopup=\"menu\"\n            aria-expanded=\"false\"\n            aria-disabled=aria_disabled\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn DropdownMenuContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dropdown-menu-content=\"\"\n            role=\"menu\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DropdownMenuGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dropdown-menu-group=\"\"\n            role=\"group\"\n            aria-label=label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn DropdownMenuItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    let is_disabled = disabled == DisabledState::Disabled;\n    view! {\n        <button\n            type=\"button\"\n            data-rs-dropdown-menu-item=\"\"\n            role=\"menuitem\"\n            data-rs-activity=\"inactive\"\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            aria-disabled=if is_disabled { Some(\"true\") } else { None }\n            tabindex=if is_disabled { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn DropdownMenuSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dropdown-menu-separator=\"\"\n            role=\"separator\"\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn DropdownMenuCheckboxItemPrimitive(\n    children: Children,\n    #[prop(default = ToggleState::Off)] checked: ToggleState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let checked_str = checked.as_str();\n    view! {\n        <button\n            type=\"button\"\n            data-rs-dropdown-menu-checkbox-item=\"\"\n            data-rs-toggle=checked_str\n            data-rs-state=checked_str\n            role=\"menuitemcheckbox\"\n            aria-checked=checked.aria_pressed()\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            <span data-rs-dropdown-menu-indicator=\"\" aria-hidden=\"true\"></span>\n            <span data-rs-dropdown-menu-label=\"\">{children()}</span>\n        </button>\n    }\n}\n\n#[component]\npub fn DropdownMenuLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-dropdown-menu-label=\"\"\n            role=\"presentation\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::separator::SeparatorOrientation;\nuse canonrs_core::primitives::{\n    DropdownMenuPrimitive, DropdownMenuContentPrimitive,\n    DropdownMenuGroupPrimitive, DropdownMenuItemPrimitive,\n    DropdownMenuCheckboxItemPrimitive, DropdownMenuTriggerPrimitive,\n    DropdownMenuLabelPrimitive,\n    SeparatorPrimitive,\n};\nuse canonrs_core::meta::{DisabledState, ToggleState, VisibilityState};\n\n#[component]\npub fn DropdownMenu(\n    children: Children,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuPrimitive state=VisibilityState::Closed class=class node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </DropdownMenuPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuTrigger(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuTriggerPrimitive disabled=disabled class=class>\n            {children()}\n        </DropdownMenuTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuContentPrimitive class=class>\n            {children()}\n        </DropdownMenuContentPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuGroupPrimitive class=class>\n            {children()}\n        </DropdownMenuGroupPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuItem(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuItemPrimitive disabled=disabled class=class>\n            {children()}\n        </DropdownMenuItemPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuCheckboxItem(\n    children: Children,\n    #[prop(default = ToggleState::Off)] checked: ToggleState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuCheckboxItemPrimitive checked=checked disabled=disabled class=class>\n            {children()}\n        </DropdownMenuCheckboxItemPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuLabelPrimitive class=class>\n            {children()}\n        </DropdownMenuLabelPrimitive>\n    }\n}\n\n#[component]\npub fn DropdownMenuSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SeparatorPrimitive orientation=SeparatorOrientation::Horizontal decorative=true class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! DropdownMenu Island — passthrough only\n\nuse leptos::prelude::*;\nuse super::dropdown_menu_ui::{\n    DropdownMenu as DropdownMenuUi,\n    DropdownMenuTrigger as DropdownMenuTriggerUi,\n    DropdownMenuContent as DropdownMenuContentUi,\n    DropdownMenuGroup as DropdownMenuGroupUi,\n    DropdownMenuItem as DropdownMenuItemUi,\n    DropdownMenuCheckboxItem as DropdownMenuCheckboxItemUi,\n    DropdownMenuSeparator as DropdownMenuSeparatorUi\n};\nuse canonrs_core::meta::{DisabledState, ToggleState};\n\n#[component]\npub fn DropdownMenu(\n    children: Children,\n    #[prop(optional, into)] trigger_label: Option<String>,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! {\n        <DropdownMenuUi class=class.unwrap_or_default()>\n            <DropdownMenuTriggerUi>{trigger_label.unwrap_or_else(|| \"Options\".to_string())}</DropdownMenuTriggerUi>\n            <DropdownMenuContentUi>{children()}</DropdownMenuContentUi>\n        </DropdownMenuUi>\n    }\n}\n\n#[component]\npub fn DropdownMenuTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DropdownMenuTriggerUi class=class>{children()}</DropdownMenuTriggerUi> }\n}\n\n#[component]\npub fn DropdownMenuContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DropdownMenuContentUi class=class>{children()}</DropdownMenuContentUi> }\n}\n\n#[component]\npub fn DropdownMenuGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DropdownMenuGroupUi class=class>{children()}</DropdownMenuGroupUi> }\n}\n\n#[component]\npub fn DropdownMenuItem(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DropdownMenuItemUi disabled=disabled class=class>{children()}</DropdownMenuItemUi> }\n}\n\n#[component]\npub fn DropdownMenuCheckboxItem(\n    children: Children,\n    #[prop(default = ToggleState::Off)] checked: ToggleState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <DropdownMenuCheckboxItemUi checked=checked disabled=disabled class=class>{children()}</DropdownMenuCheckboxItemUi> }\n}\n\n#[component]\npub fn DropdownMenuSeparator() -> impl IntoView {\n    view! { <DropdownMenuSeparatorUi /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const DROPDOWNMENU_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"trigger_label\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-trigger\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUCONTENT_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-content\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUGROUP_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-group\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUITEM_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-item\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUCHECKBOXITEM_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-checkbox-item\",\n    description: \"Dropdown menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"checked\", kind: PropType::String, required: false, default: Some(\"off\"), description: \"Whether the component is checked\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const DROPDOWNMENUSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"dropdown-menu-separator\",\n    description: \"Dropdown menu\",\n    props: &[\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::dropdown_menu_boundary::{\n    DropdownMenu, DropdownMenuItem, DropdownMenuSeparator,\n    DropdownMenuCheckboxItem,\n};\nuse canonrs_core::meta::{DisabledState, ToggleState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn DropdownMenuShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <DropdownMenu trigger_label=\"Options\">\n                <DropdownMenuItem>\"Edit\"</DropdownMenuItem>\n                <DropdownMenuItem>\"Duplicate\"</DropdownMenuItem>\n                <DropdownMenuSeparator />\n                <DropdownMenuItem disabled=DisabledState::Disabled>\"Delete\"</DropdownMenuItem>\n            </DropdownMenu>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Dropdown menu with keyboard navigation and disabled state.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With checkboxes\"</span>\n                <DropdownMenu trigger_label=\"View\">\n                    <DropdownMenuCheckboxItem checked=ToggleState::On>\"Show toolbar\"</DropdownMenuCheckboxItem>\n                    <DropdownMenuCheckboxItem>\"Show sidebar\"</DropdownMenuCheckboxItem>\n                    <DropdownMenuCheckboxItem checked=ToggleState::On>\"Show status bar\"</DropdownMenuCheckboxItem>\n                </DropdownMenu>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "empty_state",
    "label": "Empty State",
    "category": "Feedback",
    "description": "Empty state placeholder",
    "keywords": "",
    "pain": "Empty states are inconsistent and lack semantic meaning",
    "promise": "Empty state intent and variant enforced via contract",
    "why": "EmptyStatePrimitive encodes variant and ARIA role=\"status\". Variants ensure consistent messaging patterns. This guarantees predictable feedback across all empty states.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\"No data\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <EmptyState>\n    <EmptyStateTitle>\"No data\"</EmptyStateTitle>\n  </EmptyState>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "no results",
      "empty dashboards"
    ],
    "related": [
      "error_state",
      "animate"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback_state",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! EmptyState Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum EmptyStateVariant {\n    #[default]\n    Default,\n    NoData,\n    NoResults,\n    Error,\n}\nimpl EmptyStateVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default   => \"default\",\n            Self::NoData    => \"no-data\",\n            Self::NoResults => \"no-results\",\n            Self::Error     => \"error\",\n        }\n    }\n}\n\n#[component]\npub fn EmptyStatePrimitive(\n    children: Children,\n    #[prop(default = EmptyStateVariant::Default)] variant: EmptyStateVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_es = crate::infra::uid::generate(\"es\");\n    view! {\n        <div\n            data-rs-empty=\"\"\n            data-rs-uid=uid_es\n            data-rs-variant=variant.as_str()\n            role=\"status\"\n            aria-live=\"polite\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn EmptyStateIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-empty-icon=\"\" aria-hidden=\"true\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn EmptyStateTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h3 data-rs-empty-title=\"\" class=class>\n            {children()}\n        </h3>\n    }\n}\n\n#[component]\npub fn EmptyStateDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p data-rs-empty-description=\"\" class=class>\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn EmptyStateActionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-empty-action=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    EmptyStatePrimitive, EmptyStateIconPrimitive,\n    EmptyStateTitlePrimitive, EmptyStateDescriptionPrimitive,\n    EmptyStateActionPrimitive,\n};\npub use canonrs_core::primitives::EmptyStateVariant;\n\n#[component]\npub fn EmptyState(\n    children: Children,\n    #[prop(default = EmptyStateVariant::Default)] variant: EmptyStateVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyStatePrimitive variant=variant class=class>\n            {children()}\n        </EmptyStatePrimitive>\n    }\n}\n\n#[component]\npub fn EmptyStateIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyStateIconPrimitive class=class>\n            {children()}\n        </EmptyStateIconPrimitive>\n    }\n}\n\n#[component]\npub fn EmptyStateTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyStateTitlePrimitive class=class>\n            {children()}\n        </EmptyStateTitlePrimitive>\n    }\n}\n\n#[component]\npub fn EmptyStateDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyStateDescriptionPrimitive class=class>\n            {children()}\n        </EmptyStateDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn EmptyStateAction(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyStateActionPrimitive class=class>\n            {children()}\n        </EmptyStateActionPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! EmptyState Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::empty_state_ui::{\n    EmptyState as EmptyStateUi,\n    EmptyStateIcon as EmptyStateIconUi,\n    EmptyStateTitle as EmptyStateTitleUi,\n    EmptyStateDescription as EmptyStateDescriptionUi,\n    EmptyStateAction as EmptyStateActionUi\n};\npub use canonrs_core::primitives::EmptyStateVariant;\n\n#[component]\npub fn EmptyState(\n    children: Children,\n    #[prop(default = EmptyStateVariant::Default)] variant: EmptyStateVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyStateUi variant=variant class=class>{children()}</EmptyStateUi> }\n}\n\n#[component]\npub fn EmptyStateIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyStateIconUi class=class>{children()}</EmptyStateIconUi> }\n}\n\n#[component]\npub fn EmptyStateTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyStateTitleUi class=class>{children()}</EmptyStateTitleUi> }\n}\n\n#[component]\npub fn EmptyStateDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyStateDescriptionUi class=class>{children()}</EmptyStateDescriptionUi> }\n}\n\n#[component]\npub fn EmptyStateAction(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyStateActionUi class=class>{children()}</EmptyStateActionUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{EmptyStateVariant}; \n\npub const EMPTYSTATE_API: ComponentApi = ComponentApi {\n    id: \"empty-state\",\n    description: \"Empty state placeholder\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"no-data\", \"no-results\", \"error\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const EMPTYSTATEICON_API: ComponentApi = ComponentApi {\n    id: \"empty-state-icon\",\n    description: \"Empty state placeholder\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const EMPTYSTATETITLE_API: ComponentApi = ComponentApi {\n    id: \"empty-state-title\",\n    description: \"Empty state placeholder\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const EMPTYSTATEDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"empty-state-description\",\n    description: \"Empty state placeholder\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const EMPTYSTATEACTION_API: ComponentApi = ComponentApi {\n    id: \"empty-state-action\",\n    description: \"Empty state placeholder\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::empty_state_boundary::{EmptyState, EmptyStateIcon, EmptyStateTitle, EmptyStateDescription, EmptyStateAction, EmptyStateVariant};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn EmptyStateShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <EmptyState>\n                <EmptyStateIcon>\"📭\"</EmptyStateIcon>\n                <EmptyStateTitle>\"No items found\"</EmptyStateTitle>\n                <EmptyStateDescription>\"Try adjusting your search or filters.\"</EmptyStateDescription>\n                <EmptyStateAction>\"Clear filters\"</EmptyStateAction>\n            </EmptyState>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Empty state intent and variant enforced via contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Grid cols=GridCols::Two>\n                    <EmptyState>\n                        <EmptyStateIcon>\"🗂️\"</EmptyStateIcon>\n                        <EmptyStateTitle>\"Default\"</EmptyStateTitle>\n                        <EmptyStateDescription>\"Nothing here yet.\"</EmptyStateDescription>\n                    </EmptyState>\n                    <EmptyState variant=EmptyStateVariant::NoResults>\n                        <EmptyStateIcon>\"🔍\"</EmptyStateIcon>\n                        <EmptyStateTitle>\"No results\"</EmptyStateTitle>\n                        <EmptyStateDescription>\"No matches for your query.\"</EmptyStateDescription>\n                    </EmptyState>\n                    <EmptyState variant=EmptyStateVariant::NoData>\n                        <EmptyStateIcon>\"📊\"</EmptyStateIcon>\n                        <EmptyStateTitle>\"No data\"</EmptyStateTitle>\n                        <EmptyStateDescription>\"Start by adding some entries.\"</EmptyStateDescription>\n                    </EmptyState>\n                    <EmptyState variant=EmptyStateVariant::Error>\n                        <EmptyStateIcon>\"⚠️\"</EmptyStateIcon>\n                        <EmptyStateTitle>\"Something went wrong\"</EmptyStateTitle>\n                        <EmptyStateDescription>\"Please try again later.\"</EmptyStateDescription>\n                        <EmptyStateAction>\"Retry\"</EmptyStateAction>\n                    </EmptyState>\n                </Grid>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack",
      "grid"
    ]
  },
  {
    "id": "empty_table",
    "label": "Empty Table",
    "category": "Display",
    "description": "Empty table state display",
    "keywords": "",
    "pain": "Empty table rows break layout and screen reader semantics",
    "promise": "Empty state rendered as valid table row with proper ARIA",
    "why": "EmptyTablePrimitive enforces correct table structure using tr and td with colspan. It preserves row semantics while exposing status via aria-live. This guarantees no layout or accessibility break inside tables.\n",
    "before": "// ❌ Typical\nview! {\n  <tbody>\n    <div>\"No data\"</div>\n  </tbody>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <tbody>\n    <EmptyTable colspan=3u32 />\n  </tbody>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "empty data grids",
      "admin tables"
    ],
    "related": [
      "table",
      "data_table",
      "virtual_list",
      "tree",
      "list_item"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "data",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! EmptyTable Primitive - Empty state for tables\n\nuse leptos::prelude::*;\n\n#[component]\npub fn EmptyTablePrimitive(\n    children: Children,\n    #[prop(default = 1u32)] colspan: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_et = crate::infra::uid::generate(\"et\");\n    view! {\n        <tr\n            data-rs-empty-table-row=\"\"\n            data-rs-uid=uid_et\n            role=\"row\"\n            class=class\n        >\n            <td colspan=colspan role=\"cell\">\n                <div\n                    data-rs-empty-table-content=\"\"\n                    data-rs-activity=\"empty\"\n                    role=\"status\"\n                    aria-live=\"polite\"\n                >\n                    {children()}\n                </div>\n            </td>\n        </tr>\n    }\n}\n\n#[component]\npub fn EmptyTableTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-empty-table-title=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn EmptyTableDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-empty-table-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    EmptyTablePrimitive,\n    EmptyTableTitlePrimitive,\n    EmptyTableDescriptionPrimitive,\n};\n\n#[component]\npub fn EmptyTable(\n    #[prop(into, default = \"No data available\".to_string())] title: String,\n    #[prop(into, default = \"Add your first item to get started\".to_string())] description: String,\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = 999)] colspan: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <EmptyTablePrimitive colspan=colspan class=class>\n            <EmptyTableTitlePrimitive>{title}</EmptyTableTitlePrimitive>\n            <EmptyTableDescriptionPrimitive>{description}</EmptyTableDescriptionPrimitive>\n            {children.map(|c| c())}\n        </EmptyTablePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! EmptyTable Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::empty_table_ui::EmptyTable as EmptyTableUi;\n\n#[component]\npub fn EmptyTable(\n    #[prop(into, default = String::from(\"No data available\"))] title: String,\n    #[prop(into, default = String::from(\"Add your first item to get started\"))] description: String,\n    #[prop(default = 999u32)] colspan: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <EmptyTableUi title=title description=description colspan=colspan class=class />\n};\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const EMPTYTABLE_API: ComponentApi = ComponentApi {\n    id: \"empty-table\",\n    description: \"Empty table state display\",\n    props: &[\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: Some(\"No data available\"), description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: Some(\"Add your first item to get started\"), description: \"Description slot or text\" },\n        PropDef { name: \"colspan\", kind: PropType::Number, required: false, default: Some(\"999u32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::empty_table_boundary::EmptyTable;\nuse crate::blocks::data_table::DataTableBlock;\nuse crate::ui::table::table_boundary::{Table, TableHeader, TableBody, TableRow, TableHead};\nuse canonrs_core::slot;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn EmptyTableShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <DataTableBlock\n                empty=slot!(|| view! {\n                    <EmptyTable\n                        colspan=3u32\n                        title=\"No data available\"\n                        description=\"Add your first item to get started.\"\n                    />\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Empty state rendered as valid table row with proper ARIA.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Inside table\"</span>\n                <DataTableBlock\n                    header=slot!(|| view! {\n                        <Table>\n                            <TableHeader>\n                                <TableRow>\n                                    <TableHead><span>\"Name\"</span></TableHead>\n                                    <TableHead><span>\"Email\"</span></TableHead>\n                                </TableRow>\n                            </TableHeader>\n                        </Table>\n                    }.into_any())\n                    empty=slot!(|| view! {\n                        <Table>\n                            <TableBody>\n                                <EmptyTable\n                                    colspan=2u32\n                                    title=\"No users found\"\n                                    description=\"Invite your team members to get started.\"\n                                />\n                            </TableBody>\n                        </Table>\n                    }.into_any())\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "data_table_block"
    ],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "error_state",
    "label": "Error State",
    "category": "Feedback",
    "description": "Error state display",
    "keywords": "",
    "pain": "Error messages inconsistent and not announced to assistive technologies",
    "promise": "Error feedback always announced and structurally consistent",
    "why": "ErrorStatePrimitive enforces role=\"status\" with aria-live=\"assertive\". This guarantees immediate announcement of critical errors. Structure ensures consistent composition of icon, title and actions.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"error\">\"Something went wrong\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ErrorState>\n    <ErrorStateTitle>\"Error\"</ErrorStateTitle>\n  </ErrorState>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "api failures",
      "form submission errors"
    ],
    "related": [
      "empty_state",
      "animate"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback_state",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ErrorState Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[component]\npub fn ErrorStatePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ers = crate::infra::uid::generate(\"ers\");\n    view! {\n        <div\n            data-rs-error-state=\"\"\n            data-rs-uid=uid_ers\n            role=\"status\"\n            aria-live=\"assertive\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ErrorStateIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-error-state-icon=\"\" aria-hidden=\"true\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ErrorStateTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h3 data-rs-error-state-title=\"\" class=class>\n            {children()}\n        </h3>\n    }\n}\n\n#[component]\npub fn ErrorStateDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p data-rs-error-state-description=\"\" class=class>\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn ErrorStateActionsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-error-state-actions=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ErrorStatePrimitive, ErrorStateIconPrimitive,\n    ErrorStateTitlePrimitive, ErrorStateDescriptionPrimitive,\n    ErrorStateActionsPrimitive,\n};\n\n#[component]\npub fn ErrorState(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ErrorStatePrimitive class=class>\n            {children()}\n        </ErrorStatePrimitive>\n    }\n}\n\n#[component]\npub fn ErrorStateIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ErrorStateIconPrimitive class=class>\n            {children()}\n        </ErrorStateIconPrimitive>\n    }\n}\n\n#[component]\npub fn ErrorStateTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ErrorStateTitlePrimitive class=class>\n            {children()}\n        </ErrorStateTitlePrimitive>\n    }\n}\n\n#[component]\npub fn ErrorStateDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ErrorStateDescriptionPrimitive class=class>\n            {children()}\n        </ErrorStateDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn ErrorStateActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ErrorStateActionsPrimitive class=class>\n            {children()}\n        </ErrorStateActionsPrimitive>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::error_state_ui::{\n    ErrorState as ErrorStateUi,\n    ErrorStateIcon as ErrorStateIconUi,\n    ErrorStateTitle as ErrorStateTitleUi,\n    ErrorStateDescription as ErrorStateDescriptionUi,\n    ErrorStateActions as ErrorStateActionsUi\n};\n\n#[component]\npub fn ErrorState(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ErrorStateUi class=class.unwrap_or_default()>{children()}</ErrorStateUi> }\n}\n\n#[component]\npub fn ErrorStateIcon(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ErrorStateIconUi class=class.unwrap_or_default()>{children()}</ErrorStateIconUi> }\n}\n\n#[component]\npub fn ErrorStateTitle(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ErrorStateTitleUi class=class.unwrap_or_default()>{children()}</ErrorStateTitleUi> }\n}\n\n#[component]\npub fn ErrorStateDescription(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ErrorStateDescriptionUi class=class.unwrap_or_default()>{children()}</ErrorStateDescriptionUi> }\n}\n\n#[component]\npub fn ErrorStateActions(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ErrorStateActionsUi class=class.unwrap_or_default()>{children()}</ErrorStateActionsUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const ERRORSTATE_API: ComponentApi = ComponentApi {\n    id: \"error-state\",\n    description: \"Error state display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ERRORSTATEICON_API: ComponentApi = ComponentApi {\n    id: \"error-state-icon\",\n    description: \"Error state display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ERRORSTATETITLE_API: ComponentApi = ComponentApi {\n    id: \"error-state-title\",\n    description: \"Error state display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ERRORSTATEDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"error-state-description\",\n    description: \"Error state display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const ERRORSTATEACTIONS_API: ComponentApi = ComponentApi {\n    id: \"error-state-actions\",\n    description: \"Error state display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::error_state_boundary::{\n    ErrorState, ErrorStateIcon, ErrorStateTitle,\n    ErrorStateDescription, ErrorStateActions,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\n\n#[component]\npub fn ErrorStateShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <ErrorState>\n                <ErrorStateIcon>\"⚠️\"</ErrorStateIcon>\n                <ErrorStateTitle>\"Something went wrong\"</ErrorStateTitle>\n                <ErrorStateDescription>\"We encountered an unexpected error. Please try again.\"</ErrorStateDescription>\n                <ErrorStateActions>\"Retry\"</ErrorStateActions>\n            </ErrorState>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Error feedback always announced and structurally consistent.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Examples\"</span>\n                <Grid cols=GridCols::Three>\n                    <ErrorState>\n                        <ErrorStateIcon>\"🔌\"</ErrorStateIcon>\n                        <ErrorStateTitle>\"Connection failed\"</ErrorStateTitle>\n                        <ErrorStateDescription>\"Check your network and try again.\"</ErrorStateDescription>\n                        <ErrorStateActions>\"Reconnect\"</ErrorStateActions>\n                    </ErrorState>\n                    <ErrorState>\n                        <ErrorStateIcon>\"🔒\"</ErrorStateIcon>\n                        <ErrorStateTitle>\"Access denied\"</ErrorStateTitle>\n                        <ErrorStateDescription>\"You do not have permission to view this page.\"</ErrorStateDescription>\n                        <ErrorStateActions>\"Go back\"</ErrorStateActions>\n                    </ErrorState>\n                    <ErrorState>\n                        <ErrorStateIcon>\"🗄️\"</ErrorStateIcon>\n                        <ErrorStateTitle>\"Failed to load data\"</ErrorStateTitle>\n                        <ErrorStateDescription>\"The requested data could not be fetched.\"</ErrorStateDescription>\n                        <ErrorStateActions>\"Try again\"</ErrorStateActions>\n                    </ErrorState>\n                </Grid>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack",
      "grid"
    ]
  },
  {
    "id": "field",
    "label": "Field",
    "category": "Form",
    "description": "Form field wrapper with label and error",
    "keywords": "",
    "pain": "Form fields lose validation and accessibility linkage between label and input",
    "promise": "Validation, label and error state unified in a single contract",
    "why": "FieldPrimitive encodes validation and disabled state into data attributes. FieldLabel and FieldError ensure correct ARIA mapping. This guarantees consistent field behavior and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  <label>\"Email\"</label>\n  <input />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Field>\n    <FieldLabel>\"Email\"</FieldLabel>\n  </Field>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "input validation"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "input_otp",
      "textarea",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Field Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum FieldValidationState {\n    #[default]\n    Idle,\n    Valid,\n    Invalid,\n    Warning,\n}\n\nimpl FieldValidationState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Idle    => \"idle\",\n            Self::Valid   => \"valid\",\n            Self::Invalid => \"invalid\",\n            Self::Warning => \"warning\",\n        }\n    }\n\n    pub fn aria_invalid(&self) -> Option<&'static str> {\n        match self { Self::Invalid => Some(\"true\"), _ => None }\n    }\n}\n\n#[component]\npub fn FieldPrimitive(\n    children: Children,\n    #[prop(default = FieldValidationState::Idle)] validation: FieldValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_fi = crate::infra::uid::generate(\"fi\");\n    view! {\n        <div\n            data-rs-field=\"\"\n            data-rs-uid=uid_fi\n            data-rs-interaction=\"init\"\n            data-rs-validation=validation.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-invalid=validation.aria_invalid()\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn FieldLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] html_for: String,\n    #[prop(default = false)] required: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <label\n            data-rs-field-label=\"\"\n            for={if html_for.is_empty() { None } else { Some(html_for) }}\n            data-rs-required={if required { Some(\"\") } else { None }}\n            aria-required={if required { Some(\"true\") } else { None }}\n            class=class\n        >\n            {children()}\n        </label>\n    }\n}\n\n#[component]\npub fn FieldDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-field-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn FieldErrorPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-field-error=\"\"\n            role=\"alert\"\n            aria-live=\"assertive\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn FieldGroupPrimitive(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-field-group=\"\"\n            role=\"group\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn FieldSetPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <fieldset data-rs-fieldset=\"\" class=class>\n            {children()}\n        </fieldset>\n    }\n}\n\n#[component]\npub fn FieldLegendPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <legend data-rs-field-legend=\"\" class=class>\n            {children()}\n        </legend>\n    }\n}\n\n#[component]\npub fn FieldContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-field-content=\"\" class=class>{children()}</div> }\n}\n\n#[component]\npub fn FieldTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-field-title=\"\" class=class>{children()}</div> }\n}\n\n#[component]\npub fn FieldSeparatorWrapperPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-field-separator-wrapper=\"\" class=class>{children()}</div> }\n}\n\n#[component]\npub fn FieldSeparatorContentPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <span data-rs-field-separator-content=\"\">{children()}</span> }\n}\n\n#[component]\npub fn FieldErrorItemPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <span data-rs-field-error-item=\"\">{children()}</span> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::separator::SeparatorOrientation;\nuse canonrs_core::primitives::{\n    FieldPrimitive, FieldSetPrimitive, FieldLabelPrimitive,\n    FieldDescriptionPrimitive, FieldErrorPrimitive, FieldGroupPrimitive,\n    FieldLegendPrimitive, SeparatorPrimitive,\n    FieldErrorItemPrimitive, FieldSeparatorWrapperPrimitive, FieldSeparatorContentPrimitive,\n    FieldContentPrimitive, FieldTitlePrimitive,\n};\nuse super::variants::{FieldOrientation, FieldValidation};\nuse super::types::FieldLegendVariant;\n\n#[component]\npub fn FieldSet(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldSetPrimitive class=class>{children()}</FieldSetPrimitive> }\n}\n#[component]\npub fn FieldLegend(children: Children, #[prop(default = FieldLegendVariant::Legend)] variant: FieldLegendVariant, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldLegendPrimitive attr:data-rs-variant=variant.as_str() class=class>{children()}</FieldLegendPrimitive> }\n}\n#[component]\npub fn FieldGroup(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldGroupPrimitive class=class>{children()}</FieldGroupPrimitive> }\n}\n#[component]\npub fn Field(children: Children, #[prop(default = FieldOrientation::Vertical)] orientation: FieldOrientation, #[prop(default = FieldValidation::None)] _validation: FieldValidation, #[prop(default = false)] disabled: bool, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <FieldPrimitive attr:data-rs-orientation=orientation.as_str() attr:data-rs-validation=_validation.as_str() attr:data-rs-disabled=if disabled { \"true\" } else { \"false\" } class=class>\n            {children()}\n        </FieldPrimitive>\n    }\n}\n#[component]\npub fn FieldContent(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldContentPrimitive class=class>{children()}</FieldContentPrimitive> }\n}\n#[component]\npub fn FieldLabel(children: Children, #[prop(into, default = String::new())] html_for: String, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldLabelPrimitive html_for=html_for class=class>{children()}</FieldLabelPrimitive> }\n}\n#[component]\npub fn FieldTitle(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldTitlePrimitive class=class>{children()}</FieldTitlePrimitive> }\n}\n#[component]\npub fn FieldDescription(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <FieldDescriptionPrimitive class=class>{children()}</FieldDescriptionPrimitive> }\n}\n#[component]\npub fn FieldError(#[prop(default = vec![])] errors: Vec<String>, #[prop(default = FieldValidation::None)] _validation: FieldValidation, #[prop(optional)] children: Option<Children>, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    if errors.is_empty() && children.is_none() { return view! {}.into_any(); }\n    view! {\n        <FieldErrorPrimitive class=class>\n            {if let Some(child) = children { child().into_any() }\n             else { view! { {errors.into_iter().map(|e| view! { <FieldErrorItemPrimitive>{e}</FieldErrorItemPrimitive> }).collect_view()} }.into_any() }}\n        </FieldErrorPrimitive>\n    }.into_any()\n}\n#[component]\npub fn FieldSeparator(#[prop(optional)] children: Option<Children>, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <FieldSeparatorWrapperPrimitive class=class>\n            <SeparatorPrimitive orientation=SeparatorOrientation::Horizontal decorative=true class=String::new() />\n            {children.map(|c| view! { <FieldSeparatorContentPrimitive>{c()}</FieldSeparatorContentPrimitive> })}\n        </FieldSeparatorWrapperPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Field Island — Canon Rule #340 (zero-logic boundary)\n\npub use super::field_ui::{FieldLabel, FieldDescription, FieldError, FieldSet, FieldGroup, FieldContent};\npub use super::variants::{FieldOrientation, FieldValidation};\nuse leptos::prelude::*;\nuse super::field_ui::Field as FieldUi;\n\n#[component]\npub fn Field(\n    children: Children,\n    #[prop(default = FieldOrientation::Vertical)] orientation: FieldOrientation,\n    #[prop(default = FieldValidation::None)] _validation: FieldValidation,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FieldUi orientation=orientation _validation=_validation disabled=disabled class=class>\n            {children()}\n        </FieldUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const FIELD_API: ComponentApi = ComponentApi {\n    id: \"field\",\n    description: \"Form field wrapper with label and error\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"orientation\", kind: PropType::String, required: false, default: Some(\"vertical\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"_validation\", kind: PropType::String, required: false, default: Some(\"none\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::field_boundary::{Field, FieldLabel, FieldDescription, FieldError, FieldSet, FieldGroup, FieldContent};\nuse super::variants::{FieldOrientation, FieldValidation};\nuse crate::ui::input::input_boundary::Input;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn FieldShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <FieldSet>\n                <FieldGroup>\n                    <Field>\n                        <FieldLabel html_for=\"field-email\"><span>\"Email\"</span></FieldLabel>\n                        <FieldDescription><span>\"Enter your email address.\"</span></FieldDescription>\n                        <FieldContent>\n                            <Input placeholder=\"john@example.com\" />\n                        </FieldContent>\n                    </Field>\n                </FieldGroup>\n            </FieldSet>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Validation, label and error state unified in a single contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Error state\"</span>\n                <FieldSet>\n                    <FieldGroup>\n                        <Field _validation=FieldValidation::Error>\n                            <FieldLabel html_for=\"field-email2\"><span>\"Email\"</span></FieldLabel>\n                            <FieldContent>\n                                <Input placeholder=\"invalid@\" />\n                            </FieldContent>\n                            <FieldError errors=vec![\"Please enter a valid email.\".to_string()] />\n                        </Field>\n                    </FieldGroup>\n                </FieldSet>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Horizontal\"</span>\n                <FieldSet>\n                    <FieldGroup>\n                        <Field orientation=FieldOrientation::Horizontal>\n                            <FieldLabel html_for=\"field-name\"><span>\"Name\"</span></FieldLabel>\n                            <FieldContent>\n                                <Input placeholder=\"John Doe\" />\n                            </FieldContent>\n                        </Field>\n                    </FieldGroup>\n                </FieldSet>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "form_field_block"
    ],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "form",
    "label": "Form",
    "category": "Form",
    "description": "Form component",
    "keywords": "",
    "pain": "Forms mix validation, submission and accessibility inconsistently",
    "promise": "Form lifecycle and validation state enforced at container level",
    "why": "FormPrimitive encodes validation, disabled and submission states into attributes. ARIA states like busy and invalid are derived automatically. This guarantees consistent form behavior across all inputs.\n",
    "before": "// ❌ Typical\nview! {\n  <form>\n    <input />\n  </form>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Form>\n    <FormField>\n      <FormLabel>\"Name\"</FormLabel>\n    </FormField>\n  </Form>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "user forms",
      "checkout flows"
    ],
    "related": [
      "input",
      "input_group",
      "input_otp",
      "textarea",
      "field",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Form Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum FormMethod {\n    #[default]\n    Post,\n    Get,\n}\nimpl FormMethod {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Post => \"post\", Self::Get => \"get\" }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum FormEnctype {\n    #[default]\n    UrlEncoded,\n    Multipart,\n    Text,\n}\nimpl FormEnctype {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::UrlEncoded => \"application/x-www-form-urlencoded\",\n            Self::Multipart  => \"multipart/form-data\",\n            Self::Text       => \"text/plain\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum FormValidationState {\n    #[default]\n    Idle,\n    Submitting,\n    Success,\n    Error,\n}\nimpl FormValidationState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Idle       => \"idle\",\n            Self::Submitting => \"submitting\",\n            Self::Success    => \"success\",\n            Self::Error      => \"error\",\n        }\n    }\n    pub fn aria_busy(&self) -> Option<&'static str> {\n        if *self == Self::Submitting { Some(\"true\") } else { None }\n    }\n    pub fn aria_invalid(&self) -> Option<&'static str> {\n        if *self == Self::Error { Some(\"true\") } else { None }\n    }\n}\n\n#[component]\npub fn FormPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] action: String,\n    #[prop(default = FormMethod::Post)] method: FormMethod,\n    #[prop(default = FormEnctype::UrlEncoded)] enctype: FormEnctype,\n    #[prop(default = FormValidationState::Idle)] validation: FormValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = true)] novalidate: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_fo = crate::infra::uid::generate(\"fo\");\n    view! {\n        <form\n            data-rs-form=\"\"\n            data-rs-uid=uid_fo\n            data-rs-interaction=\"init\"\n            data-rs-validation=validation.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            action={if action.is_empty() { None } else { Some(action) }}\n            method=method.as_str()\n            enctype=enctype.as_str()\n            novalidate=novalidate\n            aria-busy=validation.aria_busy()\n            aria-invalid=validation.aria_invalid()\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </form>\n    }\n}\n\n#[component]\npub fn FormSectionPrimitive(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <section\n            data-rs-form-section=\"\"\n            role=\"group\"\n            aria-label=aria_label.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </section>\n    }\n}\n\n#[component]\npub fn FormActionsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-form-actions=\"\"\n            role=\"toolbar\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n// ── Form Field System ─────────────────────────────────────────────────────\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum FieldValidationState {\n    #[default]\n    Idle,\n    Valid,\n    Invalid,\n    Warning,\n}\nimpl FieldValidationState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Idle    => \"idle\",\n            Self::Valid   => \"valid\",\n            Self::Invalid => \"invalid\",\n            Self::Warning => \"warning\",\n        }\n    }\n    pub fn aria_invalid(&self) -> Option<&'static str> {\n        match self { Self::Invalid => Some(\"true\"), _ => None }\n    }\n}\n\n#[component]\npub fn FormFieldPrimitive(\n    children: ChildrenFn,\n    #[prop(default = FieldValidationState::Idle)] validation: FieldValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-form-field=\"\"\n            data-rs-validation=validation.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-invalid=validation.aria_invalid()\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn FormLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] html_for: String,\n    #[prop(default = false)] required: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <label\n            data-rs-form-label=\"\"\n            for=html_for\n            data-rs-required={if required { \"true\" } else { \"false\" }}\n            aria-required={if required { \"true\" } else { \"false\" }}\n            class=class\n        >\n            <span data-rs-label-text=\"\">{children()}</span>\n        </label>\n    }\n}\n\n#[component]\npub fn FormErrorPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-form-error=\"\"\n            role=\"alert\"\n            aria-live=\"assertive\"\n            class=class\n        >\n            <span data-rs-error-text=\"\">{children()}</span>\n        </div>\n    }\n}\n\n#[component]\npub fn FormHintPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-form-hint=\"\" class=class>\n            <span data-rs-form-hint-text=\"\">{children()}</span>\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    FormPrimitive, FormSectionPrimitive, FormActionsPrimitive,\n    FormFieldPrimitive, FormLabelPrimitive, FormErrorPrimitive, FormHintPrimitive,\n};\npub use canonrs_core::primitives::{\n    FormMethod, FormEnctype, FormValidationState, FieldValidationState,\n};\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Form(\n    children: Children,\n    #[prop(into, default = String::new())] action: String,\n    #[prop(default = FormMethod::Post)] method: FormMethod,\n    #[prop(default = FormEnctype::UrlEncoded)] enctype: FormEnctype,\n    #[prop(default = FormValidationState::Idle)] validation: FormValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = true)] novalidate: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormPrimitive\n            action=action method=method enctype=enctype\n            validation=validation disabled=disabled\n            novalidate=novalidate class=class\n        >\n            {children()}\n        </FormPrimitive>\n    }\n}\n\n#[component]\npub fn FormSection(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormSectionPrimitive aria_label=aria_label.unwrap_or_default() class=class>\n            {children()}\n        </FormSectionPrimitive>\n    }\n}\n\n#[component]\npub fn FormActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormActionsPrimitive class=class>\n            {children()}\n        </FormActionsPrimitive>\n    }\n}\n\n#[component]\npub fn FormField(\n    children: ChildrenFn,\n    #[prop(default = FieldValidationState::Idle)] validation: FieldValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormFieldPrimitive validation=validation disabled=disabled class=class>\n            {children()}\n        </FormFieldPrimitive>\n    }\n}\n\n#[component]\npub fn FormLabel(\n    children: Children,\n    #[prop(into, default = String::new())] html_for: String,\n    #[prop(default = false)] required: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormLabelPrimitive html_for=html_for required=required class=class>\n            {children()}\n        </FormLabelPrimitive>\n    }\n}\n\n#[component]\npub fn FormError(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormErrorPrimitive class=class>\n            {children()}\n        </FormErrorPrimitive>\n    }\n}\n\n#[component]\npub fn FormHint(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <FormHintPrimitive class=class>\n            {children()}\n        </FormHintPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Form Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\npub use canonrs_core::primitives::{FormValidationState, FormMethod, FormEnctype};\npub use super::form_ui::FieldValidationState;\npub use canonrs_core::meta::DisabledState;\nuse super::form_ui::{\n    Form as FormUi, FormSection as FormSectionUi, FormActions as FormActionsUi,\n    FormField as FormFieldUi, FormLabel as FormLabelUi,\n    FormHint as FormHintUi, FormError as FormErrorUi,\n};\n\n#[component]\npub fn Form(\n    children: Children,\n    #[prop(into, default = String::new())] action: String,\n    #[prop(default = FormMethod::Post)] method: FormMethod,\n    #[prop(default = FormEnctype::UrlEncoded)] enctype: FormEnctype,\n    #[prop(default = FormValidationState::Idle)] validation: FormValidationState,\n) -> impl IntoView {\n    view! { <FormUi action=action method=method enctype=enctype validation=validation>{children()}</FormUi> }\n}\n\n#[component]\npub fn FormSection(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let aria = aria_label.unwrap_or_default();\n    view! { <FormSectionUi aria_label=aria class=class>{children()}</FormSectionUi> }\n}\n\n#[component]\npub fn FormActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <FormActionsUi class=class>{children()}</FormActionsUi> }\n}\n\n#[component]\npub fn FormField(\n    children: ChildrenFn,\n    #[prop(default = FieldValidationState::Idle)] validation: FieldValidationState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <FormFieldUi validation=validation disabled=disabled class=class>{children()}</FormFieldUi> }\n}\n\n#[component]\npub fn FormLabel(\n    children: Children,\n    #[prop(into, default = String::new())] html_for: String,\n    #[prop(default = false)] required: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <FormLabelUi html_for=html_for required=required class=class>{children()}</FormLabelUi> }\n}\n\n#[component]\npub fn FormHint(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <FormHintUi class=class>{children()}</FormHintUi> }\n}\n\n#[component]\npub fn FormError(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <FormErrorUi class=class>{children()}</FormErrorUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{FormValidationState, FormMethod, FormEnctype}; \n\npub const FORM_API: ComponentApi = ComponentApi {\n    id: \"form\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"action\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"method\", kind: PropType::Enum(&[\"post\", \"get\"]), required: false, default: Some(\"post\"), description: \"Prop value\" },\n        PropDef { name: \"enctype\", kind: PropType::Enum(&[\"url-encoded\", \"multipart\", \"text\"]), required: false, default: Some(\"url-encoded\"), description: \"Prop value\" },\n        PropDef { name: \"validation\", kind: PropType::Enum(&[\"idle\", \"submitting\", \"success\", \"error\"]), required: false, default: Some(\"idle\"), description: \"Prop value\" },\n    ],\n};\n\npub const FORMSECTION_API: ComponentApi = ComponentApi {\n    id: \"form-section\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const FORMACTIONS_API: ComponentApi = ComponentApi {\n    id: \"form-actions\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const FORMFIELD_API: ComponentApi = ComponentApi {\n    id: \"form-field\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"validation\", kind: PropType::Enum(&[\"idle\", \"valid\", \"invalid\", \"warning\"]), required: false, default: Some(\"idle\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const FORMLABEL_API: ComponentApi = ComponentApi {\n    id: \"form-label\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"html_for\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"required\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const FORMHINT_API: ComponentApi = ComponentApi {\n    id: \"form-hint\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const FORMERROR_API: ComponentApi = ComponentApi {\n    id: \"form-error\",\n    description: \"Form component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::form_boundary::{Form, FormActions, FormSection, FormField, FormLabel, FormHint, FormError};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse crate::ui::button::button_boundary::Button;\nuse canonrs_core::primitives::ButtonVariant;\nuse crate::ui::input::input_boundary::Input;\n\n#[component]\npub fn FormShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Form>\n                <FormSection>\n                    <FormField>\n                        <FormLabel html_for=\"name\" required=true><span>\"Full name\"</span></FormLabel>\n                        <FormHint><span>\"Your full legal name.\"</span></FormHint>\n                        <Input placeholder=\"John Doe\" />\n                    </FormField>\n                    <FormField>\n                        <FormLabel html_for=\"email\"><span>\"Email\"</span></FormLabel>\n                        <Input placeholder=\"john@example.com\" />\n                    </FormField>\n                </FormSection>\n                <FormActions>\n                    <Button variant=ButtonVariant::Primary><span>\"Submit\"</span></Button>\n                </FormActions>\n            </Form>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Form lifecycle and validation state enforced at container level.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With validation\"</span>\n                <Form>\n                    <FormSection>\n                        <FormField >\n                            <FormLabel html_for=\"email2\"><span>\"Email\"</span></FormLabel>\n                            <Input placeholder=\"invalid@\" />\n                            <FormError><span>\"Please enter a valid email address.\"</span></FormError>\n                        </FormField>\n                        <FormField >\n                            <FormLabel html_for=\"name2\"><span>\"Name\"</span></FormLabel>\n                            <Input placeholder=\"John Doe\" />\n                        </FormField>\n                    </FormSection>\n                    <FormActions>\n                        <Button variant=ButtonVariant::Primary><span>\"Submit\"</span></Button>\n                    </FormActions>\n                </Form>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container",
      "stack"
    ]
  },
  {
    "id": "form_error_summary",
    "label": "Form Error Summary",
    "category": "Form",
    "description": "Form validation error summary",
    "keywords": "",
    "pain": "Form errors scattered and not announced collectively",
    "promise": "All form errors announced together with structured summary",
    "why": "FormErrorSummaryPrimitive uses role=\"alert\" with aria-atomic to ensure full error announcement. Errors are grouped and structured. This guarantees accessibility and visibility of all validation issues.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\"Error\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <FormErrorSummary errors=vec![] />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "form validation",
      "multi-field errors"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "input_otp",
      "textarea",
      "field",
      "label",
      "checkbox"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! FormErrorSummary Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[component]\npub fn FormErrorSummaryPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_fes = crate::infra::uid::generate(\"fes\");\n    view! {\n        <div\n            data-rs-form-error-summary=\"\"\n            data-rs-uid=uid_fes\n            role=\"alert\"\n            aria-live=\"assertive\"\n            aria-atomic=\"true\"\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    FormErrorSummaryPrimitive\n};\n\n#[derive(Clone, Debug, PartialEq)]\npub struct FormError { pub field_label: String, pub message: String }\n\n#[component]\npub fn FormErrorSummary(#[prop(default = vec![])] errors: Vec<FormError>, #[prop(into, default = \"Please fix the following errors:\".to_string())] title: String, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <FormErrorSummaryPrimitive class=class>\n            <>{title}</>\n            <>\n                {errors.iter().map(|e| view! {\n                    <>\n                        <>\n                            {e.field_label.clone()}{\": \"}{e.message.clone()}\n                        </>\n                    </>\n                }).collect_view()}\n            </>\n        </FormErrorSummaryPrimitive>\n    }\n}\n",
    "boundary_src": "//! FormErrorSummary Island — Canon Rule passthrough\nuse leptos::prelude::*;\npub use super::form_error_summary_ui::FormError;\n\n#[component]\npub fn FormErrorSummary(\n    #[prop(optional)] errors: Option<Vec<FormError>>,\n    #[prop(into, default = String::from(\"Please fix the following errors:\"))] title: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::form_error_summary_ui::FormErrorSummary\n            errors=errors.unwrap_or_default()\n            title=title\n            class=class\n        />\n}\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const FORMERRORSUMMARY_API: ComponentApi = ComponentApi {\n    id: \"form-error-summary\",\n    description: \"Form validation error summary\",\n    props: &[\n        PropDef { name: \"errors\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: Some(\"Please fix the following errors:\"), description: \"Title slot or text\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::form_error_summary_boundary::{FormErrorSummary, FormError};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn FormErrorSummaryShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <FormErrorSummary\n                errors=vec![\n                    FormError { field_label: \"Email\".to_string(),    message: \"Required field.\".to_string() },\n                    FormError { field_label: \"Password\".to_string(), message: \"Must be at least 8 characters.\".to_string() },\n                ]\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"All form errors announced together with structured summary.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Single error\"</span>\n                <FormErrorSummary\n                    title=\"Please fix this error:\"\n                    errors=vec![\n                        FormError { field_label: \"Name\".to_string(), message: \"Cannot be empty.\".to_string() },\n                    ]\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "hero_ui",
    "label": "Hero UI",
    "category": "Display",
    "description": "Hero typography and label components",
    "keywords": "",
    "pain": "Hero sections lack consistent structure and semantic grouping",
    "promise": "Hero content structured via explicit semantic primitives",
    "why": "HeroPrimitive defines a structural block with dedicated parts like title, description and actions. Each part is explicitly declared. This guarantees predictable layout composition.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"hero\">\n    <h1>\"Title\"</h1>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <HeroTitle>\"Title\"</HeroTitle>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "landing pages",
      "marketing headers"
    ],
    "related": [
      "card",
      "resizable",
      "scroll_area",
      "aspect_ratio",
      "page_header",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Zero Drift",
      "Deterministic API"
    ],
    "pillar": "layout",
    "primitive_src": "",
    "ui_src": "",
    "boundary_src": "",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const HEROTITLE_API: ComponentApi = ComponentApi {\n    id: \"hero-title\",\n    description: \"Hero typography and label components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HEROSUBTITLE_API: ComponentApi = ComponentApi {\n    id: \"hero-subtitle\",\n    description: \"Hero typography and label components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HERODESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"hero-description\",\n    description: \"Hero typography and label components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HEROMEDIA_API: ComponentApi = ComponentApi {\n    id: \"hero-media\",\n    description: \"Hero typography and label components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HEROACTIONS_API: ComponentApi = ComponentApi {\n    id: \"hero-actions\",\n    description: \"Hero typography and label components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse canonrs_core::slot;\nuse crate::blocks::hero::hero_block::{Hero, HeroVariant};\nuse super::hero_boundary::{HeroTitle, HeroSubtitle, HeroDescription, HeroActions};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse crate::ui::button::button_boundary::Button;\nuse canonrs_core::primitives::ButtonVariant;\n\n#[component]\npub fn HeroShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Hero\n                content=slot!(|| view! {\n                    <HeroTitle>\"Build faster with CanonRS\"</HeroTitle>\n                    <HeroSubtitle>\"A design system built for production.\"</HeroSubtitle>\n                    <HeroDescription>\"Composable, accessible, and fully typed components for Leptos.\"</HeroDescription>\n                }.into_any())\n                actions=slot!(|| view! {\n                    <HeroActions>\n                        <Button variant=ButtonVariant::Primary>\"Get Started\"</Button>\n                        <Button variant=ButtonVariant::Ghost>\"View Docs\"</Button>\n                    </HeroActions>\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Composable subcomponents — use only what you need.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Split variant\"</span>\n                <Hero\n                    variant=HeroVariant::Split\n                    content=slot!(|| view! {\n                        <HeroTitle>\"Visual storytelling\"</HeroTitle>\n                        <HeroSubtitle>\"Media and content side by side.\"</HeroSubtitle>\n                    }.into_any())\n                    media=slot!(|| view! {\n                        <img src=\"/placeholder.png\" alt=\"Hero media example\" />\n                    }.into_any())\n                />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "hero_block"
    ],
    "blocks_primitives": [
      "container",
      "stack",
      "flex"
    ]
  },
  {
    "id": "hover_card",
    "label": "Hover Card",
    "category": "Overlay",
    "description": "Hover card popup",
    "keywords": "",
    "pain": "Hover previews break focus and visibility synchronization",
    "promise": "Hover state and positioning enforced via visibility contract",
    "why": "HoverCardPrimitive uses VisibilityState and side enums to control display. Trigger and content share synchronized state. This guarantees consistent hover behavior and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  <div on:mouseover=show>\"Hover\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <HoverCard>\n    <HoverCardTrigger>\"Hover\"</HoverCardTrigger>\n    <HoverCardContent>\"Content\"</HoverCardContent>\n  </HoverCard>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "user previews",
      "tooltips with content"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "sheet",
      "modal",
      "confirm_dialog",
      "tooltip",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! HoverCard Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum HoverCardSide {\n    #[default]\n    Top,\n    Bottom,\n    Left,\n    Right,\n}\n\nimpl HoverCardSide {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Top    => \"top\",\n            Self::Bottom => \"bottom\",\n            Self::Left   => \"left\",\n            Self::Right  => \"right\",\n        }\n    }\n}\n\n\n#[component]\npub fn HoverCardPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_hc = crate::infra::uid::generate(\"hc\");\n    view! {\n        <div\n            data-rs-hover-card=\"\"\n            data-rs-uid=uid_hc\n            data-rs-interaction=\"overlay\"\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn HoverCardTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span\n            data-rs-hover-card-trigger=\"\"\n            data-rs-state=state.as_str()\n            aria-expanded=state.aria_expanded()\n            tabindex=\"0\"\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn HoverCardContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = HoverCardSide::Top)] side: HoverCardSide,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-hover-card-content=\"\"\n            data-rs-state=state.as_str()\n            data-rs-side=side.as_str()\n            role=\"tooltip\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    HoverCardPrimitive, HoverCardTriggerPrimitive, HoverCardContentPrimitive,\n    HoverCardSide,\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn HoverCard(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <HoverCardPrimitive state=state class=class>\n            {children()}\n        </HoverCardPrimitive>\n    }\n}\n\n#[component]\npub fn HoverCardTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <HoverCardTriggerPrimitive class=class>{children()}</HoverCardTriggerPrimitive> }\n}\n\n#[component]\npub fn HoverCardContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = HoverCardSide::Top)] side: HoverCardSide,\n) -> impl IntoView {\n    view! {\n        <HoverCardContentPrimitive side=side class=class>\n            {children()}\n        </HoverCardContentPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! HoverCard Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::hover_card_ui::{\n    HoverCard as HoverCardUi,\n    HoverCardTrigger as HoverCardTriggerUi,\n    HoverCardContent as HoverCardContentUi\n};\npub use canonrs_core::primitives::HoverCardSide;\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn HoverCard(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! {\n        <HoverCardUi state=VisibilityState::Closed class=class.unwrap_or_default()>\n            {children()}\n        </HoverCardUi>\n    }\n}\n\n#[component]\npub fn HoverCardTrigger(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <HoverCardTriggerUi class=class.unwrap_or_default()>{children()}</HoverCardTriggerUi> }\n}\n\n#[component]\npub fn HoverCardContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n    #[prop(default = HoverCardSide::Top)] side: HoverCardSide,\n) -> impl IntoView {\n    view! { <HoverCardContentUi side=side class=class.unwrap_or_default()>{children()}</HoverCardContentUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{HoverCardSide}; \n\npub const HOVERCARD_API: ComponentApi = ComponentApi {\n    id: \"hover-card\",\n    description: \"Hover card popup\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HOVERCARDTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"hover-card-trigger\",\n    description: \"Hover card popup\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const HOVERCARDCONTENT_API: ComponentApi = ComponentApi {\n    id: \"hover-card-content\",\n    description: \"Hover card popup\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n        PropDef { name: \"side\", kind: PropType::Enum(&[\"top\", \"bottom\", \"left\", \"right\"]), required: false, default: Some(\"top\"), description: \"Tooltip or popover side\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::hover_card_boundary::{HoverCard, HoverCardTrigger, HoverCardContent, HoverCardSide};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn HoverCardShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <HoverCard>\n                <HoverCardTrigger>\"Hover me\"</HoverCardTrigger>\n                <HoverCardContent side=HoverCardSide::Bottom>\n                    <p>\"This card appears on hover.\"</p>\n                </HoverCardContent>\n            </HoverCard>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"HoverCard appears on mouse enter and dismisses on mouse leave.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sides\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <HoverCard>\n                        <HoverCardTrigger>\"Top\"</HoverCardTrigger>\n                        <HoverCardContent side=HoverCardSide::Top>\"Opens above\"</HoverCardContent>\n                    </HoverCard>\n                    <HoverCard>\n                        <HoverCardTrigger>\"Bottom\"</HoverCardTrigger>\n                        <HoverCardContent side=HoverCardSide::Bottom>\"Opens below\"</HoverCardContent>\n                    </HoverCard>\n                    <HoverCard>\n                        <HoverCardTrigger>\"Right\"</HoverCardTrigger>\n                        <HoverCardContent side=HoverCardSide::Right>\"Opens right\"</HoverCardContent>\n                    </HoverCard>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "icon",
    "label": "Icon",
    "category": "Display",
    "description": "SVG icon display",
    "keywords": "",
    "pain": "Icons lack consistent sizing and variant handling",
    "promise": "Icon size and variant enforced via typed enums",
    "why": "Icon component encodes size and variant through enums. These map directly to data attributes. This guarantees consistent rendering and eliminates class-based inconsistencies.\n",
    "before": "// ❌ Typical\nview! {\n  <svg class=\"icon-lg\">\"★\"</svg>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Icon size=IconSize::Md>\"★\"</Icon>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "buttons",
      "status indicators"
    ],
    "related": [
      "avatar",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "#![allow(unused_variables)]\n//! @canon-level: strict\n//! Icon Primitive - SVG wrapper\n\nuse leptos::prelude::*;\n\n#[component]\npub fn IconPrimitive(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n    #[prop(optional, into)] id: Option<String>,\n) -> impl IntoView {\n    let _uid_ico = crate::infra::uid::generate(\"ico\");\n    view! {\n        <span data-rs-icon=\"\" class={class} id=id>\n        data-rs-uid=uid_ico\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn IconInnerPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <span data-rs-icon-inner=\"\">{children()}</span> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{IconPrimitive, IconInnerPrimitive};\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum IconSize { Sm, Md, Lg }\nimpl IconSize { pub fn as_str(&self) -> &'static str { match self { Self::Sm => \"sm\", Self::Md => \"md\", Self::Lg => \"lg\" } } }\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum IconVariant { Default, Muted, Primary, Destructive, Success, Warning }\nimpl IconVariant { pub fn as_str(&self) -> &'static str { match self { Self::Default => \"default\", Self::Muted => \"muted\", Self::Primary => \"primary\", Self::Destructive => \"destructive\", Self::Success => \"success\", Self::Warning => \"warning\" } } }\n\n#[component]\npub fn Icon(#[prop(optional)] children: Option<Children>, #[prop(default = IconSize::Md)] size: IconSize, #[prop(default = IconVariant::Default)] variant: IconVariant, #[prop(default = false)] spin: bool, #[prop(default = String::new())] class: String, #[prop(into, optional)] id: Option<String>) -> impl IntoView {\n    view! {\n        <IconPrimitive class=class>\n            <IconInnerPrimitive>\n                {children.map(|c| c())}\n            </IconInnerPrimitive>\n        </IconPrimitive>\n    }\n}\n",
    "boundary_src": "//! Icon Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\npub use super::icon_ui::{IconSize, IconVariant};\nuse super::icon_ui::Icon as IconUi;\n\n#[component]\npub fn Icon(\n    #[prop(optional)] children:                        Option<Children>,\n    #[prop(default = IconSize::Md)] size:              IconSize,\n    #[prop(default = IconVariant::Default)] variant:   IconVariant,\n    #[prop(default = false)] spin:                     bool,\n    #[prop(into, default = String::new())] class:      String,\n    #[prop(into, optional)] id:                        Option<String>,\n) -> impl IntoView {\n    view! {\n        <IconUi size=size variant=variant spin=spin class=class id=id.unwrap_or_default()>\n            {children.map(|c| c())}\n        </IconUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const ICON_API: ComponentApi = ComponentApi {\n    id: \"icon\",\n    description: \"SVG icon display\",\n    props: &[\n        PropDef { name: \"size\", kind: PropType::String, required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"variant\", kind: PropType::String, required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"spin\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::icon_boundary::{Icon, IconSize, IconVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn IconShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                <Icon size=IconSize::Lg variant=IconVariant::Primary>\"★\"</Icon>\n                <Icon size=IconSize::Lg>\"★\"</Icon>\n                <Icon size=IconSize::Lg variant=IconVariant::Muted>\"★\"</Icon>\n            </Stack>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Icon size and variant enforced via typed enums.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Icon size=IconSize::Sm>\"★\"</Icon>\n                    <Icon size=IconSize::Md>\"★\"</Icon>\n                    <Icon size=IconSize::Lg>\"★\"</Icon>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Icon>\"★\"</Icon>\n                    <Icon variant=IconVariant::Muted>\"★\"</Icon>\n                    <Icon variant=IconVariant::Primary>\"★\"</Icon>\n                    <Icon variant=IconVariant::Destructive>\"★\"</Icon>\n                    <Icon variant=IconVariant::Success>\"★\"</Icon>\n                    <Icon variant=IconVariant::Warning>\"★\"</Icon>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Spin\"</span>\n                <Icon spin=true>\"⟳\"</Icon>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "icon_button",
    "label": "Icon Button",
    "category": "Action",
    "description": "Button with icon only",
    "keywords": "",
    "pain": "Icon buttons miss accessibility labels and loading state handling",
    "promise": "Accessibility and loading state enforced in button contract",
    "why": "IconButtonPrimitive requires aria-label and encodes loading and disabled states. ARIA attributes are derived automatically. This guarantees accessible and predictable behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <button><svg /></button>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <IconButton aria_label=\"Close\">\"×\"</IconButton>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "close actions",
      "toolbar buttons"
    ],
    "related": [
      "button",
      "button_group",
      "copy_button",
      "link"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "action",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! IconButton Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::{DisabledState, LoadingState, ToggleState};\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Default, Debug)]\npub enum IconButtonSize {\n    Xs,\n    Sm,\n    #[default]\n    Md,\n    Lg,\n    Xl,\n}\nimpl IconButtonSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Xs => \"xs\",\n            Self::Sm => \"sm\",\n            Self::Md => \"md\",\n            Self::Lg => \"lg\",\n            Self::Xl => \"xl\",\n        }\n    }\n}\n\n#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Default, Debug)]\npub enum IconButtonVariant {\n    #[default]\n    Default,\n    Ghost,\n    Outline,\n    Solid,\n    Subtle,\n    Destructive,\n}\nimpl IconButtonVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default     => \"default\",\n            Self::Ghost       => \"ghost\",\n            Self::Outline     => \"outline\",\n            Self::Solid       => \"solid\",\n            Self::Subtle      => \"subtle\",\n            Self::Destructive => \"destructive\",\n        }\n    }\n}\n\n#[component]\npub fn IconButtonPrimitive(\n    children: Children,\n    #[prop(into)] aria_label: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = LoadingState::Idle)] loading: LoadingState,\n    #[prop(default = IconButtonVariant::Default)] variant: IconButtonVariant,\n    #[prop(default = IconButtonSize::Md)] size: IconButtonSize,\n    #[prop(optional)] pressed: Option<ToggleState>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ib = crate::infra::uid::generate(\"ib\");\n    let ta = pressed;\n    view! {\n        <button\n            type=\"button\"\n            data-rs-icon-button=\"\"\n            data-rs-uid=uid_ib\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            data-rs-size=size.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-loading=loading.as_str()\n            data-rs-toggle=ta.map(|t| t.as_str())\n            disabled=disabled.disabled()\n            aria-disabled=disabled.aria_disabled()\n            aria-busy=loading.aria_busy()\n            aria-pressed=ta.as_ref().map(|t| t.aria_pressed())\n            aria-label=aria_label\n            class=class\n        >\n            <span data-rs-icon-button-inner=\"\">{children()}</span>\n        </button>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::meta::{DisabledState, LoadingState, ToggleState};\nuse canonrs_core::primitives::IconButtonPrimitive;\npub use canonrs_core::primitives::{IconButtonSize, IconButtonVariant};\n\n#[component]\npub fn IconButton(\n    children: Children,\n    aria_label: String,\n    #[prop(default = IconButtonSize::Md)] size: IconButtonSize,\n    #[prop(default = IconButtonVariant::Default)] variant: IconButtonVariant,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = LoadingState::Idle)] loading: LoadingState,\n    #[prop(optional)] pressed: Option<ToggleState>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <IconButtonPrimitive\n            aria_label=aria_label\n            size=size\n            variant=variant\n            disabled=disabled\n            loading=loading\n            pressed=pressed.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </IconButtonPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! IconButton Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::icon_button_ui::IconButton as IconButtonUi;\npub use canonrs_core::primitives::{\n    IconButtonVariant,\n    IconButtonSize\n};\nuse canonrs_core::meta::{DisabledState, LoadingState, ToggleState};\n\n#[component]\npub fn IconButton(\n    children: Children,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(default = IconButtonVariant::Default)] variant: IconButtonVariant,\n    #[prop(default = IconButtonSize::Md)] size: IconButtonSize,\n    #[prop(default = false)] disabled: bool,\n    #[prop(default = false)] pressed: bool,\n    #[prop(default = false)] loading: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let disabled_state = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    let loading_state  = if loading  { LoadingState::Loading }   else { LoadingState::Idle };\n    let pressed_state  = if pressed  { ToggleState::On }         else { ToggleState::Off };\n    view! {\n        <IconButtonUi\n            aria_label=aria_label\n            variant=variant\n            size=size\n            disabled=disabled_state\n            loading=loading_state\n            pressed=pressed_state\n            class=class\n        >\n            {children()}\n        </IconButtonUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{IconButtonVariant, IconButtonSize}; \n\npub const ICONBUTTON_API: ComponentApi = ComponentApi {\n    id: \"icon-button\",\n    description: \"Button with icon only\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"ghost\", \"outline\", \"solid\", \"subtle\", \"destructive\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"xs\", \"sm\", \"md\", \"lg\", \"xl\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"pressed\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"loading\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::icon_button_boundary::{IconButton, IconButtonVariant, IconButtonSize};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\n\n#[component]\npub fn IconButtonShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <IconButton aria_label=\"Close\" variant=IconButtonVariant::Solid size=IconButtonSize::Xl>\n                \"✕\"\n            </IconButton>\n            <p data-rs-showcase-preview-anchor()>\n                \"Accessibility and loading state enforced in button contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <IconButton aria_label=\"Default\"     variant=IconButtonVariant::Default>\"★\"</IconButton>\n                    <IconButton aria_label=\"Ghost\"       variant=IconButtonVariant::Ghost>\"★\"</IconButton>\n                    <IconButton aria_label=\"Outline\"     variant=IconButtonVariant::Outline>\"★\"</IconButton>\n                    <IconButton aria_label=\"Solid\"       variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    <IconButton aria_label=\"Subtle\"      variant=IconButtonVariant::Subtle>\"★\"</IconButton>\n                    <IconButton aria_label=\"Destructive\" variant=IconButtonVariant::Destructive>\"★\"</IconButton>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <IconButton aria_label=\"Xs\" size=IconButtonSize::Xs variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    <IconButton aria_label=\"Sm\" size=IconButtonSize::Sm variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    <IconButton aria_label=\"Md\" size=IconButtonSize::Md variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    <IconButton aria_label=\"Lg\" size=IconButtonSize::Lg variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    <IconButton aria_label=\"Xl\" size=IconButtonSize::Xl variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <Grid cols=GridCols::Four>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Default\"</span>\n                        <IconButton aria_label=\"Default\" variant=IconButtonVariant::Solid>\"★\"</IconButton>\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Pressed\"</span>\n                        <IconButton aria_label=\"Pressed\" variant=IconButtonVariant::Solid pressed=true>\"★\"</IconButton>\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                        <IconButton aria_label=\"Disabled\" variant=IconButtonVariant::Solid disabled=true>\"★\"</IconButton>\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Loading\"</span>\n                        <IconButton aria_label=\"Loading\" variant=IconButtonVariant::Solid loading=true>\"★\"</IconButton>\n                    </Stack>\n                </Grid>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack",
      "grid"
    ]
  },
  {
    "id": "inline_meta",
    "label": "Inline Meta",
    "category": "Display",
    "description": "Inline metadata display for stats, versions, dates and counts",
    "keywords": "",
    "pain": "Inline metadata mixes labels and values without structure",
    "promise": "Metadata pairs structured and consistently rendered",
    "why": "InlineMetaPrimitive separates label and value into explicit primitives. This enforces consistent layout and semantics. It prevents ad-hoc inline data rendering.\n",
    "before": "// ❌ Typical\nview! {\n  <span>\"Rules: 284\"</span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <InlineMeta>\n    <InlineMetaLabel>\"Rules\"</InlineMetaLabel>\n    <InlineMetaValue>\"284\"</InlineMetaValue>\n  </InlineMeta>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "stats display",
      "metadata labels"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! InlineMeta Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[component]\npub fn InlineMetaPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_im = crate::infra::uid::generate(\"im\");\n    view! {\n        <span\n            data-rs-inline-meta=\"\"\n            data-rs-uid=uid_im\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn InlineMetaLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-inline-meta-label=\"\" class=class>{children()}</span>\n    }\n}\n\n#[component]\npub fn InlineMetaValuePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-inline-meta-value=\"\" class=class>{children()}</span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{InlineMetaPrimitive, InlineMetaLabelPrimitive, InlineMetaValuePrimitive};\n\n#[component]\npub fn InlineMeta(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineMetaPrimitive class=class>\n            {children()}\n        </InlineMetaPrimitive>\n    }\n}\n\n#[component]\npub fn InlineMetaLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineMetaLabelPrimitive class=class>\n            {children()}\n        </InlineMetaLabelPrimitive>\n    }\n}\n\n#[component]\npub fn InlineMetaValue(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineMetaValuePrimitive class=class>\n            {children()}\n        </InlineMetaValuePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! InlineMeta Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::inline_meta_ui::{\n    InlineMeta as InlineMetaUi,\n    InlineMetaLabel as InlineMetaLabelUi,\n    InlineMetaValue as InlineMetaValueUi\n};\n\n#[component]\npub fn InlineMeta(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <InlineMetaUi class=class>{children()}</InlineMetaUi> }\n}\n\n#[component]\npub fn InlineMetaLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <InlineMetaLabelUi class=class>{children()}</InlineMetaLabelUi> }\n}\n\n#[component]\npub fn InlineMetaValue(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <InlineMetaValueUi class=class>{children()}</InlineMetaValueUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const INLINEMETA_API: ComponentApi = ComponentApi {\n    id: \"inline-meta\",\n    description: \"Inline metadata display for stats, versions, dates and counts\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const INLINEMETALABEL_API: ComponentApi = ComponentApi {\n    id: \"inline-meta-label\",\n    description: \"Inline metadata display for stats, versions, dates and counts\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const INLINEMETAVALUE_API: ComponentApi = ComponentApi {\n    id: \"inline-meta-value\",\n    description: \"Inline metadata display for stats, versions, dates and counts\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::inline_meta_boundary::{InlineMeta, InlineMetaLabel, InlineMetaValue};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn InlineMetaShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <InlineMeta>\n                <InlineMetaLabel>\"Author\"</InlineMetaLabel>\n                <InlineMetaValue>\"Cristiano Bertulucci\"</InlineMetaValue>\n            </InlineMeta>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Metadata pairs structured and consistently rendered.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Pairs\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"Status\"</InlineMetaLabel>\n                        <InlineMetaValue>\"Active\"</InlineMetaValue>\n                    </InlineMeta>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"Version\"</InlineMetaLabel>\n                        <InlineMetaValue>\"1.4.2\"</InlineMetaValue>\n                    </InlineMeta>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"License\"</InlineMetaLabel>\n                        <InlineMetaValue>\"MIT\"</InlineMetaValue>\n                    </InlineMeta>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Context examples\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"Rules\"</InlineMetaLabel>\n                        <InlineMetaValue>\"284\"</InlineMetaValue>\n                    </InlineMeta>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"Components\"</InlineMetaLabel>\n                        <InlineMetaValue>\"97\"</InlineMetaValue>\n                    </InlineMeta>\n                    <InlineMeta>\n                        <InlineMetaLabel>\"Last updated\"</InlineMetaLabel>\n                        <InlineMetaValue>\"2025-06-01\"</InlineMetaValue>\n                    </InlineMeta>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "inline_notice",
    "label": "Inline Notice",
    "category": "Feedback",
    "description": "Inline notice message",
    "keywords": "",
    "pain": "Inline messages use wrong ARIA roles and urgency levels",
    "promise": "Role and aria-live automatically enforced by variant",
    "why": "InlineNoticeVariant controls both semantic role and aria-live behavior. Error uses alert/assertive while others use status/polite. This guarantees correct urgency signaling without manual ARIA decisions.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"notice error\">\"Error\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <InlineNotice variant=InlineNoticeVariant::Error>\n    <InlineNoticeContent>\"Error\"</InlineNoticeContent>\n  </InlineNotice>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "form inline errors",
      "contextual hints"
    ],
    "related": [
      "toast",
      "alert",
      "banner",
      "callout",
      "status_dot"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! InlineNotice Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum InlineNoticeVariant {\n    #[default]\n    Default,\n    Info,\n    Success,\n    Warning,\n    Error,\n}\n\nimpl InlineNoticeVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Info    => \"info\",\n            Self::Success => \"success\",\n            Self::Warning => \"warning\",\n            Self::Error   => \"error\",\n        }\n    }\n\n    pub fn role(&self) -> &'static str {\n        match self {\n            Self::Error => \"alert\",\n            _           => \"status\",\n        }\n    }\n\n    pub fn aria_live(&self) -> &'static str {\n        match self {\n            Self::Error => \"assertive\",\n            _           => \"polite\",\n        }\n    }\n}\n\n#[component]\npub fn InlineNoticePrimitive(\n    children: Children,\n    #[prop(default = InlineNoticeVariant::Default)] variant: InlineNoticeVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_in = crate::infra::uid::generate(\"in\");\n    view! {\n        <div\n            data-rs-inline-notice=\"\"\n            data-rs-uid=uid_in\n            data-rs-variant=variant.as_str()\n            role=variant.role()\n            aria-live=variant.aria_live()\n            aria-atomic=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn InlineNoticeIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span\n            data-rs-inline-notice-icon=\"\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn InlineNoticeContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-inline-notice-content=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    InlineNoticePrimitive, InlineNoticeIconPrimitive,\n    InlineNoticeContentPrimitive,\n};\npub use canonrs_core::primitives::InlineNoticeVariant;\n\n#[component]\npub fn InlineNotice(\n    children: Children,\n    #[prop(default = InlineNoticeVariant::Default)] variant: InlineNoticeVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineNoticePrimitive variant=variant class=class>\n            {children()}\n        </InlineNoticePrimitive>\n    }\n}\n\n#[component]\npub fn InlineNoticeIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineNoticeIconPrimitive class=class>\n            {children()}\n        </InlineNoticeIconPrimitive>\n    }\n}\n\n#[component]\npub fn InlineNoticeContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineNoticeContentPrimitive class=class>\n            {children()}\n        </InlineNoticeContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! InlineNotice Boundary — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::inline_notice_ui::{InlineNotice as InlineNoticeUi, InlineNoticeIcon, InlineNoticeContent};\npub use canonrs_core::primitives::InlineNoticeVariant;\n\n#[component]\npub fn InlineNotice(\n    #[prop(optional, into)] content: Option<String>,\n    #[prop(optional, into)] icon:    Option<String>,\n    #[prop(default = InlineNoticeVariant::Default)] variant: InlineNoticeVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InlineNoticeUi variant=variant class=class>\n            {icon.map(|i| view! { <InlineNoticeIcon>{i}</InlineNoticeIcon> })}\n            {content.map(|c| view! { <InlineNoticeContent>{c}</InlineNoticeContent> })}\n        </InlineNoticeUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{InlineNoticeVariant}; \n\npub const INLINENOTICE_API: ComponentApi = ComponentApi {\n    id: \"inline-notice\",\n    description: \"Inline notice message\",\n    props: &[\n        PropDef { name: \"content\", kind: PropType::String, required: false, default: None, description: \"Content region slot\" },\n        PropDef { name: \"icon\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"info\", \"success\", \"warning\", \"error\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::inline_notice_boundary::{InlineNotice, InlineNoticeVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn InlineNoticeShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <InlineNotice variant=InlineNoticeVariant::Info icon=\"ℹ\" content=\"This is an inline informational notice.\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Role and aria-live automatically enforced by variant.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <InlineNotice variant=InlineNoticeVariant::Success icon=\"✓\" content=\"Password updated successfully.\" />\n                    <InlineNotice variant=InlineNoticeVariant::Warning icon=\"⚠\" content=\"This field is required to continue.\" />\n                    <InlineNotice variant=InlineNoticeVariant::Error   icon=\"✕\" content=\"Invalid email address format.\" />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "input",
    "label": "Input",
    "category": "Form",
    "description": "Text input field",
    "keywords": "",
    "pain": "Inputs accept invalid visual states without consistent validation mapping",
    "promise": "Variant and size strictly constrained via typed enums",
    "why": "InputVariant and InputSize define allowed visual states at compile-time. DisabledState is mapped to both DOM and ARIA. This guarantees consistent rendering and prevents invalid combinations.\n",
    "before": "// ❌ Typical\nview! {\n  <input class=\"input error large\" />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Input variant=InputVariant::Error size=InputSize::Lg />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "search fields"
    ],
    "related": [
      "form",
      "input_group",
      "input_otp",
      "textarea",
      "field",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Input Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[derive(Clone, PartialEq, Default, Debug)]\npub enum InputVariant {\n    #[default]\n    Default,\n    Error,\n    Success,\n    Warning,\n}\nimpl InputVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Error   => \"error\",\n            Self::Success => \"success\",\n            Self::Warning => \"warning\",\n        }\n    }\n}\n\n#[derive(Clone, PartialEq, Default, Debug)]\npub enum InputSize {\n    #[default]\n    Md,\n    Sm,\n    Lg,\n}\nimpl InputSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Md => \"md\",\n            Self::Sm => \"sm\",\n            Self::Lg => \"lg\",\n        }\n    }\n}\n\n#[component]\npub fn InputPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = \"text\".to_string())] input_type: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] rs_value: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(default = InputVariant::Default)] variant: InputVariant,\n    #[prop(default = InputSize::Md)] size: InputSize,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Input>>,\n) -> impl IntoView {\n    let uid_inp       = crate::infra::uid::generate(\"inp\");\n    let aria_disabled = if disabled == DisabledState::Disabled { \"true\" } else { \"false\" };\n    let nr            = node_ref.unwrap_or_default();\n    view! {\n        <input\n            data-rs-input=\"\"\n            data-rs-uid=uid_inp\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            data-rs-size=size.as_str()\n            type=input_type\n            class=class\n            name=name\n            prop:value=value\n            data-rs-value=rs_value\n            placeholder=placeholder\n            disabled=disabled.as_bool()\n            aria-disabled=aria_disabled\n            aria-label=aria_label\n            node_ref=nr\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{InputPrimitive, InputVariant, InputSize};\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Input(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = \"text\".to_string())] input_type: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] rs_value: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = InputVariant::Default)] variant: InputVariant,\n    #[prop(default = InputSize::Md)] size: InputSize,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Input>>,\n) -> impl IntoView {\n    view! {\n        <InputPrimitive\n            class=class\n            name=name\n            value=value\n            rs_value=rs_value\n            disabled=disabled\n            placeholder=placeholder\n            aria_label=aria_label\n            input_type=input_type\n            variant=variant\n            size=size\n            node_ref=node_ref.unwrap_or_default()\n        />\n    }\n}\n\n",
    "boundary_src": "//! Input Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::input_ui::Input as InputUi;\npub use canonrs_core::primitives::{\n    InputVariant,\n    InputSize\n};\npub use canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Input(\n    #[prop(into, default = String::new())] class:       String,\n    #[prop(into, default = \"text\".to_string())] input_type: String,\n    #[prop(into, default = String::new())] name:        String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] aria_label:  String,\n    #[prop(default = InputVariant::Default)] variant:   InputVariant,\n    #[prop(default = InputSize::Md)] size:              InputSize,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Input>>,\n) -> impl IntoView {\n    view! {\n        <InputUi\n            class=class\n            input_type=input_type\n            name=name\n            value=value.clone()\n            rs_value=value\n            placeholder=placeholder\n            aria_label=aria_label\n            variant=variant\n            size=size\n            disabled=disabled\n            node_ref=node_ref.unwrap_or_default()\n        />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{InputVariant, InputSize}; \n\npub const INPUT_API: ComponentApi = ComponentApi {\n    id: \"input\",\n    description: \"Text input field\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"input_type\", kind: PropType::String, required: false, default: Some(\"text\"), description: \"HTML input type attribute\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"placeholder\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Placeholder text\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"error\", \"success\", \"warning\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"md\", \"sm\", \"lg\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"node_ref\", kind: PropType::String, required: false, default: None, description: \"DOM node reference\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::input_boundary::{Input, InputVariant, InputSize, DisabledState};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn InputShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Input placeholder=\"Type something...\" />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Variant and size strictly constrained via typed enums.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Grid cols=GridCols::Two>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Default\"</span>\n                        <Input placeholder=\"Default\" variant=InputVariant::Default />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Success\"</span>\n                        <Input placeholder=\"Success\" variant=InputVariant::Success />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Warning\"</span>\n                        <Input placeholder=\"Warning\" variant=InputVariant::Warning />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Error\"</span>\n                        <Input placeholder=\"Error\" variant=InputVariant::Error />\n                    </Stack>\n                </Grid>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Grid cols=GridCols::Three>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Small\"</span>\n                        <Input placeholder=\"Small\" size=InputSize::Sm />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Medium\"</span>\n                        <Input placeholder=\"Medium\" size=InputSize::Md />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <span data-rs-showcase-preview-label=\"\">\"Large\"</span>\n                        <Input placeholder=\"Large\" size=InputSize::Lg />\n                    </Stack>\n                </Grid>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <Input placeholder=\"Disabled\" disabled=DisabledState::Disabled />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack",
      "grid"
    ]
  },
  {
    "id": "input_group",
    "label": "Input Group",
    "category": "Form",
    "description": "Input group with addons",
    "keywords": "",
    "pain": "Input addons break alignment and border radius consistency",
    "promise": "Grouped inputs maintain consistent structure and visual merging",
    "why": "InputGroupPrimitive encodes merge-radius behavior via ActivityState. This ensures inputs and addons render as a unified control. It prevents layout inconsistencies across grouped inputs.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"input-group\">\n    <span>@</span>\n    <input />\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <InputGroup merge_radius=true>\n    <span data-rs-input-group-addon=\"\">\"@\"</span>\n  </InputGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "email fields",
      "currency inputs"
    ],
    "related": [
      "form",
      "input",
      "input_otp",
      "textarea",
      "field",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! InputGroup Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::ToggleState;\n\n#[component]\npub fn InputGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ToggleState::Off)] merge_radius: ToggleState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid_ig = crate::infra::uid::generate(\"ig\");\n    view! {\n        <div\n            data-rs-input-group=\"\"\n            data-rs-uid=uid_ig\n            data-rs-interaction=\"init\"\n            role=\"group\"\n            data-rs-toggle=if merge_radius == ToggleState::On { Some(\"on\") } else { None }\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn InputGroupPrefix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_igp = crate::infra::uid::generate(\"igp\");\n    view! {\n        <div\n            data-rs-input-group-prefix=\"\"\n\n                        data-rs-uid=uid_igp\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn InputGroupSuffix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_igs = crate::infra::uid::generate(\"igs\");\n    view! {\n        <div\n            data-rs-input-group-suffix=\"\"\n\n                        data-rs-uid=uid_igs\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{InputGroupPrimitive, InputGroupPrefix as InputGroupPrefixPrimitive, InputGroupSuffix as InputGroupSuffixPrimitive};\nuse canonrs_core::meta::ToggleState;\n\n#[component]\npub fn InputGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = ToggleState::Off)] merge_radius: ToggleState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    view! {\n        <InputGroupPrimitive class=class merge_radius=merge_radius node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </InputGroupPrimitive>\n    }\n}\n\n\n#[component]\npub fn InputGroupPrefix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InputGroupPrefixPrimitive class=class>\n            {children()}\n        </InputGroupPrefixPrimitive>\n    }\n}\n\n#[component]\npub fn InputGroupSuffix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InputGroupSuffixPrimitive class=class>\n            {children()}\n        </InputGroupSuffixPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! InputGroup Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::input_group_ui::{InputGroup as InputGroupUi, InputGroupPrefix as InputGroupPrefixUi, InputGroupSuffix as InputGroupSuffixUi};\nuse canonrs_core::meta::ToggleState;\n\n#[component]\npub fn InputGroup(\n    children: Children,\n    #[prop(default = false)] merge_radius: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let merge = if merge_radius { ToggleState::On\n} else { ToggleState::Off };\n    view! {\n        <InputGroupUi merge_radius=merge class=class>\n            {children()}\n        </InputGroupUi>\n    }\n}\n\n#[component]\npub fn InputGroupPrefix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InputGroupPrefixUi class=class>\n            {children()}\n        </InputGroupPrefixUi>\n    }\n}\n\n#[component]\npub fn InputGroupSuffix(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <InputGroupSuffixUi class=class>\n            {children()}\n        </InputGroupSuffixUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const INPUTGROUP_API: ComponentApi = ComponentApi {\n    id: \"input-group\",\n    description: \"Input group with addons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"merge_radius\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const INPUTGROUPPREFIX_API: ComponentApi = ComponentApi {\n    id: \"input-group-prefix\",\n    description: \"Input group with addons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const INPUTGROUPSUFFIX_API: ComponentApi = ComponentApi {\n    id: \"input-group-suffix\",\n    description: \"Input group with addons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::input_group_boundary::InputGroup;\nuse crate::ui::input::input_boundary::Input;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn InputGroupShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <InputGroup merge_radius=true>\n                <span data-rs-input-group-addon=\"\">\"@\"</span>\n                <Input placeholder=\"username\" name=\"username\" />\n            </InputGroup>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Grouped inputs maintain consistent structure and visual merging.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Detached\"</span>\n                <InputGroup>\n                    <span data-rs-input-group-addon=\"\">\"@\"</span>\n                    <Input placeholder=\"username\" name=\"username-detached\" />\n                </InputGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"URL input\"</span>\n                <InputGroup merge_radius=true>\n                    <span data-rs-input-group-addon=\"\">\"https://\"</span>\n                    <Input placeholder=\"example.com\" name=\"url\" />\n                </InputGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With suffix\"</span>\n                <InputGroup merge_radius=true>\n                    <Input placeholder=\"0.00\" name=\"amount\" />\n                    <span data-rs-input-group-addon=\"\">\"USD\"</span>\n                </InputGroup>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "input_otp",
    "label": "OTP Input",
    "category": "Form",
    "description": "One-time password input",
    "keywords": "",
    "pain": "OTP inputs require complex state sync across multiple fields",
    "promise": "OTP slots and active state managed automatically",
    "why": "InputOtp distributes value across slots using ActivityState. Each slot reflects position and focus without manual logic. This guarantees synchronized UI and input state.\n",
    "before": "// ❌ Typical\n// multiple inputs with manual focus handling\n",
    "after": "// ✅ CanonRS\nview! {\n  <InputOtp length=6 />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "2FA codes",
      "verification inputs"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "textarea",
      "field",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! InputOtp Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[component]\npub fn InputOtpPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = 1u32)] maxlength: u32,\n    #[prop(into, default = String::new())] pattern: String,\n    #[prop(into, default = String::new())] inputmode: String,\n    #[prop(into, default = String::new())] autocomplete: String,\n) -> impl IntoView {\n    let uid_otp = crate::infra::uid::generate(\"otp\");\n    view! {\n        <input\n            data-rs-input-otp=\"\"\n            data-rs-uid=uid_otp\n            data-rs-interaction=\"init\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            type=\"text\"\n            name={if name.is_empty() { None } else { Some(name) }}\n            value=value\n            disabled=disabled.disabled()\n            maxlength=maxlength.to_string()\n            pattern={if pattern.is_empty() { None } else { Some(pattern) }}\n            inputmode={if inputmode.is_empty() { None } else { Some(inputmode) }}\n            autocomplete={if autocomplete.is_empty() { None } else { Some(autocomplete) }}\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn InputOtpContainerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] disabled: Option<bool>,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-input-otp-container=\"\"\n            data-rs-disabled=disabled.filter(|&d| d).map(|_| \"disabled\")\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn InputOtpSlotsPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <div data-rs-input-otp-slots=\"\">{children()}</div> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{InputOtpPrimitive, InputOtpSlotPrimitive, InputOtpContainerPrimitive, InputOtpSlotsPrimitive};\nuse canonrs_core::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn InputOtp(#[prop(into, default = String::new())] class: String, #[prop(into, default = String::new())] name: String, #[prop(into, default = String::new())] value: String, #[prop(default = DisabledState::Enabled)] disabled: DisabledState, #[prop(default = 6u32)] length: u32) -> impl IntoView {\n    let is_disabled = disabled == DisabledState::Disabled;\n    let slots: Vec<AnyView> = (0..length).map(|i| {\n        let ch = value.chars().nth(i as usize).map(|c| c.to_string()).unwrap_or_default();\n        let state = if !is_disabled && i == value.len() as u32 { ActivityState::Active } else { ActivityState::Inactive };\n        view! { <InputOtpSlotPrimitive state=state>{ch}</InputOtpSlotPrimitive> }.into_any()\n    }).collect();\n    view! {\n        <InputOtpContainerPrimitive disabled=disabled.disabled() class=class>\n            <InputOtpPrimitive name=name value=value.clone() disabled=disabled maxlength=length inputmode=\"numeric\".to_string() autocomplete=\"one-time-code\".to_string() />\n            <InputOtpSlotsPrimitive>{slots}</InputOtpSlotsPrimitive>\n        </InputOtpContainerPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! InputOtp Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::input_otp_ui::InputOtp as InputOtpUi;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn InputOtp(\n    #[prop(default = 6)] length: u32,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] initial_value: String,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let disabled_state = if disabled { DisabledState::Disabled\n} else { DisabledState::Enabled };\n    let val = if !initial_value.is_empty() { initial_value } else { value };\n    view! {\n        <InputOtpUi length=length name=name value=val disabled=disabled_state class=class />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const INPUTOTP_API: ComponentApi = ComponentApi {\n    id: \"input-otp\",\n    description: \"One-time password input\",\n    props: &[\n        PropDef { name: \"length\", kind: PropType::Number, required: false, default: Some(\"6\"), description: \"Prop value\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"initial_value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::input_otp_boundary::InputOtp;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn InputOtpShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <InputOtp length=6 />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"OTP slots and active state managed automatically.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"4 digits\"</span>\n                <InputOtp length=4 />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Filled\"</span>\n                <InputOtp length=6 value=\"123456\".to_string() />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Partial\"</span>\n                <InputOtp length=6 initial_value=\"123\".to_string() />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <InputOtp length=6 disabled=true />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "kbd",
    "label": "Kbd",
    "category": "Display",
    "description": "Keyboard shortcut display",
    "keywords": "",
    "pain": "Keyboard shortcuts displayed inconsistently with ad-hoc styling",
    "promise": "Shortcut representation standardized via size and variant enums",
    "why": "KbdPrimitive encodes size and variant into data attributes. Group and separator primitives enforce consistent composition. This guarantees uniform shortcut display.\n",
    "before": "// ❌ Typical\nview! {\n  <span class=\"kbd\">Ctrl + K</span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <KbdGroup>\n    <Kbd>\"Ctrl\"</Kbd>\n    <KbdSeparator />\n    <Kbd>\"K\"</Kbd>\n  </KbdGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "shortcuts",
      "docs"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Kbd Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum KbdSize {\n    Sm,\n    #[default]\n    Md,\n    Lg,\n}\nimpl KbdSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Sm => \"sm\",\n            Self::Md => \"md\",\n            Self::Lg => \"lg\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum KbdVariant {\n    #[default]\n    Default,\n    Outline,\n    Ghost,\n    Muted,\n}\nimpl KbdVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Outline => \"outline\",\n            Self::Ghost   => \"ghost\",\n            Self::Muted   => \"muted\",\n        }\n    }\n}\n\n#[component]\npub fn KbdPrimitive(\n    children: Children,\n    #[prop(default = KbdSize::Md)] size: KbdSize,\n    #[prop(default = KbdVariant::Default)] variant: KbdVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_kbd = crate::infra::uid::generate(\"kbd\");\n    view! {\n        <kbd\n            data-rs-kbd=\"\"\n            data-rs-uid=uid_kbd\n            data-rs-size=size.as_str()\n            data-rs-variant=variant.as_str()\n            class=class\n        >\n            {children()}\n        </kbd>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{KbdPrimitive, KbdGroupPrimitive, KbdSeparatorPrimitive};\npub use canonrs_core::primitives::{KbdSize, KbdVariant};\n\n#[component]\npub fn Kbd(\n    children: Children,\n    #[prop(default = KbdSize::Md)] size: KbdSize,\n    #[prop(default = KbdVariant::Default)] variant: KbdVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <KbdPrimitive size=size variant=variant class=class>\n            {children()}\n        </KbdPrimitive>\n    }\n}\n\n#[component]\npub fn KbdGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <KbdGroupPrimitive class=class>\n            {children()}\n        </KbdGroupPrimitive>\n    }\n}\n\n#[component]\npub fn KbdSeparator() -> impl IntoView {\n    view! { <KbdSeparatorPrimitive /> }\n}\n\n",
    "boundary_src": "//! Kbd Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\npub use super::kbd_ui::{KbdSize, KbdVariant};\nuse super::kbd_ui;\n\n#[component]\npub fn Kbd(\n    children: Children,\n    #[prop(default = KbdSize::Md)] size:          KbdSize,\n    #[prop(default = KbdVariant::Default)] variant: KbdVariant,\n    #[prop(into, default = String::new())] class:  String,\n) -> impl IntoView {\n    view! { <kbd_ui::Kbd size=size variant=variant class=class>{children()}</kbd_ui::Kbd> }\n}\n\n#[component]\npub fn KbdGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <kbd_ui::KbdGroup class=class>{children()}</kbd_ui::KbdGroup> }\n}\n\n#[component]\npub fn KbdSeparator() -> impl IntoView {\n    view! { <kbd_ui::KbdSeparator /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const KBD_API: ComponentApi = ComponentApi {\n    id: \"kbd\",\n    description: \"Keyboard shortcut display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"sm\", \"md\", \"lg\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"outline\", \"ghost\", \"muted\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const KBDGROUP_API: ComponentApi = ComponentApi {\n    id: \"kbd-group\",\n    description: \"Keyboard shortcut display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const KBDSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"kbd-separator\",\n    description: \"Keyboard shortcut display\",\n    props: &[\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::kbd_boundary::{Kbd, KbdGroup, KbdSeparator, KbdSize, KbdVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn KbdShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <KbdGroup>\n                <Kbd>\"Ctrl\"</Kbd>\n                <KbdSeparator />\n                <Kbd>\"K\"</Kbd>\n            </KbdGroup>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Shortcut representation standardized via size and variant enums.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Size variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Kbd size=KbdSize::Sm>\"Sm\"</Kbd>\n                    <Kbd size=KbdSize::Md>\"Md\"</Kbd>\n                    <Kbd size=KbdSize::Lg>\"Lg\"</Kbd>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variant\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Kbd>\"Default\"</Kbd>\n                    <Kbd variant=KbdVariant::Outline>\"Outline\"</Kbd>\n                    <Kbd variant=KbdVariant::Ghost>\"Ghost\"</Kbd>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Common shortcuts\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <KbdGroup>\n                        <Kbd>\"Ctrl\"</Kbd><KbdSeparator /><Kbd>\"C\"</Kbd>\n                    </KbdGroup>\n                    <KbdGroup>\n                        <Kbd>\"Ctrl\"</Kbd><KbdSeparator /><Kbd>\"Shift\"</Kbd><KbdSeparator /><Kbd>\"P\"</Kbd>\n                    </KbdGroup>\n                    <KbdGroup>\n                        <Kbd>\"⌘\"</Kbd><KbdSeparator /><Kbd>\"Z\"</Kbd>\n                    </KbdGroup>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "label",
    "label": "Label",
    "category": "Form",
    "description": "Form label component",
    "keywords": "",
    "pain": "Labels not correctly associated with inputs, breaking accessibility",
    "promise": "Label-to-input association enforced via explicit html_for contract",
    "why": "LabelPrimitive ensures proper for/id mapping and required state. ARIA attributes are derived automatically. This guarantees accessible labeling without manual wiring.\n",
    "before": "// ❌ Typical\nview! {\n  <label>\"Email\"</label>\n  <input />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Label for_id=\"email\">\"Email\"</Label>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "inputs"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "input_otp",
      "textarea",
      "field",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Label Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[component]\npub fn LabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] html_for: String,\n    #[prop(default = false)] required: bool,\n) -> impl IntoView {\n    let uid_lbl = crate::infra::uid::generate(\"lbl\");\n    view! {\n        <label\n            data-rs-label=\"\"\n            data-rs-uid=uid_lbl\n            for={if html_for.is_empty() { None } else { Some(html_for) }}\n            data-rs-required={if required { Some(\"\") } else { None }}\n            aria-required={if required { Some(\"true\") } else { None }}\n            class=class\n        >\n            {children()}\n        </label>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::LabelPrimitive;\n\n#[component]\npub fn Label(\n    children: Children,\n    #[prop(into, default = String::new())] for_id: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <LabelPrimitive html_for=for_id class=class>\n            {children()}\n        </LabelPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Label Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::label_ui::Label as LabelUi;\n\n#[component]\npub fn Label(\n    children: Children,\n    #[prop(into, default = String::new())] for_id: String,\n    #[prop(into, default = String::new())] class:  String,\n) -> impl IntoView {\n    view! {\n        <LabelUi for_id=for_id class=class>\n            {children()\n};\n        </LabelUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const LABEL_API: ComponentApi = ComponentApi {\n    id: \"label\",\n    description: \"Form label component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"for_id\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::label_boundary::Label;\nuse crate::ui::input::input_boundary::Input;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn LabelShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                <Label for_id=\"label-input\">\"Username\"</Label>\n                <Input placeholder=\"johndoe\" />\n            </Stack>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Label-to-input association enforced via explicit html_for contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Multiple labels\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <Label for_id=\"label-email\"><span>\"Email\"</span></Label>\n                        <Input placeholder=\"john@example.com\" input_type=\"email\" />\n                    </Stack>\n                    <Stack direction=StackDirection::Vertical gap=StackGap::Xs>\n                        <Label for_id=\"label-password\"><span>\"Password\"</span></Label>\n                        <Input placeholder=\"••••••••\" input_type=\"password\" />\n                    </Stack>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "link",
    "label": "Link",
    "category": "Navigation",
    "description": "Hyperlink",
    "keywords": "",
    "pain": "Links misuse target, rel and disabled states inconsistently",
    "promise": "Navigation semantics and external behavior enforced structurally",
    "why": "LinkPrimitive controls variant, disabled and external behavior. It automatically sets target and rel attributes. This guarantees safe navigation and consistent semantics.\n",
    "before": "// ❌ Typical\nview! {\n  <a href=\"/\" target=\"_blank\">\"Link\"</a>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Link href=\"/\" external=true>\"Link\"</Link>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "navigation",
      "external links"
    ],
    "related": [
      "button",
      "button_group",
      "icon_button",
      "copy_button"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "action",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Link Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug, serde::Serialize, serde::Deserialize)]\npub enum LinkVariant {\n    #[default]\n    Default,\n    Muted,\n    Underline,\n}\nimpl LinkVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default   => \"default\",\n            Self::Muted     => \"muted\",\n            Self::Underline => \"underline\",\n        }\n    }\n}\n\n#[component]\npub fn LinkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = LinkVariant::Default)] variant: LinkVariant,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = false)] external: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::A>>,\n) -> impl IntoView {\n    let uid_lnk = crate::infra::uid::generate(\"lnk\");\n    let target = if external { \"_blank\" } else { \"\" };\n    let rel    = if external { \"noopener noreferrer\" } else { \"\" };\n    view! {\n        <a\n            data-rs-link=\"\"\n            data-rs-uid=uid_lnk\n            data-rs-variant=variant.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            href=href\n            target=target\n            rel=rel\n            aria-disabled=disabled.aria_disabled()\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </a>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{LinkPrimitive, LinkVariant};\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Link(\n    children: Children,\n    href: String,\n    #[prop(default = LinkVariant::Default)] variant: LinkVariant,\n    #[prop(default = false)] disabled: bool,\n    #[prop(default = false)] external: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::A>>,\n) -> impl IntoView {\n    let disabled_state = DisabledState::from(disabled);\n    view! {\n        <LinkPrimitive\n            href=href\n            variant=variant\n            disabled=disabled_state\n            external=external\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </LinkPrimitive>\n    }\n}\n",
    "boundary_src": "//! Link Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::link_ui::Link as LinkUi;\npub use canonrs_core::primitives::LinkVariant;\n\n#[component]\npub fn Link(\n    children: Children,\n    #[prop(into, default = String::new())] href:    String,\n    #[prop(default = LinkVariant::Default)] variant: LinkVariant,\n    #[prop(default = false)] disabled:               bool,\n    #[prop(default = false)] external:               bool,\n    #[prop(into, default = String::new())] class:   String,\n) -> impl IntoView {\n    view! {\n        <LinkUi href=href variant=variant disabled=disabled external=external class=class>\n            {children()\n};\n        </LinkUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{LinkVariant}; \n\npub const LINK_API: ComponentApi = ComponentApi {\n    id: \"link\",\n    description: \"Hyperlink\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"muted\", \"underline\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"external\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::link_boundary::{Link, LinkVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn LinkShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Link href=\"/showcase\" variant=LinkVariant::Default>\"View the Showcase →\"</Link>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Navigation semantics and external behavior enforced structurally.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Link href=\"#\" variant=LinkVariant::Default>\"Default\"</Link>\n                    <Link href=\"#\" variant=LinkVariant::Muted>\"Muted\"</Link>\n                    <Link href=\"#\" variant=LinkVariant::Underline>\"Underline\"</Link>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Link href=\"#\">\"Default\"</Link>\n                    <Link href=\"#\" disabled=true>\"Disabled\"</Link>\n                    <Link href=\"https://canonrs.com\" external=true>\"External ↗\"</Link>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "link_group",
    "label": "Link Group",
    "category": "Navigation",
    "description": "Wrapper that organizes multiple NavItems into a labeled navigation group",
    "keywords": "",
    "pain": "Navigation links lack grouping semantics and structural consistency",
    "promise": "Grouped navigation structured with direction and labeling contract",
    "why": "LinkGroup uses NavigationGroup primitives to enforce grouping and labeling. Direction is encoded via enum. This guarantees consistent navigation structure across layouts.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\n    <a>\"A\"</a>\n    <a>\"B\"</a>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <LinkGroup>\n    <NavItem label=\"A\" href=\"/a\" />\n  </LinkGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "sidebars",
      "footers"
    ],
    "related": [
      "navigation_menu",
      "sidebar",
      "nav_item",
      "breadcrumb",
      "pagination"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "navigation",
    "primitive_src": "//! LinkGroup Primitive\n\nuse leptos::prelude::*;\n\n#[component]\npub fn LinkGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_lg = crate::infra::uid::generate(\"lg\");\n    view! {\n        <nav\n            data-rs-link-group=\"\"\n            data-rs-uid=uid_lg\n            data-rs-interaction=\"nav\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn LinkGroupLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-link-group-label=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{LinkGroupPrimitive, LinkGroupLabelPrimitive};\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum LinkGroupDirection { #[default] Vertical, Horizontal }\nimpl LinkGroupDirection { pub fn as_str(&self) -> &'static str { match self { Self::Vertical => \"vertical\", Self::Horizontal => \"horizontal\" } } }\n\n#[component]\npub fn LinkGroup(children: Children, #[prop(optional)] label: Option<std::sync::Arc<dyn Fn() -> AnyView + Send + Sync>>, #[prop(default = LinkGroupDirection::Vertical)] direction: LinkGroupDirection, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <LinkGroupPrimitive class=class>\n            {if let Some(l) = label { view! { <LinkGroupLabelPrimitive>{l()}</LinkGroupLabelPrimitive> }.into_any() }\n             else { view! { <span data-rs-link-group-empty-label=\"\"/> }.into_any() }}\n            <div data-rs-link-group-items=\"\">\n                {children()}\n            </div>\n        </LinkGroupPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! LinkGroup Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::link_group_ui::{\n    LinkGroup as LinkGroupUi,\n    LinkGroupDirection\n};\n\n\n\n#[component]\npub fn LinkGroup(\n    children: Children,\n    #[prop(optional)] label: Option<std::sync::Arc<dyn Fn() -> AnyView + Send + Sync>>,\n    #[prop(default = LinkGroupDirection::Vertical)] direction: LinkGroupDirection,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <LinkGroupUi label=label.unwrap_or_else(|| std::sync::Arc::new(|| leptos::prelude::view! {}.into_any())) direction=direction class=class>\n            {children()}\n        </LinkGroupUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const LINKGROUP_API: ComponentApi = ComponentApi {\n    id: \"link-group\",\n    description: \"Wrapper that organizes multiple NavItems into a labeled navigation group\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"label\", kind: PropType::String, required: false, default: None, description: \"Accessible label text\" },\n        PropDef { name: \"direction\", kind: PropType::String, required: false, default: Some(\"vertical\"), description: \"Stack or flex direction\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::link_group_boundary::LinkGroup;\nuse crate::ui::nav_item::nav_item_boundary::NavItem;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn LinkGroupShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <LinkGroup label=std::sync::Arc::new(|| view! { \"Product\" }.into_any())>\n                <NavItem label=\"Features\"  href=\"/features\"  active=true.into() />\n                <NavItem label=\"Pricing\"   href=\"/pricing\" />\n                <NavItem label=\"Changelog\" href=\"/changelog\" />\n                <NavItem label=\"Roadmap\"   href=\"/roadmap\" />\n            </LinkGroup>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Grouped navigation structured with direction and labeling contract.\"\n            </p>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "list_item",
    "label": "List Item",
    "category": "Display",
    "description": "Single list item with title and description",
    "keywords": "",
    "pain": "Lists lack consistent selection, disabled and accessibility states",
    "promise": "Selection and interaction states encoded via structured attributes",
    "why": "ListItem encodes selectable, selected and disabled states into data attributes. ARIA attributes are derived automatically. This guarantees consistent list interaction behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <li class=\"active\">\"Item\"</li>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <List>\n    <ListItem selectable=true selected=true>\"Item\"</ListItem>\n  </List>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "menus",
      "lists"
    ],
    "related": [
      "table",
      "data_table",
      "virtual_list",
      "empty_table",
      "tree"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "data",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! List Primitives - Accessible list container + items\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState, ActivityState};\n\n#[component]\npub fn ListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n) -> impl IntoView {\n    let uid_lst = crate::infra::uid::generate(\"lst\");\n    view! {\n        <div\n            data-rs-list=\"\"\n            data-rs-uid=uid_lst\n            data-rs-interaction=\"data\"\n            role=\"listbox\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ListItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = ActivityState::Inactive)] focused: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let tabindex = if focused.as_str() == \"active\" { \"0\" } else { \"-1\" };\n    view! {\n        <div\n            data-rs-list-item=\"\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-focused=focused.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            role=\"option\"\n            tabindex=tabindex\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ListItemTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-list-item-title=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ListItemDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-list-item-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ListPrimitive, ListItemPrimitive,\n    ListItemTitlePrimitive, ListItemDescriptionPrimitive,\n};\n\n#[derive(Clone, Copy, PartialEq, Debug, Default)]\npub enum ListSelectionMode { #[default] None, Single, Multiple }\nimpl ListSelectionMode { pub fn as_str(&self) -> Option<&'static str> { match self { Self::None => None, Self::Single => Some(\"single\"), Self::Multiple => Some(\"multiple\") } } }\n\n#[component]\npub fn List(children: Children, #[prop(default = ListSelectionMode::None)] selection_mode: ListSelectionMode, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <ListPrimitive class=class attr:data-rs-selection=selection_mode.as_str()>{children()}</ListPrimitive> }\n}\n#[component]\npub fn ListItem(children: Children, #[prop(into, default = String::new())] class: String, #[prop(default = false)] selected: bool, #[prop(default = false)] disabled: bool) -> impl IntoView {\n    view! {\n        <ListItemPrimitive class=class attr:data-rs-state=if selected { \"selected\" } else { \"idle\" } attr:data-rs-disabled=disabled.then_some(\"\") attr:aria-selected=selected.then_some(\"true\") attr:aria-disabled=disabled.then_some(\"true\") attr:tabindex=if !disabled { Some(\"0\") } else { None }>\n            <div data-rs-list-item-content=\"\">{children()}</div>\n        </ListItemPrimitive>\n    }\n}\n#[component]\npub fn ListItemTitle(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <ListItemTitlePrimitive class=class>{children()}</ListItemTitlePrimitive> }\n}\n#[component]\npub fn ListItemDescription(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <ListItemDescriptionPrimitive class=class>{children()}</ListItemDescriptionPrimitive> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! ListItem Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::list_item_ui::{\n    List as ListUi,\n    ListItem as ListItemUi,\n    ListItemTitle as ListItemTitleUi,\n    ListItemDescription as ListItemDescriptionUi,\n};\npub use super::list_item_ui::ListSelectionMode;\n\n#[component]\npub fn List(\n    children: Children,\n    #[prop(default = ListSelectionMode::None)] selection_mode: ListSelectionMode,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ListUi selection_mode=selection_mode class=class>\n            {children()}\n        </ListUi>\n    }\n}\n\n#[component]\npub fn ListItem(\n    children: Children,\n    #[prop(default = false)] selected: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ListItemUi selected=selected disabled=disabled class=class>\n            {children()}\n        </ListItemUi>\n    }\n}\n\n#[component]\npub fn ListItemTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ListItemTitleUi class=class>\n            {children()}\n        </ListItemTitleUi>\n    }\n}\n\n#[component]\npub fn ListItemDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ListItemDescriptionUi class=class>\n            {children()}\n        </ListItemDescriptionUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const LIST_API: ComponentApi = ComponentApi {\n    id: \"list\",\n    description: \"Single list item with title and description\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selection_mode\", kind: PropType::String, required: false, default: Some(\"none\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const LISTITEM_API: ComponentApi = ComponentApi {\n    id: \"list-item\",\n    description: \"Single list item with title and description\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selected\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const LISTITEMTITLE_API: ComponentApi = ComponentApi {\n    id: \"list-item-title\",\n    description: \"Single list item with title and description\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const LISTITEMDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"list-item-description\",\n    description: \"Single list item with title and description\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::list_item_boundary::{List, ListItem, ListItemTitle, ListItemDescription, ListSelectionMode};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ListItemShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <List>\n                <ListItem>\n                    <ListItemTitle>\"Alice Johnson\"</ListItemTitle>\n                    <ListItemDescription>\"Engineer · Active\"</ListItemDescription>\n                </ListItem>\n                <ListItem>\n                    <ListItemTitle>\"Bob Smith\"</ListItemTitle>\n                    <ListItemDescription>\"Designer · Away\"</ListItemDescription>\n                </ListItem>\n                <ListItem>\n                    <ListItemTitle>\"Carol White\"</ListItemTitle>\n                    <ListItemDescription>\"Manager · Active\"</ListItemDescription>\n                </ListItem>\n            </List>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Selection and interaction states encoded via structured attributes.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Selectable\"</span>\n                <List selection_mode=ListSelectionMode::Single>\n                    <ListItem selected=true>\n                        <ListItemTitle>\"Alice Johnson\"</ListItemTitle>\n                        <ListItemDescription>\"Engineer\"</ListItemDescription>\n                    </ListItem>\n                    <ListItem>\n                        <ListItemTitle>\"Bob Smith\"</ListItemTitle>\n                        <ListItemDescription>\"Designer\"</ListItemDescription>\n                    </ListItem>\n                    <ListItem disabled=true>\n                        <ListItemTitle>\"Carol White\"</ListItemTitle>\n                        <ListItemDescription>\"Disabled\"</ListItemDescription>\n                    </ListItem>\n                </List>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "loading_overlay",
    "label": "Loading Overlay",
    "category": "Display",
    "description": "Full loading overlay",
    "keywords": "",
    "pain": "Loading states require manual visibility and aria synchronization",
    "promise": "Loading visibility and aria-busy managed automatically",
    "why": "LoadingOverlayPrimitive maps LoadingState to visibility and ARIA attributes. Overlay visibility is derived automatically. This guarantees consistent loading feedback without manual logic.\n",
    "before": "// ❌ Typical\nview! {\n  {if loading { view! { <div class=\"overlay\">\"Loading\"</div> } }}\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <LoadingOverlay state=LoadingState::Loading>\n    \"Content\"\n  </LoadingOverlay>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "async operations",
      "page blocking"
    ],
    "related": [
      "progress",
      "spinner",
      "skeleton",
      "pulse",
      "doc_progress"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! LoadingOverlay Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::LoadingState;\n\n#[derive(Clone, PartialEq, Default)]\npub enum OverlayMode {\n    #[default]\n    Blocking,\n    Subtle,\n    Skeleton,\n}\n\nimpl OverlayMode {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            OverlayMode::Blocking => \"blocking\",\n            OverlayMode::Subtle   => \"subtle\",\n            OverlayMode::Skeleton => \"skeleton\",\n        }\n    }\n}\n\n#[component]\npub fn LoadingOverlayPrimitive(\n    children: Children,\n    #[prop(default = LoadingState::Idle)] state: LoadingState,\n    #[prop(default = OverlayMode::Blocking)] mode: OverlayMode,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_lo = crate::infra::uid::generate(\"lo\");\n    let is_loading = state == LoadingState::Loading;\n    let data_state = if is_loading { \"loading\" } else { \"idle\" };\n    let overlay_aria_hidden = if is_loading { \"false\" } else { \"true\" };\n    view! {\n        <div\n            data-rs-overlay-container=\"\" data-rs-interaction=\"init\"\n            data-rs-loading=data_state\n            data-rs-overlay-mode=mode.as_str()\n            aria-busy=if is_loading { \"true\" } else { \"false\" }\n            class=class\n        >\n            <div data-rs-overlay-content=\"\">\n                {children()}\n            </div>\n            <div\n                data-rs-loading-overlay=\"\"\n                data-rs-uid=uid_lo\n                aria-hidden=overlay_aria_hidden\n                aria-live=\"polite\"\n            >\n                <span data-rs-loading-overlay-spinner=\"\" aria-hidden=\"true\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg></span>\n            </div>\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{LoadingOverlayPrimitive, OverlayMode};\nuse canonrs_core::meta::LoadingState;\n\npub use canonrs_core::primitives::OverlayMode as LoadingOverlayMode;\n\n#[component]\npub fn LoadingOverlay(\n    children: Children,\n    #[prop(default = LoadingState::Idle)] state: LoadingState,\n    #[prop(default = OverlayMode::Blocking)] mode: OverlayMode,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <LoadingOverlayPrimitive state=state mode=mode class=class>\n            {children()}\n        </LoadingOverlayPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! LoadingOverlay Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::loading_overlay_ui::{\n    LoadingOverlay as LoadingOverlayUi,\n    LoadingOverlayMode\n};\nuse canonrs_core::meta::LoadingState;\n\n#[component]\npub fn LoadingOverlay(\n    children: Children,\n    #[prop(into, default = String::new())] state: String,\n    #[prop(into, default = String::new())] mode: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let loading_state = match state.as_str() {\n        \"loading\" => LoadingState::Loading,\n        _         => LoadingState::Idle,\n    };\n    let overlay_mode = match mode.as_str() {\n        \"subtle\"   => LoadingOverlayMode::Subtle,\n        \"skeleton\" => LoadingOverlayMode::Skeleton,\n        _          => LoadingOverlayMode::Blocking,\n    };\n    view! {\n        <LoadingOverlayUi state=loading_state mode=overlay_mode class=class>\n            {children()}\n        </LoadingOverlayUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const LOADINGOVERLAY_API: ComponentApi = ComponentApi {\n    id: \"loading-overlay\",\n    description: \"Full loading overlay\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"mode\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Operational mode of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::loading_overlay_boundary::LoadingOverlay;\nuse crate::blocks::card::CardBlock;\nuse crate::ui::card::{CardHeader, CardTitle, CardContent};\nuse canonrs_core::slot;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn LoadingOverlayShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <CardBlock\n                header=slot!(|| view! {\n                    <CardHeader><CardTitle>\"Loading\"</CardTitle></CardHeader>\n                }.into_any())\n                content=slot!(|| view! {\n                    <CardContent>\n                        <LoadingOverlay state=\"loading\">\n                            <div data-rs-loading-demo=\"\">\n                                <span>\"Card title\"</span>\n                                <span>\"Card description content\"</span>\n                            </div>\n                        </LoadingOverlay>\n                    </CardContent>\n                }.into_any())\n            />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Loading visibility and aria-busy managed automatically.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <CardBlock content=slot!(|| view! {\n                        <CardContent>\n                            <LoadingOverlay>\"Idle — content visible\"</LoadingOverlay>\n                        </CardContent>\n                    }.into_any()) />\n                    <CardBlock content=slot!(|| view! {\n                        <CardContent>\n                            <LoadingOverlay state=\"loading\">\"Loading — content blocked\"</LoadingOverlay>\n                        </CardContent>\n                    }.into_any()) />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Modes\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                    <CardBlock content=slot!(|| view! {\n                        <CardContent>\n                            <LoadingOverlay state=\"loading\" mode=\"blocking\">\"Blocking\"</LoadingOverlay>\n                        </CardContent>\n                    }.into_any()) />\n                    <CardBlock content=slot!(|| view! {\n                        <CardContent>\n                            <LoadingOverlay state=\"loading\" mode=\"subtle\">\"Subtle\"</LoadingOverlay>\n                        </CardContent>\n                    }.into_any()) />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [
      "card_block"
    ],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "logo",
    "label": "Site Logo",
    "category": "Brand",
    "description": "CanonRS logo combining SVG icon, wordmark and optional tagline",
    "keywords": "",
    "pain": "Brand logos implemented inconsistently across layouts and break navigation semantics",
    "promise": "Brand identity structure and navigation behavior enforced in a single contract",
    "why": "LogoPrimitive enforces anchor semantics, size and variant at the root element. Icon, wordmark and tagline are explicitly structured parts. This guarantees consistent brand rendering and correct navigation behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <a href=\"/\" class=\"logo\">\n    <img src=\"/logo.svg\" />\n    <span>\"Brand\"</span>\n  </a>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Logo>\n    <LogoWordmarkPrimitive>\"Brand\"</LogoWordmarkPrimitive>\n  </Logo>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "site header",
      "app navigation"
    ],
    "related": [
      "avatar",
      "icon",
      "code_block",
      "markdown",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Logo Primitive - Brand identity anchor\n\nuse leptos::prelude::*;\n\n#[component]\npub fn LogoPrimitive(\n    children: Children,\n    #[prop(into, default = \"/\".to_string())] href: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = \"md\".to_string())] size: String,\n    #[prop(into, default = \"brand\".to_string())] variant: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_lgo = crate::infra::uid::generate(\"lgo\");\n    view! {\n        <a\n            data-rs-logo=\"\"\n            data-rs-uid=uid_lgo\n            data-rs-size=size\n            data-rs-variant=variant\n            href=href\n            aria-label=aria_label.unwrap_or_default()\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn LogoIconPrimitive(\n    #[prop(into)] src: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <img\n            data-rs-logo-icon=\"\"\n            src=src\n            alt=\"\"\n            aria-hidden=\"true\"\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn LogoWordmarkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-logo-wordmark=\"\" class=class>{children()}</span>\n    }\n}\n\n#[component]\npub fn LogoTaglinePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-logo-tagline=\"\" class=class>{children()}</span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{LogoPrimitive, LogoIconPrimitive, LogoWordmarkPrimitive, LogoTaglinePrimitive};\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum LogoSize {\n    Sm,\n    #[default]\n    Md,\n    Lg,\n}\n\nimpl LogoSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Sm => \"sm\",\n            Self::Md => \"md\",\n            Self::Lg => \"lg\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum LogoVariant {\n    #[default]\n    Brand,\n    Neutral,\n}\n\nimpl LogoVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Brand   => \"brand\",\n            Self::Neutral => \"neutral\",\n        }\n    }\n}\n\n#[component]\npub fn Logo(\n    #[prop(default = LogoSize::Md)] size: LogoSize,\n    #[prop(default = LogoVariant::Brand)] variant: LogoVariant,\n    #[prop(optional)] wordmark: Option<ChildrenFn>,\n    #[prop(optional)] tagline: Option<ChildrenFn>,\n    #[prop(into, default = \"/\".to_string())] href: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <LogoPrimitive\n            href=href\n            aria_label=aria_label.unwrap_or_default()\n            size=size.as_str().to_string()\n            variant=variant.as_str().to_string()\n            class=class\n        >\n            <LogoIconPrimitive src=\"/assets/logo_canonrs.svg\".to_string() />\n            {wordmark.map(|w| view! {\n                <LogoWordmarkPrimitive>{w()}</LogoWordmarkPrimitive>\n            })}\n            {tagline.map(|t| view! {\n                <LogoTaglinePrimitive>{t()}</LogoTaglinePrimitive>\n            })}\n        </LogoPrimitive>\n    }\n}\n",
    "boundary_src": "//! Logo Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n//! Note: match on wordmark/tagline is structural (Option<ChildrenFn> Leptos constraint), not logic.\n\nuse leptos::prelude::*;\npub use super::logo_ui::{LogoSize, LogoVariant};\nuse super::logo_ui::Logo as LogoUi;\n\n#[component]\npub fn Logo(\n    #[prop(default = LogoSize::Md)] size:          LogoSize,\n    #[prop(default = LogoVariant::Brand)] variant: LogoVariant,\n    #[prop(optional)] wordmark:                    Option<ChildrenFn>,\n    #[prop(optional)] tagline:                     Option<ChildrenFn>,\n    #[prop(into, default = \"/\".to_string())] href: String,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class:  String,\n) -> impl IntoView {\n    match (wordmark, tagline) {\n        (Some(wm), Some(tl)) => view! {\n            <LogoUi size=size variant=variant wordmark=wm tagline=tl href=href aria_label=aria_label class=class />\n        }.into_any(),\n        (Some(wm), None) => view! {\n            <LogoUi size=size variant=variant wordmark=wm href=href aria_label=aria_label class=class />\n        }.into_any(),\n        (None, Some(tl)) => view! {\n            <LogoUi size=size variant=variant tagline=tl href=href aria_label=aria_label class=class />\n        }.into_any(),\n        (None, None) => view! {\n            <LogoUi size=size variant=variant href=href aria_label=aria_label class=class />\n        }.into_any(),\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const LOGO_API: ComponentApi = ComponentApi {\n    id: \"logo\",\n    description: \"CanonRS logo combining SVG icon, wordmark and optional tagline\",\n    props: &[\n        PropDef { name: \"size\", kind: PropType::String, required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"variant\", kind: PropType::String, required: false, default: Some(\"brand\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"wordmark\", kind: PropType::Children, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"tagline\", kind: PropType::Children, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"/\"), description: \"Navigation target URL\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::logo_boundary::{Logo, LogoSize, LogoVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn LogoShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <Logo />\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Brand identity structure and navigation behavior enforced in a single contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Lg>\n                    <Logo size=LogoSize::Sm />\n                    <Logo size=LogoSize::Md />\n                    <Logo size=LogoSize::Lg />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Lg>\n                    <Logo variant=LogoVariant::Brand />\n                    <Logo variant=LogoVariant::Neutral />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With wordmark\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Lg>\n                    <Logo wordmark=leptos::children::ToChildren::to_children(|| view! { \"CanonRS\" }) />\n                    <Logo\n                        wordmark=leptos::children::ToChildren::to_children(|| view! { \"CanonRS\" })\n                        tagline=leptos::children::ToChildren::to_children(|| view! { \"Design System\" })\n                    />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "markdown",
    "label": "Markdown",
    "category": "Display",
    "description": "Rendered markdown content",
    "keywords": "",
    "pain": "Client-side markdown rendering causes hydration mismatch and inconsistent DOM",
    "promise": "SSR-safe markdown rendering with deterministic DOM output",
    "why": "MarkdownPrimitive injects HTML only during SSR and avoids client mutation. Content and TOC are generated as stable HTML structure. This guarantees hydration-safe rendering with no runtime divergence.\n",
    "before": "// ❌ Typical\nview! {\n  <div inner_html={render_markdown(md)} />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <MarkdownSurface rendered=rendered />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "docs",
      "blog content"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "chart",
      "stat",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "#![allow(unused_variables)]\n//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Markdown Primitive - HTML puro\n\nuse leptos::prelude::*;\nuse crate::meta::{NavigationState, VisibilityState};\n\n#[component]\npub fn MarkdownPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] inner: String,\n) -> impl IntoView {\n    let uid_md = crate::infra::uid::generate(\"md\");\n    // inner contém o HTML do layout completo (TOC + content)\n    // É injetado via inner_html apenas em SSR — hydration via MarkdownContentPrimitive\n    #[cfg(feature = \"ssr\")]\n    {\n        view! {\n            <div\n                data-rs-markdown=\"\"\n            data-rs-uid=uid_md\n            data-rs-interaction=\"content\"\n                class=class\n                inner_html=inner\n            ></div>\n        }.into_any()\n    }\n    #[cfg(not(feature = \"ssr\"))]\n    {\n        let _ = inner;\n        view! {\n            <div\n                data-rs-markdown=\"\"\n                class=class\n            ></div>\n        }.into_any()\n    }\n}\n\n#[component]\npub fn MarkdownToolbarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-markdown-toolbar=\"\"\n            role=\"toolbar\"\n            aria-label=\"Markdown toolbar\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MarkdownToolbarItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] action: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-markdown-toolbar-item=\"\"\n            data-rs-action=action\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn MarkdownTocPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <nav\n            data-rs-markdown-toc=\"\"\n            data-rs-state=state.as_str()\n            aria-hidden=state.aria_hidden()\n            aria-label=\"Table of contents\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn MarkdownTocItemPrimitive(\n    #[prop(into)] href: String,\n    #[prop(into)] text: String,\n    #[prop(default = 2u8)] level: u8,\n    #[prop(default = NavigationState::Inactive)] state: NavigationState,\n) -> impl IntoView {\n    let aria_current = if state == NavigationState::Current { Some(\"page\") } else { None };\n    view! {\n        <li\n            data-rs-markdown-toc-item=\"\"\n            data-rs-level=level.to_string()\n            data-rs-navigation=state.as_str()\n        >\n            <a\n                data-rs-markdown-toc-link=\"\"\n                aria-current=aria_current\n                href=href\n            >{text}</a>\n        </li>\n    }\n}\n\n#[component]\npub fn MarkdownContentPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] html: String,\n) -> impl IntoView {\n    #[cfg(feature = \"ssr\")]\n    let inner = html;\n    #[cfg(not(feature = \"ssr\"))]\n    let inner = { let _ = html; String::new() };\n    view! {\n        <div\n            data-rs-markdown-content=\"\"\n            class=class\n            inner_html=inner.clone()\n        ></div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::TocItem;\nuse crate::ui::table_of_contents::table_of_contents_boundary::TableOfContents;\nuse crate::ui::scroll_area::scroll_area_boundary::ScrollArea;\nuse canonrs_core::primitives::table_of_contents::TocMode;\n\n#[derive(Clone, Debug, Default)]\npub struct RenderedMarkdown {\n    pub html: String,\n    pub toc: Vec<TocItem>,\n}\n\n#[derive(Clone, Copy, Debug, Default, PartialEq)]\npub enum TocPosition {\n    #[default]\n    Top,\n    Sidebar,\n}\n\n#[component]\npub fn MarkdownSurface(\n    rendered: RenderedMarkdown,\n    #[prop(default = true)] show_toc: bool,\n    #[prop(default = true)] show_toolbar: bool,\n    #[prop(default = TocPosition::Top)] toc_position: TocPosition,\n    #[prop(default = false)] contained: bool,\n    #[prop(into, default = String::new())] id: String,\n) -> impl IntoView {\n    let has_toc = !rendered.toc.is_empty() && show_toc;\n    let is_sidebar = toc_position == TocPosition::Sidebar;\n    let toc_items = rendered.toc.clone();\n    let content_id = format!(\"{}-content\", id);\n    let html = rendered.html.clone();\n    let _ = show_toolbar;\n\n    let container_style = if contained {\n        \"display:flex;flex-direction:row;gap:var(--space-xl);height:500px\"\n    } else if has_toc && is_sidebar {\n        \"display:flex;flex-direction:row;gap:var(--space-xl)\"\n    } else {\n        \"\"\n    };\n\n    view! {\n        <div\n            data-rs-markdown=\"\"\n            data-rs-uid=canonrs_core::infra::uid::generate(\"md\")\n            data-rs-interaction=\"content\"\n            data-toc-position=if is_sidebar { \"sidebar\" } else { \"top\" }\n            data-rs-value=id\n            style=container_style\n        >\n            {(has_toc && is_sidebar).then(|| view! {\n                <aside\n                    data-rs-md-toc-sidebar=\"\"\n                    style=\"width:var(--markdown-toc-width);flex-shrink:0;height:100%;overflow-y:auto\"\n                >\n                    <TableOfContents\n                        items=toc_items\n                        mode=TocMode::Nested\n                        title=\"On this page\"\n                    />\n                </aside>\n            })}\n            {if contained { view! {\n                <ScrollArea attr:style=\"flex:1;min-width:0;max-width:66%;height:100%\">\n                    <div\n                        data-rs-markdown-content=\"\"\n                        id=content_id\n                        inner_html=html\n                    />\n                </ScrollArea>\n            }.into_any() } else { view! {\n                <div\n                    data-rs-markdown-content=\"\"\n                    id=content_id\n                    inner_html=html\n                />\n            }.into_any() }}\n        </div>\n    }\n}\n\n#[component]\npub fn MarkdownLayout(\n    children: Children,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = TocPosition::Sidebar)] toc_position: TocPosition,\n) -> impl IntoView {\n    let toc_pos = if toc_position == TocPosition::Sidebar { \"sidebar\" } else { \"top\" };\n    view! {\n        <div\n            data-rs-markdown=\"\"\n            data-rs-component=\"Markdown\"\n            data-rs-interaction=\"content\"\n            data-toc-position=toc_pos\n            data-rs-value=value\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MarkdownContent(\n    rendered: RenderedMarkdown,\n    #[prop(into, default = String::new())] id: String,\n) -> impl IntoView {\n    let content_id = format!(\"{}-content\", id);\n    view! {\n        <div\n            data-rs-markdown-content=\"\"\n            id=content_id\n            inner_html=rendered.html\n        />\n    }\n}\n\n#[component]\npub fn MarkdownTOC(\n    toc: Vec<TocItem>,\n    #[prop(into, default = String::new())] id: String,\n    #[prop(into, optional)] scroll_target: Option<String>,\n) -> impl IntoView {\n    let _ = id;\n    let _ = scroll_target;\n    view! {\n        <aside data-rs-md-toc-sidebar=\"\">\n            <TableOfContents\n                items=toc\n                mode=TocMode::Nested\n                title=\"On this page\"\n            />\n        </aside>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::markdown_ui::{\n    MarkdownSurface as MarkdownSurfaceUi,\n    MarkdownTOC as MarkdownTOCUi,\n    MarkdownContent as MarkdownContentUi,\n    MarkdownLayout as MarkdownLayoutUi,\n    RenderedMarkdown,\n};\n\npub use super::markdown_ui::TocPosition;\n\n#[component]\npub fn MarkdownSurface(\n    rendered: RenderedMarkdown,\n    #[prop(optional)] show_toc: Option<bool>,\n    #[prop(optional)] show_toolbar: Option<bool>,\n    #[prop(optional)] toc_position: Option<TocPosition>,\n    #[prop(default = false)] contained: bool,\n    #[prop(optional, into)] id: Option<String>,\n) -> impl IntoView {\n    let toc_pos = toc_position.unwrap_or(TocPosition::Top);\n    view! {\n        <MarkdownSurfaceUi\n            rendered=rendered\n            show_toc=show_toc.unwrap_or(true)\n            show_toolbar=show_toolbar.unwrap_or(true)\n            toc_position=toc_pos\n            contained=contained\n            id=id.unwrap_or_default()\n        />\n    }\n}\n\n#[component]\npub fn MarkdownLayout(\n    children: Children,\n    #[prop(optional, into)] value: Option<String>,\n    #[prop(optional)] toc_position: Option<TocPosition>,\n) -> impl IntoView {\n    let toc_pos = toc_position.unwrap_or(TocPosition::Top);\n    view! {\n        <MarkdownLayoutUi value=value.unwrap_or_default() toc_position=toc_pos>\n            {children()}\n        </MarkdownLayoutUi>\n    }\n}\n\n#[component]\npub fn MarkdownContent(\n    rendered: RenderedMarkdown,\n    #[prop(optional, into)] id: Option<String>,\n) -> impl IntoView {\n    view! { <MarkdownContentUi rendered=rendered id=id.unwrap_or_default() /> }\n}\n\n#[component]\npub fn MarkdownTOC(\n    toc: Vec<canonrs_core::TocItem>,\n    #[prop(optional, into)] id: Option<String>,\n    #[prop(optional, into)] scroll_target: Option<String>,\n) -> impl IntoView {\n    view! { <MarkdownTOCUi toc=toc id=id.unwrap_or_default() scroll_target=scroll_target.unwrap_or_default() /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const MARKDOWNSURFACE_API: ComponentApi = ComponentApi {\n    id: \"markdown-surface\",\n    description: \"Rendered markdown content\",\n    props: &[\n        PropDef { name: \"rendered\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"show_toc\", kind: PropType::Bool, required: false, default: None, description: \"Whether to show table of contents\" },\n        PropDef { name: \"show_toolbar\", kind: PropType::Bool, required: false, default: None, description: \"Whether to show markdown toolbar\" },\n        PropDef { name: \"toc_position\", kind: PropType::String, required: false, default: None, description: \"Position of table of contents\" },\n        PropDef { name: \"contained\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether to constrain width\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n    ],\n};\n\npub const MARKDOWNLAYOUT_API: ComponentApi = ComponentApi {\n    id: \"markdown-layout\",\n    description: \"Rendered markdown content\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: None, description: \"Current value\" },\n        PropDef { name: \"toc_position\", kind: PropType::String, required: false, default: None, description: \"Position of table of contents\" },\n    ],\n};\n\npub const MARKDOWNCONTENT_API: ComponentApi = ComponentApi {\n    id: \"markdown-content\",\n    description: \"Rendered markdown content\",\n    props: &[\n        PropDef { name: \"rendered\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n    ],\n};\n\npub const MARKDOWNTOC_API: ComponentApi = ComponentApi {\n    id: \"markdown-t-o-c\",\n    description: \"Rendered markdown content\",\n    props: &[\n        PropDef { name: \"toc\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n        PropDef { name: \"scroll_target\", kind: PropType::String, required: false, default: None, description: \"Scroll target element id\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::markdown_boundary::{MarkdownSurface, TocPosition};\nuse super::render_markdown;\n\n#[component]\npub fn MarkdownShowcasePreview() -> impl IntoView {\n    let sample = concat!(\n        \"# CanonRS Design System\\n\\n\",\n        \"CanonRS is a design system built with **Leptos** and **Rust**. \\n\",\n        \"Every component follows a strict contract between primitives, tokens, and interaction modules.\\n\\n\",\n        \"## Architecture\\n\\n\",\n        \"The system is built on three layers: primitives define the contract, \\n\",\n        \"UI components compose them, and interaction modules handle behavior exclusively on the client.\\n\\n\",\n        \"### Primitives\\n\\n\",\n        \"Primitives are the foundation. They render SSR-safe HTML with `data-rs-*` attributes \\n\",\n        \"that declare behavior without executing it. No logic lives inside a primitive.\\n\\n\",\n        \"### Tokens\\n\\n\",\n        \"All visual decisions are encoded as CSS custom properties. \\n\",\n        \"Tokens are organized by family — layout, color, motion, typography — \\n\",\n        \"and are the single source of truth for theming.\\n\\n\",\n        \"## Features\\n\\n\",\n        \"- SSR-safe rendering with deterministic DOM output\\n\",\n        \"- Token-driven theming via CSS custom properties\\n\",\n        \"- Behavior layer that runs exclusively on the client\\n\",\n        \"- Full ARIA compliance via structured contracts\\n\",\n        \"- Zero hydration mismatch by design\\n\\n\",\n        \"## Component Table\\n\\n\",\n        \"| Component | Category | Status |\\n\",\n        \"|-----------|----------|--------|\\n\",\n        \"| Button | Actions | Stable |\\n\",\n        \"| Avatar | Identity | Stable |\\n\",\n        \"| Progress | Feedback | Stable |\\n\",\n        \"| CodeBlock | Content | Stable |\\n\",\n        \"| Markdown | Content | Stable |\\n\\n\",\n        \"## Code Example\\n\\n\",\n        \"```rust\\n\",\n        \"fn main() {\\n\",\n        \"    println!(\\\"Hello, CanonRS!\\\");\\n\",\n        \"}\\n\",\n        \"```\\n\\n\",\n        \"## Interaction Model\\n\\n\",\n        \"All behavior is delegated to WASM modules that operate directly on the DOM. \\n\",\n        \"The boundary layer is zero-logic — it declares, never executes.\\n\\n\",\n        \"### Init vs Interaction\\n\\n\",\n        \"Simple stateless behaviors use the init layer. \\n\",\n        \"Complex coordinated behaviors — sorting, selection engines, virtualization — \\n\",\n        \"belong to the interaction layer and run as dedicated WASM modules.\\n\\n\",\n        \"## Summary\\n\\n\",\n        \"All components follow the Canon contract. \\n\",\n        \"The DOM is the source of truth. CSS reacts to state. WASM drives behavior.\\n\"\n    );\n\n    let rendered = render_markdown(sample);\n\n    view! {\n        <MarkdownSurface\n            rendered=rendered\n            show_toc=true\n            show_toolbar=false\n            toc_position=TocPosition::Sidebar\n            contained=true\n            id=\"md-preview\"\n        />\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "menu",
    "label": "Menu",
    "category": "Navigation",
    "description": "Menu component",
    "keywords": "",
    "pain": "Menus lack consistent selection, disabled and focus behavior",
    "promise": "Menu interaction fully governed via structured ARIA and state attributes",
    "why": "MenuItemPrimitive encodes selection, disabled and activity states into data-rs and ARIA attributes. Navigation semantics are enforced at the container level. This guarantees predictable keyboard and accessibility behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"menu\">\n    <button class=\"active\">\"Item\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Menu>\n    <MenuItem selected=true>\"Item\"</MenuItem>\n  </Menu>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "dropdown lists",
      "action menus"
    ],
    "related": [
      "dropdown_menu",
      "context_menu",
      "menubar",
      "command"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "menu",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Menu Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn MenuPrimitive(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_mn = crate::infra::uid::generate(\"mn\");\n    view! {\n        <nav\n            data-rs-menu=\"\"\n            data-rs-uid=uid_mn\n            data-rs-interaction=\"init\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn MenuItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_mi = crate::infra::uid::generate(\"mi\");\n    view! {\n        <button\n            type=\"button\"\n            data-rs-menu-item=\"\"\n\n                        data-rs-uid=uid_mi\n            role=\"menuitem\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn MenuGroupPrimitive(\n    children: Children,\n    #[prop(into, optional)] label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-menu-group=\"\"\n            role=\"group\"\n            aria-label=label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MenuLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-menu-label=\"\"\n            role=\"presentation\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MenuSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-menu-separator=\"\" role=\"separator\" class=class />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    MenuPrimitive, MenuItemPrimitive, MenuGroupPrimitive,\n    MenuLabelPrimitive, MenuSeparatorPrimitive,\n};\nuse canonrs_core::meta::{DisabledState, SelectionState};\n\n#[component]\npub fn Menu(\n    children: Children,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenuPrimitive aria_label=aria_label.unwrap_or_default() class=class>\n            {children()}\n        </MenuPrimitive>\n    }\n}\n\n#[component]\npub fn MenuItem(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenuItemPrimitive disabled=disabled selected=selected class=class>\n            {children()}\n        </MenuItemPrimitive>\n    }\n}\n\n#[component]\npub fn MenuGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenuGroupPrimitive class=class>\n            {children()}\n        </MenuGroupPrimitive>\n    }\n}\n\n#[component]\npub fn MenuLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenuLabelPrimitive class=class>\n            {children()}\n        </MenuLabelPrimitive>\n    }\n}\n\n#[component]\npub fn MenuSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenuSeparatorPrimitive class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Menu Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::menu_ui::{\n    Menu as MenuUi,\n    MenuItem as MenuItemUi\n};\nuse canonrs_core::meta::{DisabledState, SelectionState};\n\n#[component]\npub fn Menu(\n    children: Children,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <MenuUi aria_label=aria_label class=class>{children()}</MenuUi> }\n}\n\n#[component]\npub fn MenuItem(\n    children: Children,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = false)] selected: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let selected_state = if selected { SelectionState::Selected } else { SelectionState::Unselected };\n    let disabled_state = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    let _ = value; // stored in data-rs-value by primitive\n    view! { <MenuItemUi selected=selected_state disabled=disabled_state class=class>{children()}</MenuItemUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const MENU_API: ComponentApi = ComponentApi {\n    id: \"menu\",\n    description: \"Menu component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUITEM_API: ComponentApi = ComponentApi {\n    id: \"menu-item\",\n    description: \"Menu component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"selected\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::menu_boundary::{Menu, MenuItem};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn MenuShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Menu interaction fully governed via DOM — SSR-safe, hydration-safe.\"\n            </p>\n            <Menu aria_label=\"Main menu\">\n                <MenuItem value=\"new\">\"New file\"</MenuItem>\n                <MenuItem value=\"open\">\"Open file\"</MenuItem>\n                <MenuItem value=\"save\" selected=true>\"Save\"</MenuItem>\n                <MenuItem value=\"export\" disabled=true>\"Export (disabled)\"</MenuItem>\n            </Menu>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Edit menu\"</span>\n                <Menu aria_label=\"Edit menu\">\n                    <MenuItem value=\"cut\">\"Cut\"</MenuItem>\n                    <MenuItem value=\"copy\">\"Copy\"</MenuItem>\n                    <MenuItem value=\"paste\">\"Paste\"</MenuItem>\n                    <MenuItem value=\"undo\">\"Undo\"</MenuItem>\n                    <MenuItem value=\"redo\">\"Redo\"</MenuItem>\n                </Menu>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "menubar",
    "label": "Menubar",
    "category": "Navigation",
    "description": "Menu bar navigation",
    "keywords": "",
    "pain": "Horizontal menus break ARIA roles and keyboard navigation",
    "promise": "Menubar semantics and structure enforced via primitives",
    "why": "MenubarPrimitive enforces role=\"menubar\" and structured menu composition. Trigger and content follow strict ARIA relationships. This guarantees accessible and predictable navigation behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"menubar\">\n    <button>\"File\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Menubar>\n    <MenubarMenu>\n      <MenubarTrigger>\"File\"</MenubarTrigger>\n    </MenubarMenu>\n  </Menubar>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "desktop apps",
      "top navigation"
    ],
    "related": [
      "dropdown_menu",
      "context_menu",
      "menu",
      "command"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "menu",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Menubar Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[component]\npub fn MenubarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_mb = crate::infra::uid::generate(\"mb\");\n    view! {\n        <div\n            data-rs-menubar=\"\"\n            data-rs-uid=uid_mb\n            data-rs-interaction=\"nav\"\n            role=\"menubar\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MenubarMenuPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-menubar-menu=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MenubarTriggerPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-menubar-trigger=\"\"\n            role=\"menuitem\"\n            aria-haspopup=\"menu\"\n            aria-expanded=\"false\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n                <svg data-rs-menubar-chevron=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"/></svg>\n        </button>\n    }\n}\n\n#[component]\npub fn MenubarContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-menubar-content=\"\"\n            role=\"menu\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn MenubarItemPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-menubar-item=\"\"\n            role=\"menuitem\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn MenubarSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-menubar-separator=\"\" role=\"separator\" class=class />\n    }\n}\n\n#[component]\npub fn MenubarLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-menubar-label=\"\"\n            role=\"presentation\"\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    MenubarPrimitive,\n    MenubarMenuPrimitive,\n    MenubarTriggerPrimitive,\n    MenubarContentPrimitive,\n    MenubarItemPrimitive,\n    MenubarSeparatorPrimitive,\n};\n\n#[component]\npub fn Menubar(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarPrimitive class=class>\n            {children()}\n        </MenubarPrimitive>\n    }\n}\n\n#[component]\npub fn MenubarMenu(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarMenuPrimitive class=class>\n            {children()}\n        </MenubarMenuPrimitive>\n    }\n}\n\n#[component]\npub fn MenubarTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarTriggerPrimitive class=class>\n            {children()}\n        </MenubarTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn MenubarContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarContentPrimitive class=class>\n            {children()}\n        </MenubarContentPrimitive>\n    }\n}\n\n#[component]\npub fn MenubarItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarItemPrimitive class=class>\n            {children()}\n        </MenubarItemPrimitive>\n    }\n}\n\n#[component]\npub fn MenubarSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <MenubarSeparatorPrimitive class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Menubar Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::menubar_ui::{\n    Menubar as MenubarUi,\n    MenubarMenu as MenubarMenuUi,\n    MenubarTrigger as MenubarTriggerUi,\n    MenubarContent as MenubarContentUi,\n    MenubarItem as MenubarItemUi,\n    MenubarSeparator as MenubarSeparatorUi\n};\n\n\n\n#[component]\npub fn Menubar(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! {\n        <MenubarUi class=class.unwrap_or_default()>{children()}</MenubarUi>\n    }\n}\n\n#[component]\npub fn MenubarMenu(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <MenubarMenuUi class=class.unwrap_or_default()>{children()}</MenubarMenuUi> }\n}\n\n#[component]\npub fn MenubarTrigger(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <MenubarTriggerUi class=class.unwrap_or_default()>{children()}</MenubarTriggerUi> }\n}\n\n#[component]\npub fn MenubarContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <MenubarContentUi class=class.unwrap_or_default()>{children()}</MenubarContentUi> }\n}\n\n#[component]\npub fn MenubarItem(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <MenubarItemUi class=class.unwrap_or_default()>{children()}</MenubarItemUi> }\n}\n\n#[component]\npub fn MenubarSeparator(\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <MenubarSeparatorUi class=class.unwrap_or_default() /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const MENUBAR_API: ComponentApi = ComponentApi {\n    id: \"menubar\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUBARMENU_API: ComponentApi = ComponentApi {\n    id: \"menubar-menu\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUBARTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"menubar-trigger\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUBARCONTENT_API: ComponentApi = ComponentApi {\n    id: \"menubar-content\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUBARITEM_API: ComponentApi = ComponentApi {\n    id: \"menubar-item\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MENUBARSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"menubar-separator\",\n    description: \"Menu bar navigation\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::menubar_boundary::{\n    Menubar, MenubarMenu, MenubarTrigger,\n    MenubarContent, MenubarItem, MenubarSeparator,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn MenubarShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Menubar semantics and structure governed by DOM state — SSR-safe, hydration-safe.\"\n            </p>\n            <Menubar>\n                <MenubarMenu>\n                    <MenubarTrigger>\"File\"</MenubarTrigger>\n                    <MenubarContent>\n                        <MenubarItem>\"New\"</MenubarItem>\n                        <MenubarItem>\"Open\"</MenubarItem>\n                        <MenubarSeparator />\n                        <MenubarItem>\"Exit\"</MenubarItem>\n                    </MenubarContent>\n                </MenubarMenu>\n                <MenubarMenu>\n                    <MenubarTrigger>\"Edit\"</MenubarTrigger>\n                    <MenubarContent>\n                        <MenubarItem>\"Cut\"</MenubarItem>\n                        <MenubarItem>\"Copy\"</MenubarItem>\n                        <MenubarItem>\"Paste\"</MenubarItem>\n                    </MenubarContent>\n                </MenubarMenu>\n                <MenubarMenu>\n                    <MenubarTrigger>\"View\"</MenubarTrigger>\n                    <MenubarContent>\n                        <MenubarItem>\"Zoom in\"</MenubarItem>\n                        <MenubarItem>\"Zoom out\"</MenubarItem>\n                        <MenubarItem>\"Full screen\"</MenubarItem>\n                    </MenubarContent>\n                </MenubarMenu>\n                <MenubarMenu>\n                    <MenubarTrigger>\"Help\"</MenubarTrigger>\n                    <MenubarContent>\n                        <MenubarItem>\"Documentation\"</MenubarItem>\n                        <MenubarItem>\"About\"</MenubarItem>\n                    </MenubarContent>\n                </MenubarMenu>\n            </Menubar>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "modal",
    "label": "Modal",
    "category": "Overlay",
    "description": "Modal window component",
    "keywords": "",
    "pain": "Modals desync visibility, aria-hidden and focus management",
    "promise": "Modal visibility and accessibility fully synchronized via state",
    "why": "ModalPrimitive maps VisibilityState to aria-hidden and hidden attributes. Trigger and content share the same state contract. This guarantees consistent open/close behavior and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  {if open { view! { <div class=\"modal\">\"Content\"</div> } }}\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Modal state=VisibilityState::Open>\n    <ModalContent>\"Content\"</ModalContent>\n  </Modal>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "dialogs",
      "overlays"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "sheet",
      "confirm_dialog",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Modal Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n\n#[component]\npub fn ModalPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_mo = crate::infra::uid::generate(\"mo\");\n    view! {\n        <div\n            data-rs-modal=\"\"\n            data-rs-interaction=\"overlay\"\n            data-rs-uid=uid_mo\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ModalTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(optional, into)] aria_controls: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-modal-trigger=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"primary\"\n            data-rs-state=state.as_str()\n            aria-haspopup=\"dialog\"\n            aria-expanded=state.aria_expanded()\n            aria-controls=aria_controls\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ModalOverlayPrimitive(\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-modal-overlay=\"\"\n            data-rs-state=state.as_str()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn ModalContentPrimitive(\n    children: Children,\n    #[prop(optional, into)] aria_labelledby: Option<String>,\n    #[prop(optional, into)] aria_describedby: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-modal-content=\"\"\n            role=\"dialog\"\n            aria-modal=\"true\"\n            aria-labelledby=aria_labelledby\n            aria-describedby=aria_describedby\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ModalPortalPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-modal-portal=\"\" class=class>{children()}</div> }\n}\n\n#[component]\npub fn ModalTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <h2 data-rs-modal-title=\"\" class=class>{children()}</h2> }\n}\n\n#[component]\npub fn ModalDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <p data-rs-modal-description=\"\" class=class>{children()}</p> }\n}\n\n#[component]\npub fn ModalClosePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button type=\"button\" data-rs-modal-close=\"\" data-rs-button=\"\" data-rs-variant=\"ghost\" class=class>\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ModalFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-modal-footer=\"\" class=class>{children()}</div> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ModalPrimitive, ModalTriggerPrimitive, ModalPortalPrimitive,\n    ModalOverlayPrimitive, ModalContentPrimitive, ModalTitlePrimitive,\n    ModalDescriptionPrimitive, ModalClosePrimitive, ModalFooterPrimitive,\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Modal(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalPrimitive state=state class=class>{children()}</ModalPrimitive> }\n}\n\n#[component]\npub fn ModalTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalTriggerPrimitive class=class>{children()}</ModalTriggerPrimitive> }\n}\n\n#[component]\npub fn ModalPortal(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalPortalPrimitive class=class>{children()}</ModalPortalPrimitive> }\n}\n\n#[component]\npub fn ModalOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalOverlayPrimitive class=class /> }\n}\n\n#[component]\npub fn ModalContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalContentPrimitive class=class>{children()}</ModalContentPrimitive> }\n}\n\n#[component]\npub fn ModalTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalTitlePrimitive class=class>{children()}</ModalTitlePrimitive> }\n}\n\n#[component]\npub fn ModalDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalDescriptionPrimitive class=class>{children()}</ModalDescriptionPrimitive> }\n}\n\n#[component]\npub fn ModalClose(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalClosePrimitive class=class>{children()}</ModalClosePrimitive> }\n}\n\n#[component]\npub fn ModalFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalFooterPrimitive class=class>{children()}</ModalFooterPrimitive> }\n}\n",
    "boundary_src": "//! Modal Island — Canon Rule #340 passthrough\nuse leptos::prelude::*;\nuse super::modal_ui::{\n    Modal as ModalUi,\n    ModalTrigger as ModalTriggerUi,\n    ModalPortal as ModalPortalUi,\n    ModalOverlay as ModalOverlayUi,\n    ModalContent as ModalContentUi,\n    ModalTitle as ModalTitleUi,\n    ModalDescription as ModalDescriptionUi,\n    ModalClose as ModalCloseUi,\n    ModalFooter as ModalFooterUi\n};\n\n#[component]\npub fn Modal(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ModalUi class=class>{children()}</ModalUi> }\n}\n\n#[component]\npub fn ModalTrigger(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalTriggerUi class=class.unwrap_or_default()>{children()}</ModalTriggerUi> }\n}\n\n#[component]\npub fn ModalPortal(\n    children: Children,\n) -> impl IntoView {\n    view! { <ModalPortalUi>{children()}</ModalPortalUi> }\n}\n\n#[component]\npub fn ModalOverlay(\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalOverlayUi class=class.unwrap_or_default() /> }\n}\n\n#[component]\npub fn ModalContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalContentUi class=class.unwrap_or_default()>{children()}</ModalContentUi> }\n}\n\n#[component]\npub fn ModalTitle(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalTitleUi class=class.unwrap_or_default()>{children()}</ModalTitleUi> }\n}\n\n#[component]\npub fn ModalDescription(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalDescriptionUi class=class.unwrap_or_default()>{children()}</ModalDescriptionUi> }\n}\n\n#[component]\npub fn ModalClose(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalCloseUi class=class.unwrap_or_default()>{children()}</ModalCloseUi> }\n}\n\n#[component]\npub fn ModalFooter(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n) -> impl IntoView {\n    view! { <ModalFooterUi class=class.unwrap_or_default()>{children()}</ModalFooterUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const MODAL_API: ComponentApi = ComponentApi {\n    id: \"modal\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"modal-trigger\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALPORTAL_API: ComponentApi = ComponentApi {\n    id: \"modal-portal\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\npub const MODALOVERLAY_API: ComponentApi = ComponentApi {\n    id: \"modal-overlay\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALCONTENT_API: ComponentApi = ComponentApi {\n    id: \"modal-content\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALTITLE_API: ComponentApi = ComponentApi {\n    id: \"modal-title\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"modal-description\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALCLOSE_API: ComponentApi = ComponentApi {\n    id: \"modal-close\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\npub const MODALFOOTER_API: ComponentApi = ComponentApi {\n    id: \"modal-footer\",\n    description: \"Modal window component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::modal_boundary::{Modal, ModalTrigger, ModalPortal, ModalOverlay, ModalContent, ModalTitle, ModalDescription, ModalClose, ModalFooter};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse crate::ui::button::button_boundary::Button;\nuse canonrs_core::primitives::ButtonVariant;\n\n#[component]\npub fn ModalShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Modal accessibility and lifecycle enforced via primitives.\"\n            </p>\n            <Modal>\n                <ModalTrigger>\"Open Modal\"</ModalTrigger>\n                <ModalPortal>\n                <ModalOverlay />\n                <ModalContent>\n                    <ModalTitle>\"Confirm action\"</ModalTitle>\n                    <ModalDescription>\"Are you sure? This action cannot be undone.\"</ModalDescription>\n                    <ModalFooter>\n                        <ModalClose>\"Cancel\"</ModalClose>\n                        <Button variant=ButtonVariant::Primary>\"Confirm\"</Button>\n                    </ModalFooter>\n                </ModalContent>\n                </ModalPortal>\n            </Modal>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Form dialog\"</span>\n                <Modal>\n                    <ModalTrigger>\"Edit profile\"</ModalTrigger>\n                    <ModalPortal>\n                    <ModalOverlay />\n                    <ModalContent>\n                        <ModalTitle>\"Edit profile\"</ModalTitle>\n                        <ModalDescription>\"Update your profile information below.\"</ModalDescription>\n                        <ModalFooter>\n                            <ModalClose>\"Cancel\"</ModalClose>\n                            <Button variant=ButtonVariant::Primary>\"Save changes\"</Button>\n                        </ModalFooter>\n                    </ModalContent>\n                    </ModalPortal>\n                </Modal>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center",
      "stack"
    ]
  },
  {
    "id": "nav_item",
    "label": "Nav Item",
    "category": "Navigation",
    "description": "Single navigation item",
    "keywords": "",
    "pain": "Navigation links lack active state and accessibility consistency",
    "promise": "Active and disabled navigation states enforced structurally",
    "why": "NavItemPrimitive encodes ActivityState and DisabledState into data attributes and ARIA. aria-current is derived automatically. This guarantees consistent navigation behavior and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  <a class=\"active\" href=\"/\">\"Home\"</a>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <NavItem label=\"Home\" active=true />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "sidebars",
      "menus"
    ],
    "related": [
      "navigation_menu",
      "sidebar",
      "breadcrumb",
      "pagination",
      "link_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "navigation",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! NavItem Primitive - Item atomico de navegacao\n\nuse leptos::prelude::*;\nuse crate::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn NavItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    let uid_ni = crate::infra::uid::generate(\"ni\");\n    let is_active = active == ActivityState::Active;\n    view! {\n        <a\n            data-rs-nav-item=\"\"\n            data-rs-uid=uid_ni\n            data-rs-interaction=\"init\"\n            data-rs-activity=active.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-current=if is_active { Some(\"page\") } else { None }\n            aria-label=aria_label\n            aria-disabled=disabled.aria_disabled()\n            href=if disabled.disabled() { \"#\".to_string() } else { href }\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn NavGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::from(\"vertical\"))] direction: String,\n) -> impl IntoView {\n    let uid_ng = crate::infra::uid::generate(\"ng\");\n    view! {\n        <nav\n            data-rs-nav-group=\"\"\n\n                        data-rs-uid=uid_ng\n            data-rs-interaction=\"init\"\n            data-rs-direction=direction\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn NavItemIconPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <span data-rs-nav-item-icon=\"\">{children()}</span> }\n}\n\n#[component]\npub fn NavItemLabelPrimitive(\n    children: Children,\n) -> impl IntoView {\n    view! { <span data-rs-nav-item-label=\"\">{children()}</span> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{NavItemPrimitive, NavGroupPrimitive, NavItemIconPrimitive, NavItemLabelPrimitive};\nuse canonrs_core::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn NavItem(#[prop(into)] label: String, #[prop(optional, into)] href: Option<String>, #[prop(default = ActivityState::Inactive)] active: ActivityState, #[prop(default = DisabledState::Enabled)] disabled: DisabledState, #[prop(optional)] icon: Option<Children>, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <NavItemPrimitive href=href.unwrap_or_default() active=active disabled=disabled class=class>\n            {icon.map(|i| view! { <NavItemIconPrimitive>{i()}</NavItemIconPrimitive> })}\n            <NavItemLabelPrimitive>{label}</NavItemLabelPrimitive>\n        </NavItemPrimitive>\n    }\n}\n#[component]\npub fn NavGroup(children: Children, #[prop(into, default = String::new())] class: String, #[prop(into, optional)] aria_label: Option<String>, #[prop(into, default = String::from(\"vertical\"))] direction: String) -> impl IntoView {\n    view! { <NavGroupPrimitive class=class aria_label=aria_label.unwrap_or_default() direction=direction>{children()}</NavGroupPrimitive> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! NavItem Boundary — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::nav_item_ui::{NavItem as NavItemUi, NavGroup as NavGroupUi};\nuse canonrs_core::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn NavItem(\n    #[prop(into)] label: String,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <NavItemUi label=label href=href active=active disabled=disabled class=class /> }\n}\n\n#[component]\npub fn NavGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::from(\"vertical\"))] direction: String,\n) -> impl IntoView {\n    view! { <NavGroupUi class=class aria_label=aria_label.unwrap_or_default() direction=direction>{children()}</NavGroupUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const NAVITEM_API: ComponentApi = ComponentApi {\n    id: \"nav-item\",\n    description: \"Single navigation item\",\n    props: &[\n        PropDef { name: \"label\", kind: PropType::String, required: true, default: None, description: \"Accessible label text\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"active\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Active/selected state\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const NAVGROUP_API: ComponentApi = ComponentApi {\n    id: \"nav-group\",\n    description: \"Single navigation item\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n        PropDef { name: \"direction\", kind: PropType::String, required: false, default: Some(\"vertical\"), description: \"Stack or flex direction\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::nav_item_boundary::{NavItem, NavGroup};\nuse canonrs_core::meta::{ActivityState, DisabledState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn NavItemShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Active and disabled navigation states enforced structurally.\"\n            </p>\n\n            // Vertical (sidebar)\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Vertical (sidebar)\"</span>\n                <NavGroup>\n                    <NavItem label=\"Dashboard\" href=\"#\" active=ActivityState::Active />\n                    <NavItem label=\"Components\" href=\"#\" />\n                    <NavItem label=\"Tokens\" href=\"#\" />\n                    <NavItem label=\"Settings\" href=\"#\" />\n                </NavGroup>\n            </Stack>\n\n            // Horizontal (inline nav)\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Horizontal (inline)\"</span>\n                <NavGroup direction=\"horizontal\">\n                    <NavItem label=\"Home\" href=\"#\" active=ActivityState::Active />\n                    <NavItem label=\"About\" href=\"#\" />\n                    <NavItem label=\"Contact\" href=\"#\" />\n                </NavGroup>\n            </Stack>\n\n            // States\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <NavGroup>\n                    <NavItem label=\"Active\" href=\"#\" active=ActivityState::Active />\n                    <NavItem label=\"Inactive\" href=\"#\" />\n                    <NavItem label=\"Disabled\" href=\"#\" disabled=DisabledState::Disabled />\n                </NavGroup>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "navigation_menu",
    "label": "Navigation Menu",
    "category": "Navigation",
    "description": "Navigation menu",
    "keywords": "",
    "pain": "Nested navigation menus require id wiring and break interaction consistency",
    "promise": "Trigger-content relationship enforced without id wiring",
    "why": "NavigationMenu uses DOM structure and data-rs-state instead of ids. Trigger and content are linked via closest/sibling logic. This guarantees stable interaction without manual wiring.\n",
    "before": "// ❌ Typical\nview! {\n  <button id=\"trigger\">\"Menu\"</button>\n  <div id=\"content\">\"Items\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <NavigationMenu>\n    <NavigationMenuItem>\n      <NavigationMenuTrigger>\"Menu\"</NavigationMenuTrigger>\n      <NavigationMenuContent>\"Items\"</NavigationMenuContent>\n    </NavigationMenuItem>\n  </NavigationMenu>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "site navigation",
      "dropdown navigation"
    ],
    "related": [
      "sidebar",
      "nav_item",
      "breadcrumb",
      "pagination",
      "link_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "navigation",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! NavigationMenu Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[component]\npub fn NavigationMenuPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_nm = crate::infra::uid::generate(\"nm\");\n    view! {\n        <nav\n            data-rs-navigation-menu=\"\"\n            data-rs-uid=uid_nm\n            data-rs-interaction=\"init\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn NavigationMenuListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ul\n            data-rs-navigation-menu-list=\"\"\n            role=\"menubar\"\n            aria-orientation=\"horizontal\"\n            class=class\n        >\n            {children()}\n        </ul>\n    }\n}\n\n#[component]\npub fn NavigationMenuItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let item_uid = crate::infra::uid::generate(\"ni\");\n    view! {\n        <li data-rs-navigation-menu-item=\"\" data-rs-uid=item_uid class=class>\n            {children()}\n        </li>\n    }\n}\n\n/// Trigger sem id wiring — relação com content via DOM closest/sibling\n#[component]\npub fn NavigationMenuTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_nt = crate::infra::uid::generate(\"nt\");\n    view! {\n        <button\n            type=\"button\"\n            data-rs-navigation-menu-trigger=\"\"\n            data-rs-uid=uid_nt\n            data-rs-state=state.as_str()\n            aria-haspopup=\"menu\"\n            aria-expanded=state.aria_expanded()\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n/// Content — visibilidade controlada por CSS via data-rs-state no trigger pai\n#[component]\npub fn NavigationMenuContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-navigation-menu-content=\"\"\n            data-rs-state=state.as_str()\n            aria-hidden=state.aria_hidden()\n            role=\"menu\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn NavigationMenuLinkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <a\n            data-rs-navigation-menu-link=\"\"\n            role=\"menuitem\"\n            href=href\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn NavigationMenuSubItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-navigation-menu-subitem=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::VisibilityState;\nuse canonrs_core::primitives::{\n    NavigationMenuPrimitive,\n    NavigationMenuListPrimitive,\n    NavigationMenuItemPrimitive,\n    NavigationMenuTriggerPrimitive,\n    NavigationMenuContentPrimitive,\n    NavigationMenuLinkPrimitive,\n    NavigationMenuSubItemPrimitive,\n};\n\n#[component]\npub fn NavigationMenu(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuPrimitive class=class>\n            {children()}\n        </NavigationMenuPrimitive>\n    }\n}\n\n#[component]\npub fn NavigationMenuList(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuListPrimitive class=class>\n            {children()}\n        </NavigationMenuListPrimitive>\n    }\n}\n\n#[component]\npub fn NavigationMenuItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuItemPrimitive class=class>\n            {children()}\n        </NavigationMenuItemPrimitive>\n    }\n}\n\n/// Trigger sem id wiring — behavior JS conecta via DOM closest\n#[component]\npub fn NavigationMenuTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuTriggerPrimitive state=VisibilityState::Closed class=class>\n            {children()}\n        </NavigationMenuTriggerPrimitive>\n    }\n}\n\n/// Content sem id wiring — abre via CSS :hover/:focus-within + behavior keyboard\n#[component]\npub fn NavigationMenuContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuContentPrimitive class=class>\n            {children()}\n        </NavigationMenuContentPrimitive>\n    }\n}\n\n#[component]\npub fn NavigationMenuLink(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuLinkPrimitive href=href class=class>\n            {children()}\n        </NavigationMenuLinkPrimitive>\n    }\n}\n\n#[component]\npub fn NavigationMenuSubItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <NavigationMenuSubItemPrimitive class=class>\n            {children()}\n        </NavigationMenuSubItemPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! NavigationMenu Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::navigation_menu_ui::{\n    NavigationMenu as NavigationMenuUi,\n    NavigationMenuItem as NavigationMenuItemUi,\n    NavigationMenuTrigger as NavigationMenuTriggerUi,\n    NavigationMenuContent as NavigationMenuContentUi,\n    NavigationMenuLink as NavigationMenuLinkUi\n};\n\n#[component]\npub fn NavigationMenu(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <NavigationMenuUi class=class>{children()}</NavigationMenuUi> }\n}\n\n#[component]\npub fn NavigationMenuItem(children: Children) -> impl IntoView {\n    view! { <NavigationMenuItemUi>{children()}</NavigationMenuItemUi> }\n}\n\n#[component]\npub fn NavigationMenuTrigger(children: Children) -> impl IntoView {\n    view! { <NavigationMenuTriggerUi>{children()}</NavigationMenuTriggerUi> }\n}\n\n#[component]\npub fn NavigationMenuContent(children: Children) -> impl IntoView {\n    view! { <NavigationMenuContentUi>{children()}</NavigationMenuContentUi> }\n}\n\n#[component]\npub fn NavigationMenuLink(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n) -> impl IntoView {\n    view! { <NavigationMenuLinkUi href=href>{children()}</NavigationMenuLinkUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const NAVIGATIONMENU_API: ComponentApi = ComponentApi {\n    id: \"navigation-menu\",\n    description: \"Navigation menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const NAVIGATIONMENUITEM_API: ComponentApi = ComponentApi {\n    id: \"navigation-menu-item\",\n    description: \"Navigation menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\npub const NAVIGATIONMENUCONTENT_API: ComponentApi = ComponentApi {\n    id: \"navigation-menu-content\",\n    description: \"Navigation menu\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::navigation_menu_boundary::{\n    NavigationMenu, NavigationMenuItem, NavigationMenuTrigger,\n    NavigationMenuContent, NavigationMenuLink,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn NavigationMenuShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Trigger-content relationship governed by DOM — no id wiring needed.\"\n            </p>\n            <NavigationMenu>\n                <NavigationMenuItem>\n                    <NavigationMenuTrigger>\"Products\"</NavigationMenuTrigger>\n                    <NavigationMenuContent>\n                        <NavigationMenuLink href=\"#\">\"CanonRS Core\"</NavigationMenuLink>\n                        <NavigationMenuLink href=\"#\">\"CanonRS UI\"</NavigationMenuLink>\n                        <NavigationMenuLink href=\"#\">\"CanonRS Tokens\"</NavigationMenuLink>\n                    </NavigationMenuContent>\n                </NavigationMenuItem>\n                <NavigationMenuItem>\n                    <NavigationMenuTrigger>\"Docs\"</NavigationMenuTrigger>\n                    <NavigationMenuContent>\n                        <NavigationMenuLink href=\"#\">\"Getting Started\"</NavigationMenuLink>\n                        <NavigationMenuLink href=\"#\">\"API Reference\"</NavigationMenuLink>\n                    </NavigationMenuContent>\n                </NavigationMenuItem>\n                <NavigationMenuItem>\n                    <NavigationMenuLink href=\"#\">\"Pricing\"</NavigationMenuLink>\n                </NavigationMenuItem>\n                <NavigationMenuItem>\n                    <NavigationMenuLink href=\"#\">\"Blog\"</NavigationMenuLink>\n                </NavigationMenuItem>\n            </NavigationMenu>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "page_header",
    "label": "Page Header",
    "category": "Display",
    "description": "Page header with title and actions",
    "keywords": "",
    "pain": "Page headers mix title, actions and breadcrumbs inconsistently",
    "promise": "Header structure enforced with explicit semantic regions",
    "why": "PageHeaderPrimitive defines structured parts like title, description and actions. Each region is explicitly declared. This guarantees consistent layout composition across pages.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"header\">\n    <h1>\"Title\"</h1>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <PageHeader>\n    <PageHeaderContent>\n      <PageHeaderTitle>\"Title\"</PageHeaderTitle>\n    </PageHeaderContent>\n  </PageHeader>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "dashboards",
      "admin pages"
    ],
    "related": [
      "card",
      "resizable",
      "scroll_area",
      "aspect_ratio",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! PageHeader Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[component]\npub fn PageHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ph = crate::infra::uid::generate(\"ph\");\n    view! {\n        <header\n            data-rs-page-header=\"\"\n            data-rs-uid=uid_ph\n            role=\"banner\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </header>\n    }\n}\n\n#[component]\npub fn PageHeaderBreadcrumbsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <nav\n            data-rs-page-header-breadcrumbs=\"\"\n            aria-label=\"Breadcrumb\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn PageHeaderContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-page-header-content=\"\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn PageHeaderTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <h1\n            data-rs-page-header-title=\"\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </h1>\n    }\n}\n\n#[component]\npub fn PageHeaderDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p\n            data-rs-page-header-description=\"\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn PageHeaderActionsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-page-header-actions=\"\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn PageHeaderTabsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-page-header-tabs=\"\"\n            class={(!class.is_empty()).then(|| class)}\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    PageHeaderPrimitive,\n    PageHeaderBreadcrumbsPrimitive,\n    PageHeaderContentPrimitive,\n    PageHeaderTitlePrimitive,\n    PageHeaderDescriptionPrimitive,\n    PageHeaderActionsPrimitive,\n    PageHeaderTabsPrimitive,\n};\n\n#[component]\npub fn PageHeader(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderPrimitive class=class>\n            {children()}\n        </PageHeaderPrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderBreadcrumbs(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderBreadcrumbsPrimitive class=class>\n            {children()}\n        </PageHeaderBreadcrumbsPrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderContentPrimitive class=class>\n            {children()}\n        </PageHeaderContentPrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderTitlePrimitive class=class>\n            {children()}\n        </PageHeaderTitlePrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderDescriptionPrimitive class=class>\n            {children()}\n        </PageHeaderDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderActionsPrimitive class=class>\n            {children()}\n        </PageHeaderActionsPrimitive>\n    }\n}\n\n#[component]\npub fn PageHeaderTabs(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PageHeaderTabsPrimitive class=class>\n            {children()}\n        </PageHeaderTabsPrimitive>\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::page_header_ui::{\n    PageHeader as PageHeaderUi,\n    PageHeaderBreadcrumbs as PageHeaderBreadcrumbsUi,\n    PageHeaderContent as PageHeaderContentUi,\n    PageHeaderTitle as PageHeaderTitleUi,\n    PageHeaderDescription as PageHeaderDescriptionUi,\n    PageHeaderActions as PageHeaderActionsUi,\n    PageHeaderTabs as PageHeaderTabsUi\n};\n\n#[component]\npub fn PageHeader(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderUi class=class>{children()}</PageHeaderUi> }\n}\n\n#[component]\npub fn PageHeaderBreadcrumbs(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderBreadcrumbsUi class=class>{children()}</PageHeaderBreadcrumbsUi> }\n}\n\n#[component]\npub fn PageHeaderContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderContentUi class=class>{children()}</PageHeaderContentUi> }\n}\n\n#[component]\npub fn PageHeaderTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderTitleUi class=class>{children()}</PageHeaderTitleUi> }\n}\n\n#[component]\npub fn PageHeaderDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderDescriptionUi class=class>{children()}</PageHeaderDescriptionUi> }\n}\n\n#[component]\npub fn PageHeaderActions(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderActionsUi class=class>{children()}</PageHeaderActionsUi> }\n}\n\n#[component]\npub fn PageHeaderTabs(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PageHeaderTabsUi class=class>{children()}</PageHeaderTabsUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const PAGEHEADER_API: ComponentApi = ComponentApi {\n    id: \"page-header\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERBREADCRUMBS_API: ComponentApi = ComponentApi {\n    id: \"page-header-breadcrumbs\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERCONTENT_API: ComponentApi = ComponentApi {\n    id: \"page-header-content\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERTITLE_API: ComponentApi = ComponentApi {\n    id: \"page-header-title\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERDESCRIPTION_API: ComponentApi = ComponentApi {\n    id: \"page-header-description\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERACTIONS_API: ComponentApi = ComponentApi {\n    id: \"page-header-actions\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGEHEADERTABS_API: ComponentApi = ComponentApi {\n    id: \"page-header-tabs\",\n    description: \"Page header with title and actions\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::page_header_boundary::{\n    PageHeader, PageHeaderBreadcrumbs, PageHeaderContent,\n    PageHeaderTitle, PageHeaderDescription, PageHeaderActions,\n    PageHeaderTabs,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn PageHeaderShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Header structure enforced with explicit semantic regions.\"\n            </p>\n            <PageHeader>\n                <PageHeaderBreadcrumbs>\n                    <span>\"Home\"</span>\n                    <span>\" / \"</span>\n                    <span>\"Components\"</span>\n                    <span>\" / \"</span>\n                    <span>\"PageHeader\"</span>\n                </PageHeaderBreadcrumbs>\n                <PageHeaderContent>\n                    <PageHeaderTitle>\"Page Title\"</PageHeaderTitle>\n                    <PageHeaderDescription>\"Header structure enforced with explicit semantic regions.\"</PageHeaderDescription>\n                </PageHeaderContent>\n                <PageHeaderActions>\n                    <span data-rs-button=\"\">\"Action\"</span>\n                </PageHeaderActions>\n            </PageHeader>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Md>\n                    <PageHeader>\n                        <PageHeaderContent>\n                            <PageHeaderTitle>\"Title only\"</PageHeaderTitle>\n                        </PageHeaderContent>\n                    </PageHeader>\n                    <PageHeader>\n                        <PageHeaderContent>\n                            <PageHeaderTitle>\"With description\"</PageHeaderTitle>\n                            <PageHeaderDescription>\"A short description of this page.\"</PageHeaderDescription>\n                        </PageHeaderContent>\n                    </PageHeader>\n                    <PageHeader>\n                        <PageHeaderContent>\n                            <PageHeaderTitle>\"With tabs\"</PageHeaderTitle>\n                        </PageHeaderContent>\n                        <PageHeaderTabs>\n                            <span>\"Overview\"</span>\n                            <span>\"Settings\"</span>\n                            <span>\"Members\"</span>\n                        </PageHeaderTabs>\n                    </PageHeader>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "pagination",
    "label": "Pagination",
    "category": "Navigation",
    "description": "Page navigation control",
    "keywords": "",
    "pain": "Pagination links lack active state and disabled navigation semantics",
    "promise": "Navigation state and accessibility enforced via structured primitives",
    "why": "PaginationPrimitive encodes navigation semantics with aria-current and disabled states. Previous and next controls enforce accessibility automatically. This guarantees consistent pagination behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <a class=\"active\">\"1\"</a>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Pagination>\n    <PaginationContent>\n      <PaginationLink state=ActivityState::Active href=\"#\">\"1\"</PaginationLink>\n    </PaginationContent>\n  </Pagination>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "tables",
      "lists"
    ],
    "related": [
      "navigation_menu",
      "sidebar",
      "nav_item",
      "breadcrumb",
      "link_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "navigation",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Pagination Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn PaginationPrimitive(\n    children: Children,\n    #[prop(default = 1usize)] current_page: usize,\n    #[prop(default = 1usize)] total_pages: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_pg = crate::infra::uid::generate(\"pg\");\n    view! {\n        <nav\n            data-rs-pagination=\"\"\n            data-rs-current-page=current_page.to_string()\n            data-rs-total-pages=total_pages.to_string()\n            data-rs-uid=uid_pg\n            data-rs-interaction=\"nav\"\n            aria-label=\"Page navigation\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn PaginationContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ul data-rs-pagination-content=\"\" class=class>\n            {children()}\n        </ul>\n    }\n}\n\n#[component]\npub fn PaginationItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <li data-rs-pagination-item=\"\" class=class>\n            {children()}\n        </li>\n    }\n}\n\n#[component]\npub fn PaginationLinkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n    #[prop(default = 0usize)] page: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_active = state == ActivityState::Active;\n    view! {\n        <a\n            data-rs-pagination-link=\"\"\n            data-rs-page=page.to_string()\n            data-rs-activity=state.as_str()\n            aria-current=if is_active { Some(\"page\") } else { None }\n            href=href\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn PaginationPreviousPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <a\n            data-rs-pagination-previous=\"\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            aria-label=\"Go to previous page\"\n            href=if disabled.disabled() { \"#\".to_string() } else { href }\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn PaginationNextPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <a\n            data-rs-pagination-next=\"\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            aria-label=\"Go to next page\"\n            href=if disabled.disabled() { \"#\".to_string() } else { href }\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn PaginationEllipsisPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-pagination-ellipsis=\"\" aria-hidden=\"true\" class=class>\n            \"\\u{2026}\"\n            <span class=\"sr-only\">\"More pages\"</span>\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::meta::{ActivityState, DisabledState};\nuse canonrs_core::primitives::{\n    PaginationPrimitive, PaginationContentPrimitive, PaginationItemPrimitive,\n    PaginationLinkPrimitive, PaginationPreviousPrimitive, PaginationNextPrimitive,\n    PaginationEllipsisPrimitive,\n};\n\n#[component]\npub fn Pagination(\n    children: Children,\n    #[prop(default = 1usize)] current_page: usize,\n    #[prop(default = 1usize)] total_pages: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationPrimitive current_page=current_page total_pages=total_pages class=class>\n            {children()}\n        </PaginationPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationContentPrimitive class=class>\n            {children()}\n        </PaginationContentPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationItemPrimitive class=class>\n            {children()}\n        </PaginationItemPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationLink(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n    #[prop(default = 0usize)] page: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationLinkPrimitive href=href state=state page=page class=class>\n            {children()}\n        </PaginationLinkPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationPrevious(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationPreviousPrimitive href=href disabled=disabled class=class>\n            {children()}\n        </PaginationPreviousPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationNext(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationNextPrimitive href=href disabled=disabled class=class>\n            {children()}\n        </PaginationNextPrimitive>\n    }\n}\n\n#[component]\npub fn PaginationEllipsis(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationEllipsisPrimitive class=class />\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Pagination Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::pagination_ui::{\n    Pagination as PaginationUi,\n    PaginationContent as PaginationContentUi,\n    PaginationItem as PaginationItemUi,\n    PaginationLink as PaginationLinkUi,\n    PaginationPrevious as PaginationPreviousUi,\n    PaginationNext as PaginationNextUi,\n    PaginationEllipsis as PaginationEllipsisUi\n};\nuse canonrs_core::meta::{ActivityState, DisabledState};\n\n\n\n#[component]\npub fn Pagination(\n    children: Children,\n    #[prop(default = 1usize)] current_page: usize,\n    #[prop(default = 1usize)] total_pages: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PaginationUi current_page=current_page total_pages=total_pages class=class>{children()}</PaginationUi>\n    }\n}\n\n#[component]\npub fn PaginationContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationContentUi class=class>{children()}</PaginationContentUi> }\n}\n\n#[component]\npub fn PaginationItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationItemUi class=class>{children()}</PaginationItemUi> }\n}\n\n#[component]\npub fn PaginationLink(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] state: ActivityState,\n    #[prop(default = 0usize)] page: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationLinkUi href=href state=state page=page class=class>{children()}</PaginationLinkUi> }\n}\n\n#[component]\npub fn PaginationPrevious(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationPreviousUi href=href disabled=disabled class=class>{children()}</PaginationPreviousUi> }\n}\n\n#[component]\npub fn PaginationNext(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationNextUi href=href disabled=disabled class=class>{children()}</PaginationNextUi> }\n}\n\n#[component]\npub fn PaginationEllipsis(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <PaginationEllipsisUi class=class /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const PAGINATION_API: ComponentApi = ComponentApi {\n    id: \"pagination\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"current_page\", kind: PropType::Number, required: false, default: Some(\"1usize\"), description: \"Prop value\" },\n        PropDef { name: \"total_pages\", kind: PropType::Number, required: false, default: Some(\"1usize\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONCONTENT_API: ComponentApi = ComponentApi {\n    id: \"pagination-content\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONITEM_API: ComponentApi = ComponentApi {\n    id: \"pagination-item\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONLINK_API: ComponentApi = ComponentApi {\n    id: \"pagination-link\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"page\", kind: PropType::Number, required: false, default: Some(\"0usize\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONPREVIOUS_API: ComponentApi = ComponentApi {\n    id: \"pagination-previous\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONNEXT_API: ComponentApi = ComponentApi {\n    id: \"pagination-next\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const PAGINATIONELLIPSIS_API: ComponentApi = ComponentApi {\n    id: \"pagination-ellipsis\",\n    description: \"Page navigation control\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::pagination_boundary::{\n    Pagination, PaginationContent, PaginationItem,\n    PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis,\n};\nuse canonrs_core::meta::{ActivityState, DisabledState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn PaginationShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Navigation state and accessibility governed by DOM.\"\n            </p>\n            <Pagination current_page=3 total_pages=10>\n                <PaginationContent>\n                    <PaginationItem>\n                        <PaginationPrevious href=\"#\">\"←\"</PaginationPrevious>\n                    </PaginationItem>\n                    <PaginationItem><PaginationLink href=\"#\" page=1>\"1\"</PaginationLink></PaginationItem>\n                    <PaginationItem><PaginationLink href=\"#\" page=2>\"2\"</PaginationLink></PaginationItem>\n                    <PaginationItem><PaginationLink href=\"#\" page=3 state=ActivityState::Active>\"3\"</PaginationLink></PaginationItem>\n                    <PaginationItem><PaginationLink href=\"#\" page=4>\"4\"</PaginationLink></PaginationItem>\n                    <PaginationItem><PaginationEllipsis /></PaginationItem>\n                    <PaginationItem><PaginationLink href=\"#\" page=10>\"10\"</PaginationLink></PaginationItem>\n                    <PaginationItem>\n                        <PaginationNext href=\"#\">\"→\"</PaginationNext>\n                    </PaginationItem>\n                </PaginationContent>\n            </Pagination>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"First page (prev disabled)\"</span>\n                <Pagination current_page=1 total_pages=5>\n                    <PaginationContent>\n                        <PaginationItem>\n                            <PaginationPrevious href=\"#\" disabled=DisabledState::Disabled>\"←\"</PaginationPrevious>\n                        </PaginationItem>\n                        <PaginationItem><PaginationLink href=\"#\" page=1 state=ActivityState::Active>\"1\"</PaginationLink></PaginationItem>\n                        <PaginationItem><PaginationLink href=\"#\" page=2>\"2\"</PaginationLink></PaginationItem>\n                        <PaginationItem><PaginationLink href=\"#\" page=3>\"3\"</PaginationLink></PaginationItem>\n                        <PaginationItem>\n                            <PaginationNext href=\"#\">\"→\"</PaginationNext>\n                        </PaginationItem>\n                    </PaginationContent>\n                </Pagination>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "popover",
    "label": "Popover",
    "category": "Overlay",
    "description": "Floating popover component",
    "keywords": "",
    "pain": "Popovers lose sync between trigger state and content visibility",
    "promise": "Trigger and content visibility governed by shared state contract",
    "why": "PopoverPrimitive uses VisibilityState across trigger and content. ARIA attributes and positioning are derived automatically. This guarantees consistent overlay behavior without manual sync.\n",
    "before": "// ❌ Typical\nview! {\n  <button on:click=toggle>\"Open\"</button>\n  {if open { view! { <div>\"Popover\"</div> } }}\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Popover>\n    <button data-rs-popover-trigger=\"\">\"Open\"</button>\n    <PopoverContent>\"Popover\"</PopoverContent>\n  </Popover>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "context actions",
      "tooltips with actions"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "sheet",
      "modal",
      "confirm_dialog",
      "tooltip",
      "hover_card"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Popover Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum PopoverSide {\n    #[default]\n    Bottom,\n    Top,\n    Left,\n    Right,\n}\n\nimpl PopoverSide {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Bottom => \"bottom\",\n            Self::Top    => \"top\",\n            Self::Left   => \"left\",\n            Self::Right  => \"right\",\n        }\n    }\n}\n\n\n#[component]\npub fn PopoverPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    let uid_pop = crate::infra::uid::generate(\"pop\");\n    view! {\n        <div\n            data-rs-popover=\"\"\n            data-rs-uid=uid_pop\n            data-rs-interaction=\"overlay\"\n            data-rs-state=state.as_str()\n            data-rs-name=name\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn PopoverTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-popover-trigger=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"outline\"\n            data-rs-state=state.as_str()\n            data-rs-value=value\n            data-rs-label=label\n            aria-haspopup=\"dialog\"\n            aria-expanded=state.aria_expanded()\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn PopoverContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = PopoverSide::Bottom)] side: PopoverSide,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-popover-content=\"\"\n            data-rs-state=state.as_str()\n            data-rs-side=side.as_str()\n            role=\"dialog\"\n            aria-modal=\"false\"\n            aria-label=aria_label\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{PopoverPrimitive, PopoverTriggerPrimitive, PopoverContentPrimitive};\nuse canonrs_core::primitives::PopoverSide;\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Popover(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    view! {\n        <PopoverPrimitive state=state class=class name=name>\n            {children()}\n        </PopoverPrimitive>\n    }\n}\n\n#[component]\npub fn PopoverTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n) -> impl IntoView {\n    view! { <PopoverTriggerPrimitive class=class value=value label=label>{children()}</PopoverTriggerPrimitive> }\n}\n\n#[component]\npub fn PopoverContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = PopoverSide::Bottom)] side: PopoverSide,\n) -> impl IntoView {\n    view! {\n        <PopoverContentPrimitive side=side class=class>\n            {children()}\n        </PopoverContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Popover Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::popover_ui::{\n    Popover as PopoverUi,\n    PopoverTrigger as PopoverTriggerUi,\n    PopoverContent as PopoverContentUi\n};\nuse canonrs_core::meta::VisibilityState;\npub use canonrs_core::primitives::PopoverSide;\n\n\n\n#[component]\npub fn Popover(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    view! {\n        <PopoverUi state=VisibilityState::Closed class=class.unwrap_or_default() name=name>\n            {children()}\n        </PopoverUi>\n    }\n}\n\n#[component]\npub fn PopoverContent(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n    #[prop(default = PopoverSide::Bottom)] side: PopoverSide,\n) -> impl IntoView {\n    view! { <PopoverContentUi side=side class=class.unwrap_or_default()>{children()}</PopoverContentUi> }\n}\n\n#[component]\npub fn PopoverTrigger(\n    children: Children,\n    #[prop(optional, into)] class: Option<String>,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] label: String,\n) -> impl IntoView {\n    view! { <PopoverTriggerUi class=class.unwrap_or_default() value=value label=label>{children()}</PopoverTriggerUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{PopoverSide}; \n\npub const POPOVER_API: ComponentApi = ComponentApi {\n    id: \"popover\",\n    description: \"Floating popover component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n    ],\n};\n\npub const POPOVERCONTENT_API: ComponentApi = ComponentApi {\n    id: \"popover-content\",\n    description: \"Floating popover component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n        PropDef { name: \"side\", kind: PropType::Enum(&[\"bottom\", \"top\", \"left\", \"right\"]), required: false, default: Some(\"bottom\"), description: \"Tooltip or popover side\" },\n    ],\n};\n\npub const POPOVERTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"popover-trigger\",\n    description: \"Floating popover component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: None, description: \"Additional CSS class names\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label text\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::popover_boundary::{Popover, PopoverTrigger, PopoverContent, PopoverSide};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn PopoverShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Popover with keyboard and click-outside dismiss.\"\n            </p>\n            <Popover>\n                <PopoverTrigger>\"Open Popover\"</PopoverTrigger>\n                <PopoverContent>\n                    <p>\"This is a popover. Click outside to close.\"</p>\n                </PopoverContent>\n            </Popover>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sides\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Sm>\n                    <Popover>\n                        <PopoverTrigger>\"Bottom\"</PopoverTrigger>\n                        <PopoverContent side=PopoverSide::Bottom>\"Opens below\"</PopoverContent>\n                    </Popover>\n                    <Popover>\n                        <PopoverTrigger>\"Top\"</PopoverTrigger>\n                        <PopoverContent side=PopoverSide::Top>\"Opens above\"</PopoverContent>\n                    </Popover>\n                    <Popover>\n                        <PopoverTrigger>\"Right\"</PopoverTrigger>\n                        <PopoverContent side=PopoverSide::Right>\"Opens right\"</PopoverContent>\n                    </Popover>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "progress",
    "label": "Progress",
    "category": "Feedback",
    "description": "Progress bar indicator",
    "keywords": "",
    "pain": "Progress bars overflow or misreport values beyond valid range",
    "promise": "Progress value always clamped and ARIA-compliant",
    "why": "ProgressPrimitive clamps value between 0–100 and maps it to aria-valuenow. Indicator movement is derived from this value. This guarantees consistent visual and accessibility behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"progress\" style=\"width:150%\"></div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Progress value=75.0 />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "file upload",
      "task completion"
    ],
    "related": [
      "spinner",
      "skeleton",
      "pulse",
      "loading_overlay",
      "doc_progress"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Progress Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum ProgressState {\n    #[default]\n    Default,\n    Indeterminate,\n    Loading,\n}\n\nimpl ProgressState {\n    pub fn as_str(&self) -> Option<&'static str> {\n        match self {\n            ProgressState::Default => None,\n            ProgressState::Indeterminate => Some(\"indeterminate\"),\n            ProgressState::Loading => Some(\"loading\"),\n        }\n    }\n}\n\n#[component]\npub fn ProgressPrimitive(\n    children: Children,\n    #[prop(default = 0.0)] value: f64,\n    #[prop(default = ProgressState::Default)] state: ProgressState,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_pr = crate::infra::uid::generate(\"pr\");\n    let clamped = value.clamp(0.0, 100.0);\n    let aria_now = if state == ProgressState::Indeterminate { None } else { Some(clamped.to_string()) };\n    view! {\n        <div\n            data-rs-progress=\"\"\n            data-rs-uid=uid_pr\n            data-rs-interaction=\"init\"\n            data-rs-value=clamped.to_string()\n            data-rs-loading=state.as_str()\n            role=\"progressbar\"\n            aria-valuemin=\"0\"\n            aria-valuemax=\"100\"\n            aria-valuenow=aria_now\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ProgressIndicatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] style: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-progress-indicator=\"\"\n            class=class\n            style=style\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{ProgressPrimitive, ProgressIndicatorPrimitive};\nuse canonrs_core::primitives::progress::ProgressState;\n\n#[component]\npub fn Progress(\n    #[prop(default = 0.0)] value: f64,\n    #[prop(default = ProgressState::Default)] state: ProgressState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let clamped = value.clamp(0.0, 100.0);\n    let transform = format!(\"transform: translateX(-{:.0}%)\", 100.0 - clamped);\n    view! {\n        <ProgressPrimitive value=clamped state=state class=class>\n            <ProgressIndicatorPrimitive style=transform />\n        </ProgressPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Progress Boundary — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::progress_ui::Progress as ProgressUi;\nuse canonrs_core::primitives::progress::ProgressState;\n\n#[component]\npub fn Progress(\n    #[prop(default = 0.0)] value: f64,\n    #[prop(default = ProgressState::Default)] state: ProgressState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ProgressUi value=value state=state class=class /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ProgressState}; \n\npub const PROGRESS_API: ComponentApi = ComponentApi {\n    id: \"progress\",\n    description: \"Progress bar indicator\",\n    props: &[\n        PropDef { name: \"value\", kind: PropType::Number, required: false, default: Some(\"0.0\"), description: \"Current value\" },\n        PropDef { name: \"state\", kind: PropType::Enum(&[\"default\", \"indeterminate\", \"loading\"]), required: false, default: Some(\"default\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::progress_boundary::Progress;\nuse canonrs_core::primitives::progress::ProgressState;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ProgressShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Value always clamped between 0-100 and ARIA-compliant.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Values\"</span>\n                <Progress value=0.0 />\n                <Progress value=25.0 />\n                <Progress value=50.0 />\n                <Progress value=75.0 />\n                <Progress value=100.0 />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Indeterminate\"</span>\n                <Progress state=ProgressState::Indeterminate />\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Loading\"</span>\n                <Progress state=ProgressState::Loading />\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "pulse",
    "label": "Pulse",
    "category": "Feedback",
    "description": "Pulse animation wrapper",
    "keywords": "",
    "pain": "Animations applied inconsistently with arbitrary classes and speeds",
    "promise": "Animation variant, size and speed strictly typed",
    "why": "PulsePrimitive encodes variant, size and speed as enums mapped to data attributes. This removes class-based inconsistencies. It guarantees predictable animation behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <span class=\"pulse-fast big\"></span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Pulse variant=PulseVariant::Emphasized speed=PulseSpeed::Fast />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "status indicators",
      "attention highlights"
    ],
    "related": [
      "progress",
      "spinner",
      "skeleton",
      "loading_overlay",
      "doc_progress"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Pulse Primitive - Motion indicator\n\nuse leptos::prelude::*;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum PulseVariant {\n    #[default]\n    Default,\n    Subtle,\n    Emphasized,\n}\nimpl PulseVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default    => \"default\",\n            Self::Subtle     => \"subtle\",\n            Self::Emphasized => \"emphasized\",\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum PulseSize {\n    Small,\n    #[default]\n    Medium,\n    Large,\n}\nimpl PulseSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Small  => \"small\",\n            Self::Medium => \"medium\",\n            Self::Large  => \"large\",\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum PulseSpeed {\n    Slow,\n    #[default]\n    Normal,\n    Fast,\n}\nimpl PulseSpeed {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Slow   => \"slow\",\n            Self::Normal => \"normal\",\n            Self::Fast   => \"fast\",\n        }\n    }\n}\n\n#[component]\npub fn PulsePrimitive(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = PulseVariant::Default)] variant: PulseVariant,\n    #[prop(default = PulseSize::Medium)] size: PulseSize,\n    #[prop(default = PulseSpeed::Normal)] speed: PulseSpeed,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_pls = crate::infra::uid::generate(\"pls\");\n    view! {\n        <span\n            data-rs-pulse=\"\"\n            data-rs-uid=uid_pls\n            data-rs-variant=variant.as_str()\n            data-rs-size=size.as_str()\n            data-rs-speed=speed.as_str()\n            aria-hidden=\"true\"\n            class=class\n        >\n            {children.map(|c| c())}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::PulsePrimitive;\npub use canonrs_core::primitives::{PulseVariant, PulseSize, PulseSpeed};\n\n#[component]\npub fn Pulse(\n    children: Children,\n    #[prop(default = PulseVariant::Default)] variant: PulseVariant,\n    #[prop(default = PulseSize::Medium)] size: PulseSize,\n    #[prop(default = PulseSpeed::Normal)] speed: PulseSpeed,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <PulsePrimitive\n            variant=variant\n            size=size\n            speed=speed\n            class=class\n        >\n            {children()}\n        </PulsePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Pulse Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\npub use super::pulse_ui::{PulseVariant, PulseSize, PulseSpeed};\nuse super::pulse_ui::Pulse as PulseUi;\n\n#[component]\npub fn Pulse(\n    #[prop(default = PulseVariant::Default)] variant: PulseVariant,\n    #[prop(default = PulseSize::Medium)] size:         PulseSize,\n    #[prop(default = PulseSpeed::Normal)] speed:       PulseSpeed,\n    #[prop(into, default = String::new())] class:      String,\n) -> impl IntoView {\n    view! { <PulseUi variant=variant size=size speed=speed class=class>{\"\"}</PulseUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const PULSE_API: ComponentApi = ComponentApi {\n    id: \"pulse\",\n    description: \"Pulse animation wrapper\",\n    props: &[\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"subtle\", \"emphasized\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"small\", \"medium\", \"large\"]), required: false, default: Some(\"medium\"), description: \"Size variant of the component\" },\n        PropDef { name: \"speed\", kind: PropType::Enum(&[\"slow\", \"normal\", \"fast\"]), required: false, default: Some(\"normal\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::pulse_boundary::{Pulse, PulseVariant, PulseSize, PulseSpeed};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn PulseShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Animation variant, size and speed strictly typed.\"\n            </p>\n            <Pulse />\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Pulse variant=PulseVariant::Subtle />\n                    <Pulse />\n                    <Pulse variant=PulseVariant::Emphasized />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Pulse size=PulseSize::Small />\n                    <Pulse size=PulseSize::Medium />\n                    <Pulse size=PulseSize::Large />\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Speed\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <Pulse speed=PulseSpeed::Slow />\n                    <Pulse speed=PulseSpeed::Normal />\n                    <Pulse speed=PulseSpeed::Fast />\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "radio",
    "label": "Radio",
    "category": "Form",
    "description": "Radio button input",
    "keywords": "",
    "pain": "Radio inputs desync checked state and accessibility attributes",
    "promise": "Selection state mapped directly to DOM and ARIA",
    "why": "RadioPrimitive maps SelectionState to checked and aria attributes. Disabled state is also enforced structurally. This guarantees consistent selection behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"radio\" checked />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Radio value=\"a\" name=\"group\" checked=true>\"Option\"</Radio>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "single choice inputs"
    ],
    "related": [
      "select",
      "combobox",
      "radio_group",
      "color_picker",
      "slider"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Radio Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn RadioPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ra = crate::infra::uid::generate(\"ra\");\n    let is_selected = selected == SelectionState::Selected;\n    let is_disabled = disabled == DisabledState::Disabled;\n\n    view! {\n        <label\n            data-rs-radio=\"\"\n            data-rs-uid=uid_ra\n            data-rs-interaction=\"init\"\n            data-rs-selection=if is_selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            class=class\n        >\n            <input\n                type=\"radio\"\n                data-rs-radio-input=\"\"\n                name=name\n                value=value\n                checked=is_selected\n                disabled=is_disabled\n                aria-checked=if is_selected { \"true\" } else { \"false\" }\n                aria-disabled=if is_disabled { Some(\"true\") } else { None }\n            />\n            <span data-rs-radio-indicator=\"\" />\n            {children()}\n        </label>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{RadioPrimitive, RadioGroupPrimitive, RadioGroupItemPrimitive};\nuse canonrs_core::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn Radio(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioPrimitive\n            selected=selected\n            disabled=disabled\n            value=value\n            name=name\n            class=class\n        >\n            {children()}\n        </RadioPrimitive>\n    }\n}\n\n#[component]\npub fn RadioGroup(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioGroupPrimitive disabled=disabled class=class>\n            {children()}\n        </RadioGroupPrimitive>\n    }\n}\n\n#[component]\npub fn RadioGroupItem(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioGroupItemPrimitive\n            selected=selected\n            disabled=disabled\n            value=value\n            name=name\n            class=class\n        >\n            {children()}\n        </RadioGroupItemPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Radio Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::radio_ui::RadioGroup as RadioGroupUi;\nuse canonrs_core::meta::{\n    SelectionState,\n    DisabledState\n};\n\n\n\n#[component]\npub fn RadioGroup(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioGroupUi disabled=disabled class=class>{children()}</RadioGroupUi>\n    }\n}\n\n#[component]\npub fn Radio(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::radio_ui::Radio selected=selected disabled=disabled value=value name=name class=class>\n            {children()}\n        </super::radio_ui::Radio>\n    }\n}\n\n#[component]\npub fn RadioGroupItem(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::radio_ui::RadioGroupItem selected=selected disabled=disabled value=value name=name class=class>\n            {children()}\n        </super::radio_ui::RadioGroupItem>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const RADIOGROUP_API: ComponentApi = ComponentApi {\n    id: \"radio-group\",\n    description: \"Radio button input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const RADIO_API: ComponentApi = ComponentApi {\n    id: \"radio\",\n    description: \"Radio button input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selected\", kind: PropType::String, required: false, default: Some(\"unselected\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const RADIOGROUPITEM_API: ComponentApi = ComponentApi {\n    id: \"radio-group-item\",\n    description: \"Radio button input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selected\", kind: PropType::String, required: false, default: Some(\"unselected\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::radio_boundary::Radio;\nuse canonrs_core::meta::{SelectionState, DisabledState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn RadioShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Selection state mapped directly to DOM and ARIA.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <Radio value=\"leptos\" name=\"framework\">\"Leptos\"</Radio>\n                <Radio value=\"dioxus\" name=\"framework\" selected=SelectionState::Selected>\"Dioxus\"</Radio>\n                <Radio value=\"yew\" name=\"framework\">\"Yew\"</Radio>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <Radio value=\"a\" name=\"disabled-radio\" disabled=DisabledState::Disabled>\"Option A\"</Radio>\n                <Radio value=\"b\" name=\"disabled-radio\" disabled=DisabledState::Disabled>\"Option B\"</Radio>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "radio_group",
    "label": "Radio Group",
    "category": "Form",
    "description": "Group of radio buttons",
    "keywords": "",
    "pain": "Radio groups lose exclusivity and accessibility grouping",
    "promise": "Group semantics and exclusivity enforced at container level",
    "why": "RadioGroupPrimitive enforces role=\"radiogroup\" and shared disabled state. Items derive selection state consistently. This guarantees exclusive selection behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\n    <input type=\"radio\" name=\"a\" />\n    <input type=\"radio\" name=\"a\" />\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <RadioGroup>\n    <RadioGroupItem name=\"a\" value=\"1\">\"One\"</RadioGroupItem>\n  </RadioGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "settings",
      "forms"
    ],
    "related": [
      "select",
      "combobox",
      "radio",
      "color_picker",
      "slider"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! RadioGroup Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn RadioGroupPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_rg = crate::infra::uid::generate(\"rg\");\n    let is_disabled = disabled == DisabledState::Disabled;\n\n    view! {\n        <div\n            data-rs-radio-group=\"\"\n            data-rs-uid=uid_rg\n            data-rs-interaction=\"selection\"\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            role=\"radiogroup\"\n            aria-disabled=if is_disabled { Some(\"true\") } else { None }\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn RadioGroupItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_selected = selected == SelectionState::Selected;\n    let is_disabled = disabled == DisabledState::Disabled;\n\n    view! {\n        <label\n            data-rs-radio=\"\"\n            data-rs-selection=if is_selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            class=class\n        >\n            <input\n                type=\"radio\"\n                data-rs-radio-input=\"\"\n                name=name\n                value=value\n                checked=is_selected\n                disabled=is_disabled\n                aria-checked=if is_selected { \"true\" } else { \"false\" }\n                aria-disabled=if is_disabled { Some(\"true\") } else { None }\n            />\n            <span data-rs-radio-indicator=\"\" />\n            {children()}\n        </label>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{RadioGroupPrimitive, RadioGroupItemPrimitive};\nuse canonrs_core::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn RadioGroup(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioGroupPrimitive disabled=disabled class=class>\n            {children()}\n        </RadioGroupPrimitive>\n    }\n}\n\n#[component]\npub fn RadioGroupItem(\n    children: Children,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <RadioGroupItemPrimitive\n            selected=selected\n            disabled=disabled\n            value=value\n            name=name\n            class=class\n        >\n            {children()}\n        </RadioGroupItemPrimitive>\n    }\n}\n\n",
    "boundary_src": "// Re-export from radio island — RadioGroup covers radio_group functionality\npub use crate::ui::radio::{RadioGroup, Radio, RadioGroupItem};\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_ui.rs\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const RADIOGROUP_API: ComponentApi = ComponentApi {\n    id: \"radio-group\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"\" },\n    ],\n};\n\npub const RADIOGROUPITEM_API: ComponentApi = ComponentApi {\n    id: \"radio-group-item\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"\" },\n        PropDef { name: \"selected\", kind: PropType::String, required: false, default: Some(\"unselected\"), description: \"\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::radio_group_boundary::{RadioGroup, RadioGroupItem};\nuse canonrs_core::meta::{SelectionState, DisabledState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn RadioGroupShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Selection state mapped directly to DOM and ARIA.\"\n            </p>\n            <RadioGroup>\n                <RadioGroupItem value=\"leptos\" name=\"framework\">\"Leptos\"</RadioGroupItem>\n                <RadioGroupItem value=\"dioxus\" name=\"framework\">\"Dioxus\"</RadioGroupItem>\n                <RadioGroupItem value=\"yew\" name=\"framework\">\"Yew\"</RadioGroupItem>\n            </RadioGroup>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Pre-selected\"</span>\n                <RadioGroup>\n                    <RadioGroupItem value=\"sm\" name=\"size\">\"Small\"</RadioGroupItem>\n                    <RadioGroupItem value=\"md\" name=\"size\" selected=SelectionState::Selected>\"Medium\"</RadioGroupItem>\n                    <RadioGroupItem value=\"lg\" name=\"size\">\"Large\"</RadioGroupItem>\n                </RadioGroup>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <RadioGroup disabled=DisabledState::Disabled>\n                    <RadioGroupItem value=\"a\" name=\"dis\">\"Option A\"</RadioGroupItem>\n                    <RadioGroupItem value=\"b\" name=\"dis\">\"Option B\"</RadioGroupItem>\n                </RadioGroup>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "resizable",
    "label": "Resizable",
    "category": "Layout",
    "description": "Resizable panel component",
    "keywords": "",
    "pain": "Resizable panels break layout constraints and overflow limits",
    "promise": "Panel sizes constrained and behavior encoded structurally",
    "why": "ResizablePrimitive defines orientation and size limits via attributes. Panels and handles follow strict composition. This guarantees controlled resizing behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"split\">\n    <div></div>\n    <div></div>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Resizable>\n    <ResizablePanel />\n    <ResizableHandle />\n  </Resizable>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "editors",
      "dashboards"
    ],
    "related": [
      "card",
      "scroll_area",
      "aspect_ratio",
      "page_header",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! Resizable Primitives\nuse leptos::prelude::*;\nuse crate::infra::uid::generate;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug, serde::Serialize, serde::Deserialize)]\npub enum ResizableOrientation { #[default] Horizontal, Vertical }\nimpl ResizableOrientation {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Horizontal => \"horizontal\", Self::Vertical => \"vertical\" }\n    }\n}\n\n#[component]\npub fn ResizablePrimitive(\n    children: Children,\n    #[prop(default = ResizableOrientation::Horizontal)] orientation: ResizableOrientation,\n    #[prop(default = 20u32)] min_size: u32,\n    #[prop(default = 80u32)] max_size: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid = generate(\"rs\");\n    view! {\n        <div\n            data-rs-resizable=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"gesture\"\n            data-rs-orientation=orientation.as_str()\n            data-rs-min-size=min_size.to_string()\n            data-rs-max-size=max_size.to_string()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ResizablePanelPrimitive(\n    children: Children,\n    #[prop(default = 50u32)] default_size: u32,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] id: Option<String>,\n) -> impl IntoView {\n    let uid = generate(\"rsp\");\n    view! {\n        <div\n            data-rs-resizable-panel=\"\"\n            data-rs-uid=uid\n            data-rs-default-size=default_size.to_string()\n            id=id\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ResizableHandlePrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] id: Option<String>,\n    #[prop(default = false)] disabled: bool,\n) -> impl IntoView {\n    let uid = generate(\"rsh\");\n    view! {\n        <div\n            data-rs-resizable-handle=\"\"\n            data-rs-uid=uid\n            data-rs-disabled=disabled.then_some(\"disabled\")\n            aria-disabled=if disabled { Some(\"true\") } else { None }\n            id=id\n            class=class\n        >\n            <span data-rs-resizable-handle-icon=\"\" aria-hidden=\"true\" />\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{ResizablePrimitive, ResizablePanelPrimitive, ResizableHandlePrimitive, ResizableOrientation};\n\n#[component]\npub fn Resizable(\n    children: Children,\n    #[prop(default = ResizableOrientation::Horizontal)] orientation: ResizableOrientation,\n    #[prop(default = 20u32)] min_size: u32,\n    #[prop(default = 80u32)] max_size: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ResizablePrimitive orientation=orientation min_size=min_size max_size=max_size class=class>{children()}</ResizablePrimitive> }\n}\n\n#[component]\npub fn ResizablePanel(\n    children: Children,\n    #[prop(default = 50u32)] default_size: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ResizablePanelPrimitive default_size=default_size class=class>{children()}</ResizablePanelPrimitive> }\n}\n\n#[component]\npub fn ResizableHandle(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ResizableHandlePrimitive class=class /> }\n}\n",
    "boundary_src": "//! Resizable Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::resizable_ui::{\n    Resizable as ResizableUi,\n    ResizablePanel as ResizablePanelUi,\n    ResizableHandle as ResizableHandleUi\n};\npub use canonrs_core::primitives::ResizableOrientation;\n\n#[component]\npub fn Resizable(\n    children: Children,\n    #[prop(default = ResizableOrientation::Horizontal)] orientation: ResizableOrientation,\n    #[prop(default = 20u32)] min_size: u32,\n    #[prop(default = 80u32)] max_size: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ResizableUi orientation=orientation min_size=min_size max_size=max_size class=class>\n            {children()}\n        </ResizableUi>\n    }\n}\n\n#[component]\npub fn ResizablePanel(\n    children: Children,\n    #[prop(default = 50u32)] default_size: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ResizablePanelUi default_size=default_size class=class>\n            {children()}\n        </ResizablePanelUi>\n    }\n}\n\n#[component]\npub fn ResizableHandle(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ResizableHandleUi class=class /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ResizableOrientation}; \n\npub const RESIZABLE_API: ComponentApi = ComponentApi {\n    id: \"resizable\",\n    description: \"Resizable panel component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"orientation\", kind: PropType::String, required: false, default: Some(\"horizontal\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"min_size\", kind: PropType::Number, required: false, default: Some(\"20u32\"), description: \"Prop value\" },\n        PropDef { name: \"max_size\", kind: PropType::Number, required: false, default: Some(\"80u32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const RESIZABLEPANEL_API: ComponentApi = ComponentApi {\n    id: \"resizable-panel\",\n    description: \"Resizable panel component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"default_size\", kind: PropType::Number, required: false, default: Some(\"50u32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const RESIZABLEHANDLE_API: ComponentApi = ComponentApi {\n    id: \"resizable-handle\",\n    description: \"Resizable panel component\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::resizable_boundary::{Resizable, ResizablePanel, ResizableHandle, ResizableOrientation};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ResizableShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Panel sizes constrained and behavior encoded structurally.\"\n            </p>\n            <div style=\"height:200px;width:100%;\">\n                <Resizable>\n                    <ResizablePanel default_size=50u32>\n                        <div style=\"padding:var(--space-md);height:100%;display:flex;align-items:center;justify-content:center;border-right:1px solid rgba(255,255,255,0.06);overflow:hidden;\">\n                            \"Left Panel\"\n                        </div>\n                    </ResizablePanel>\n                    <ResizableHandle />\n                    <ResizablePanel default_size=50u32>\n                        <div style=\"padding:var(--space-md);height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;\">\n                            \"Right Panel\"\n                        </div>\n                    </ResizablePanel>\n                </Resizable>\n            </div>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Vertical\"</span>\n                <div style=\"height:200px;width:100%;\">\n                    <Resizable orientation=ResizableOrientation::Vertical>\n                        <ResizablePanel default_size=50u32>\n                            <div style=\"padding:var(--space-md);width:100%;display:flex;align-items:center;justify-content:center;border-bottom:1px solid rgba(255,255,255,0.06);overflow:hidden;\">\n                                \"Top Panel\"\n                            </div>\n                        </ResizablePanel>\n                        <ResizableHandle />\n                        <ResizablePanel default_size=50u32>\n                            <div style=\"padding:var(--space-md);width:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;\">\n                                \"Bottom Panel\"\n                            </div>\n                        </ResizablePanel>\n                    </Resizable>\n                </div>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "scroll_area",
    "label": "Scroll Area",
    "category": "Layout",
    "description": "Scrollable area container",
    "keywords": "",
    "pain": "Custom scroll containers break keyboard navigation and accessibility",
    "promise": "Scroll behavior and accessibility enforced via structured container",
    "why": "ScrollAreaPrimitive defines viewport, scrollbars and orientation explicitly. ARIA roles and keyboard access are enforced. This guarantees accessible scrolling behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <div style=\"overflow:auto;height:200px\"></div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ScrollArea>\n    <div>\"Content\"</div>\n  </ScrollArea>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "long lists",
      "logs"
    ],
    "related": [
      "card",
      "resizable",
      "aspect_ratio",
      "page_header",
      "toolbar",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ScrollArea Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, Debug, Default, PartialEq)]\npub enum ScrollOrientation {\n    #[default]\n    Vertical,\n    Horizontal,\n    Both,\n}\n\nimpl ScrollOrientation {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Vertical   => \"vertical\",\n            Self::Horizontal => \"horizontal\",\n            Self::Both       => \"both\",\n        }\n    }\n}\n\n#[component]\npub fn ScrollAreaPrimitive(\n    children: Children,\n    #[prop(default = ScrollOrientation::Vertical)] orientation: ScrollOrientation,\n    #[prop(default = true)] auto_hide: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] style: String,\n    #[prop(into, optional)] viewport_id: Option<String>,\n) -> impl IntoView {\n    let uid_sa = crate::infra::uid::generate(\"sa\");\n    let show_v = matches!(orientation, ScrollOrientation::Vertical | ScrollOrientation::Both);\n    let show_h = matches!(orientation, ScrollOrientation::Horizontal | ScrollOrientation::Both);\n\n    view! {\n        <div\n            data-rs-scroll-area=\"\"\n            data-rs-uid=uid_sa\n            data-rs-interaction=\"gesture\"\n            data-rs-orientation=orientation.as_str()\n            data-rs-auto-hide={auto_hide.then_some(\"\")}\n            role=\"region\"\n            class=class\n            style=style\n        >\n            <div\n                data-rs-scroll-viewport=\"\"\n                id={viewport_id}\n                role=\"presentation\"\n                tabindex=\"0\"\n            >\n                {children()}\n            </div>\n\n            {show_v.then(|| view! {\n                <div data-rs-scrollbar=\"\" data-rs-orientation=\"vertical\" role=\"scrollbar\" aria-orientation=\"vertical\">\n                    <div data-rs-scroll-track=\"\">\n                        <div data-rs-scroll-thumb=\"\" data-rs-orientation=\"vertical\" />\n                    </div>\n                </div>\n            })}\n\n            {show_h.then(|| view! {\n                <div data-rs-scrollbar=\"\" data-rs-orientation=\"horizontal\" role=\"scrollbar\" aria-orientation=\"horizontal\">\n                    <div data-rs-scroll-track=\"\">\n                        <div data-rs-scroll-thumb=\"\" data-rs-orientation=\"horizontal\" />\n                    </div>\n                </div>\n            })}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{ScrollAreaPrimitive, ScrollOrientation};\n\n#[component]\npub fn ScrollArea(\n    children: Children,\n    #[prop(default = ScrollOrientation::Vertical)] orientation: ScrollOrientation,\n    #[prop(default = true)] auto_hide: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] style: String,\n    #[prop(into, optional)] viewport_id: Option<String>,\n) -> impl IntoView {\n    view! {\n        <ScrollAreaPrimitive\n            orientation=orientation\n            auto_hide=auto_hide\n            class=class\n            style=style\n            viewport_id=viewport_id.unwrap_or_default()\n        >\n            {children()}\n        </ScrollAreaPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! ScrollArea Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::scroll_area_ui::ScrollArea as ScrollAreaUi;\npub use canonrs_core::primitives::ScrollOrientation;\n\n#[component]\npub fn ScrollArea(\n    children: Children,\n    #[prop(default = ScrollOrientation::Vertical)] orientation: ScrollOrientation,\n    #[prop(default = true)] auto_hide: bool,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] style: String,\n    #[prop(into, default = String::new())] viewport_id: String,\n) -> impl IntoView {\n    view! {\n        <ScrollAreaUi style=style orientation=orientation auto_hide=auto_hide class=class viewport_id=viewport_id>\n            {children()}\n        </ScrollAreaUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ScrollOrientation}; \n\npub const SCROLLAREA_API: ComponentApi = ComponentApi {\n    id: \"scroll-area\",\n    description: \"Scrollable area container\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"orientation\", kind: PropType::Enum(&[\"vertical\", \"horizontal\", \"both\"]), required: false, default: Some(\"vertical\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"auto_hide\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"style\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"viewport_id\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::scroll_area_boundary::{ScrollArea, ScrollOrientation};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn ScrollAreaShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Custom scrollbar with auto-hide and orientation control.\"\n            </p>\n            <ScrollArea style=\"height:200px;\">\n                <div style=\"padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-xs);\">\n                    {(1..=20).map(|i| view! {\n                        <div style=\"padding:var(--space-xs) 0;border-bottom:1px solid rgba(255,255,255,0.05);\">\n                            {format!(\"Item {:02}\", i)}\n                        </div>\n                    }).collect::<Vec<_>>()}\n                </div>\n            </ScrollArea>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Horizontal\"</span>\n                <div style=\"width:100%;overflow:hidden;\">\n                    <ScrollArea orientation=ScrollOrientation::Horizontal>\n                        <div style=\"display:flex;gap:var(--space-md);padding:var(--space-sm);width:200px;\">\n                            {(1..=12).map(|i| view! {\n                                <div style=\"width:120px;flex-shrink:0;padding:var(--space-sm);border:1px solid rgba(255,255,255,0.08);border-radius:var(--radius-md);text-align:center;\">\n                                    {format!(\"Card {:02}\", i)}\n                                </div>\n                            }).collect::<Vec<_>>()}\n                        </div>\n                    </ScrollArea>\n                </div>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container",
      "stack"
    ]
  },
  {
    "id": "section_ui",
    "label": "Section UI",
    "category": "Display",
    "description": "Section header typography components",
    "keywords": "",
    "pain": "",
    "promise": "",
    "why": "",
    "before": "",
    "after": "",
    "rules": [],
    "use_cases": [],
    "related": [],
    "badges": [],
    "pillar": "",
    "primitive_src": "",
    "ui_src": "",
    "boundary_src": "",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const SECTIONHEADER_API: ComponentApi = ComponentApi {\n    id: \"section-header\",\n    description: \"Section header typography components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SECTIONTITLE_API: ComponentApi = ComponentApi {\n    id: \"section-title\",\n    description: \"Section header typography components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SECTIONSUBTITLE_API: ComponentApi = ComponentApi {\n    id: \"section-subtitle\",\n    description: \"Section header typography components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SECTIONBADGE_API: ComponentApi = ComponentApi {\n    id: \"section-badge\",\n    description: \"Section header typography components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SECTIONACTIONS_API: ComponentApi = ComponentApi {\n    id: \"section-actions\",\n    description: \"Section header typography components\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::section_boundary::{\n    SectionHeader, SectionTitle, SectionSubtitle,\n    SectionBadge, SectionActions,\n};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn SectionShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Semantic layout components for composing section headers.\"\n            </p>\n            <SectionHeader>\n                <SectionTitle>\"Section Title\"</SectionTitle>\n                <SectionSubtitle>\"Section subtitle description.\"</SectionSubtitle>\n            </SectionHeader>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Header with badge\"</span>\n                <SectionHeader>\n                    <SectionTitle>\"Users\"</SectionTitle>\n                    <SectionBadge>\"New\"</SectionBadge>\n                </SectionHeader>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Header with actions\"</span>\n                <SectionHeader>\n                    <SectionTitle>\"Reports\"</SectionTitle>\n                    <SectionSubtitle>\"Monthly overview.\"</SectionSubtitle>\n                    <SectionActions>\n                        <span>\"Export\"</span>\n                    </SectionActions>\n                </SectionHeader>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Title only\"</span>\n                <SectionTitle>\"Standalone Title\"</SectionTitle>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container"
    ]
  },
  {
    "id": "select",
    "label": "Select",
    "category": "Form",
    "description": "Dropdown select input",
    "keywords": "",
    "pain": "Select components require manual state sync between trigger and options",
    "promise": "Selection, visibility and interaction fully governed by structure",
    "why": "SelectPrimitive encodes open state, selection and disabled behavior via data attributes. Trigger and content are synchronized without id wiring. This guarantees consistent dropdown behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <select>\n    <option>\"A\"</option>\n  </select>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Select>\n    <SelectTrigger>\n      <SelectValue placeholder=\"Select...\" />\n    </SelectTrigger>\n    <SelectContent>\n      <SelectItem value=\"a\">\"A\"</SelectItem>\n    </SelectContent>\n  </Select>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "forms",
      "filters"
    ],
    "related": [
      "combobox",
      "radio",
      "radio_group",
      "color_picker",
      "slider"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Select Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, VisibilityState, DisabledState};\n\n#[component]\npub fn SelectPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] name: String,\n) -> impl IntoView {\n    let uid_sel = crate::infra::uid::generate(\"sel\");\n    let is_disabled = disabled == DisabledState::Disabled;\n    let is_open = state == VisibilityState::Open;\n\n    view! {\n        <div\n            data-rs-select=\"\"\n            data-rs-uid=uid_sel\n            data-rs-interaction=\"selection\"\n            data-rs-role=\"root\"\n            data-rs-state=if is_open { \"open\" } else { \"closed\" }\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            data-rs-name=name\n            aria-disabled=if is_disabled { \"true\" } else { \"false\" }\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SelectTriggerPrimitive(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_disabled = disabled == DisabledState::Disabled;\n    view! {\n        <button\n            type=\"button\"\n            data-rs-select-trigger=\"\"\n            aria-haspopup=\"listbox\"\n            aria-expanded=\"false\"\n            aria-disabled=if is_disabled { \"true\" } else { \"false\" }\n            class=class\n        >\n            {children()}\n            <svg data-rs-select-chevron=\"\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"/></svg>\n        </button>\n    }\n}\n\n#[component]\npub fn SelectValuePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span\n            data-rs-select-value=\"\"\n            data-rs-placeholder=placeholder\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn SelectContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-select-content=\"\"\n            role=\"listbox\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SelectItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_selected = selected == SelectionState::Selected;\n    let is_disabled = disabled == DisabledState::Disabled;\n\n    view! {\n        <div\n            data-rs-select-item=\"\"\n            data-rs-selection=if is_selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            data-rs-value=value\n            role=\"option\"\n            tabindex=\"-1\"\n            aria-selected=if is_selected { \"true\" } else { \"false\" }\n            aria-disabled=if is_disabled { \"true\" } else { \"false\" }\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SelectSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-select-separator=\"\"\n            role=\"separator\"\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::meta::{SelectionState, DisabledState, VisibilityState};\nuse canonrs_core::primitives::{\n    SelectPrimitive, SelectTriggerPrimitive, SelectValuePrimitive,\n    SelectContentPrimitive, SelectItemPrimitive, SelectSeparatorPrimitive,\n};\n\n#[component]\npub fn Select(\n    children: Children,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SelectPrimitive state=VisibilityState::Closed disabled=disabled class=class node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </SelectPrimitive>\n    }\n}\n\n#[component]\npub fn SelectTrigger(\n    children: Children,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SelectTriggerPrimitive disabled=disabled class=class>\n            {children()}\n        </SelectTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn SelectValue(\n    children: Children,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SelectValuePrimitive placeholder=placeholder class=class>\n            {children()}\n        </SelectValuePrimitive>\n    }\n}\n\n#[component]\npub fn SelectContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SelectContentPrimitive class=class>\n            {children()}\n        </SelectContentPrimitive>\n    }\n}\n\n#[component]\npub fn SelectItem(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SelectItemPrimitive selected=selected disabled=disabled value=value class=class>\n            {children()}\n        </SelectItemPrimitive>\n    }\n}\n\n#[component]\npub fn SelectSeparator(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SelectSeparatorPrimitive class=class /> }\n}\n\n",
    "boundary_src": "//! Select Island — Canon Rule passthrough\nuse leptos::prelude::*;\n\npub use canonrs_core::meta::{DisabledState, SelectionState};\npub use super::select_ui::{\n    SelectTrigger, SelectValue, SelectContent, SelectItem, SelectSeparator,\n};\n\n#[component]\npub fn Select(\n    children: Children,\n    #[prop(optional)] node_ref: Option<leptos::prelude::NodeRef<leptos::html::Div>>,\n    #[prop(default = canonrs_core::meta::DisabledState::Enabled)] disabled: canonrs_core::meta::DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <super::select_ui::Select class=class disabled=disabled node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </super::select_ui::Select>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const SELECT_API: ComponentApi = ComponentApi {\n    id: \"select\",\n    description: \"Dropdown select input\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"node_ref\", kind: PropType::String, required: false, default: None, description: \"DOM node reference\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::select_boundary::{Select, SelectTrigger, SelectValue, SelectContent, SelectItem};\nuse canonrs_core::meta::{DisabledState, SelectionState};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::container::{ContainerPrimitive as Container, ContainerSize};\n\n#[component]\npub fn SelectShowcasePreview() -> impl IntoView {\n    view! {\n        <Container size=ContainerSize::Sm>\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Selection, visibility and interaction fully governed by structure.\"\n            </p>\n            <Select>\n                <SelectTrigger>\n                    <SelectValue placeholder=\"Choose a framework...\">{\"\"}</SelectValue>\n                </SelectTrigger>\n                <SelectContent>\n                    <SelectItem value=\"leptos\">\"Leptos\"</SelectItem>\n                    <SelectItem value=\"dioxus\">\"Dioxus\"</SelectItem>\n                    <SelectItem value=\"yew\" disabled=DisabledState::Disabled>\"Yew (disabled)\"</SelectItem>\n                </SelectContent>\n            </Select>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Pre-selected\"</span>\n                <Select>\n                    <SelectTrigger>\n                        <SelectValue placeholder=\"Select size...\">\"Medium\"</SelectValue>\n                    </SelectTrigger>\n                    <SelectContent>\n                        <SelectItem value=\"sm\">\"Small\"</SelectItem>\n                        <SelectItem value=\"md\" selected=SelectionState::Selected>\"Medium\"</SelectItem>\n                        <SelectItem value=\"lg\">\"Large\"</SelectItem>\n                    </SelectContent>\n                </Select>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"With disabled options\"</span>\n                <Select>\n                    <SelectTrigger>\n                        <SelectValue placeholder=\"Select plan...\">{\"\"}</SelectValue>\n                    </SelectTrigger>\n                    <SelectContent>\n                        <SelectItem value=\"free\">\"Free\"</SelectItem>\n                        <SelectItem value=\"pro\">\"Pro\"</SelectItem>\n                        <SelectItem value=\"enterprise\" disabled=DisabledState::Disabled>\"Enterprise (disabled)\"</SelectItem>\n                        <SelectItem value=\"custom\" disabled=DisabledState::Disabled>\"Custom (disabled)\"</SelectItem>\n                    </SelectContent>\n                </Select>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Many options — keyboard nav\"</span>\n                <Select>\n                    <SelectTrigger>\n                        <SelectValue placeholder=\"Select country...\">{\"\"}</SelectValue>\n                    </SelectTrigger>\n                    <SelectContent>\n                        <SelectItem value=\"br\">\"Brazil\"</SelectItem>\n                        <SelectItem value=\"us\">\"United States\"</SelectItem>\n                        <SelectItem value=\"de\">\"Germany\"</SelectItem>\n                        <SelectItem value=\"jp\">\"Japan\"</SelectItem>\n                        <SelectItem value=\"fr\">\"France\"</SelectItem>\n                        <SelectItem value=\"uk\">\"United Kingdom\"</SelectItem>\n                    </SelectContent>\n                </Select>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <Select disabled=DisabledState::Disabled>\n                    <SelectTrigger disabled=DisabledState::Disabled>\n                        <SelectValue placeholder=\"Disabled...\">{\"\"}</SelectValue>\n                    </SelectTrigger>\n                    <SelectContent>\n                        <SelectItem value=\"a\">\"Option A\"</SelectItem>\n                    </SelectContent>\n                </Select>\n            </Stack>\n        </Stack>\n        </Container>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "separator",
    "label": "Separator",
    "category": "Layout",
    "description": "Visual divider line",
    "keywords": "",
    "pain": "Dividers lack semantic meaning and accessibility roles",
    "promise": "Separator semantics enforced via orientation and role contract",
    "why": "SeparatorPrimitive encodes orientation and decorative behavior. ARIA roles are derived automatically. This guarantees semantic and accessible separators.\n",
    "before": "// ❌ Typical\nview! {\n  <hr />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Separator />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "layout separation",
      "menus"
    ],
    "related": [
      "card",
      "resizable",
      "scroll_area",
      "aspect_ratio",
      "page_header",
      "toolbar"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Separator Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum SeparatorOrientation {\n    #[default]\n    Horizontal,\n    Vertical,\n}\nimpl SeparatorOrientation {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Horizontal => \"horizontal\",\n            Self::Vertical   => \"vertical\",\n        }\n    }\n}\n\n#[component]\npub fn SeparatorPrimitive(\n    #[prop(default = SeparatorOrientation::Horizontal)] orientation: SeparatorOrientation,\n    #[prop(default = true)] decorative: bool,\n    #[prop(optional, into)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sep = crate::infra::uid::generate(\"sep\");\n    let role = if decorative { \"presentation\" } else { \"separator\" };\n    let aria_orientation = if !decorative { Some(orientation.as_str()) } else { None };\n    let aria_label_val = if !decorative { aria_label } else { None };\n    view! {\n        <div\n            data-rs-separator=\"\"\n            data-rs-uid=uid_sep\n            data-rs-orientation=orientation.as_str()\n            role=role\n            aria-orientation=aria_orientation\n            aria-label=aria_label_val\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::SeparatorPrimitive;\nuse canonrs_core::separator::SeparatorOrientation;\n\n#[component]\npub fn Separator(#[prop(default = SeparatorOrientation::Horizontal)] orientation: SeparatorOrientation, #[prop(default = true)] decorative: bool, #[prop(into, default = String::new())] aria_label: String, #[prop(default = String::new())] class: String, #[prop(into, optional)] id: Option<String>) -> impl IntoView {\n    view! { <SeparatorPrimitive orientation=orientation decorative=decorative aria_label=aria_label class=class /> }\n}\n",
    "boundary_src": "//! Separator Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::separator_ui::Separator as SeparatorUi;\nuse canonrs_core::separator::SeparatorOrientation;\n\n#[component]\npub fn Separator(\n    #[prop(default = SeparatorOrientation::Horizontal)] orientation: SeparatorOrientation,\n    #[prop(default = true)] decorative:                     bool,\n    #[prop(into, default = String::new())] aria_label:      String,\n    #[prop(into, default = String::new())] class:           String,\n    #[prop(optional)] id:                                  Option<String>,\n) -> impl IntoView {\n    view! {\n        <SeparatorUi\n            orientation=orientation\n            decorative=decorative\n            aria_label=aria_label\n            class=class\n            id=id.unwrap_or_default()\n        />\n};\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const SEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"separator\",\n    description: \"Visual divider line\",\n    props: &[\n        PropDef { name: \"orientation\", kind: PropType::Enum(&[\"horizontal\", \"vertical\"]), required: false, default: Some(\"horizontal\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"decorative\", kind: PropType::Bool, required: false, default: Some(\"true\"), description: \"Prop value\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"id\", kind: PropType::String, required: false, default: None, description: \"Element id attribute\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse canonrs_core::separator::SeparatorOrientation;\nuse super::separator_boundary::Separator;\nuse canonrs_core::Orientation;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\n\n#[component]\npub fn SeparatorShowcasePreview() -> impl IntoView {\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Lg>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Separator semantics enforced via orientation and role contract.\"\n            </p>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Md>\n                <span>\"Above\"</span>\n                <Separator />\n                <span>\"Below\"</span>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Vertical\"</span>\n                <Stack direction=StackDirection::Horizontal gap=StackGap::Md>\n                    <span>\"Left\"</span>\n                    <Separator orientation=SeparatorOrientation::Vertical />\n                    <span>\"Center\"</span>\n                    <Separator orientation=SeparatorOrientation::Vertical />\n                    <span>\"Right\"</span>\n                </Stack>\n            </Stack>\n            <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                <span data-rs-showcase-preview-label=\"\">\"Semantic\"</span>\n                <Stack direction=StackDirection::Vertical gap=StackGap::Md>\n                    <span>\"Section A\"</span>\n                    <Separator decorative=false aria_label=\"Between sections\" />\n                    <span>\"Section B\"</span>\n                </Stack>\n            </Stack>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "sheet",
    "label": "Sheet",
    "category": "Overlay",
    "description": "Sheet panel overlay",
    "keywords": "",
    "pain": "Side panels desync visibility, overlay and focus behavior",
    "promise": "Sheet visibility and overlay fully governed via shared state",
    "why": "SheetPrimitive maps VisibilityState to both panel and overlay. Side positioning is encoded structurally. This guarantees consistent slide-in behavior and accessibility.\n",
    "before": "// ❌ Typical\nview! {\n  {if open { view! { <div class=\"drawer\">\"Content\"</div> } }}\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Sheet>\n    <SheetContent aria_labelledby=\"title\">\"Content\"</SheetContent>\n  </Sheet>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "mobile navigation",
      "side panels"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "modal",
      "confirm_dialog",
      "tooltip",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Sheet Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum SheetSide {\n    #[default]\n    Right,\n    Left,\n    Top,\n    Bottom,\n}\nimpl SheetSide {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Right  => \"right\",\n            Self::Left   => \"left\",\n            Self::Top    => \"top\",\n            Self::Bottom => \"bottom\",\n        }\n    }\n}\n\n\n#[component]\npub fn SheetPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = SheetSide::Right)] side: SheetSide,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sh = crate::infra::uid::generate(\"sh\");\n    view! {\n        <div\n            data-rs-sheet=\"\"\n            data-rs-interaction=\"overlay\"\n            data-rs-uid=uid_sh\n            data-rs-state=state.as_str()\n            data-rs-side=side.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SheetTriggerPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(optional, into)] aria_controls: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-sheet-trigger=\"\"\n            data-rs-button=\"\"\n            data-rs-variant=\"primary\"\n            data-rs-state=state.as_str()\n            aria-haspopup=\"dialog\"\n            aria-expanded=state.aria_expanded()\n            aria-controls=aria_controls\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn SheetContentPrimitive(\n    children: Children,\n    #[prop(optional, into)] aria_labelledby: Option<String>,\n    #[prop(optional, into)] aria_describedby: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-sheet-content=\"\"\n            role=\"dialog\"\n            aria-modal=\"true\"\n            aria-labelledby=aria_labelledby\n            aria-describedby=aria_describedby\n            tabindex=\"-1\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SheetOverlayPrimitive(\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-sheet-overlay=\"\"\n            data-rs-state=state.as_str()\n            class=class\n        />\n    }\n}\n\n#[component]\npub fn SheetPortalPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <div data-rs-sheet-portal=\"\" class=class>{children()}</div> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{SheetPrimitive, SheetTriggerPrimitive, SheetOverlayPrimitive, SheetContentPrimitive, SheetSide};\nuse canonrs_core::primitives::SheetPortalPrimitive;\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Sheet(\n    children: Children,\n    #[prop(default = SheetSide::Right)] side: SheetSide,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SheetPrimitive side=side state=state class=class>\n            {children()}\n        </SheetPrimitive>\n    }\n}\n\n#[component]\npub fn SheetOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SheetOverlayPrimitive class=class /> }\n}\n\n#[component]\npub fn SheetContent(\n    children: Children,\n    #[prop(into)] aria_labelledby: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] aria_describedby: Option<String>,\n) -> impl IntoView {\n    view! {\n        <SheetContentPrimitive\n            class=class\n            aria_labelledby=aria_labelledby\n            aria_describedby=aria_describedby.unwrap_or_default()\n        >\n            {children()}\n        </SheetContentPrimitive>\n    }\n}\n\n\n#[component]\npub fn SheetTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SheetTriggerPrimitive class=class>{children()}</SheetTriggerPrimitive> }\n}\n\n#[component]\npub fn SheetPortal(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SheetPortalPrimitive class=class>{children()}</SheetPortalPrimitive> }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Sheet Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v3.0.0: interaction delegated to canonrs-interactions-overlay\n\nuse leptos::prelude::*;\nuse super::sheet_ui::{\n    Sheet as SheetUi,\n    SheetTrigger,\n    SheetOverlay as SheetOverlayUi,\n    SheetContent as SheetContentUi,\n    SheetPortal\n};\npub use canonrs_core::primitives::SheetSide;\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn Sheet(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::from(\"Open\"))] trigger_label: String,\n    #[prop(into, default = String::from(\"Close\"))] close_label: String,\n    #[prop(into, optional)] title: Option<String>,\n    #[prop(into, optional)] description: Option<String>,\n    #[prop(default = SheetSide::Right)] side: SheetSide,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SheetUi side=side state=VisibilityState::Closed class=class>\n            {if !trigger_label.is_empty() { Some(view! { <SheetTrigger>{trigger_label}</SheetTrigger> }) } else { None }}\n            <SheetPortal>\n            <SheetOverlayUi />\n            <SheetContentUi aria_labelledby=\"sheet-title\">\n                <h2 data-rs-sheet-title=\"\">{title.unwrap_or_default()}</h2>\n                <p data-rs-sheet-description=\"\">{description.unwrap_or_default()}</p>\n                {children.map(|c| c())}\n                <button type=\"button\" data-rs-sheet-close=\"\">\n                    {close_label}\n                </button>\n            </SheetContentUi>\n            </SheetPortal>\n        </SheetUi>\n    }\n}\n\n#[component]\npub fn SheetOverlay(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SheetOverlayUi class=class /> }\n}\n\n#[component]\npub fn SheetContent(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into)] aria_labelledby: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] aria_describedby: String,\n) -> impl IntoView {\n    view! {\n        <SheetContentUi\n            aria_labelledby=aria_labelledby\n            aria_describedby=aria_describedby\n            class=class\n        >\n            {children.map(|c| c())}\n        </SheetContentUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{SheetSide}; \n\npub const SHEET_API: ComponentApi = ComponentApi {\n    id: \"sheet\",\n    description: \"Sheet panel overlay\",\n    props: &[\n        PropDef { name: \"trigger_label\", kind: PropType::String, required: false, default: Some(\"Open\"), description: \"Prop value\" },\n        PropDef { name: \"close_label\", kind: PropType::String, required: false, default: Some(\"Close\"), description: \"Prop value\" },\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"side\", kind: PropType::Enum(&[\"right\", \"left\", \"top\", \"bottom\"]), required: false, default: Some(\"right\"), description: \"Tooltip or popover side\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SHEETOVERLAY_API: ComponentApi = ComponentApi {\n    id: \"sheet-overlay\",\n    description: \"Sheet panel overlay\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SHEETCONTENT_API: ComponentApi = ComponentApi {\n    id: \"sheet-content\",\n    description: \"Sheet panel overlay\",\n    props: &[\n        PropDef { name: \"aria_labelledby\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"aria_describedby\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::sheet_boundary::Sheet;\n\n#[component]\npub fn SheetShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Sheet\n                    trigger_label=\"Open Sheet\"\n                    title=\"Sheet Title\"\n                    description=\"Sheet slides in from the right. Visibility fully governed via shared state.\"\n                    close_label=\"Close\"\n                />\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Sheet visibility and overlay fully governed via shared state.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Settings panel\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Sheet\n                        trigger_label=\"Open settings\"\n                        title=\"Settings\"\n                        description=\"Manage your account settings and preferences.\"\n                        close_label=\"Close\"\n                    />\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "sidebar",
    "label": "Sidebar",
    "category": "Navigation",
    "description": "Sidebar navigation component",
    "keywords": "",
    "pain": "Sidebars lose active state, disabled links and structural consistency",
    "promise": "Navigation state and structure enforced at component level",
    "why": "SidebarPrimitive encodes visibility, variant and navigation semantics. Menu items derive active and disabled states automatically. This guarantees consistent navigation behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <aside>\n    <a class=\"active\">\"Home\"</a>\n  </aside>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Sidebar>\n    <SidebarMenu>\n      <SidebarMenuItem active=ActivityState::Active href=\"/\">\"Home\"</SidebarMenuItem>\n    </SidebarMenu>\n  </Sidebar>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "app navigation",
      "admin panels"
    ],
    "related": [
      "navigation_menu",
      "nav_item",
      "breadcrumb",
      "pagination",
      "link_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "navigation",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Sidebar Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{VisibilityState, ActivityState, DisabledState};\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum SidebarVariant {\n    #[default]\n    Default,\n    Rail,\n}\nimpl SidebarVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Rail => \"rail\",\n        }\n    }\n}\n\n#[component]\npub fn SidebarPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n    #[prop(default = SidebarVariant::Default)] variant: SidebarVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sb = crate::infra::uid::generate(\"sb\");\n    let state_str = match state {\n        VisibilityState::Open => \"expanded\",\n        _ => \"collapsed\",\n    };\n    view! {\n        <aside\n            data-rs-sidebar=\"\"\n            data-rs-uid=uid_sb\n            data-rs-interaction=\"nav\"\n            data-rs-state=state_str\n            data-rs-variant=variant.as_str()\n            aria-hidden=state.aria_hidden()\n            role=\"complementary\"\n            class=class\n        >\n            {children()}\n        </aside>\n    }\n}\n\n#[component]\npub fn SidebarHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-header=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-content=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-footer=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarMenuPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <nav data-rs-sidebar-menu=\"\" role=\"navigation\" class=class>\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn SidebarMenuItemPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_active = active == ActivityState::Active;\n    view! {\n        <a\n            data-rs-sidebar-menu-item=\"\"\n            data-rs-activity=active.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            href=if disabled.disabled() { \"#\".to_string() } else { href }\n            aria-current=if is_active { Some(\"page\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled.disabled() { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn SidebarMenuGroupPrimitive(\n    children: Children,\n    #[prop(into, optional)] label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-menu-group=\"\" role=\"group\" aria-label=label class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-separator=\"\" role=\"separator\" aria-orientation=\"horizontal\" class=class />\n    }\n}\n\n#[component]\npub fn SidebarGroupLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-group-label=\"\" role=\"presentation\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] root: bool,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n) -> impl IntoView {\n    let state_str = match state {\n        VisibilityState::Open => \"expanded\",\n        _ => \"collapsed\",\n    };\n    view! {\n        <div\n            data-rs-sidebar-group=\"\"\n            data-rs-sidebar-group-root=if root { Some(\"true\") } else { None }\n            data-rs-state=state_str\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarGroupTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button type=\"button\" data-rs-sidebar-group-toggle=\"\" class=class>\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn SidebarGroupContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-group-content=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SidebarTriggerPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] style: String,\n) -> impl IntoView {\n    view! {\n        <button type=\"button\" data-rs-sidebar-toggle=\"\" aria-expanded=\"false\" class=class style=style>\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn SidebarLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-sidebar-label=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn SidebarIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-sidebar-icon=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn SidebarUserPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-sidebar-user=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    SidebarPrimitive, SidebarVariant, SidebarHeaderPrimitive, SidebarContentPrimitive,\n    SidebarFooterPrimitive, SidebarMenuPrimitive, SidebarMenuItemPrimitive,\n    SidebarMenuGroupPrimitive, SidebarSeparatorPrimitive, SidebarGroupLabelPrimitive,\n    SidebarGroupPrimitive, SidebarGroupTriggerPrimitive, SidebarGroupContentPrimitive,\n    SidebarLabelPrimitive, SidebarIconPrimitive, SidebarUserPrimitive,\n};\nuse canonrs_core::meta::{VisibilityState, ActivityState, DisabledState};\n\n#[component]\npub fn Sidebar(\n    children: Children,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n    #[prop(default = SidebarVariant::Default)] variant: SidebarVariant,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarPrimitive state=state variant=variant class=class>\n            {children()}\n        </SidebarPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarHeader(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarHeaderPrimitive class=class>\n            {children()}\n        </SidebarHeaderPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarContent(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarContentPrimitive class=class>\n            {children()}\n        </SidebarContentPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarFooter(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarFooterPrimitive class=class>\n            {children()}\n        </SidebarFooterPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarMenu(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarMenuPrimitive class=class>\n            {children()}\n        </SidebarMenuPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarMenuItem(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n    #[prop(default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    view! {\n        <SidebarMenuItemPrimitive class=class href=href active=active disabled=disabled>\n            {children()}\n        </SidebarMenuItemPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarMenuGroup(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n    #[prop(into, optional)] label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <SidebarMenuGroupPrimitive class=class label=label.unwrap_or_default()>\n            {children()}\n        </SidebarMenuGroupPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarSeparator(\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarSeparatorPrimitive class=class /> }\n}\n\n#[component]\npub fn SidebarGroupLabel(\n    children: Children,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarGroupLabelPrimitive class=class>\n            {children()}\n        </SidebarGroupLabelPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] root: bool,\n    #[prop(default = false)] hidden: bool,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n) -> impl IntoView {\n    view! {\n        <SidebarGroupPrimitive class=class root=root state=state attr:hidden=hidden.then(|| \"\")>\n            {children()}\n        </SidebarGroupPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarGroupTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarGroupTriggerPrimitive class=class>\n            {children()}\n        </SidebarGroupTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarGroupContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarGroupContentPrimitive class=class>\n            {children()}\n        </SidebarGroupContentPrimitive>\n    }\n}\n\n#[component]\npub fn SidebarLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarLabelPrimitive class=class>{children()}</SidebarLabelPrimitive> }\n}\n\n#[component]\npub fn SidebarIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarIconPrimitive class=class>{children()}</SidebarIconPrimitive> }\n}\n\n#[component]\npub fn SidebarUser(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarUserPrimitive class=class>{children()}</SidebarUserPrimitive> }\n}\n\n",
    "boundary_src": "//! Sidebar Boundary — componentes passthrough + unified boundary\n\nuse leptos::prelude::*;\nuse super::sidebar_ui::{\n    SidebarGroup as SidebarGroupUi,\n    SidebarGroupTrigger as SidebarGroupTriggerUi,\n    SidebarGroupContent as SidebarGroupContentUi,\n    Sidebar as SidebarUi,\n    SidebarHeader as SidebarHeaderUi,\n    SidebarContent as SidebarContentUi,\n    SidebarFooter as SidebarFooterUi,\n    SidebarMenu as SidebarMenuUi,\n    SidebarMenuItem as SidebarMenuItemUi,\n    SidebarMenuGroup as SidebarMenuGroupUi,\n    SidebarSeparator as SidebarSeparatorUi,\n    SidebarGroupLabel as SidebarGroupLabelUi,\n    SidebarLabel as SidebarLabelUi,\n    SidebarIcon as SidebarIconUi,\n    SidebarUser as SidebarUserUi,\n};\npub use canonrs_core::primitives::SidebarTriggerPrimitive as SidebarTrigger;\npub use canonrs_core::primitives::SidebarVariant;\npub use canonrs_core::primitives::BadgeVariant;\npub use canonrs_core::meta::{VisibilityState, ActivityState, DisabledState};\nuse crate::ui::badge::badge_boundary::Badge;\nuse crate::ui::tooltip::tooltip_boundary::{Tooltip, TooltipTrigger, TooltipContent};\nuse crate::ui::command::command_boundary::{Command, CommandItem};\n\npub use super::sidebar_data::{NavBadge, NavItem, NavGroup, SidebarConfig};\n\n// ─── Boundary components ─────────────────────────────────────────────────────\n\n#[component]\npub fn Sidebar(\n    children: Children,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n    #[prop(default = SidebarVariant::Default)] variant: SidebarVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SidebarUi state=state variant=variant class=class>{children()}</SidebarUi>\n    }\n}\n\n#[component]\npub fn SidebarHeader(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarHeaderUi class=class>{children()}</SidebarHeaderUi> }\n}\n\n#[component]\npub fn SidebarContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarContentUi class=class>{children()}</SidebarContentUi> }\n}\n\n#[component]\npub fn SidebarFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarFooterUi class=class>{children()}</SidebarFooterUi> }\n}\n\n#[component]\npub fn SidebarMenu(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarMenuUi class=class>{children()}</SidebarMenuUi> }\n}\n\n#[component]\npub fn SidebarMenuItem(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n) -> impl IntoView {\n    view! { <SidebarMenuItemUi class=class href=href active=active disabled=disabled>{children()}</SidebarMenuItemUi> }\n}\n\n#[component]\npub fn SidebarMenuGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional, into)] label: Option<String>,\n) -> impl IntoView {\n    view! { <SidebarMenuGroupUi class=class label=label.unwrap_or_default()>{children()}</SidebarMenuGroupUi> }\n}\n\n#[component]\npub fn SidebarSeparator(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] hidden: bool,\n) -> impl IntoView {\n    view! { <SidebarSeparatorUi class=class attr:hidden=hidden.then(|| \"\") /> }\n}\n\n#[component]\npub fn SidebarGroupLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarGroupLabelUi class=class>{children()}</SidebarGroupLabelUi> }\n}\n\n#[component]\npub fn SidebarGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] root: bool,\n    #[prop(default = false)] hidden: bool,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n) -> impl IntoView {\n    view! { <SidebarGroupUi class=class root=root state=state hidden=hidden>{children()}</SidebarGroupUi> }\n}\n\n#[component]\npub fn SidebarGroupTrigger(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarGroupTriggerUi class=class>{children()}</SidebarGroupTriggerUi> }\n}\n\n#[component]\npub fn SidebarGroupContent(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarGroupContentUi class=class>{children()}</SidebarGroupContentUi> }\n}\n\n#[component]\npub fn SidebarLabel(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarLabelUi class=class>{children()}</SidebarLabelUi> }\n}\n\n#[component]\npub fn SidebarIcon(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarIconUi class=class>{children()}</SidebarIconUi> }\n}\n\n#[component]\npub fn SidebarUser(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <SidebarUserUi class=class>{children()}</SidebarUserUi> }\n}\n\n\n// ─── Unified Boundary ────────────────────────────────────────────────────────\n\n#[component]\npub fn SidebarUnifiedBoundary(config: SidebarConfig) -> impl IntoView {\n    let tooltips  = config.tooltips;\n    let pinnable  = config.pinnable;\n    let user_name  = config.user_name;\n    let user_email = config.user_email;\n    let groups     = config.groups.clone();\n    let search     = config.search;\n    let state      = config.state;\n    let variant    = config.variant;\n\n    let search_items: Vec<(String, String, String)> = groups.iter()\n        .flat_map(|g| g.items.iter())\n        .map(|item| (item.icon.to_string(), item.label.to_string(), item.href.to_string()))\n        .collect();\n\n    let has_separator = groups.len() > 1;\n\n    view! {\n        <Sidebar state=state variant=variant>\n            <SidebarHeader>\n                <div style=\"display:flex; align-items:center; justify-content:space-between; width:100%;\">\n                    <SidebarUser>\n                        <SidebarLabel>{user_name}</SidebarLabel>\n                        <SidebarLabel>{user_email}</SidebarLabel>\n                    </SidebarUser>\n                    <div style=\"display:flex; align-items:center; gap:var(--space-xs);\">\n                        <SidebarTrigger>\"⇔\"</SidebarTrigger>\n                        <button\n                            type=\"button\"\n                            data-rs-sidebar-pin-toggle=\"\"\n                            hidden=(!pinnable)\n                            style=\"padding: var(--space-xs); background: transparent; border: none; cursor: pointer; font-size: var(--font-size-md);\"\n                        >\n                            \"📍\"\n                        </button>\n                    </div>\n                </div>\n            </SidebarHeader>\n\n            <SidebarContent>\n                <div data-rs-sidebar-search=\"\" hidden=(!search)>\n                    <Command placeholder=\"Search...\".to_string()>\n                        {search_items.into_iter().map(|(icon, label, href)| {\n                            let label2 = label.clone();\n                            view! {\n                                <CommandItem value=href>\n                                    <SidebarIcon>{icon}</SidebarIcon>\n                                    <SidebarLabel>{label2}</SidebarLabel>\n                                </CommandItem>\n                            }\n                        }).collect::<Vec<_>>()}\n                    </Command>\n                </div>\n                <SidebarMenu>\n                    {groups.into_iter().enumerate().map(|(i, group)| {\n                        let items      = group.items.clone();\n                        let items2     = items.clone();\n                        let collapsible = group.collapsible;\n                        let label      = group.label.to_string();\n                        let label2     = label.clone();\n                        let icon       = group.icon.to_string();\n                        view! {\n                            <div>\n                                <SidebarGroup root=true hidden=(!collapsible)>\n                                    <SidebarGroupTrigger>\n                                        <SidebarIcon>{icon.clone()}</SidebarIcon>\n                                        <SidebarLabel>{label}</SidebarLabel>\n                                        <span data-rs-sidebar-group-chevron=\"\">\"▼\"</span>\n                                    </SidebarGroupTrigger>\n                                    <SidebarGroupContent>\n                                        {render_items(items, tooltips)}\n                                    </SidebarGroupContent>\n                                </SidebarGroup>\n                                <div hidden=collapsible>\n                                    <SidebarGroupLabel>{label2}</SidebarGroupLabel>\n                                    {render_items(items2, tooltips)}\n                                </div>\n                                <SidebarSeparator hidden=(!has_separator || i >= 1) />\n                            </div>\n                        }\n                    }).collect::<Vec<_>>()}\n                </SidebarMenu>\n            </SidebarContent>\n\n            <SidebarFooter>\n                <SidebarLabel>\"© 2026 CanonRS\"</SidebarLabel>\n            </SidebarFooter>\n        </Sidebar>\n    }\n}\n\nfn render_items(items: Vec<NavItem>, tooltips: bool) -> impl IntoView {\n    items.into_iter().map(|item| {\n        let has_children = !item.children.is_empty();\n        let active       = if item.active { ActivityState::Active } else { ActivityState::Inactive };\n        let children     = item.children.clone();\n        let badge        = item.badge.clone();\n        let label        = item.label.to_string();\n        let label2       = label.clone();\n        let label3       = label.clone();\n        let label4       = label.clone();\n        let icon         = item.icon.to_string();\n        let icon2        = icon.clone();\n        let icon3        = icon.clone();\n        let href         = item.href.to_string();\n        let href2        = href.clone();\n        let has_badge    = badge.is_some();\n        let badge_variant  = badge.as_ref().map(|b| b.variant.clone()).unwrap_or_default();\n        let badge_variant2 = badge_variant.clone();\n        let badge_label    = badge.as_ref().map(|b| b.label.to_string()).unwrap_or_default();\n        let badge_label2   = badge_label.clone();\n\n        view! {\n            <div>\n                <SidebarGroup state=VisibilityState::Closed hidden=(!has_children)>\n                    <SidebarGroupTrigger>\n                        <SidebarIcon>{icon}</SidebarIcon>\n                        <SidebarLabel>{label}</SidebarLabel>\n                        <span data-rs-sidebar-group-chevron=\"\">\"▼\"</span>\n                    </SidebarGroupTrigger>\n                    <SidebarGroupContent>\n                        {render_items(children, tooltips)}\n                    </SidebarGroupContent>\n                </SidebarGroup>\n                <div hidden=has_children>\n                    <div hidden=tooltips>\n                        <SidebarMenuItem href=href.clone() active=active>\n                            <SidebarIcon>{icon2.clone()}</SidebarIcon>\n                            <SidebarLabel>{label2.clone()}</SidebarLabel>\n                            <Badge variant=badge_variant.clone() hidden=(!has_badge)>{badge_label.clone()}</Badge>\n                        </SidebarMenuItem>\n                    </div>\n                    <div hidden=(!tooltips)>\n                        <Tooltip>\n                            <TooltipTrigger>\n                                <SidebarMenuItem href=href2 active=active>\n                                    <SidebarIcon>{icon3}</SidebarIcon>\n                                    <SidebarLabel>{label3}</SidebarLabel>\n                                    <Badge variant=badge_variant2 hidden=(!has_badge)>{badge_label2}</Badge>\n                                </SidebarMenuItem>\n                            </TooltipTrigger>\n                            <TooltipContent>{label4}</TooltipContent>\n                        </Tooltip>\n                    </div>\n                </div>\n            </div>\n        }\n    }).collect::<Vec<_>>()\n}\n\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{SidebarTriggerPrimitive as SidebarTrigger, SidebarVariant, BadgeVariant}; \n\npub const SIDEBAR_API: ComponentApi = ComponentApi {\n    id: \"sidebar\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"open\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"rail\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARHEADER_API: ComponentApi = ComponentApi {\n    id: \"sidebar-header\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARCONTENT_API: ComponentApi = ComponentApi {\n    id: \"sidebar-content\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARFOOTER_API: ComponentApi = ComponentApi {\n    id: \"sidebar-footer\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARMENU_API: ComponentApi = ComponentApi {\n    id: \"sidebar-menu\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARMENUITEM_API: ComponentApi = ComponentApi {\n    id: \"sidebar-menu-item\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Navigation target URL\" },\n        PropDef { name: \"active\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Active/selected state\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n    ],\n};\n\npub const SIDEBARMENUGROUP_API: ComponentApi = ComponentApi {\n    id: \"sidebar-menu-group\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"label\", kind: PropType::String, required: false, default: None, description: \"Accessible label text\" },\n    ],\n};\n\npub const SIDEBARSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"sidebar-separator\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"hidden\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n    ],\n};\n\npub const SIDEBARGROUPLABEL_API: ComponentApi = ComponentApi {\n    id: \"sidebar-group-label\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARGROUP_API: ComponentApi = ComponentApi {\n    id: \"sidebar-group\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"root\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"hidden\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"state\", kind: PropType::String, required: false, default: Some(\"open\"), description: \"Loading or visibility state\" },\n    ],\n};\n\npub const SIDEBARGROUPTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"sidebar-group-trigger\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARGROUPCONTENT_API: ComponentApi = ComponentApi {\n    id: \"sidebar-group-content\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARLABEL_API: ComponentApi = ComponentApi {\n    id: \"sidebar-label\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARICON_API: ComponentApi = ComponentApi {\n    id: \"sidebar-icon\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARUSER_API: ComponentApi = ComponentApi {\n    id: \"sidebar-user\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SIDEBARUNIFIEDBOUNDARY_API: ComponentApi = ComponentApi {\n    id: \"sidebar-unified-boundary\",\n    description: \"Sidebar navigation component\",\n    props: &[\n        PropDef { name: \"config\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "//! SidebarPreviewUnified — 10 demos via SidebarConfig\n\nuse leptos::prelude::*;\nuse super::sidebar_boundary::{SidebarConfig, NavGroup, NavItem, SidebarUnifiedBoundary, VisibilityState, SidebarVariant, BadgeVariant};\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse canonrs_core::primitives::layout::grid::{GridPrimitive as Grid, GridCols, GridGap};\n\nfn nav_items_basic() -> Vec<NavGroup> {\n    vec![\n        NavGroup::new(\"Navigation\", vec![\n            NavItem::new(\"📊\", \"Dashboard\", \"/dashboard\").active(),\n            NavItem::new(\"📁\", \"Projects\", \"/projects\"),\n            NavItem::new(\"✓\", \"Tasks\", \"/tasks\"),\n        ]),\n        NavGroup::new(\"Settings\", vec![\n            NavItem::new(\"👤\", \"Profile\", \"/profile\"),\n            NavItem::new(\"⚙\", \"Preferences\", \"/preferences\"),\n        ]),\n    ]\n}\n\nfn nav_items_with_badges() -> Vec<NavGroup> {\n    vec![\n        NavGroup::new(\"Navigation\", vec![\n            NavItem::new(\"📊\", \"Dashboard\", \"/dashboard\").active(),\n            NavItem::new(\"📁\", \"Projects\", \"/projects\").badge(\"12\", BadgeVariant::Primary),\n            NavItem::new(\"✓\", \"Tasks\", \"/tasks\").badge(\"5\", BadgeVariant::Destructive),\n            NavItem::new(\"💬\", \"Messages\", \"/messages\").badge(\"3\", BadgeVariant::Warning),\n        ]),\n        NavGroup::new(\"Settings\", vec![\n            NavItem::new(\"🔔\", \"Notifications\", \"/notifications\").badge(\"New\", BadgeVariant::Success),\n            NavItem::new(\"👤\", \"Profile\", \"/profile\"),\n        ]),\n    ]\n}\n\nfn nav_items_collapsible() -> Vec<NavGroup> {\n    vec![\n        NavGroup::new(\"Navigation\", vec![\n            NavItem::new(\"📊\", \"Dashboard\", \"/dashboard\").active(),\n            NavItem::new(\"📁\", \"Projects\", \"/projects\"),\n            NavItem::new(\"✓\", \"Tasks\", \"/tasks\"),\n        ]).icon(\"🧭\").collapsible(),\n        NavGroup::new(\"Settings\", vec![\n            NavItem::new(\"👤\", \"Profile\", \"/profile\"),\n            NavItem::new(\"⚙\", \"Preferences\", \"/preferences\"),\n        ]).icon(\"⚙\").collapsible(),\n    ]\n}\n\nfn nav_items_multi_level() -> Vec<NavGroup> {\n    vec![\n        NavGroup::new(\"Navigation\", vec![\n            NavItem::new(\"📊\", \"Dashboard\", \"/dashboard\").active(),\n            NavItem::new(\"📁\", \"Projects\", \"/projects\").children(vec![\n                NavItem::new(\"\", \"Frontend\", \"/projects/frontend\").children(vec![\n                    NavItem::new(\"\", \"Components\", \"/projects/frontend/components\"),\n                    NavItem::new(\"\", \"Pages\", \"/projects/frontend/pages\"),\n                ]),\n                NavItem::new(\"\", \"Backend\", \"/projects/backend\").children(vec![\n                    NavItem::new(\"\", \"API\", \"/projects/backend/api\"),\n                    NavItem::new(\"\", \"Database\", \"/projects/backend/database\"),\n                ]),\n                NavItem::new(\"\", \"Documentation\", \"/projects/docs\"),\n            ]),\n            NavItem::new(\"✓\", \"Tasks\", \"/tasks\"),\n        ]),\n    ]\n}\n\npub fn config_for(demo: &str) -> SidebarConfig {\n    match demo {\n        \"simple\"     => SidebarConfig { groups: nav_items_basic(), ..Default::default() },\n        \"basic\"      => SidebarConfig { groups: nav_items_collapsible(), ..Default::default() },\n        \"tooltips\"   => SidebarConfig { groups: nav_items_basic(), tooltips: true, ..Default::default() },\n        \"multilevel\" => SidebarConfig { groups: nav_items_multi_level(), ..Default::default() },\n        \"search\"     => SidebarConfig { groups: nav_items_basic(), search: true, ..Default::default() },\n        \"rail\"       => SidebarConfig {\n            groups: nav_items_basic(),\n            state: VisibilityState::Closed,\n            variant: SidebarVariant::Rail,\n            tooltips: false,\n            ..Default::default()\n        },\n        \"pinnable\"   => SidebarConfig { groups: nav_items_basic(), pinnable: true, ..Default::default() },\n        \"badges\"     => SidebarConfig { groups: nav_items_with_badges(), ..Default::default() },\n        \"groups\"     => SidebarConfig { groups: nav_items_collapsible(), ..Default::default() },\n        \"responsive\" => SidebarConfig { groups: nav_items_basic(), responsive: true, ..Default::default() },\n        _            => SidebarConfig::default(),\n    }\n}\n\n#[component]\npub fn SidebarPreviewUnified(#[prop(into)] demo: String) -> impl IntoView {\n    let config = config_for(&demo);\n    view! { <SidebarUnifiedBoundary config=config /> }\n}\n\n#[component]\npub fn SidebarShowcasePreview() -> impl IntoView {\n    let demos: &[(&str, &str)] = &[\n        (\"simple\",     \"Simple\"),\n        (\"basic\",      \"Collapsible Groups\"),\n        (\"badges\",     \"With Badges\"),\n        (\"search\",     \"With Search\"),\n        (\"multilevel\", \"Multi-level\"),\n        (\"tooltips\",   \"With Tooltips\"),\n        (\"rail\",       \"Rail Mode\"),\n        (\"pinnable\",   \"Pinnable\"),\n        (\"groups\",     \"Groups\"),\n        (\"responsive\", \"Responsive\"),\n    ];\n\n    view! {\n        <Stack direction=StackDirection::Vertical gap=StackGap::Xl>\n            <Grid cols=GridCols::Two gap=GridGap::Lg>\n                {demos.iter().map(|(demo, label)| {\n                    let config = config_for(demo);\n                    view! {\n                        <Stack direction=StackDirection::Vertical gap=StackGap::Sm>\n                            <span data-rs-showcase-label=\"\">{*label}</span>\n                            <div data-rs-showcase-preview-stage=\"\" style=\"height: 400px; overflow: hidden; border: 1px solid var(--theme-surface-border); border-radius: var(--radius-lg); position: relative;\">\n                                <SidebarUnifiedBoundary config=config />\n                            </div>\n                        </Stack>\n                    }\n                }).collect::<Vec<_>>()}\n            </Grid>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Sidebar — 10 variants: simple, collapsible, badges, search, multilevel, tooltips, rail, pinnable, groups, responsive.\"\n            </p>\n        </Stack>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "skeleton",
    "label": "Skeleton",
    "category": "Feedback",
    "description": "Loading skeleton placeholder",
    "keywords": "",
    "pain": "Loading placeholders inconsistent and lack accessibility semantics",
    "promise": "Skeleton state and variant standardized via structure",
    "why": "SkeletonPrimitive encodes variant and loading state with aria-busy. This guarantees consistent placeholder rendering and accessibility feedback.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"skeleton\"></div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Skeleton variant=SkeletonVariant::Text />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "loading states",
      "content placeholders"
    ],
    "related": [
      "progress",
      "spinner",
      "pulse",
      "loading_overlay",
      "doc_progress"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Skeleton Primitive - HTML puro\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub enum SkeletonVariant {\n    #[default]\n    Rectangle,\n    Text,\n    Circle,\n}\nimpl SkeletonVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Rectangle => \"rectangle\",\n            Self::Text      => \"text\",\n            Self::Circle    => \"circle\",\n        }\n    }\n}\n\n#[component]\npub fn SkeletonPrimitive(\n    children: Children,\n    #[prop(default = SkeletonVariant::Rectangle)] variant: SkeletonVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_skl = crate::infra::uid::generate(\"skl\");\n    view! {\n        <div\n            data-rs-skeleton=\"\"\n            data-rs-uid=uid_skl\n            data-rs-variant=variant.as_str()\n            aria-busy=\"true\"\n            aria-live=\"polite\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::SkeletonPrimitive;\npub use canonrs_core::primitives::SkeletonVariant;\n\n#[component]\npub fn Skeleton(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = SkeletonVariant::Rectangle)] variant: SkeletonVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SkeletonPrimitive variant=variant class=class>\n            {children.map(|c| c())}\n        </SkeletonPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! Skeleton Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::skeleton_ui::Skeleton as SkeletonUi;\npub use canonrs_core::primitives::SkeletonVariant;\n\n#[component]\npub fn Skeleton(\n    #[prop(default = SkeletonVariant::Rectangle)] variant: SkeletonVariant,\n    #[prop(into, default = String::new())] class:          String,\n) -> impl IntoView {\n    view! { <SkeletonUi variant=variant class=class /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{SkeletonVariant}; \n\npub const SKELETON_API: ComponentApi = ComponentApi {\n    id: \"skeleton\",\n    description: \"Loading skeleton placeholder\",\n    props: &[\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"rectangle\", \"text\", \"circle\"]), required: false, default: Some(\"rectangle\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::skeleton_boundary::{Skeleton, SkeletonVariant};\n\n#[component]\npub fn SkeletonShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <div style=\"display:flex;flex-direction:column;gap:var(--space-sm);width:100%;\">\n                    <Skeleton variant=SkeletonVariant::Rectangle />\n                    <Skeleton variant=SkeletonVariant::Text />\n                    <Skeleton variant=SkeletonVariant::Circle />\n                </div>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Placeholder de carregamento com variantes padronizadas via enum.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <div data-rs-showcase-preview-row=\"\" style=\"display:flex;flex-direction:column;gap:var(--space-sm);width:100%;\">\n                    <Skeleton variant=SkeletonVariant::Rectangle />\n                    <Skeleton variant=SkeletonVariant::Text />\n                    <Skeleton variant=SkeletonVariant::Circle />\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack",
      "grid"
    ]
  },
  {
    "id": "slider",
    "label": "Slider",
    "category": "Form",
    "description": "Range slider input",
    "keywords": "",
    "pain": "Sliders allow invalid values and break accessibility attributes",
    "promise": "Value clamped and ARIA attributes enforced automatically",
    "why": "SliderPrimitive clamps value within min/max and maps percent and aria-valuenow. Track and thumb are structurally defined. This guarantees consistent interaction behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"range\" value=\"200\" />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Slider min=0.0 max=100.0 value=50.0 />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "volume control",
      "range selection"
    ],
    "related": [
      "select",
      "combobox",
      "radio",
      "radio_group",
      "color_picker"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "select",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Slider Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[component]\npub fn SliderPrimitive(\n    children: Children,\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 1.0)] step: f64,\n    #[prop(default = 0.0)] value: f64,\n    #[prop(into, default = \"horizontal\".to_string())] orientation: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sl = crate::infra::uid::generate(\"sl\");\n    let safe_value = if value.is_nan() { min } else { value };\n    let safe_min = if min.is_nan() { 0.0 } else { min };\n    let safe_max = if max.is_nan() || max <= safe_min { safe_min + 100.0 } else { max };\n    let clamped_value = safe_value.clamp(safe_min, safe_max);\n    let percent = ((clamped_value - safe_min) / (safe_max - safe_min)) * 100.0;\n    view! {\n        <div\n            data-rs-slider=\"\"\n            data-rs-uid=uid_sl\n            data-rs-interaction=\"gesture\"\n            data-rs-orientation=orientation.clone()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-min=safe_min.to_string()\n            data-rs-max=safe_max.to_string()\n            data-rs-value=clamped_value.to_string()\n            data-rs-percent=percent.to_string()\n            data-rs-step=step.to_string()\n            role=\"slider\"\n            aria-valuemin=min.to_string()\n            aria-valuemax=max.to_string()\n            aria-valuenow=clamped_value.to_string()\n            aria-orientation=orientation\n            aria-disabled=disabled.aria_disabled()\n            tabindex=if disabled == DisabledState::Disabled { \"-1\" } else { \"0\" }\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SliderTrackPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-slider-track=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn SliderRangePrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-slider-range=\"\" class=class />\n    }\n}\n\n#[component]\npub fn SliderThumbPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-slider-thumb=\"\" tabindex=\"0\" aria-label=\"Slider thumb\" class=class />\n    }\n}\n\n#[component]\npub fn SliderMarksPrimitive(\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 10.0)] step: f64,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let safe_step = if step <= 0.0 { 10.0 } else { step };\n    let count = ((max - min) / safe_step).round() as usize + 1;\n    let marks: Vec<f64> = (0..count)\n        .map(|i| min + i as f64 * safe_step)\n        .filter(|v| *v <= max + 1e-9)\n        .collect();\n    view! {\n        <div data-rs-slider-marks=\"\" class=class>\n            {marks.into_iter().map(|v| {\n                let pct = ((v - min) / (max - min)) * 100.0;\n                let style = format!(\"left: {:.4}%\", pct);\n                view! { <span data-rs-slider-mark=\"\" style=style /> }\n            }).collect::<Vec<_>>()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::Orientation;\nuse canonrs_core::primitives::{\n    SliderPrimitive, SliderTrackPrimitive,\n    SliderRangePrimitive, SliderThumbPrimitive, SliderMarksPrimitive,\n};\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Slider(\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 1.0)] step: f64,\n    #[prop(default = 50.0)] value: f64,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = Orientation::Horizontal)] orientation: Orientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SliderPrimitive\n            min={min}\n            max={max}\n            step={step}\n            value={value}\n            orientation=orientation.as_str().to_string()\n            disabled=disabled\n            class={class}\n        >\n            <SliderTrackPrimitive>\n                <SliderRangePrimitive />\n                <SliderThumbPrimitive />\n            </SliderTrackPrimitive>\n        </SliderPrimitive>\n    }\n}\n\n\n#[component]\npub fn SliderWithMarks(\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 10.0)] step: f64,\n    #[prop(default = 50.0)] value: f64,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = Orientation::Horizontal)] orientation: Orientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SliderPrimitive\n            min={min}\n            max={max}\n            step={step}\n            value={value}\n            orientation=orientation.as_str().to_string()\n            disabled=disabled\n            class={class}\n        >\n            <SliderTrackPrimitive>\n                <SliderRangePrimitive />\n                <SliderThumbPrimitive />\n            </SliderTrackPrimitive>\n            <SliderMarksPrimitive min={min} max={max} step={step} />\n        </SliderPrimitive>\n    }\n}\n",
    "boundary_src": "//! Slider Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::slider_ui::{\n    Slider as SliderUi,\n    SliderWithMarks as SliderWithMarksUi\n};\nuse canonrs_core::meta::DisabledState;\nuse canonrs_core::Orientation;\n\n#[component]\npub fn Slider(\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 1.0)] step: f64,\n    #[prop(default = 50.0)] value: f64,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = Orientation::Horizontal)] orientation: Orientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SliderUi min=min max=max step=step value=value disabled=disabled orientation=orientation class=class />\n    }\n}\n\n#[component]\npub fn SliderWithMarks(\n    #[prop(default = 0.0)] min: f64,\n    #[prop(default = 100.0)] max: f64,\n    #[prop(default = 10.0)] step: f64,\n    #[prop(default = 50.0)] value: f64,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = Orientation::Horizontal)] orientation: Orientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SliderWithMarksUi min=min max=max step=step value=value disabled=disabled orientation=orientation class=class />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const SLIDER_API: ComponentApi = ComponentApi {\n    id: \"slider\",\n    description: \"Range slider input\",\n    props: &[\n        PropDef { name: \"min\", kind: PropType::Number, required: false, default: Some(\"0.0\"), description: \"Prop value\" },\n        PropDef { name: \"max\", kind: PropType::Number, required: false, default: Some(\"100.0\"), description: \"Prop value\" },\n        PropDef { name: \"step\", kind: PropType::Number, required: false, default: Some(\"1.0\"), description: \"Prop value\" },\n        PropDef { name: \"value\", kind: PropType::Number, required: false, default: Some(\"50.0\"), description: \"Current value\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"orientation\", kind: PropType::String, required: false, default: Some(\"horizontal\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const SLIDERWITHMARKS_API: ComponentApi = ComponentApi {\n    id: \"slider-with-marks\",\n    description: \"Range slider input\",\n    props: &[\n        PropDef { name: \"min\", kind: PropType::Number, required: false, default: Some(\"0.0\"), description: \"Prop value\" },\n        PropDef { name: \"max\", kind: PropType::Number, required: false, default: Some(\"100.0\"), description: \"Prop value\" },\n        PropDef { name: \"step\", kind: PropType::Number, required: false, default: Some(\"10.0\"), description: \"Prop value\" },\n        PropDef { name: \"value\", kind: PropType::Number, required: false, default: Some(\"50.0\"), description: \"Current value\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"orientation\", kind: PropType::String, required: false, default: Some(\"horizontal\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::slider_boundary::{Slider, SliderWithMarks};\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn SliderShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Slider value=50.0 />\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Drag to set value — interaction-driven, DOM as source of truth.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Steps\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Slider step=10.0 value=30.0 />\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Slider value=60.0 disabled=DisabledState::Disabled />\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"With Marks\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <SliderWithMarks step=10.0 value=40.0 />\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "spinner",
    "label": "Spinner",
    "category": "Feedback",
    "description": "Loading spinner",
    "keywords": "",
    "pain": "Loading indicators lack consistent size and accessibility state",
    "promise": "Spinner state and size strictly controlled via enums",
    "why": "SpinnerPrimitive encodes size and LoadingState into ARIA attributes. aria-busy and role=status are enforced. This guarantees accessible loading indicators.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"spinner\"></div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Spinner size=SpinnerSize::Large />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "loading indicators",
      "async feedback"
    ],
    "related": [
      "progress",
      "skeleton",
      "pulse",
      "loading_overlay",
      "doc_progress"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "progress",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Spinner Primitive - Loading indicator\n\nuse leptos::prelude::*;\nuse crate::meta::LoadingState;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum SpinnerSize {\n    Small,\n    #[default]\n    Medium,\n    Large,\n}\nimpl SpinnerSize {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Small  => \"small\",\n            Self::Medium => \"medium\",\n            Self::Large  => \"large\",\n        }\n    }\n}\n\n#[component]\npub fn SpinnerPrimitive(\n    #[prop(default = SpinnerSize::Medium)] size: SpinnerSize,\n    #[prop(default = LoadingState::Loading)] state: LoadingState,\n    #[prop(into, default = \"Loading\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_spn = crate::infra::uid::generate(\"spn\");\n    view! {\n        <svg\n            data-rs-spinner=\"\"\n            data-rs-uid=uid_spn\n            data-rs-size=size.as_str()\n            data-rs-loading=state.as_str()\n            role=\"status\"\n            aria-label=aria_label\n            aria-busy=state.aria_busy()\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-width=\"2\"\n            stroke-linecap=\"round\"\n            stroke-linejoin=\"round\"\n            class=class\n        >\n            <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n        </svg>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::SpinnerPrimitive;\nuse canonrs_core::meta::LoadingState;\npub use canonrs_core::primitives::SpinnerSize;\n\n#[component]\npub fn Spinner(\n    #[prop(default = SpinnerSize::Medium)] size: SpinnerSize,\n    #[prop(default = false)] paused: bool,\n    #[prop(into, default = \"Loading\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let state = if paused { LoadingState::Idle } else { LoadingState::Loading };\n    view! {\n        <SpinnerPrimitive\n            size=size\n            state=state\n            aria_label=aria_label\n            class=class\n        />\n    }\n}\n\n",
    "boundary_src": "use leptos::prelude::*;\nuse super::spinner_ui::Spinner as SpinnerUi;\npub use canonrs_core::primitives::SpinnerSize;\n\n#[component]\npub fn Spinner(\n    #[prop(default = SpinnerSize::Medium)] size: SpinnerSize,\n    #[prop(default = false)] paused: bool,\n    #[prop(into, default = \"Loading\".to_string())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SpinnerUi size=size paused=paused aria_label=aria_label class=class />\n};\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{SpinnerSize}; \n\npub const SPINNER_API: ComponentApi = ComponentApi {\n    id: \"spinner\",\n    description: \"Loading spinner\",\n    props: &[\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"small\", \"medium\", \"large\"]), required: false, default: Some(\"medium\"), description: \"Size variant of the component\" },\n        PropDef { name: \"paused\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether spinner animation is paused\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"Loading\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::spinner_boundary::{Spinner, SpinnerSize};\n\n#[component]\npub fn SpinnerShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Spinner />\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Loading state enforced by primitive.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Sizes\"</span>\n                <div data-rs-showcase-preview-row=\"\" style=\"display:flex;align-items:center;gap:var(--space-md);\">\n                    <Spinner size=SpinnerSize::Small />\n                    <Spinner size=SpinnerSize::Medium />\n                    <Spinner size=SpinnerSize::Large />\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Paused\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Spinner paused=true />\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "center"
    ]
  },
  {
    "id": "stat",
    "label": "Stat",
    "category": "Display",
    "description": "Metric stat display",
    "keywords": "",
    "pain": "Metrics displayed without consistent structure or alignment",
    "promise": "Metric layout and semantics enforced via structured primitives",
    "why": "StatPrimitive enforces composition of value, label and optional delta. Size, alignment and trend are encoded via attributes. This guarantees consistent KPI display.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\n    <h1>\"100\"</h1>\n    <p>\"Users\"</p>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Stat>\n    <StatValue>\"100\"</StatValue>\n    <StatLabel>\"Users\"</StatLabel>\n  </Stat>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "dashboards",
      "analytics"
    ],
    "related": [
      "avatar",
      "icon",
      "logo",
      "code_block",
      "markdown",
      "chart",
      "inline_meta",
      "kbd",
      "badge",
      "carousel"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "content_display",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Stat Primitive - Number + label display\n\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum StatSize {\n    Sm,\n    #[default]\n    Md,\n    Lg,\n}\nimpl StatSize {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Sm => \"sm\", Self::Md => \"md\", Self::Lg => \"lg\" }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum StatTrend {\n    #[default]\n    Neutral,\n    Increase,\n    Decrease,\n}\nimpl StatTrend {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Neutral => \"neutral\", Self::Increase => \"increase\", Self::Decrease => \"decrease\" }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum StatAlign {\n    #[default]\n    Start,\n    Center,\n    End,\n}\nimpl StatAlign {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Start => \"start\", Self::Center => \"center\", Self::End => \"end\" }\n    }\n}\n\nuse leptos::prelude::*;\n\n#[component]\npub fn StatPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sta = crate::infra::uid::generate(\"sta\");\n    view! {\n        <div\n            data-rs-stat=\"\"\n            data-rs-uid=uid_sta\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn StatValuePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-stat-value=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn StatLabelPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-stat-label=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn StatDeltaPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-stat-delta=\"\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn StatIconPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-stat-icon=\"\" aria-hidden=\"true\" class=class>\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn StatHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-stat-header=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn StatBodyPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-stat-body=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn StatWrapperPrimitive(\n    children: Children,\n    #[prop(default = StatSize::Md)]    size:  StatSize,\n    #[prop(default = StatTrend::Neutral)] trend: StatTrend,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-stat-wrapper=\"\"\n            data-rs-size=size.as_str()\n            data-rs-trend=trend.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    StatSize, StatTrend, StatAlign,\n    StatPrimitive, StatValuePrimitive, StatLabelPrimitive,\n    StatDeltaPrimitive, StatIconPrimitive, StatHeaderPrimitive, StatBodyPrimitive, StatWrapperPrimitive,\n};\nuse canonrs_core::LoadingState;\n\n#[component]\npub fn Stat(children: Children, #[prop(default = StatSize::Md)] size: StatSize, #[prop(default = StatAlign::Start)] align: StatAlign, #[prop(optional)] trend: Option<StatTrend>, #[prop(default = LoadingState::Idle)] loading: LoadingState, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <StatPrimitive class=class>\n            <StatWrapperPrimitive size=size trend=trend.unwrap_or_default()>\n                {children()}\n            </StatWrapperPrimitive>\n        </StatPrimitive>\n    }\n}\n#[component]\npub fn StatHeader(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatHeaderPrimitive class=class>{children()}</StatHeaderPrimitive> }\n}\n#[component]\npub fn StatBody(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatBodyPrimitive class=class>{children()}</StatBodyPrimitive> }\n}\n#[component]\npub fn StatValue(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatValuePrimitive class=class>{children()}</StatValuePrimitive> }\n}\n#[component]\npub fn StatLabel(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatLabelPrimitive class=class>{children()}</StatLabelPrimitive> }\n}\n#[component]\npub fn StatDelta(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatDeltaPrimitive class=class>{children()}</StatDeltaPrimitive> }\n}\n#[component]\npub fn StatIcon(children: Children, #[prop(default = String::new())] class: String) -> impl IntoView {\n    view! { <StatIconPrimitive class=class>{children()}</StatIconPrimitive> }\n}\n",
    "boundary_src": "//! Stat Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::stat_ui::{\n    Stat as StatUi,\n    StatHeader as StatHeaderUi,\n    StatBody as StatBodyUi,\n    StatValue as StatValueUi,\n    StatLabel as StatLabelUi,\n    StatDelta as StatDeltaUi,\n    StatIcon as StatIconUi,\n};\npub use canonrs_core::primitives::{StatSize, StatAlign, StatTrend};\nuse canonrs_core::meta::LoadingState;\n\n#[component]\npub fn Stat(\n    children: Children,\n    #[prop(default = StatSize::Md)] size:          StatSize,\n    #[prop(default = StatAlign::Start)] align:     StatAlign,\n    #[prop(default = StatTrend::Neutral)] trend:   StatTrend,\n    #[prop(default = LoadingState::Idle)] loading: LoadingState,\n    #[prop(into, default = String::new())] class:  String,\n) -> impl IntoView {\n    view! { <StatUi size=size align=align trend=trend loading=loading class=class>{children()}</StatUi> }\n}\n\n#[component]\npub fn StatHeader(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatHeaderUi class=class>{children()}</StatHeaderUi> }\n}\n\n#[component]\npub fn StatBody(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatBodyUi class=class>{children()}</StatBodyUi> }\n}\n\n#[component]\npub fn StatValue(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatValueUi class=class>{children()}</StatValueUi> }\n}\n\n#[component]\npub fn StatLabel(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatLabelUi class=class>{children()}</StatLabelUi> }\n}\n\n#[component]\npub fn StatDelta(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatDeltaUi class=class>{children()}</StatDeltaUi> }\n}\n\n#[component]\npub fn StatIcon(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <StatIconUi class=class>{children()}</StatIconUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{StatSize, StatAlign, StatTrend}; \n\npub const STAT_API: ComponentApi = ComponentApi {\n    id: \"stat\",\n    description: \"Metric stat display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"size\", kind: PropType::Enum(&[\"sm\", \"md\", \"lg\"]), required: false, default: Some(\"md\"), description: \"Size variant of the component\" },\n        PropDef { name: \"align\", kind: PropType::Enum(&[\"start\", \"center\", \"end\"]), required: false, default: Some(\"start\"), description: \"Flex or stack align-items\" },\n        PropDef { name: \"trend\", kind: PropType::Enum(&[\"neutral\", \"increase\", \"decrease\"]), required: false, default: Some(\"neutral\"), description: \"Trend direction: increase, decrease or neutral\" },\n        PropDef { name: \"loading\", kind: PropType::String, required: false, default: Some(\"idle\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const STATHEADER_API: ComponentApi = ComponentApi {\n    id: \"stat-header\",\n    description: \"Metric stat display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const STATVALUE_API: ComponentApi = ComponentApi {\n    id: \"stat-value\",\n    description: \"Metric stat display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const STATDELTA_API: ComponentApi = ComponentApi {\n    id: \"stat-delta\",\n    description: \"Metric stat display\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::stat_boundary::{\n    Stat, StatHeader, StatBody,\n    StatValue, StatLabel, StatDelta, StatIcon,\n};\nuse super::{StatSize, StatAlign, StatTrend};\n\n#[component]\npub fn StatShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Stat size=StatSize::Lg trend=StatTrend::Increase>\n                    <StatHeader>\n                        <StatIcon>\"📈\"</StatIcon>\n                        <StatLabel>\"Total Revenue\"</StatLabel>\n                    </StatHeader>\n                    <StatBody>\n                        <StatValue>\"$89,432\"</StatValue>\n                        <StatDelta>\"+18.2%\"</StatDelta>\n                    </StatBody>\n                </Stat>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Metric layout and semantics enforced via structured primitives.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Trend variants\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Stat trend=StatTrend::Increase>\n                        <StatLabel>\"Active Users\"</StatLabel>\n                        <StatBody>\n                            <StatValue>\"2,350\"</StatValue>\n                            <StatDelta>\"+12%\"</StatDelta>\n                        </StatBody>\n                    </Stat>\n                    <Stat trend=StatTrend::Decrease>\n                        <StatLabel>\"Bounce Rate\"</StatLabel>\n                        <StatBody>\n                            <StatValue>\"3.2%\"</StatValue>\n                            <StatDelta>\"-0.5%\"</StatDelta>\n                        </StatBody>\n                    </Stat>\n                    <Stat trend=StatTrend::Neutral>\n                        <StatLabel>\"Sessions\"</StatLabel>\n                        <StatBody>\n                            <StatValue>\"1,024\"</StatValue>\n                            <StatDelta>\"0%\"</StatDelta>\n                        </StatBody>\n                    </Stat>\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Size variants\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Stat size=StatSize::Sm>\n                        <StatLabel>\"Small\"</StatLabel>\n                        <StatValue>\"123\"</StatValue>\n                    </Stat>\n                    <Stat size=StatSize::Md>\n                        <StatLabel>\"Medium\"</StatLabel>\n                        <StatValue>\"4,567\"</StatValue>\n                    </Stat>\n                    <Stat size=StatSize::Lg>\n                        <StatLabel>\"Large\"</StatLabel>\n                        <StatValue>\"89,432\"</StatValue>\n                    </Stat>\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Align + Icon\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Stat align=StatAlign::Center>\n                        <StatLabel>\"Centered\"</StatLabel>\n                        <StatValue>\"999\"</StatValue>\n                    </Stat>\n                    <Stat>\n                        <StatHeader>\n                            <StatIcon>\"💰\"</StatIcon>\n                            <StatLabel>\"Sales\"</StatLabel>\n                        </StatHeader>\n                        <StatValue>\"$12,234\"</StatValue>\n                    </Stat>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "grid"
    ]
  },
  {
    "id": "status_dot",
    "label": "Status Dot",
    "category": "Display",
    "description": "Status indicator dot",
    "keywords": "",
    "pain": "Status indicators mix semantic feedback with presence states",
    "promise": "Presence states strictly separated from semantic feedback",
    "why": "StatusDotVariant encodes only presence states like online or busy. ARIA labels are derived automatically. This guarantees correct semantic usage.\n",
    "before": "// ❌ Typical\nview! {\n  <span class=\"green-dot\"></span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <StatusDot variant=StatusDotVariant::Online />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "user presence",
      "chat apps"
    ],
    "related": [
      "toast",
      "alert",
      "banner",
      "callout",
      "inline_notice"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//!\n//! StatusDot Primitive - User Presence Indicator\n//!\n//! Domain: User presence/availability ONLY\n//! NOT semantic feedback (success/error/warning)\n//! Use Badge for semantic states\n//! Use InlineNotice for feedback states\n\nuse leptos::prelude::*;\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum StatusDotVariant {\n    Online,\n    #[default]\n    Offline,\n    Away,\n    Busy,\n    DoNotDisturb,\n}\n\nimpl StatusDotVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Online        => \"online\",\n            Self::Offline       => \"offline\",\n            Self::Away          => \"away\",\n            Self::Busy          => \"busy\",\n            Self::DoNotDisturb  => \"do-not-disturb\",\n        }\n    }\n\n    pub fn state(&self) -> &'static str {\n        match self {\n            Self::Online => \"active\",\n            _            => \"inactive\",\n        }\n    }\n    pub fn aria_label(&self) -> &'static str {\n        match self {\n            Self::Online       => \"Online\",\n            Self::Offline      => \"Offline\",\n            Self::Away         => \"Away\",\n            Self::Busy         => \"Busy\",\n            Self::DoNotDisturb => \"Do not disturb\",\n        }\n    }\n}\n\n#[component]\npub fn StatusDotPrimitive(\n    children: Children,\n    #[prop(default = StatusDotVariant::Offline)] variant: StatusDotVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sd = crate::infra::uid::generate(\"sd\");\n    view! {\n        <span\n            data-rs-status-dot=\"\"\n            data-rs-uid=uid_sd\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            role=\"img\"\n            aria-label=variant.aria_label()\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::StatusDotPrimitive;\npub use canonrs_core::primitives::StatusDotVariant;\n\n#[component]\npub fn StatusDot(\n    children: Children,\n    #[prop(default = StatusDotVariant::Offline)] variant: StatusDotVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <StatusDotPrimitive variant=variant class=class>\n            {children()}\n        </StatusDotPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! StatusDot Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::status_dot_ui::StatusDot as StatusDotUi;\npub use canonrs_core::primitives::StatusDotVariant;\n\n#[component]\npub fn StatusDot(\n    #[prop(default = StatusDotVariant::Offline)] variant: StatusDotVariant,\n    #[prop(into, optional)] label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span data-rs-status-dot-wrapper=\"\" style=\"display:inline-flex;align-items:center;gap:var(--space-xs);\">\n            <StatusDotUi variant=variant class=class>\n                <span></span>\n            </StatusDotUi>\n            {label.map(|l| view! { <span data-rs-status-dot-label=\"\">{l\n};</span> })}\n        </span>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{StatusDotVariant}; \n\npub const STATUSDOT_API: ComponentApi = ComponentApi {\n    id: \"status-dot\",\n    description: \"Status indicator dot\",\n    props: &[\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"online\", \"offline\", \"away\", \"busy\", \"do-not-disturb\"]), required: false, default: Some(\"offline\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"label\", kind: PropType::String, required: false, default: None, description: \"Accessible label text\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::status_dot_boundary::{StatusDot, StatusDotVariant};\n\n#[component]\npub fn StatusDotShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <div style=\"display:flex;flex-direction:column;gap:var(--space-sm);\">\n                    <StatusDot variant=StatusDotVariant::Online       label=\"Online\" />\n                    <StatusDot variant=StatusDotVariant::Away         label=\"Away\" />\n                    <StatusDot variant=StatusDotVariant::Busy         label=\"Busy\" />\n                    <StatusDot variant=StatusDotVariant::DoNotDisturb label=\"Do not disturb\" />\n                    <StatusDot variant=StatusDotVariant::Offline      label=\"Offline\" />\n                </div>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Presence states strictly separated from semantic feedback.\"\n            </p>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "switch",
    "label": "Switch",
    "category": "Form",
    "description": "Toggle switch on off",
    "keywords": "",
    "pain": "Toggle inputs desync visual state and checked value",
    "promise": "Toggle state mapped directly to DOM and interaction state",
    "why": "SwitchPrimitive maps SelectionState to checked and data attributes. Disabled state is enforced consistently. This guarantees reliable toggle behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <input type=\"checkbox\" checked />\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Switch checked=true>\"On\"</Switch>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "settings",
      "toggles"
    ],
    "related": [
      "toggle",
      "toggle_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "toggle",
    "primitive_src": "#![allow(unused_variables)]\n//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Switch Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState};\n\n\n#[component]\npub fn SwitchPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] checked: SelectionState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_sw = crate::infra::uid::generate(\"sw\");\n    let is_checked = checked == SelectionState::Selected;\n    let _is_disabled = disabled == DisabledState::Disabled;\n    let aria_checked = if is_checked { \"true\" } else { \"false\" };\n    view! {\n        <label\n            data-rs-switch=\"\"\n            data-rs-uid=uid_sw\n            data-rs-interaction=\"init\"\n            data-rs-selection=if checked == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            <input\n                type=\"checkbox\"\n                role=\"switch\"\n                data-rs-switch-input=\"\"\n                name=if name.is_empty() { None } else { Some(name) }\n                value=value\n                checked=is_checked\n                aria-checked=aria_checked\n                tabindex=\"0\"\n            />\n            {children()}\n        </label>\n    }\n}\n\n#[component]\npub fn SwitchThumbPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <span data-rs-switch-thumb=\"\" class=class /> }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{SwitchPrimitive, SwitchThumbPrimitive};\nuse canonrs_core::meta::{SelectionState, DisabledState};\n\n#[component]\npub fn Switch(\n    children: Children,\n    #[prop(default = false)] checked: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let checked_state  = if checked  { SelectionState::Selected } else { SelectionState::Unselected };\n    let disabled_state = if disabled { DisabledState::Disabled }  else { DisabledState::Enabled };\n    view! {\n        <SwitchPrimitive\n            checked=checked_state\n            disabled=disabled_state\n            name=name\n            value=value\n            class=class\n        >\n            <SwitchThumbPrimitive />\n            {children()}\n        </SwitchPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Switch Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::switch_ui::Switch as SwitchUi;\n\n#[component]\npub fn Switch(\n    #[prop(default = false)] checked: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <SwitchUi checked=checked disabled=disabled name=name value=value class=class>\n            \"\"\n        </SwitchUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const SWITCH_API: ComponentApi = ComponentApi {\n    id: \"switch\",\n    description: \"Toggle switch on off\",\n    props: &[\n        PropDef { name: \"checked\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is checked\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::switch_boundary::Switch;\n\n#[component]\npub fn SwitchShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Switch />\n                <Switch checked=true />\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Toggle state mapped directly to DOM and interaction state.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <div style=\"display:flex;flex-direction:column;align-items:center;gap:var(--space-xs)\">\n                        <Switch />\n                        <span data-rs-showcase-preview-label=\"\">\"Off\"</span>\n                    </div>\n                    <div style=\"display:flex;flex-direction:column;align-items:center;gap:var(--space-xs)\">\n                        <Switch checked=true />\n                        <span data-rs-showcase-preview-label=\"\">\"On\"</span>\n                    </div>\n                    <div style=\"display:flex;flex-direction:column;align-items:center;gap:var(--space-xs)\">\n                        <Switch disabled=true />\n                        <span data-rs-showcase-preview-label=\"\">\"Disabled Off\"</span>\n                    </div>\n                    <div style=\"display:flex;flex-direction:column;align-items:center;gap:var(--space-xs)\">\n                        <Switch checked=true disabled=true />\n                        <span data-rs-showcase-preview-label=\"\">\"Disabled On\"</span>\n                    </div>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "table",
    "label": "Table",
    "category": "Data",
    "description": "HTML table component",
    "keywords": "",
    "pain": "Tables lack consistent state handling and accessibility attributes",
    "promise": "Table state, sorting and selection enforced structurally",
    "why": "TablePrimitive encodes state, striped and hoverable behavior. Rows and headers derive selection and sort semantics. This guarantees consistent data table behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <table>\n    <tr><td>\"Data\"</td></tr>\n  </table>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Table>\n    <TableBody>\n      <TableRow>\n        <TableCell>\"Data\"</TableCell>\n      </TableRow>\n    </TableBody>\n  </Table>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "data grids",
      "reports"
    ],
    "related": [
      "data_table",
      "virtual_list",
      "empty_table",
      "tree",
      "list_item"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "data",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Table Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::SelectionState;\n\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum TableState {\n    #[default]\n    Idle,\n    Loading,\n    Empty,\n    Error,\n}\nimpl TableState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Idle    => \"idle\",\n            Self::Loading => \"loading\",\n            Self::Empty   => \"empty\",\n            Self::Error   => \"error\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum SortDirection {\n    #[default]\n    None,\n    Ascending,\n    Descending,\n}\nimpl SortDirection {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::None       => \"none\",\n            Self::Ascending  => \"ascending\",\n            Self::Descending => \"descending\",\n        }\n    }\n    pub fn aria_sort(&self) -> Option<&'static str> {\n        match self {\n            Self::None => None,\n            Self::Ascending  => Some(\"ascending\"),\n            Self::Descending => Some(\"descending\"),\n        }\n    }\n}\n\n#[component]\npub fn TableWrapperPrimitive(\n    children: Children,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-table-wrapper=\"\"\n            role=\"region\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn TablePrimitive(\n    children: Children,\n    #[prop(default = TableState::Idle)] state: TableState,\n    #[prop(default = false)] striped: bool,\n    #[prop(default = false)] hoverable: bool,\n    #[prop(default = false)] sheet_context: bool,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_tbl = crate::infra::uid::generate(\"tbl\");\n    view! {\n        <table\n            data-rs-table=\"\"\n            data-rs-uid=uid_tbl\n            data-rs-interaction=\"init\"\n            data-rs-activity=state.as_str()\n            data-rs-striped={striped.then_some(\"\")}\n            data-rs-hoverable={hoverable.then_some(\"\")}\n            data-rs-table-context={sheet_context.then_some(\"\")}\n            aria-busy={if state == TableState::Loading { Some(\"true\") } else { None }}\n            aria-label=aria_label\n            class=class\n            tabindex=\"-1\"\n        >\n            {children()}\n        </table>\n    }\n}\n\n#[component]\npub fn TableHeaderPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <thead data-rs-table-header=\"\" class=class>\n            {children()}\n        </thead>\n    }\n}\n\n#[component]\npub fn TableBodyPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <tbody data-rs-table-body=\"\" class=class>\n            {children()}\n        </tbody>\n    }\n}\n\n#[component]\npub fn TableFooterPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <tfoot data-rs-table-footer=\"\" class=class>\n            {children()}\n        </tfoot>\n    }\n}\n\n#[component]\npub fn TableRowPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = TextProp::from(\"\"))] class: TextProp,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] row_action: String,\n    #[prop(into, default = String::new())] row_label: String,\n    #[prop(into, default = String::new())] row_meta: String,\n) -> impl IntoView {\n    let action_attr = if !row_action.is_empty() { Some(row_action.clone()) } else if !href.is_empty() { Some(\"navigate\".to_string()) } else { None };\n    let href_attr = if href.is_empty() { None } else { Some(href) };\n    let row_label = if row_label.is_empty() { None } else { Some(row_label) };\n    let row_meta = if row_meta.is_empty() { None } else { Some(row_meta) };\n    view! {\n        <tr\n            data-rs-table-row=\"\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            tabindex=\"0\"\n            data-rs-action=action_attr\n            data-rs-href=href_attr\n            data-rs-label=row_label\n            data-rs-meta=row_meta\n            role=\"row\"\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            class=move || class.get().to_string()\n        >\n            {children()}\n        </tr>\n    }\n}\n\n#[component]\npub fn TableHeadPrimitive(\n    children: Children,\n    #[prop(default = SortDirection::None)] sort: SortDirection,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <th\n            data-rs-table-head=\"\"\n            data-rs-sort=sort.as_str()\n            scope=\"col\"\n            role=\"columnheader\"\n            aria-sort=sort.aria_sort()\n            class=class\n        >\n            {children()}\n        </th>\n    }\n}\n\n#[component]\npub fn TableCellPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] copyable: bool,\n    #[prop(default = false)] truncate: bool,\n) -> impl IntoView {\n    view! {\n        <td\n            data-rs-table-cell=\"\"\n            data-rs-copyable={copyable.then(|| \"\")}\n            data-rs-truncate={truncate.then(|| \"\")}\n            class=class\n        >\n            {children()}\n        </td>\n    }\n}\n\n#[component]\npub fn TableCaptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <caption data-rs-table-caption=\"\" class=class>\n            {children()}\n        </caption>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    TablePrimitive, TableHeaderPrimitive,\n    TableBodyPrimitive, TableFooterPrimitive, TableRowPrimitive,\n    TableHeadPrimitive, TableCellPrimitive, TableCaptionPrimitive,\n    SortDirection,\n};\nuse canonrs_core::meta::SelectionState;\npub use canonrs_core::primitives::TableState;\n\n#[component]\npub fn Table(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = TableState::Idle)] state: TableState,\n    #[prop(default = false)] striped: bool,\n    #[prop(default = false)] hoverable: bool,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TablePrimitive state=state striped=striped hoverable=hoverable aria_label=aria_label.unwrap_or_default() class=class>\n            {children.map(|c| c())}\n        </TablePrimitive>\n    }\n}\n\n#[component]\npub fn TableHeader(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TableHeaderPrimitive class=class>\n            {children.map(|c| c())}\n        </TableHeaderPrimitive>\n    }\n}\n\n#[component]\npub fn TableBody(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TableBodyPrimitive class=class>\n            {children.map(|c| c())}\n        </TableBodyPrimitive>\n    }\n}\n\n#[component]\npub fn TableFooter(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TableFooterPrimitive class=class>\n            {children.map(|c| c())}\n        </TableFooterPrimitive>\n    }\n}\n\n#[component]\npub fn TableRow(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, default = TextProp::from(\"\"))] class: TextProp,\n    #[prop(into, optional)] href: Option<String>,\n    #[prop(into, optional)] row_action: Option<String>,\n    #[prop(into, optional)] row_label: Option<String>,\n    #[prop(into, optional)] row_meta: Option<String>,\n) -> impl IntoView {\n    let href = href.unwrap_or_default();\n    let row_action = row_action.unwrap_or_default();\n    let row_label = row_label.unwrap_or_default();\n    let row_meta = row_meta.unwrap_or_default();\n    view! {\n        <TableRowPrimitive selected=selected class=class href=href row_action=row_action row_label=row_label row_meta=row_meta>\n            {children.map(|c| c())}\n        </TableRowPrimitive>\n    }\n}\n\n#[component]\npub fn TableHead(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(default = SortDirection::None)] sort: SortDirection,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TableHeadPrimitive sort=sort class=class>\n            {children.map(|c| c())}\n        </TableHeadPrimitive>\n    }\n}\n\n#[component]\npub fn TableCell(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] copyable: bool,\n    #[prop(default = false)] truncate: bool,\n) -> impl IntoView {\n    view! {\n        <TableCellPrimitive class=class copyable=copyable truncate=truncate>\n            {children.map(|c| c())}\n        </TableCellPrimitive>\n    }\n}\n\n#[component]\npub fn TableCaption(\n    #[prop(optional)] children: Option<Children>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TableCaptionPrimitive class=class>\n            {children.map(|c| c())}\n        </TableCaptionPrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Table Boundary — Canon Rule #340 (zero-logic passthrough)\n\nuse leptos::prelude::*;\nuse super::table_ui::{\n    Table as TableUi,\n    TableHeader as TableHeaderUi,\n    TableBody as TableBodyUi,\n    TableRow as TableRowUi,\n    TableHead as TableHeadUi,\n    TableCell as TableCellUi,\n    TableFooter as TableFooterUi,\n    TableCaption as TableCaptionUi,\n};\npub use canonrs_core::primitives::SortDirection;\nuse canonrs_core::meta::SelectionState;\npub use super::table_ui::TableState;\n\n#[component]\npub fn Table(\n    children: Children,\n    #[prop(default = TableState::Idle)] state: TableState,\n    #[prop(default = false)] striped: bool,\n    #[prop(default = false)] hoverable: bool,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableUi state=state striped=striped hoverable=hoverable aria_label=aria_label.unwrap_or_default() class=class>{children()}</TableUi> }\n}\n\n#[component]\npub fn TableHeader(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableHeaderUi class=class>{children()}</TableHeaderUi> }\n}\n\n#[component]\npub fn TableBody(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableBodyUi class=class>{children()}</TableBodyUi> }\n}\n\n#[component]\npub fn TableFooter(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableFooterUi class=class>{children()}</TableFooterUi> }\n}\n\n#[component]\npub fn TableRow(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(into, optional)] href: Option<String>,\n    #[prop(into, default = TextProp::from(\"\"))] class: TextProp,\n) -> impl IntoView {\n    let href = href.unwrap_or_default();\n    view! { <TableRowUi selected=selected href=href class=class>{children()}</TableRowUi> }\n}\n\n#[component]\npub fn TableHead(\n    children: Children,\n    #[prop(default = SortDirection::None)] sort: SortDirection,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableHeadUi sort=sort class=class>{children()}</TableHeadUi> }\n}\n\n#[component]\npub fn TableCell(\n    children: Children,\n    #[prop(default = false)] copyable: bool,\n    #[prop(default = false)] truncate: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableCellUi copyable=copyable truncate=truncate class=class>{children()}</TableCellUi> }\n}\n\n#[component]\npub fn TableCaption(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TableCaptionUi class=class>{children()}</TableCaptionUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{SortDirection}; \n\npub const TABLE_API: ComponentApi = ComponentApi {\n    id: \"table\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"state\", kind: PropType::Enum(&[\"idle\", \"loading\", \"empty\", \"error\"]), required: false, default: Some(\"idle\"), description: \"Loading or visibility state\" },\n        PropDef { name: \"striped\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"hoverable\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: None, description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLEHEADER_API: ComponentApi = ComponentApi {\n    id: \"table-header\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLEBODY_API: ComponentApi = ComponentApi {\n    id: \"table-body\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLEFOOTER_API: ComponentApi = ComponentApi {\n    id: \"table-footer\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLEROW_API: ComponentApi = ComponentApi {\n    id: \"table-row\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"selected\", kind: PropType::String, required: false, default: Some(\"unselected\"), description: \"Prop value\" },\n        PropDef { name: \"href\", kind: PropType::String, required: false, default: None, description: \"Navigation target URL\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"from\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLEHEAD_API: ComponentApi = ComponentApi {\n    id: \"table-head\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"sort\", kind: PropType::Enum(&[\"none\", \"ascending\", \"descending\"]), required: false, default: Some(\"none\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLECELL_API: ComponentApi = ComponentApi {\n    id: \"table-cell\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"copyable\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"truncate\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABLECAPTION_API: ComponentApi = ComponentApi {\n    id: \"table-caption\",\n    description: \"HTML table component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::table_boundary::{Table, TableHeader, TableBody, TableRow, TableHead, TableCell};\nuse crate::blocks::data_table::DataTableBlock;\nuse crate::ui::sheet::sheet_boundary::Sheet;\nuse canonrs_core::slot;\nuse canonrs_core::meta::SelectionState;\n\n#[component]\npub fn TableShowcasePreview() -> impl IntoView {\n    view! {\n        <DataTableBlock\n            body=slot!(|| view! {\n                <div data-rs-table-context=\"\" data-rs-uid=\"table-ctx-1\" data-rs-interaction=\"init\">\n                    <Table hoverable=true>\n                        <TableHeader>\n                            <TableRow>\n                                <TableHead>\"Name\"</TableHead>\n                                <TableHead>\"Role\"</TableHead>\n                                <TableHead>\"Status\"</TableHead>\n                                <TableHead>\"Email\"</TableHead>\n                            </TableRow>\n                        </TableHeader>\n                        <TableBody>\n                            <TableRow attr:data-rs-action=\"open-sheet\" attr:data-rs-label=\"Alice\" attr:data-rs-meta=\"Engineer · Active\">\n                                <TableCell copyable=true>\"Alice\"</TableCell>\n                                <TableCell>\"Engineer\"</TableCell>\n                                <TableCell>\"Active\"</TableCell>\n                                <TableCell truncate=true>\"alice@example.com · alice.secondary@company.org\"</TableCell>\n                            </TableRow>\n                            <TableRow attr:data-rs-action=\"open-sheet\" attr:data-rs-label=\"Bob\" attr:data-rs-meta=\"Designer · Active\">\n                                <TableCell copyable=true>\"Bob\"</TableCell>\n                                <TableCell>\"Designer\"</TableCell>\n                                <TableCell>\"Active\"</TableCell>\n                                <TableCell truncate=true>\"bob@example.com · bob.work@company.org\"</TableCell>\n                            </TableRow>\n                            <TableRow attr:data-rs-action=\"open-sheet\" attr:data-rs-label=\"Carol\" attr:data-rs-meta=\"Manager · Inactive\">\n                                <TableCell copyable=true>\"Carol\"</TableCell>\n                                <TableCell>\"Manager\"</TableCell>\n                                <TableCell>\"Inactive\"</TableCell>\n                                <TableCell truncate=true>\"carol@example.com · carol.backup@company.org\"</TableCell>\n                            </TableRow>\n                            <TableRow attr:data-rs-action=\"open-sheet\" attr:data-rs-label=\"Dave\" attr:data-rs-meta=\"DevOps · Active\" selected=SelectionState::Selected>\n                                <TableCell copyable=true>\"Dave\"</TableCell>\n                                <TableCell>\"DevOps\"</TableCell>\n                                <TableCell>\"Active\"</TableCell>\n                                <TableCell truncate=true>\"dave@example.com · dave.ops@company.org\"</TableCell>\n                            </TableRow>\n                            <TableRow attr:data-rs-action=\"open-sheet\" attr:data-rs-label=\"Eve\" attr:data-rs-meta=\"QA · Active\">\n                                <TableCell copyable=true>\"Eve\"</TableCell>\n                                <TableCell>\"QA\"</TableCell>\n                                <TableCell>\"Active\"</TableCell>\n                                <TableCell truncate=true>\"eve@example.com · eve.testing@company.org\"</TableCell>\n                            </TableRow>\n                        </TableBody>\n                    </Table>\n                    <Sheet trigger_label=\"\" close_label=\"Close\" />\n                </div>\n            }.into_any())\n        />\n        <p data-rs-showcase-preview-anchor=\"\">\n            \"Click any row to open a detail sheet. Copy cells and truncation included.\"\n        </p>\n        <DataTableBlock\n            body=slot!(|| view! {\n                <Table striped=true hoverable=true>\n                    <TableHeader>\n                        <TableRow>\n                            <TableHead>\"Name\"</TableHead>\n                            <TableHead>\"Score\"</TableHead>\n                        </TableRow>\n                    </TableHeader>\n                    <TableBody>\n                        <TableRow><TableCell>\"Alice\"</TableCell><TableCell>\"98\"</TableCell></TableRow>\n                        <TableRow><TableCell>\"Bob\"</TableCell><TableCell>\"87\"</TableCell></TableRow>\n                        <TableRow><TableCell>\"Carol\"</TableCell><TableCell>\"75\"</TableCell></TableRow>\n                        <TableRow selected=SelectionState::Selected><TableCell>\"Dave\"</TableCell><TableCell>\"92\"</TableCell></TableRow>\n                        <TableRow><TableCell>\"Eve\"</TableCell><TableCell>\"81\"</TableCell></TableRow>\n                    </TableBody>\n                </Table>\n            }.into_any())\n        />\n    }\n}\n",
    "block": [
      "data_table_block"
    ],
    "blocks_primitives": [
      "container"
    ]
  },
  {
    "id": "table_of_contents",
    "label": "Table of Contents",
    "category": "Navigation",
    "description": "Document table of contents",
    "keywords": "",
    "pain": "TOC structures inconsistent and hard to sync with document hierarchy",
    "promise": "TOC hierarchy and state derived from structured data model",
    "why": "TocPrimitive encodes mode and item states with hierarchical structure. SSR rendering ensures deterministic output. This guarantees consistent navigation.\n",
    "before": "// ❌ Typical\nview! {\n  <ul>\n    <li><a href=\"#a\">\"A\"</a></li>\n  </ul>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <TableOfContents items=items />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "docs navigation",
      "long pages"
    ],
    "related": [
      "tabs"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "tabs",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! TableOfContents Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum TocMode {\n    #[default]\n    Simple,\n    Expand,\n    Nested,\n}\n\nimpl TocMode {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Simple => \"simple\",\n            Self::Expand => \"expand\",\n            Self::Nested => \"nested\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum TocItemState {\n    #[default]\n    Idle,\n    Active,\n    Ancestor,\n}\n\nimpl TocItemState {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Idle     => \"idle\",\n            Self::Active   => \"active\",\n            Self::Ancestor => \"ancestor\",\n        }\n    }\n}\n\n#[component]\npub fn TocPrimitive(\n    children: Children,\n    #[prop(default = TocMode::Simple)] mode: TocMode,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_toc = crate::infra::uid::generate(\"toc\");\n    view! {\n        <nav\n            data-rs-toc=\"\"\n            data-rs-uid=uid_toc\n            data-rs-interaction=\"init\"\n            data-rs-mode=mode.as_str()\n            aria-label=\"Table of contents\"\n            class=class\n        >\n            {children()}\n        </nav>\n    }\n}\n\n#[component]\npub fn TocTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <p data-rs-toc-title=\"\" class=class>\n            {children()}\n        </p>\n    }\n}\n\n#[component]\npub fn TocListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ul data-rs-toc-list=\"\" class=class>\n            {children()}\n        </ul>\n    }\n}\n\n#[component]\npub fn TocSubtreePrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ul\n            data-rs-toc-subtree=\"\"\n            data-rs-navigation=state.as_str()\n            class=class\n        >\n            {children()}\n        </ul>\n    }\n}\n\n#[component]\npub fn TocItemPrimitive(\n    children: Children,\n    #[prop(into)] data_level: String,\n    #[prop(into, default = String::new())] data_target: String,\n    #[prop(default = TocItemState::Idle)] state: TocItemState,\n    #[prop(default = false)] is_child: bool,\n    #[prop(default = false)] has_children: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <li\n            data-rs-toc-item=\"\"\n            data-rs-level=data_level\n            data-rs-target=data_target\n            data-rs-navigation=state.as_str()\n            data-rs-child=if is_child { \"true\" } else { \"false\" }\n            data-rs-has-children=if has_children { \"true\" } else { \"false\" }\n            class=class\n        >\n            {children()}\n        </li>\n    }\n}\n\n#[component]\npub fn TocLinkPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] href: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <a data-rs-toc-link=\"\" href=href class=class>\n            {children()}\n        </a>\n    }\n}\n\n#[component]\npub fn TocExpandButtonPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let open = state == VisibilityState::Open;\n    view! {\n        <button\n            type=\"button\"\n            data-rs-toc-expand-btn=\"\"\n            data-rs-navigation=state.as_str()\n            aria-expanded=if open { \"true\" } else { \"false\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::structural::toc_item::{TocItemRowPrimitive, TocExpandIconPrimitive};\nuse canonrs_core::TocItem;\nuse canonrs_core::primitives::table_of_contents::*;\n#[cfg(feature = \"ssr\")]\nuse canonrs_core::VisibilityState;\n\n#[component]\npub fn TableOfContents(items: Vec<TocItem>, #[prop(default = TocMode::Simple)] mode: TocMode, #[prop(into, default = String::new())] class: String, #[prop(into, default = \"On this page\".to_string())] title: String) -> impl IntoView {\n    #[cfg(feature = \"ssr\")]\n    {\n        view! {\n            <TocPrimitive class=class mode=mode>\n                <TocTitlePrimitive>{title}</TocTitlePrimitive>\n                {match mode {\n                    TocMode::Simple => render_simple(items).into_any(),\n                    TocMode::Expand => render_expand(items).into_any(),\n                    TocMode::Nested => render_nested(items).into_any(),\n                }}\n            </TocPrimitive>\n        }.into_any()\n    }\n    #[cfg(not(feature = \"ssr\"))]\n    {\n        let _ = (items, mode, class, title);\n        view! { <TocPrimitive class=String::new() mode=TocMode::Simple>{()}</TocPrimitive> }.into_any()\n    }\n}\n\n#[cfg(feature = \"ssr\")]\nfn render_simple(items: Vec<TocItem>) -> impl IntoView {\n    view! {\n        <TocListPrimitive>\n            {items.into_iter().map(|item| view! {\n                <TocItemPrimitive data_level=item.level.to_string() data_target=item.id.clone() state=TocItemState::Idle is_child=false has_children=false>\n                    <TocLinkPrimitive href=format!(\"#{}\", item.id)>{item.text}</TocLinkPrimitive>\n                </TocItemPrimitive>\n            }).collect::<Vec<_>>()}\n        </TocListPrimitive>\n    }\n}\n\n#[cfg(feature = \"ssr\")]\nfn render_expand(items: Vec<TocItem>) -> impl IntoView {\n    view! {\n        <TocListPrimitive>\n            {items.into_iter().map(|item| {\n                let is_child = item.level > 1;\n                view! {\n                    <TocItemPrimitive data_level=item.level.to_string() data_target=item.id.clone() state=TocItemState::Idle is_child=is_child has_children=false>\n                        <TocLinkPrimitive href=format!(\"#{}\", item.id)>{item.text}</TocLinkPrimitive>\n                    </TocItemPrimitive>\n                }\n            }).collect::<Vec<_>>()}\n        </TocListPrimitive>\n    }\n}\n\n#[cfg(feature = \"ssr\")]\nfn render_nested(items: Vec<TocItem>) -> impl IntoView {\n    let tree = build_tree(items);\n    view! { <TocListPrimitive>{render_tree_nodes(tree)}</TocListPrimitive> }\n}\n\n#[derive(Clone)]\n#[cfg(feature = \"ssr\")]\nstruct TocNode { item: TocItem, children: Vec<TocNode> }\n\n#[cfg(feature = \"ssr\")]\nfn build_tree(items: Vec<TocItem>) -> Vec<TocNode> {\n    let flat: Vec<TocNode> = items.into_iter().map(|item| TocNode { item, children: Vec::new() }).collect();\n    let n = flat.len();\n    let mut parent: Vec<Option<usize>> = vec![None; n];\n    let mut stack: Vec<(u8, usize)> = Vec::new();\n    for i in 0..n {\n        let level = flat[i].item.level;\n        while stack.last().map(|(l, _)| *l >= level).unwrap_or(false) { stack.pop(); }\n        if let Some(&(_, p)) = stack.last() { parent[i] = Some(p); }\n        stack.push((level, i));\n    }\n    let mut nodes: Vec<Option<TocNode>> = flat.into_iter().map(Some).collect();\n    for i in (0..n).rev() {\n        if let Some(p) = parent[i] { let child = nodes[i].take().unwrap(); nodes[p].as_mut().unwrap().children.insert(0, child); }\n    }\n    nodes.into_iter().enumerate().filter(|(i, _)| parent[*i].is_none()).filter_map(|(_, n)| n).collect()\n}\n\n#[cfg(feature = \"ssr\")]\nfn render_tree_nodes(nodes: Vec<TocNode>) -> Vec<AnyView> {\n    nodes.into_iter().map(|node| -> AnyView {\n        let has_children = !node.children.is_empty();\n        let item = node.item;\n        let children = node.children;\n        view! {\n            <TocItemPrimitive data_level=item.level.to_string() data_target=item.id.clone() state=TocItemState::Idle is_child=false has_children=has_children>\n                <TocItemRowPrimitive>\n                    {has_children.then(|| view! { <TocExpandButtonPrimitive><TocExpandIconPrimitive/></TocExpandButtonPrimitive> }.into_any())}\n                    <TocLinkPrimitive href=format!(\"#{}\", item.id)>{item.text}</TocLinkPrimitive>\n                </TocItemRowPrimitive>\n                {has_children.then(|| view! {\n                    <TocSubtreePrimitive state=VisibilityState::Closed>{render_tree_nodes(children)}</TocSubtreePrimitive>\n                }.into_any())}\n            </TocItemPrimitive>\n        }.into_any()\n    }).collect()\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! TableOfContents Boundary — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::table_of_contents_ui::TableOfContents as TableOfContentsUi;\npub use canonrs_core::TocItem;\nuse canonrs_core::primitives::table_of_contents::TocMode;\n\n#[component]\npub fn TableOfContents(\n    items: Vec<TocItem>,\n    #[prop(into, default = String::from(\"On this page\"))] title: String,\n    #[prop(optional)] mode: Option<TocMode>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let toc_mode = mode.unwrap_or(TocMode::Simple);\n    view! { <TableOfContentsUi items=items title=title mode=toc_mode class=class /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{TocMode}; \n\npub const TABLEOFCONTENTS_API: ComponentApi = ComponentApi {\n    id: \"table-of-contents\",\n    description: \"Document table of contents\",\n    props: &[\n        PropDef { name: \"items\", kind: PropType::String, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: Some(\"On this page\"), description: \"Title slot or text\" },\n        PropDef { name: \"mode\", kind: PropType::Enum(&[\"simple\", \"expand\", \"nested\"]), required: false, default: None, description: \"Operational mode of the component\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::table_of_contents_boundary::TableOfContents;\nuse super::table_of_contents_boundary::TocItem;\nuse canonrs_core::primitives::table_of_contents::TocMode;\nuse canonrs_core::primitives::layout::stack::{StackPrimitive as Stack, StackDirection, StackGap};\nuse crate::ui::scroll_area::scroll_area_boundary::ScrollArea;\n\nfn demo_items() -> Vec<TocItem> {\n    vec![\n        TocItem::new(\"toc-intro\".into(),   \"Introduction\".into(),  1),\n        TocItem::new(\"toc-setup\".into(),   \"Setup\".into(),         1),\n        TocItem::new(\"toc-install\".into(), \"Installation\".into(),  2),\n        TocItem::new(\"toc-config\".into(),  \"Configuration\".into(), 2),\n        TocItem::new(\"toc-env\".into(),     \"Environment\".into(),   3),\n        TocItem::new(\"toc-usage\".into(),   \"Usage\".into(),         1),\n        TocItem::new(\"toc-examples\".into(),\"Examples\".into(),      2),\n        TocItem::new(\"toc-api\".into(),     \"API Reference\".into(), 1),\n        TocItem::new(\"toc-props\".into(),   \"Props\".into(),         2),\n        TocItem::new(\"toc-events\".into(),  \"Events\".into(),        2),\n    ]\n}\n\n#[component]\npub fn TableOfContentsShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"TOC hierarchy and state derived from structured data model.\"\n            </p>\n            <div data-rs-showcase-preview-stage=\"\" style=\"padding:0\">\n                <div style=\"display:grid;grid-template-columns:1fr 1fr 1fr 2fr;gap:var(--space-md);height:400px;width:100%\">\n                    <div style=\"display:flex;flex-direction:column;gap:var(--space-xs)\">\n                        <span data-rs-showcase-preview-label=\"\">\"Simple\"</span>\n                        <TableOfContents mode=TocMode::Simple title=\"On this page\" items=demo_items() />\n                    </div>\n                    <div style=\"display:flex;flex-direction:column;gap:var(--space-xs)\">\n                        <span data-rs-showcase-preview-label=\"\">\"Expand\"</span>\n                        <TableOfContents mode=TocMode::Expand title=\"On this page\" items=demo_items() />\n                    </div>\n                    <div style=\"display:flex;flex-direction:column;gap:var(--space-xs)\">\n                        <span data-rs-showcase-preview-label=\"\">\"Nested\"</span>\n                        <TableOfContents mode=TocMode::Nested title=\"On this page\" items=demo_items() />\n                    </div>\n                    <div style=\"height:400px;display:flex;flex-direction:column\">\n                        <span data-rs-showcase-preview-label=\"\">\"Content\"</span>\n                        <div style=\"flex:1;min-height:0\">\n                            <ScrollArea>\n                                <Stack direction=StackDirection::Vertical gap=StackGap::Xl>\n                                    <section>\n                                        <h2 id=\"toc-intro\">\"Introduction\"</h2>\n                                        <p>\"Introduction content goes here. This section covers the basic concepts and goals of the library. Understanding the foundation will help you get the most out of CanonRS.\"</p>\n                                        <p>\"CanonRS is built on a strict contract between primitives, tokens, and interaction modules. Each layer has a single responsibility and clear boundaries.\"</p>\n                                    </section>\n                                    <section>\n                                        <h2 id=\"toc-setup\">\"Setup\"</h2>\n                                        <p>\"Before you begin, make sure you have Rust and the WASM toolchain installed. The setup process is straightforward and takes only a few minutes.\"</p>\n                                        <p>\"You will also need to configure your build pipeline to output WASM artifacts. Follow the steps below carefully to avoid common pitfalls.\"</p>\n                                    </section>\n                                    <section>\n                                        <h3 id=\"toc-install\">\"Installation\"</h3>\n                                        <p>\"Install via cargo add canonrs. You can also add it manually to your Cargo.toml. Make sure to enable the ssr feature for server-side rendering support.\"</p>\n                                        <p>\"After installation, run cargo build to verify everything compiles correctly.\"</p>\n                                    </section>\n                                    <section>\n                                        <h3 id=\"toc-config\">\"Configuration\"</h3>\n                                        <p>\"Configure tokens, themes and behavior. The token system is the foundation of all visual decisions. Start by selecting a base theme and customize from there.\"</p>\n                                        <p>\"All configuration is done through CSS custom properties. No JavaScript configuration is required.\"</p>\n                                    </section>\n                                    <section>\n                                        <h4 id=\"toc-env\">\"Environment\"</h4>\n                                        <p>\"Set the CANON_ENV variable to production before deploying. This enables optimized output and disables debug logging. Make sure all required environment variables are set.\"</p>\n                                    </section>\n                                    <section>\n                                        <h2 id=\"toc-usage\">\"Usage\"</h2>\n                                        <p>\"Import components from canonrs::ui. Each component follows the same pattern: primitive, UI, boundary. Use the boundary in your application code.\"</p>\n                                        <p>\"Components are designed to be composable. You can nest them freely as long as you follow the contract defined by each primitive.\"</p>\n                                    </section>\n                                    <section>\n                                        <h3 id=\"toc-examples\">\"Examples\"</h3>\n                                        <p>\"See the examples directory for working demos of each component. Each example is self-contained and can be run independently. Use them as a starting point for your own implementation.\"</p>\n                                    </section>\n                                    <section>\n                                        <h2 id=\"toc-api\">\"API Reference\"</h2>\n                                        <p>\"Full API reference documentation. Every component, primitive, and token is documented here. Use the search to find what you need quickly.\"</p>\n                                        <p>\"The API is versioned and follows semantic versioning. Breaking changes are announced in the changelog.\"</p>\n                                    </section>\n                                    <section>\n                                        <h3 id=\"toc-props\">\"Props\"</h3>\n                                        <p>\"Each component accepts a set of typed props defined by its primitive. Props are validated at compile time by the Rust type system. Optional props have sensible defaults.\"</p>\n                                    </section>\n                                    <section>\n                                        <h3 id=\"toc-events\">\"Events\"</h3>\n                                        <p>\"Components emit events via data-rs-action attributes. Listen for these in your interaction modules. Events bubble up through the DOM following standard browser conventions.\"</p>\n                                    </section>\n                                </Stack>\n                            </ScrollArea>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "tabs",
    "label": "Tabs",
    "category": "Navigation",
    "description": "Tabbed navigation",
    "keywords": "",
    "pain": "Tabs require manual state sync between triggers and panels",
    "promise": "Active state governs trigger and content without manual wiring",
    "why": "TabsPrimitive uses ActivityState to synchronize triggers and panels. ARIA roles and visibility are derived automatically. This guarantees consistent tab behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <button>\"Tab\"</button>\n  <div>\"Content\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Tabs>\n    <TabsList>\n      <TabsTrigger value=\"a\" active=true>\"Tab\"</TabsTrigger>\n    </TabsList>\n    <TabsContent value=\"a\" active=true>\"Content\"</TabsContent>\n  </Tabs>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "panel navigation",
      "settings"
    ],
    "related": [
      "table_of_contents"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "tabs",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Tabs Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{ActivityState, DisabledState};\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum TabsOrientation {\n    #[default]\n    Horizontal,\n    Vertical,\n}\nimpl TabsOrientation {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Horizontal => \"horizontal\", Self::Vertical => \"vertical\" }\n    }\n}\n\n\n#[component]\npub fn TabsPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid_tab = crate::infra::uid::generate(\"tab\");\n    view! {\n        <div\n            data-rs-tabs=\"\"\n            data-rs-uid=uid_tab\n            data-rs-interaction=\"nav\"\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn TabsListPrimitive(\n    children: Children,\n    #[prop(default = TabsOrientation::Horizontal)] orientation: TabsOrientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-tabs-list=\"\"\n            role=\"tablist\"\n            aria-orientation=orientation.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn TabsTriggerPrimitive(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let is_disabled = disabled == DisabledState::Disabled;\n    view! {\n        <button\n            type=\"button\"\n            role=\"tab\"\n            data-rs-tabs-trigger=\"\"\n            data-rs-value=value\n            data-rs-activity=active.as_str()\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            aria-selected=active.aria_selected()\n            aria-disabled=if is_disabled { \"true\" } else { \"false\" }\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn TabsContentPrimitive(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-tabs-content=\"\"\n            data-rs-value=value\n            data-rs-activity=active.as_str()\n            role=\"tabpanel\"\n            hidden=active.hidden()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::meta::{ActivityState, DisabledState};\nuse canonrs_core::primitives::{\n    TabsPrimitive, TabsListPrimitive,\n    TabsTriggerPrimitive, TabsContentPrimitive,\n};\n\n#[component]\npub fn Tabs(\n    children: Children,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] default_value: String,\n) -> impl IntoView {\n    view! {\n        <TabsPrimitive class=class attr:data-rs-default-tab=default_value node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </TabsPrimitive>\n    }\n}\n\n#[component]\npub fn TabsList(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TabsListPrimitive class=class>\n            {children()}\n        </TabsListPrimitive>\n    }\n}\n\n#[component]\npub fn TabsTrigger(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TabsTriggerPrimitive value=value active=active disabled=disabled class=class>\n            {children()}\n        </TabsTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn TabsContent(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TabsContentPrimitive value=value active=active class=class>\n            {children()}\n        </TabsContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Tabs Boundary — Canon Rule #341 (zero-logic boundary)\n//! CR-342 v4.0.0: interaction delegated to canonrs-interactions-nav\n\nuse leptos::prelude::*;\nuse super::tabs_ui::{Tabs, TabsList, TabsTrigger as TabsTriggerUi, TabsContent as TabsContentUi};\nuse canonrs_core::meta::{ActivityState, DisabledState};\n\n#[component]\npub fn TabsRoot(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] default_value: String,\n) -> impl IntoView {\n    view! { <Tabs class=class default_value=default_value>{children()}</Tabs> }\n}\n\n#[component]\npub fn TabsListBoundary(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TabsList class=class>{children()}</TabsList> }\n}\n\n#[component]\npub fn TabsTrigger(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n    #[prop(default = false)] disabled: bool,\n) -> impl IntoView {\n    let dis = if disabled { DisabledState::Disabled } else { DisabledState::Enabled };\n    view! { <TabsTriggerUi value=value active=active disabled=dis>{children()}</TabsTriggerUi> }\n}\n\n#[component]\npub fn TabsContent(\n    children: Children,\n    #[prop(into)] value: String,\n    #[prop(default = ActivityState::Inactive)] active: ActivityState,\n) -> impl IntoView {\n    view! { <TabsContentUi value=value active=active>{children()}</TabsContentUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const TABSROOT_API: ComponentApi = ComponentApi {\n    id: \"tabs-root\",\n    description: \"Tabbed navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n        PropDef { name: \"default_value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Default selected tab value\" },\n    ],\n};\n\npub const TABSLISTBOUNDARY_API: ComponentApi = ComponentApi {\n    id: \"tabs-list-boundary\",\n    description: \"Tabbed navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TABSTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"tabs-trigger\",\n    description: \"Tabbed navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: true, default: None, description: \"Current value\" },\n        PropDef { name: \"active\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Active/selected state\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n    ],\n};\n\npub const TABSCONTENT_API: ComponentApi = ComponentApi {\n    id: \"tabs-content\",\n    description: \"Tabbed navigation\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: true, default: None, description: \"Current value\" },\n        PropDef { name: \"active\", kind: PropType::String, required: false, default: Some(\"inactive\"), description: \"Active/selected state\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::tabs_boundary::{TabsRoot, TabsListBoundary, TabsTrigger, TabsContent};\n\n#[component]\npub fn TabsShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <TabsRoot>\n                    <TabsListBoundary>\n                        <TabsTrigger value=\"overview\">\"Overview\"</TabsTrigger>\n                        <TabsTrigger value=\"api\">\"API\"</TabsTrigger>\n                        <TabsTrigger value=\"examples\">\"Examples\"</TabsTrigger>\n                    </TabsListBoundary>\n                    <TabsContent value=\"overview\">\"Overview content — structure drives state.\"</TabsContent>\n                    <TabsContent value=\"api\">\"API reference content.\"</TabsContent>\n                    <TabsContent value=\"examples\">\"Examples content.\"</TabsContent>\n                </TabsRoot>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Tab selection governed by DOM — SSR-safe, hydration-safe.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"With disabled tab\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <TabsRoot>\n                        <TabsListBoundary>\n                            <TabsTrigger value=\"x\">\"Active\"</TabsTrigger>\n                            <TabsTrigger value=\"y\" disabled=true>\"Disabled\"</TabsTrigger>\n                            <TabsTrigger value=\"z\">\"Normal\"</TabsTrigger>\n                        </TabsListBoundary>\n                        <TabsContent value=\"x\">\"Active content.\"</TabsContent>\n                        <TabsContent value=\"y\">\"Disabled content.\"</TabsContent>\n                        <TabsContent value=\"z\">\"Normal content.\"</TabsContent>\n                    </TabsRoot>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "textarea",
    "label": "Textarea",
    "category": "Form",
    "description": "Multi-line text input",
    "keywords": "",
    "pain": "Textarea misses required, readonly and aria attributes consistency",
    "promise": "All form states mapped directly to DOM and ARIA",
    "why": "TextareaPrimitive encodes disabled, readonly and required into both DOM and ARIA attributes. Label and description linkage is explicit. This guarantees accessible multi-line input behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <textarea placeholder=\"Type...\"></textarea>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Textarea placeholder=\"Type...\" required=true />\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "comments",
      "descriptions"
    ],
    "related": [
      "form",
      "input",
      "input_group",
      "input_otp",
      "field",
      "label",
      "checkbox",
      "form_error_summary"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "form",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Textarea Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[component]\npub fn TextareaPrimitive(\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = false)] readonly: bool,\n    #[prop(default = false)] required: bool,\n    #[prop(into, optional)] aria_labelledby: Option<String>,\n    #[prop(into, optional)] aria_describedby: Option<String>,\n    #[prop(optional)] rows: Option<u32>,\n) -> impl IntoView {\n    let uid_ta2 = crate::infra::uid::generate(\"ta2\");\n    view! {\n        <textarea\n            data-rs-textarea=\"\"\n            data-rs-uid=uid_ta2\n            data-rs-interaction=\"init\"\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-readonly={if readonly { Some(\"\") } else { None }}\n            data-rs-required={if required { Some(\"\") } else { None }}\n            prop:value=value\n            placeholder={if placeholder.is_empty() { None } else { Some(placeholder) }}\n            name={if name.is_empty() { None } else { Some(name) }}\n            disabled=disabled.disabled()\n            aria-disabled=disabled.aria_disabled()\n            readonly=readonly\n            aria-readonly={if readonly { Some(\"true\") } else { None }}\n            aria-required={if required { Some(\"true\") } else { None }}\n            aria-labelledby=aria_labelledby\n            aria-describedby=aria_describedby\n            rows=rows\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::TextareaPrimitive;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Textarea(\n    #[prop(into, default = String::new())] value: String,\n    #[prop(into, default = String::new())] placeholder: String,\n    #[prop(into, default = String::new())] name: String,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = false)] readonly: bool,\n    #[prop(default = false)] required: bool,\n    #[prop(optional)] aria_labelledby: Option<String>,\n    #[prop(optional)] aria_describedby: Option<String>,\n    #[prop(optional)] rows: Option<u32>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TextareaPrimitive\n            value=value\n            placeholder=placeholder\n            name=name\n            disabled=disabled\n            readonly=readonly\n            required=required\n            aria_labelledby=aria_labelledby.unwrap_or_default()\n            aria_describedby=aria_describedby.unwrap_or_default()\n            rows=rows.unwrap_or(3)\n            class=class\n        />\n    }\n}\n\n",
    "boundary_src": "//! Textarea Island — Canon Rule #340\n//! Passthrough only. Zero logic, zero transformation.\n\nuse leptos::prelude::*;\nuse super::textarea_ui::Textarea as TextareaUi;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn Textarea(\n    #[prop(into, default = String::new())] value:            String,\n    #[prop(into, default = String::new())] placeholder:      String,\n    #[prop(into, default = String::new())] name:             String,\n    #[prop(default = DisabledState::Enabled)] disabled:      DisabledState,\n    #[prop(default = false)] readonly:                       bool,\n    #[prop(default = false)] required:                       bool,\n    #[prop(into, default = String::new())] aria_labelledby:  String,\n    #[prop(into, default = String::new())] aria_describedby: String,\n    #[prop(default = 3u32)] rows:                            u32,\n    #[prop(into, default = String::new())] class:            String,\n) -> impl IntoView {\n    view! {\n        <TextareaUi\n            value=value\n            placeholder=placeholder\n            name=name\n            disabled=disabled\n            readonly=readonly\n            required=required\n            aria_labelledby=aria_labelledby\n            aria_describedby=aria_describedby\n            rows=rows\n            class=class\n        />\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const TEXTAREA_API: ComponentApi = ComponentApi {\n    id: \"textarea\",\n    description: \"Multi-line text input\",\n    props: &[\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"placeholder\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Placeholder text\" },\n        PropDef { name: \"name\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Form field name\" },\n        PropDef { name: \"disabled\", kind: PropType::String, required: false, default: Some(\"enabled\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"readonly\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"required\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"aria_labelledby\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"aria_describedby\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"rows\", kind: PropType::Number, required: false, default: Some(\"3u32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use super::textarea_boundary::Textarea;\nuse leptos::prelude::*;\nuse canonrs_core::meta::DisabledState;\n\n#[component]\npub fn TextareaShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Textarea placeholder=\"Type here...\" rows=3 />\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"All form states mapped directly to DOM and ARIA.\"\n            </p>\n\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Variants\"</span>\n                <div data-rs-preview-dev-grid=\"\">\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Default\"</span>\n                        <Textarea placeholder=\"Default\" rows=2 />\n                    </div>\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Success\"</span>\n                        <Textarea placeholder=\"Success\" rows=2 />\n                    </div>\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Warning\"</span>\n                        <Textarea placeholder=\"Warning\" rows=2 />\n                    </div>\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Error\"</span>\n                        <Textarea placeholder=\"Error\" rows=2 />\n                    </div>\n                </div>\n            </div>\n\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Rows\"</span>\n                <div data-rs-preview-dev-grid=\"\">\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"2 rows\"</span>\n                        <Textarea placeholder=\"2 rows\" rows=2 />\n                    </div>\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"5 rows\"</span>\n                        <Textarea placeholder=\"5 rows\" rows=5 />\n                    </div>\n                </div>\n            </div>\n\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <div data-rs-preview-dev-grid=\"\">\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Readonly\"</span>\n                        <Textarea placeholder=\"Readonly\" readonly=true rows=2 />\n                    </div>\n                    <div data-rs-showcase-preview-section=\"\">\n                        <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                        <Textarea placeholder=\"Disabled\" disabled=DisabledState::Disabled rows=2 />\n                    </div>\n                </div>\n            </div>\n\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "toast",
    "label": "Toast",
    "category": "Feedback",
    "description": "Toast notification message",
    "keywords": "",
    "pain": "Notifications misuse urgency, role and lifecycle behavior",
    "promise": "Variant enforces correct role and aria-live automatically",
    "why": "ToastVariant defines role and aria-live behavior per type. Lifecycle and visibility are encoded structurally. This guarantees correct notification semantics and timing.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"toast error\">\"Error\"</div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Toast variant=ToastVariant::Error>\n    <ToastTitle>\"Error\"</ToastTitle>\n  </Toast>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "system notifications",
      "user feedback"
    ],
    "related": [
      "alert",
      "banner",
      "callout",
      "inline_notice",
      "status_dot"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "feedback",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Toast Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum ToastVariant {\n    #[default]\n    Default,\n    Success,\n    Warning,\n    Error,\n    Info,\n}\n\nimpl ToastVariant {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Default => \"default\",\n            Self::Success => \"success\",\n            Self::Warning => \"warning\",\n            Self::Error => \"error\",\n            Self::Info => \"info\",\n        }\n    }\n    pub fn aria_live(&self) -> &'static str {\n        match self { Self::Error | Self::Warning => \"assertive\", _ => \"polite\" }\n    }\n    pub fn role(&self) -> &'static str {\n        match self { Self::Error | Self::Warning => \"alert\", _ => \"status\" }\n    }\n}\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum ToastLifecycle {\n    #[default]\n    Open,\n    Closing,\n    Closed,\n}\n\nimpl ToastLifecycle {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Open => \"open\", Self::Closing => \"closing\", Self::Closed => \"closed\" }\n    }\n}\n\n#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]\npub enum ToastPosition {\n    #[default]\n    TopRight,\n    TopLeft,\n    BottomRight,\n    BottomLeft,\n    TopCenter,\n    BottomCenter,\n}\n\nimpl ToastPosition {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::TopRight => \"top-right\",\n            Self::TopLeft => \"top-left\",\n            Self::BottomRight => \"bottom-right\",\n            Self::BottomLeft => \"bottom-left\",\n            Self::TopCenter => \"top-center\",\n            Self::BottomCenter => \"bottom-center\",\n        }\n    }\n}\n\n#[component]\npub fn ToastPrimitive(\n    children: Children,\n    #[prop(default = ToastVariant::Default)] variant: ToastVariant,\n    #[prop(default = VisibilityState::Open)] state: VisibilityState,\n    #[prop(default = ToastLifecycle::Open)] lifecycle: ToastLifecycle,\n    #[prop(into, optional)] title_id: Option<String>,\n    #[prop(into, optional)] description_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_ts = crate::infra::uid::generate(\"ts\");\n    view! {\n        <div\n            data-rs-toast=\"\"\n            data-rs-uid=uid_ts\n            data-rs-interaction=\"init\"\n            data-rs-variant=variant.as_str()\n            data-rs-state=state.as_str()\n            data-rs-lifecycle=lifecycle.as_str()\n            role=variant.role()\n            aria-live=variant.aria_live()\n            aria-atomic=\"true\"\n            aria-labelledby=title_id\n            aria-describedby=description_id\n            hidden=state.hidden()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToastViewportPrimitive(\n    children: Children,\n    #[prop(default = ToastPosition::TopRight)] position: ToastPosition,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-toast-viewport=\"\"\n            data-rs-position=position.as_str()\n            aria-label=\"Notifications\"\n            role=\"region\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToastTitlePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-toast-title=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToastDescriptionPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-toast-description=\"\" class=class>\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToastActionPrimitive(\n    children: Children,\n    #[prop(into)] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-toast-action=\"\"\n            aria-label=aria_label\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n\n#[component]\npub fn ToastClosePrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <button\n            type=\"button\"\n            data-rs-toast-close=\"\"\n            aria-label=\"Close notification\"\n            class=class\n        >\n            {children()}\n        </button>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    ToastPrimitive, ToastViewportPrimitive,\n    ToastTitlePrimitive, ToastDescriptionPrimitive,\n    ToastActionPrimitive, ToastClosePrimitive,\n};\npub use canonrs_core::primitives::ToastVariant;\n\n#[component]\npub fn Toast(\n    children: Children,\n    #[prop(default = ToastVariant::Default)] variant: ToastVariant,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastPrimitive variant=variant class=class>\n            {children()}\n        </ToastPrimitive>\n    }\n}\n\n#[component]\npub fn ToastViewport(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastViewportPrimitive class=class>\n            {children()}\n        </ToastViewportPrimitive>\n    }\n}\n\n#[component]\npub fn ToastTitle(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastTitlePrimitive class=class>\n            {children()}\n        </ToastTitlePrimitive>\n    }\n}\n\n#[component]\npub fn ToastDescription(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastDescriptionPrimitive class=class>\n            {children()}\n        </ToastDescriptionPrimitive>\n    }\n}\n\n#[component]\npub fn ToastAction(\n    children: Children,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastActionPrimitive aria_label=aria_label class=class>\n            {children()}\n        </ToastActionPrimitive>\n    }\n}\n\n#[component]\npub fn ToastClose(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastClosePrimitive class=class>\n            {children()}\n        </ToastClosePrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Toast Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::toast_ui::{\n    Toast as ToastUi,\n    ToastViewport as ToastViewportUi\n};\npub use canonrs_core::primitives::ToastVariant;\n\n#[allow(unused_variables)]\n#[component]\npub fn Toast(\n    #[prop(into, optional)] title: Option<String>,\n    #[prop(into, optional)] description: Option<String>,\n    #[prop(default = ToastVariant::Default)] variant: ToastVariant,\n    #[prop(default = 5000u32)] duration_ms: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToastUi variant=variant class=class>\n            {title.map(|t| view! { <p data-rs-toast-title=\"\">{t}</p> })}\n            {description.map(|d| view! { <p data-rs-toast-description=\"\">{d}</p> })}\n        </ToastUi>\n    }\n}\n\n#[component]\npub fn ToastViewport(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <ToastViewportUi class=class>{children()}</ToastViewportUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ToastVariant}; \n\npub const TOAST_API: ComponentApi = ComponentApi {\n    id: \"toast\",\n    description: \"Toast notification message\",\n    props: &[\n        PropDef { name: \"title\", kind: PropType::String, required: false, default: None, description: \"Title slot or text\" },\n        PropDef { name: \"description\", kind: PropType::String, required: false, default: None, description: \"Description slot or text\" },\n        PropDef { name: \"variant\", kind: PropType::Enum(&[\"default\", \"success\", \"warning\", \"error\", \"info\"]), required: false, default: Some(\"default\"), description: \"Visual variant of the component\" },\n        PropDef { name: \"duration_ms\", kind: PropType::Number, required: false, default: Some(\"5000u32\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOASTVIEWPORT_API: ComponentApi = ComponentApi {\n    id: \"toast-viewport\",\n    description: \"Toast notification message\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::toast_boundary::{Toast, ToastVariant};\n\n#[component]\npub fn ToastShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <div style=\"display:flex;flex-direction:column;gap:var(--space-sm);\">\n                    <Toast title=\"Notification\" description=\"Your settings have been saved.\" duration_ms=60000 />\n                    <Toast variant=ToastVariant::Success title=\"Success\" description=\"File uploaded.\" duration_ms=60000 />\n                    <Toast variant=ToastVariant::Error title=\"Error\" description=\"Something went wrong.\" duration_ms=60000 />\n                    <Toast variant=ToastVariant::Warning title=\"Warning\" description=\"Session expires soon.\" duration_ms=60000 />\n                </div>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Variant enforces correct role and aria-live automatically.\"\n            </p>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "toggle",
    "label": "Toggle",
    "category": "Form",
    "description": "Toggle button",
    "keywords": "",
    "pain": "Toggle buttons desync pressed state and visual representation",
    "promise": "Pressed state mapped directly to DOM and interaction state",
    "why": "TogglePrimitive maps ToggleState to data-rs-state and checkbox checked state. Disabled and aria-label are enforced. This guarantees consistent toggle behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <button class=\"active\">\"On\"</button>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Toggle pressed=true>\"On\"</Toggle>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "formatting tools",
      "feature toggles"
    ],
    "related": [
      "switch",
      "toggle_group"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "toggle",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Toggle Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{ToggleState, DisabledState};\n\n\n#[component]\npub fn TogglePrimitive(\n    children: Children,\n    #[prop(default = ToggleState::Off)] pressed: ToggleState,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_tog = crate::infra::uid::generate(\"tog\");\n    view! {\n        <label\n            data-rs-toggle=\"\"\n            data-rs-uid=uid_tog\n            data-rs-interaction=\"init\"\n            data-rs-pressed=pressed.as_str()\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            aria-label=if aria_label.is_empty() { None } else { Some(aria_label) }\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            <input\n                type=\"checkbox\"\n                data-rs-toggle-input=\"\"\n                checked=pressed.as_str() == \"on\"\n                tabindex=\"-1\"\n            />\n            <span data-rs-toggle-content=\"\">\n                {children()}\n            </span>\n        </label>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::TogglePrimitive;\n\n#[component]\npub fn Toggle(children: Children, #[prop(into, default = String::new())] class: String, #[prop(default = false)] pressed: bool, #[prop(default = false)] disabled: bool, #[prop(into, default = String::new())] aria_label: String) -> impl IntoView {\n    view! {\n        <TogglePrimitive class=class pressed=pressed.into() disabled=disabled.into() aria_label=aria_label>\n            {children()}\n        </TogglePrimitive>\n    }\n}\n",
    "boundary_src": "//! @canon-level: strict\n//! Toggle Island — Canon Rule #340 (zero-logic boundary)\n\nuse leptos::prelude::*;\nuse super::toggle_ui::Toggle as ToggleUi;\n\n#[component]\npub fn Toggle(\n    children: Children,\n    #[prop(default = false)] pressed: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] aria_label: String,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToggleUi pressed=pressed disabled=disabled aria_label=aria_label class=class>\n            {children()}\n        </ToggleUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const TOGGLE_API: ComponentApi = ComponentApi {\n    id: \"toggle\",\n    description: \"Toggle button\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"pressed\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::toggle_boundary::Toggle;\n\n#[component]\npub fn ToggleShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Toggle><span>{\"Bold\"}</span></Toggle>\n                <Toggle pressed=true><span>{\"Italic\"}</span></Toggle>\n                <Toggle><span>{\"Underline\"}</span></Toggle>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Pressed state mapped directly to DOM and interaction state.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"States\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Toggle><span>{\"Unpressed\"}</span></Toggle>\n                    <Toggle pressed=true><span>{\"Pressed\"}</span></Toggle>\n                    <Toggle disabled=true><span>{\"Disabled\"}</span></Toggle>\n                    <Toggle pressed=true disabled=true><span>{\"Disabled On\"}</span></Toggle>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "toggle_group",
    "label": "Toggle Group",
    "category": "Action",
    "description": "Group of toggle buttons",
    "keywords": "",
    "pain": "Grouped toggles lack exclusivity and shared disabled state",
    "promise": "Group behavior and selection mode enforced structurally",
    "why": "ToggleGroupPrimitive encodes multiple selection and disabled state at container level. Child toggles inherit behavior. This guarantees consistent grouped interactions.\n",
    "before": "// ❌ Typical\nview! {\n  <div>\n    <button>\"A\"</button>\n    <button>\"B\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <ToggleGroup multiple=false>\n    <Toggle>\"A\"</Toggle>\n  </ToggleGroup>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "toolbars",
      "option groups"
    ],
    "related": [
      "switch",
      "toggle"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "toggle",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! ToggleGroup Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::DisabledState;\n\n#[component]\npub fn ToggleGroupPrimitive(\n    children: Children,\n    #[prop(default = false)] multiple: bool,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    let uid_tg = crate::infra::uid::generate(\"tg\");\n    let is_disabled = disabled == DisabledState::Disabled;\n\n    view! {\n        <div\n            data-rs-toggle-group=\"\"\n            data-rs-uid=uid_tg\n            data-rs-interaction=\"selection\"\n            data-rs-multiple=if multiple { \"true\" } else { \"false\" }\n            data-rs-disabled=if is_disabled { Some(\"disabled\") } else { None }\n            role=\"group\"\n            aria-disabled=if is_disabled { \"true\" } else { \"false\" }\n            class=class\n            node_ref=node_ref.unwrap_or_default()\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::meta::DisabledState;\nuse canonrs_core::primitives::ToggleGroupPrimitive;\n\n#[component]\npub fn ToggleGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(default = false)] multiple: bool,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(optional)] node_ref: Option<NodeRef<leptos::html::Div>>,\n) -> impl IntoView {\n    view! {\n        <ToggleGroupPrimitive class=class multiple=multiple disabled=disabled node_ref=node_ref.unwrap_or_default()>\n            {children()}\n        </ToggleGroupPrimitive>\n    }\n}\n",
    "boundary_src": "//! ToggleGroup Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::toggle_group_ui::ToggleGroup as ToggleGroupUi;\n\n#[component]\npub fn ToggleGroup(\n    children: Children,\n    #[prop(default = false)] multiple: bool,\n    #[prop(default = false)] disabled: bool,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let state = if disabled { \"disabled\"\n} else { \"\" };\n    view! {\n        <ToggleGroupUi multiple=multiple class=class attr:data-rs-state=state>\n            {children()}\n        </ToggleGroupUi>\n    }\n}\n\n#[component]\npub fn ToggleGroupItem(\n    children: Children,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = false)] on: bool,\n    #[prop(default = false)] disabled: bool,\n) -> impl IntoView {\n    let state = if disabled {\n        format!(\"{} disabled\", if on { \"on\" } else { \"off\" })\n    } else {\n        if on { \"on\".into() } else { \"off\".into() }\n    };\n    view! {\n        <button\n            type=\"button\"\n            data-rs-toggle=\"\"\n            data-rs-component=\"Toggle\"\n            data-rs-value=value\n            data-rs-state=state\n            aria-pressed=if on { \"true\" } else { \"false\" }\n            role=\"button\"\n        >\n            {children()}\n        </button>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const TOGGLEGROUP_API: ComponentApi = ComponentApi {\n    id: \"toggle-group\",\n    description: \"Group of toggle buttons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"multiple\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOGGLEGROUPITEM_API: ComponentApi = ComponentApi {\n    id: \"toggle-group-item\",\n    description: \"Group of toggle buttons\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"on\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::toggle_group_boundary::{ToggleGroup, ToggleGroupItem};\n\n#[component]\npub fn ToggleGroupShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <ToggleGroup>\n                    <ToggleGroupItem value=\"left\" on=true>\"Left\"</ToggleGroupItem>\n                    <ToggleGroupItem value=\"center\">\"Center\"</ToggleGroupItem>\n                    <ToggleGroupItem value=\"right\">\"Right\"</ToggleGroupItem>\n                </ToggleGroup>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Group behavior and selection mode enforced structurally.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Multiple selection\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <ToggleGroup multiple=true>\n                        <ToggleGroupItem value=\"bold\" on=true>\"Bold\"</ToggleGroupItem>\n                        <ToggleGroupItem value=\"italic\" on=true>\"Italic\"</ToggleGroupItem>\n                        <ToggleGroupItem value=\"underline\">\"Underline\"</ToggleGroupItem>\n                        <ToggleGroupItem value=\"strike\">\"Strike\"</ToggleGroupItem>\n                    </ToggleGroup>\n                </div>\n            </div>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Disabled\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <ToggleGroup disabled=true>\n                        <ToggleGroupItem value=\"a\">\"Option A\"</ToggleGroupItem>\n                        <ToggleGroupItem value=\"b\">\"Option B\"</ToggleGroupItem>\n                    </ToggleGroup>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex",
      "stack"
    ]
  },
  {
    "id": "toolbar",
    "label": "Toolbar",
    "category": "Layout",
    "description": "Action toolbar component",
    "keywords": "",
    "pain": "Action groups lack orientation and accessibility semantics",
    "promise": "Toolbar role and orientation enforced via contract",
    "why": "ToolbarPrimitive encodes orientation and role=\"toolbar\". ARIA labeling is explicit. This guarantees accessible grouping of actions.\n",
    "before": "// ❌ Typical\nview! {\n  <div class=\"toolbar\">\n    <button>\"Bold\"</button>\n  </div>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Toolbar aria_label=\"Editor\">\n    <button>\"Bold\"</button>\n  </Toolbar>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "editors",
      "action bars"
    ],
    "related": [
      "card",
      "resizable",
      "scroll_area",
      "aspect_ratio",
      "page_header",
      "separator"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift"
    ],
    "pillar": "layout",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Toolbar Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum ToolbarOrientation {\n    #[default]\n    Horizontal,\n    Vertical,\n}\n\nimpl ToolbarOrientation {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Horizontal => \"horizontal\",\n            Self::Vertical   => \"vertical\",\n        }\n    }\n}\n\n#[component]\npub fn ToolbarPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(default = ToolbarOrientation::Horizontal)] orientation: ToolbarOrientation,\n) -> impl IntoView {\n    let uid = if uid.is_empty() { crate::infra::uid::generate(\"tb2\") } else { uid };\n    view! {\n        <div\n            data-rs-toolbar=\"\"\n            data-rs-uid=uid\n            data-rs-interaction=\"nav\"\n            data-rs-variant=orientation.as_str()\n            role=\"toolbar\"\n            aria-label=aria_label\n            aria-orientation=orientation.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToolbarSeparatorPrimitive(\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-toolbar-separator=\"\"\n            role=\"separator\"\n            aria-orientation=\"vertical\"\n            class=class\n        />\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{ToolbarPrimitive, ToolbarSeparatorPrimitive, ToolbarOrientation};\n\n#[component]\npub fn Toolbar(\n    children: Children,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into)] aria_label: String,\n    #[prop(default = ToolbarOrientation::Horizontal)] orientation: ToolbarOrientation,\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToolbarPrimitive\n            uid=uid\n            class=class\n            aria_label=aria_label\n            orientation=orientation\n        >\n            {children()}\n        </ToolbarPrimitive>\n    }\n}\n\n#[component]\npub fn ToolbarSeparator(\n    #[prop(default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToolbarSeparatorPrimitive class=class />\n    }\n}\n",
    "boundary_src": "//! Toolbar Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::toolbar_ui::{\n    Toolbar as ToolbarUi,\n    ToolbarSeparator as ToolbarSeparatorUi\n};\npub use canonrs_core::primitives::ToolbarOrientation;\n\n#[component]\npub fn Toolbar(\n    children: Children,\n    #[prop(into, default = String::new())] uid: String,\n    #[prop(into, default = String::from(\"Toolbar\"))] aria_label: String,\n    #[prop(default = ToolbarOrientation::Horizontal)] orientation: ToolbarOrientation,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <ToolbarUi uid=uid aria_label=aria_label orientation=orientation class=class>\n            {children()}\n        </ToolbarUi>\n    }\n}\n\n#[component]\npub fn ToolbarItem(\n    children: Children,\n    #[prop(into, default = String::new())] value: String,\n    #[prop(default = false)] disabled: bool,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-toolbar-item=\"\"\n            data-rs-value=value\n            tabindex=\"-1\"\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn ToolbarSeparator() -> impl IntoView {\n    view! { <ToolbarSeparatorUi /> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{ToolbarOrientation}; \n\npub const TOOLBAR_API: ComponentApi = ComponentApi {\n    id: \"toolbar\",\n    description: \"Action toolbar component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"uid\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Prop value\" },\n        PropDef { name: \"aria_label\", kind: PropType::String, required: false, default: Some(\"Toolbar\"), description: \"Accessible label for screen readers\" },\n        PropDef { name: \"orientation\", kind: PropType::Enum(&[\"horizontal\", \"vertical\"]), required: false, default: Some(\"horizontal\"), description: \"Horizontal or vertical orientation\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOOLBARITEM_API: ComponentApi = ComponentApi {\n    id: \"toolbar-item\",\n    description: \"Action toolbar component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"value\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Current value\" },\n        PropDef { name: \"disabled\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Whether the component is disabled\" },\n    ],\n};\n\npub const TOOLBARSEPARATOR_API: ComponentApi = ComponentApi {\n    id: \"toolbar-separator\",\n    description: \"Action toolbar component\",\n    props: &[\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::toolbar_boundary::{Toolbar, ToolbarItem, ToolbarSeparator, ToolbarOrientation};\n\n#[component]\npub fn ToolbarShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\" style=\"width:100%;\">\n                <Toolbar aria_label=\"Text formatting\">\n                    <ToolbarItem value=\"bold\">\"B\"</ToolbarItem>\n                    <ToolbarItem value=\"italic\">\"I\"</ToolbarItem>\n                    <ToolbarItem value=\"underline\">\"U\"</ToolbarItem>\n                    <ToolbarSeparator />\n                    <ToolbarItem value=\"left\">\"←\"</ToolbarItem>\n                    <ToolbarItem value=\"center\">\"↔\"</ToolbarItem>\n                    <ToolbarItem value=\"right\">\"→\"</ToolbarItem>\n                    <ToolbarSeparator />\n                    <ToolbarItem value=\"link\">\"🔗\"</ToolbarItem>\n                </Toolbar>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Toolbar role and orientation enforced via contract.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Vertical\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <Toolbar aria_label=\"Actions\" orientation=ToolbarOrientation::Vertical>\n                        <ToolbarItem value=\"cut\">\"✂\"</ToolbarItem>\n                        <ToolbarItem value=\"copy\">\"⎘\"</ToolbarItem>\n                        <ToolbarItem value=\"paste\">\"📋\"</ToolbarItem>\n                        <ToolbarSeparator />\n                        <ToolbarItem value=\"delete\">\"🗑\"</ToolbarItem>\n                    </Toolbar>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "flex"
    ]
  },
  {
    "id": "tooltip",
    "label": "Tooltip",
    "category": "Overlay",
    "description": "Hover tooltip",
    "keywords": "",
    "pain": "Tooltip requires id wiring and loses sync between trigger and content",
    "promise": "Trigger-content relationship enforced without manual wiring",
    "why": "TooltipPrimitive uses visibility state and DOM structure instead of ids. aria-describedby is optional but supported. This guarantees consistent overlay behavior.\n",
    "before": "// ❌ Typical\nview! {\n  <span title=\"Info\">\"Hover\"</span>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Tooltip>\n    <TooltipTrigger>\"Hover\"</TooltipTrigger>\n    <TooltipContent>\"Info\"</TooltipContent>\n  </Tooltip>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "hints",
      "help text"
    ],
    "related": [
      "dialog",
      "alert_dialog",
      "drawer",
      "sheet",
      "modal",
      "confirm_dialog",
      "hover_card",
      "popover"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "overlay",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Tooltip Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::VisibilityState;\n\n#[derive(Debug, Clone, Copy, PartialEq, Default)]\npub enum TooltipSide {\n    #[default]\n    Top,\n    Bottom,\n    Left,\n    Right,\n}\n\nimpl TooltipSide {\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            Self::Top => \"top\",\n            Self::Bottom => \"bottom\",\n            Self::Left => \"left\",\n            Self::Right => \"right\",\n        }\n    }\n}\n\n\n#[component]\npub fn TooltipPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_tip = crate::infra::uid::generate(\"tip\");\n    view! {\n        <div\n            data-rs-tooltip=\"\"\n            data-rs-uid=uid_tip\n            data-rs-interaction=\"init\"\n            data-rs-state=state.as_str()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n// Trigger é span — tooltip funciona em qualquer elemento\n#[component]\npub fn TooltipTriggerPrimitive(\n    children: Children,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <span\n            data-rs-tooltip-trigger=\"\"\n            aria-describedby=tooltip_id\n            tabindex=\"0\"\n            class=class\n        >\n            {children()}\n        </span>\n    }\n}\n\n#[component]\npub fn TooltipContentPrimitive(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = TooltipSide::Top)] side: TooltipSide,\n    #[prop(default = true)] arrow: bool,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-tooltip-content=\"\"\n            data-rs-state=state.as_str()\n            data-rs-side=side.as_str()\n            id=tooltip_id\n            role=\"tooltip\"\n            class=class\n        >\n            {children()}\n            {arrow.then(|| view! { <span data-rs-tooltip-arrow=\"\" /> })}\n        </div>\n    }\n}\n\n#[component]\npub fn TooltipProviderPrimitive(\n    children: Children,\n    #[prop(default = 400)] delay_open: u32,\n    #[prop(default = 100)] delay_close: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-tooltip-provider=\"\"\n            data-rs-delay-open=delay_open.to_string()\n            data-rs-delay-close=delay_close.to_string()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    TooltipProviderPrimitive, TooltipPrimitive,\n    TooltipTriggerPrimitive, TooltipContentPrimitive, TooltipSide,\n};\nuse canonrs_core::meta::VisibilityState;\n\n#[component]\npub fn TooltipProvider(\n    children: Children,\n    #[prop(default = 400)] delay_open: u32,\n    #[prop(default = 100)] delay_close: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TooltipProviderPrimitive delay_open=delay_open delay_close=delay_close class=class>\n            {children()}\n        </TooltipProviderPrimitive>\n    }\n}\n\n#[component]\npub fn Tooltip(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TooltipPrimitive state=state class=class>\n            {children()}\n        </TooltipPrimitive>\n    }\n}\n\n#[component]\npub fn TooltipTrigger(\n    children: Children,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TooltipTriggerPrimitive tooltip_id=tooltip_id.unwrap_or_default() class=class>\n            {children()}\n        </TooltipTriggerPrimitive>\n    }\n}\n\n#[component]\npub fn TooltipContent(\n    children: Children,\n    #[prop(default = VisibilityState::Closed)] state: VisibilityState,\n    #[prop(default = TooltipSide::Top)] side: TooltipSide,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <TooltipContentPrimitive state=state side=side tooltip_id=tooltip_id.unwrap_or_default() class=class>\n            {children()}\n        </TooltipContentPrimitive>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! Tooltip Island — Canon Rule #340 (zero-logic boundary)\n//! CR-342 v3.0.0: interaction delegated to canonrs-interactions-overlay\n\nuse leptos::prelude::*;\nuse super::tooltip_ui::{\n    TooltipProvider as TooltipProviderUi,\n    Tooltip as TooltipUi,\n    TooltipTrigger as TooltipTriggerUi,\n    TooltipContent as TooltipContentUi\n};\npub use canonrs_core::primitives::TooltipSide;\n\n#[component]\npub fn TooltipProvider(\n    children: Children,\n    #[prop(default = 400)] delay_open: u32,\n    #[prop(default = 100)] delay_close: u32,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TooltipProviderUi delay_open=delay_open delay_close=delay_close class=class>{children()}</TooltipProviderUi> }\n}\n\n#[component]\npub fn Tooltip(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TooltipUi class=class>{children()}</TooltipUi> }\n}\n\n#[component]\npub fn TooltipTrigger(\n    children: Children,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let tooltip_id = tooltip_id.unwrap_or_default();\n    view! { <TooltipTriggerUi tooltip_id=tooltip_id class=class>{children()}</TooltipTriggerUi> }\n}\n\n#[component]\npub fn TooltipContent(\n    children: Children,\n    #[prop(default = TooltipSide::Top)] side: TooltipSide,\n    #[prop(into, optional)] tooltip_id: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let tooltip_id = tooltip_id.unwrap_or_default();\n    view! { <TooltipContentUi side=side tooltip_id=tooltip_id class=class>{children()}</TooltipContentUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\n// imports: use canonrs::primitives::{TooltipSide}; \n\npub const TOOLTIPPROVIDER_API: ComponentApi = ComponentApi {\n    id: \"tooltip-provider\",\n    description: \"Hover tooltip\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"delay_open\", kind: PropType::Number, required: false, default: Some(\"400\"), description: \"Delay in ms before opening\" },\n        PropDef { name: \"delay_close\", kind: PropType::Number, required: false, default: Some(\"100\"), description: \"Delay in ms before closing\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOOLTIP_API: ComponentApi = ComponentApi {\n    id: \"tooltip\",\n    description: \"Hover tooltip\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOOLTIPTRIGGER_API: ComponentApi = ComponentApi {\n    id: \"tooltip-trigger\",\n    description: \"Hover tooltip\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"tooltip_id\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TOOLTIPCONTENT_API: ComponentApi = ComponentApi {\n    id: \"tooltip-content\",\n    description: \"Hover tooltip\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"side\", kind: PropType::Enum(&[\"top\", \"bottom\", \"left\", \"right\"]), required: false, default: Some(\"top\"), description: \"Tooltip or popover side\" },\n        PropDef { name: \"tooltip_id\", kind: PropType::String, required: false, default: None, description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::tooltip_boundary::{TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, TooltipSide};\n\n#[component]\npub fn TooltipShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <TooltipProvider>\n                    <Tooltip>\n                        <TooltipTrigger tooltip_id=\"tt-1\">\"Hover me\"</TooltipTrigger>\n                        <TooltipContent tooltip_id=\"tt-1\">\"Tooltip content\"</TooltipContent>\n                    </Tooltip>\n                </TooltipProvider>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Tooltip appears on hover and focus with configurable delay.\"\n            </p>\n            <div data-rs-showcase-preview-section=\"\">\n                <span data-rs-showcase-preview-label=\"\">\"Sides\"</span>\n                <div data-rs-showcase-preview-row=\"\">\n                    <TooltipProvider>\n                        <Tooltip>\n                            <TooltipTrigger tooltip_id=\"tt-top\">\"Top\"</TooltipTrigger>\n                            <TooltipContent side=TooltipSide::Top tooltip_id=\"tt-top\">\"Opens above\"</TooltipContent>\n                        </Tooltip>\n                    </TooltipProvider>\n                    <TooltipProvider>\n                        <Tooltip>\n                            <TooltipTrigger tooltip_id=\"tt-bottom\">\"Bottom\"</TooltipTrigger>\n                            <TooltipContent side=TooltipSide::Bottom tooltip_id=\"tt-bottom\">\"Opens below\"</TooltipContent>\n                        </Tooltip>\n                    </TooltipProvider>\n                    <TooltipProvider>\n                        <Tooltip>\n                            <TooltipTrigger tooltip_id=\"tt-right\">\"Right\"</TooltipTrigger>\n                            <TooltipContent side=TooltipSide::Right tooltip_id=\"tt-right\">\"Opens right\"</TooltipContent>\n                        </Tooltip>\n                    </TooltipProvider>\n                </div>\n            </div>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "tree",
    "label": "Tree",
    "category": "Display",
    "description": "Tree view component",
    "keywords": "",
    "pain": "Tree structures lose selection, expansion and focus consistency",
    "promise": "Hierarchy state fully governed via structured attributes",
    "why": "TreePrimitive and TreeItemPrimitive encode selection, focus and expansion via data attributes. ARIA roles are enforced. This guarantees accessible hierarchical navigation.\n",
    "before": "// ❌ Typical\nview! {\n  <ul>\n    <li>\"Item\"</li>\n  </ul>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <Tree>\n    <TreeItem has_children=true>\"Item\"</TreeItem>\n  </Tree>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "file explorers",
      "nested navigation"
    ],
    "related": [
      "table",
      "data_table",
      "virtual_list",
      "empty_table",
      "list_item"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "data",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! Tree Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\nuse crate::meta::{SelectionState, DisabledState, ActivityState};\n\n#[derive(Clone, Copy, PartialEq, Default, Debug)]\npub enum TreeSelectionMode {\n    #[default]\n    Single,\n    Multiple,\n}\nimpl TreeSelectionMode {\n    pub fn as_str(&self) -> &'static str {\n        match self { Self::Single => \"single\", Self::Multiple => \"multiple\" }\n    }\n    pub fn aria_multiselectable(&self) -> Option<&'static str> {\n        match self { Self::Multiple => Some(\"true\"), Self::Single => None }\n    }\n}\n\n\n\n\n\n\n\n\n\n\n#[component]\npub fn TreePrimitive(\n    children: Children,\n    #[prop(default = TreeSelectionMode::Single)] selection: TreeSelectionMode,\n    #[prop(into, optional)] aria_label: Option<String>,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_tr = crate::infra::uid::generate(\"tr\");\n    view! {\n        <div\n            data-rs-tree=\"\"\n            data-rs-uid=uid_tr\n            data-rs-interaction=\"selection\"\n            data-rs-selection=selection.as_str()\n            role=\"tree\"\n            aria-label=aria_label\n            aria-multiselectable=selection.aria_multiselectable()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn TreeItemPrimitive(\n    children: Children,\n    #[prop(default = SelectionState::Unselected)] selected: SelectionState,\n    #[prop(default = ActivityState::Inactive)] focused: ActivityState,\n    #[prop(default = false)] expanded: bool,\n    #[prop(default = DisabledState::Enabled)] disabled: DisabledState,\n    #[prop(default = false)] has_children: bool,\n    #[prop(default = 0u8)] depth: u8,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let tabindex = if focused.as_str() == \"active\" { \"0\" } else { \"-1\" };\n    let depth_str = depth.to_string();\n    view! {\n        <div\n            data-rs-tree-item=\"\"\n            data-rs-selection=if selected == SelectionState::Selected { Some(\"selected\") } else { None }\n            data-rs-focused=focused.as_str()\n            data-rs-expanded={if has_children { Some(if expanded { \"true\" } else { \"false\" }) } else { None }}\n            data-rs-disabled=if disabled.disabled() { Some(\"disabled\") } else { None }\n            data-rs-depth=depth_str\n            role=\"treeitem\"\n            tabindex=tabindex\n            aria-selected=if selected == SelectionState::Selected { Some(\"true\") } else { None }\n            aria-expanded={if has_children { Some(if expanded { \"true\" } else { \"false\" }) } else { None }}\n            aria-disabled=disabled.aria_disabled()\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn TreeGroupPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div data-rs-tree-group=\"\" role=\"group\" class=class>\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{\n    TreePrimitive, TreeItemPrimitive, TreeGroupPrimitive,\n    };\n\n#[component]\npub fn Tree(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <TreePrimitive class=class>{children()}</TreePrimitive> }\n}\n#[component]\npub fn TreeItem(children: Children, #[prop(default = false)] has_children: bool, #[prop(default = 0u8)] depth: u8, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! {\n        <TreeItemPrimitive has_children=has_children depth=depth class=class>\n            {if has_children {\n                view! { <span data-rs-tree-toggle=\"\"/> }.into_any()\n            } else {\n                view! { <span data-rs-tree-indent=\"\"/> }.into_any()\n            }}\n            <span data-rs-tree-icon=\"\"/>\n            {children()}\n        </TreeItemPrimitive>\n    }\n}\n#[component]\npub fn TreeGroup(children: Children, #[prop(into, default = String::new())] class: String) -> impl IntoView {\n    view! { <TreeGroupPrimitive class=class>{children()}</TreeGroupPrimitive> }\n}\n",
    "boundary_src": "//! Tree Island — Canon Rule passthrough\nuse leptos::prelude::*;\nuse super::tree_ui::{\n    Tree as TreeUi,\n    TreeItem as TreeItemUi,\n    TreeGroup as TreeGroupUi\n};\n\n#[component]\npub fn Tree(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TreeUi class=class>{children()}</TreeUi> }\n}\n\n#[component]\npub fn TreeItem(\n    children: Children,\n    #[prop(default = false)] has_children: bool,\n    #[prop(default = 0u8)] depth: u8,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TreeItemUi has_children=has_children depth=depth class=class>{children()}</TreeItemUi> }\n}\n\n#[component]\npub fn TreeGroup(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! { <TreeGroupUi class=class>{children()}</TreeGroupUi> }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const TREE_API: ComponentApi = ComponentApi {\n    id: \"tree\",\n    description: \"Tree view component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TREEITEM_API: ComponentApi = ComponentApi {\n    id: \"tree-item\",\n    description: \"Tree view component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"has_children\", kind: PropType::Bool, required: false, default: Some(\"false\"), description: \"Prop value\" },\n        PropDef { name: \"depth\", kind: PropType::String, required: false, default: Some(\"0u8\"), description: \"Prop value\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\npub const TREEGROUP_API: ComponentApi = ComponentApi {\n    id: \"tree-group\",\n    description: \"Tree view component\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"class\", kind: PropType::String, required: false, default: Some(\"\"), description: \"Additional CSS class names\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::tree_boundary::{Tree, TreeItem, TreeGroup};\n\n#[component]\npub fn TreeShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Tree>\n                    <TreeItem depth=0>\"Documents\"</TreeItem>\n                    <TreeItem has_children=true depth=0>\"Projects\"</TreeItem>\n                    <TreeGroup>\n                        <TreeItem depth=1>\"canonrs\"</TreeItem>\n                        <TreeItem depth=1>\"monorepo\"</TreeItem>\n                    </TreeGroup>\n                    <TreeItem depth=0>\"Settings\"</TreeItem>\n                </Tree>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"Tree structure governed by DOM — keyboard nav and expand/collapse via data-rs-expanded.\"\n            </p>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "stack"
    ]
  },
  {
    "id": "virtual_list",
    "label": "Virtual List",
    "category": "Display",
    "description": "Virtualized list for large datasets",
    "keywords": "",
    "pain": "Large lists render all items causing performance degradation",
    "promise": "List virtualization enforced structurally for large datasets",
    "why": "VirtualListPrimitive encodes list structure and item indexing. Viewport and content separation enable virtualization logic. This guarantees scalable rendering.\n",
    "before": "// ❌ Typical\nview! {\n  <ul>\n    {items.map(|i| view! { <li>{i}</li> })}\n  </ul>\n}\n",
    "after": "// ✅ CanonRS\nview! {\n  <VirtualList items_count=1000 item_height=40.0>\n    \"Item\"\n  </VirtualList>\n}\n",
    "rules": [
      "CR-001",
      "CR-004"
    ],
    "use_cases": [
      "logs",
      "large datasets"
    ],
    "related": [
      "table",
      "data_table",
      "empty_table",
      "tree",
      "list_item"
    ],
    "badges": [
      "SSR Safe",
      "Hydration Safe",
      "Token Driven",
      "Deterministic API",
      "Zero Drift",
      "Island Architecture"
    ],
    "pillar": "data",
    "primitive_src": "//! @canon-level: strict\n//! @canon-owner: primitives-team\n//! VirtualList Primitive - HTML puro + ARIA\n\nuse leptos::prelude::*;\n\n#[component]\npub fn VirtualListPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    let uid_vl = crate::infra::uid::generate(\"vl\");\n    view! {\n        <div\n            data-rs-virtual-list=\"\"\n            data-rs-uid=uid_vl\n            data-rs-interaction=\"data\"\n            role=\"list\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn VirtualListViewportPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n    #[prop(into, optional)] aria_label: Option<String>,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-virtual-list-viewport=\"\"\n            role=\"presentation\"\n            aria-label=aria_label\n            tabindex=\"0\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn VirtualListContentPrimitive(\n    children: Children,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-virtual-list-content=\"\"\n            role=\"presentation\"\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n\n#[component]\npub fn VirtualListItemPrimitive(\n    children: Children,\n    #[prop(default = 0usize)] index: usize,\n    #[prop(into, default = String::new())] class: String,\n) -> impl IntoView {\n    view! {\n        <div\n            data-rs-virtual-list-item=\"\"\n            data-rs-index=index.to_string()\n            role=\"listitem\"\n            aria-setsize=\"-1\"\n            aria-posinset={(index + 1).to_string()}\n            class=class\n        >\n            {children()}\n        </div>\n    }\n}\n",
    "ui_src": "#![allow(unreachable_pub, dead_code)]\n\nuse leptos::prelude::*;\nuse canonrs_core::primitives::{VirtualListPrimitive, VirtualListViewportPrimitive, ScrollOrientation};\nuse crate::ui::scroll_area::scroll_area_boundary::ScrollArea;\n\n#[component]\npub fn VirtualList(\n    #[prop(into)] items_count: usize,\n    #[prop(into, default = 40.0f64)] item_height: f64,\n    #[prop(into, default = 400u32)] height: u32,\n    #[prop(into, default = String::new())] class: String,\n    children: Children,\n) -> impl IntoView {\n    view! {\n        <ScrollArea\n            orientation=ScrollOrientation::Vertical\n            attr:style=format!(\"height:{}px;\", height)\n        >\n            <VirtualListPrimitive\n                class=class\n                attr:data-items-count=items_count.to_string()\n                attr:data-item-height=item_height.to_string()\n            >\n                <VirtualListViewportPrimitive>\n                    {children()}\n                </VirtualListViewportPrimitive>\n            </VirtualListPrimitive>\n        </ScrollArea>\n    }\n}\n\n",
    "boundary_src": "//! @canon-level: strict\n//! VirtualList Island — bootstrap only, delegates to interaction engine\n\nuse leptos::prelude::*;\nuse super::virtual_list_ui::VirtualList as VirtualListUi;\n\n#[component]\npub fn VirtualList(\n    #[prop(into)] items_count: usize,\n    #[prop(into, default = 40.0f64)] item_height: f64,\n    #[prop(into, default = 400u32)] height: u32,\n    children: Children,\n) -> impl IntoView {\n    view! {\n        <VirtualListUi items_count=items_count item_height=item_height height=height>\n            {children()}\n        </VirtualListUi>\n    }\n}\n",
    "api_src": "// AUTO-GENERATED by build.rs — do not edit manually.\n// Source: *_boundary.rs + builder.yaml\nuse crate::catalog_types::{ComponentApi, PropDef, PropType};\n\npub const VIRTUALLIST_API: ComponentApi = ComponentApi {\n    id: \"virtual-list\",\n    description: \"Virtualized list for large datasets\",\n    props: &[\n        PropDef { name: \"children\", kind: PropType::Children, required: true, default: None, description: \"Child elements\" },\n        PropDef { name: \"items_count\", kind: PropType::Number, required: true, default: None, description: \"Prop value\" },\n        PropDef { name: \"item_height\", kind: PropType::Number, required: false, default: Some(\"40.0f64\"), description: \"Prop value\" },\n        PropDef { name: \"height\", kind: PropType::Number, required: false, default: Some(\"400u32\"), description: \"Prop value\" },\n    ],\n};\n\n",
    "preview_src": "use leptos::prelude::*;\nuse super::virtual_list_boundary::VirtualList;\nuse canonrs_core::primitives::layout::container::{ContainerPrimitive as Container, ContainerSize};\n\n#[component]\npub fn VirtualListShowcasePreview() -> impl IntoView {\n    view! {\n        <div data-rs-showcase-preview-hero=\"\">\n            <div data-rs-showcase-preview-stage=\"\">\n                <Container size=ContainerSize::Sm>\n                    <VirtualList items_count=10000usize item_height=40.0f64>\n                        \"\"\n                    </VirtualList>\n                </Container>\n            </div>\n            <p data-rs-showcase-preview-anchor=\"\">\n                \"List virtualization enforced structurally for large datasets.\"\n            </p>\n        </div>\n    }\n}\n",
    "block": [],
    "blocks_primitives": [
      "container"
    ]
  }
]