@dyrected/admin 2.5.51 → 2.5.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/admin.css CHANGED
@@ -237,6 +237,12 @@
237
237
 
238
238
  .dy-admin-ui {
239
239
  color-scheme: light;
240
+ /* Base text/background so elements without an explicit color utility (raw
241
+ inputs via `color: inherit`, ghost/outline buttons, plain text) resolve
242
+ to the themed foreground instead of the browser default black — which is
243
+ invisible in dark mode. Resolves per-theme via the --foreground var. */
244
+ color: hsl(var(--foreground));
245
+ background-color: hsl(var(--background));
240
246
  font-family: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
241
247
  }
242
248
 
@@ -1329,6 +1335,10 @@
1329
1335
  margin-bottom: -1.5rem;
1330
1336
  }
1331
1337
 
1338
+ .dy--mb-px{
1339
+ margin-bottom: -1px;
1340
+ }
1341
+
1332
1342
  .dy--ml-4{
1333
1343
  margin-left: -1rem;
1334
1344
  }
@@ -1365,6 +1375,10 @@
1365
1375
  margin-bottom: 1rem;
1366
1376
  }
1367
1377
 
1378
+ .dy-mb-5{
1379
+ margin-bottom: 1.25rem;
1380
+ }
1381
+
1368
1382
  .dy-mb-6{
1369
1383
  margin-bottom: 1.5rem;
1370
1384
  }
@@ -1409,6 +1423,10 @@
1409
1423
  margin-right: 0.75rem;
1410
1424
  }
1411
1425
 
1426
+ .dy-mt-0{
1427
+ margin-top: 0px;
1428
+ }
1429
+
1412
1430
  .dy-mt-0\.5{
1413
1431
  margin-top: 0.125rem;
1414
1432
  }
@@ -1452,6 +1470,10 @@
1452
1470
  display: inline-block;
1453
1471
  }
1454
1472
 
1473
+ .\!dy-flex{
1474
+ display: flex !important;
1475
+ }
1476
+
1455
1477
  .dy-flex{
1456
1478
  display: flex;
1457
1479
  }
@@ -1594,6 +1616,10 @@
1594
1616
  height: 300px;
1595
1617
  }
1596
1618
 
1619
+ .dy-h-\[3px\]{
1620
+ height: 3px;
1621
+ }
1622
+
1597
1623
  .dy-h-\[400px\]{
1598
1624
  height: 400px;
1599
1625
  }
@@ -1698,6 +1724,10 @@
1698
1724
  max-height: 60vh;
1699
1725
  }
1700
1726
 
1727
+ .dy-max-h-\[85vh\]{
1728
+ max-height: 85vh;
1729
+ }
1730
+
1701
1731
  .dy-max-h-\[90dvh\]{
1702
1732
  max-height: 90dvh;
1703
1733
  }
@@ -1778,14 +1808,14 @@
1778
1808
  min-height: 100svh;
1779
1809
  }
1780
1810
 
1781
- .dy-w-0{
1782
- width: 0px;
1783
- }
1784
-
1785
1811
  .dy-w-1\.5{
1786
1812
  width: 0.375rem;
1787
1813
  }
1788
1814
 
1815
+ .dy-w-1\/2{
1816
+ width: 50%;
1817
+ }
1818
+
1789
1819
  .dy-w-10{
1790
1820
  width: 2.5rem;
1791
1821
  }
@@ -1814,6 +1844,14 @@
1814
1844
  width: 5rem;
1815
1845
  }
1816
1846
 
1847
+ .dy-w-24{
1848
+ width: 6rem;
1849
+ }
1850
+
1851
+ .dy-w-28{
1852
+ width: 7rem;
1853
+ }
1854
+
1817
1855
  .dy-w-3{
1818
1856
  width: 0.75rem;
1819
1857
  }
@@ -1838,6 +1876,10 @@
1838
1876
  width: 10rem;
1839
1877
  }
1840
1878
 
1879
+ .dy-w-48{
1880
+ width: 12rem;
1881
+ }
1882
+
1841
1883
  .dy-w-5{
1842
1884
  width: 1.25rem;
1843
1885
  }
@@ -1850,6 +1892,10 @@
1850
1892
  width: 1.5rem;
1851
1893
  }
1852
1894
 
1895
+ .dy-w-64{
1896
+ width: 16rem;
1897
+ }
1898
+
1853
1899
  .dy-w-7{
1854
1900
  width: 1.75rem;
1855
1901
  }
@@ -1963,6 +2009,10 @@
1963
2009
  min-width: 2.75rem;
1964
2010
  }
1965
2011
 
2012
+ .dy-min-w-4{
2013
+ min-width: 1rem;
2014
+ }
2015
+
1966
2016
  .dy-min-w-44{
1967
2017
  min-width: 11rem;
1968
2018
  }
@@ -1991,10 +2041,6 @@
1991
2041
  min-width: 120px;
1992
2042
  }
1993
2043
 
1994
- .dy-min-w-\[150px\]{
1995
- min-width: 150px;
1996
- }
1997
-
1998
2044
  .dy-min-w-\[180px\]{
1999
2045
  min-width: 180px;
2000
2046
  }
@@ -2036,6 +2082,18 @@
2036
2082
  max-width: 150px;
2037
2083
  }
2038
2084
 
2085
+ .dy-max-w-\[250px\]{
2086
+ max-width: 250px;
2087
+ }
2088
+
2089
+ .dy-max-w-\[80\%\]{
2090
+ max-width: 80%;
2091
+ }
2092
+
2093
+ .dy-max-w-\[85\%\]{
2094
+ max-width: 85%;
2095
+ }
2096
+
2039
2097
  .dy-max-w-full{
2040
2098
  max-width: 100%;
2041
2099
  }
@@ -2186,6 +2244,14 @@
2186
2244
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
2187
2245
  }
2188
2246
 
2247
+ .dy-animate-\[dy-splash-breathe_1\.8s_ease-in-out_infinite\]{
2248
+ animation: dy-splash-breathe 1.8s ease-in-out infinite;
2249
+ }
2250
+
2251
+ .dy-animate-\[dy-splash-slide_1\.2s_ease-in-out_infinite\]{
2252
+ animation: dy-splash-slide 1.2s ease-in-out infinite;
2253
+ }
2254
+
2189
2255
  @keyframes dy-bounce{
2190
2256
 
2191
2257
  0%, 100%{
@@ -2394,19 +2460,10 @@
2394
2460
  column-gap: 1rem;
2395
2461
  }
2396
2462
 
2397
- .dy-gap-x-8{
2398
- -moz-column-gap: 2rem;
2399
- column-gap: 2rem;
2400
- }
2401
-
2402
2463
  .dy-gap-y-3{
2403
2464
  row-gap: 0.75rem;
2404
2465
  }
2405
2466
 
2406
- .dy-gap-y-4{
2407
- row-gap: 1rem;
2408
- }
2409
-
2410
2467
  .dy-gap-y-5{
2411
2468
  row-gap: 1.25rem;
2412
2469
  }
@@ -2415,12 +2472,6 @@
2415
2472
  row-gap: 1.5rem;
2416
2473
  }
2417
2474
 
2418
- .dy-space-x-2 > :not([hidden]) ~ :not([hidden]){
2419
- --tw-space-x-reverse: 0;
2420
- margin-right: calc(0.5rem * var(--tw-space-x-reverse));
2421
- margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
2422
- }
2423
-
2424
2475
  .dy-space-y-0 > :not([hidden]) ~ :not([hidden]){
2425
2476
  --tw-space-y-reverse: 0;
2426
2477
  margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
@@ -2535,10 +2586,6 @@
2535
2586
  white-space: nowrap;
2536
2587
  }
2537
2588
 
2538
- .dy-text-nowrap{
2539
- text-wrap: nowrap;
2540
- }
2541
-
2542
2589
  .dy-break-words{
2543
2590
  overflow-wrap: break-word;
2544
2591
  }
@@ -2611,6 +2658,10 @@
2611
2658
  border-width: 1px;
2612
2659
  }
2613
2660
 
2661
+ .dy-border-0{
2662
+ border-width: 0px;
2663
+ }
2664
+
2614
2665
  .dy-border-2{
2615
2666
  border-width: 2px;
2616
2667
  }
@@ -2631,10 +2682,6 @@
2631
2682
  border-left-width: 1px;
2632
2683
  }
2633
2684
 
2634
- .dy-border-l-0{
2635
- border-left-width: 0px;
2636
- }
2637
-
2638
2685
  .dy-border-r{
2639
2686
  border-right-width: 1px;
2640
2687
  }
@@ -2905,6 +2952,10 @@
2905
2952
  background-color: rgb(0 0 0 / 0.05);
2906
2953
  }
2907
2954
 
2955
+ .dy-bg-black\/50{
2956
+ background-color: rgb(0 0 0 / 0.5);
2957
+ }
2958
+
2908
2959
  .dy-bg-black\/60{
2909
2960
  background-color: rgb(0 0 0 / 0.6);
2910
2961
  }
@@ -2940,6 +2991,10 @@
2940
2991
  background-color: hsl(var(--border) / 0.5);
2941
2992
  }
2942
2993
 
2994
+ .dy-bg-border\/60{
2995
+ background-color: hsl(var(--border) / 0.6);
2996
+ }
2997
+
2943
2998
  .dy-bg-card{
2944
2999
  background-color: hsl(var(--card));
2945
3000
  }
@@ -3198,6 +3253,11 @@
3198
3253
  padding-right: 0px;
3199
3254
  }
3200
3255
 
3256
+ .dy-px-0\.5{
3257
+ padding-left: 0.125rem;
3258
+ padding-right: 0.125rem;
3259
+ }
3260
+
3201
3261
  .dy-px-1{
3202
3262
  padding-left: 0.25rem;
3203
3263
  padding-right: 0.25rem;
@@ -3293,11 +3353,6 @@
3293
3353
  padding-bottom: 0.75rem;
3294
3354
  }
3295
3355
 
3296
- .dy-py-3\.5{
3297
- padding-top: 0.875rem;
3298
- padding-bottom: 0.875rem;
3299
- }
3300
-
3301
3356
  .dy-py-4{
3302
3357
  padding-top: 1rem;
3303
3358
  padding-bottom: 1rem;
@@ -3417,10 +3472,6 @@
3417
3472
  padding-top: 1.25rem;
3418
3473
  }
3419
3474
 
3420
- .dy-pt-8{
3421
- padding-top: 2rem;
3422
- }
3423
-
3424
3475
  .dy-text-left{
3425
3476
  text-align: left;
3426
3477
  }
@@ -3429,6 +3480,10 @@
3429
3480
  text-align: center;
3430
3481
  }
3431
3482
 
3483
+ .dy-text-right{
3484
+ text-align: right;
3485
+ }
3486
+
3432
3487
  .dy-align-top{
3433
3488
  vertical-align: top;
3434
3489
  }
@@ -3836,10 +3891,6 @@
3836
3891
  opacity: 1;
3837
3892
  }
3838
3893
 
3839
- .dy-opacity-35{
3840
- opacity: 0.35;
3841
- }
3842
-
3843
3894
  .dy-opacity-50{
3844
3895
  opacity: 0.5;
3845
3896
  }
@@ -4259,6 +4310,12 @@
4259
4310
  appearance: textfield;
4260
4311
  }
4261
4312
 
4313
+ .dy-admin-ui [data-dy-path]:hover{
4314
+ border-width: 1px;
4315
+ border-style: dashed;
4316
+ border-color: hsl(var(--primary) / 0.1);
4317
+ }
4318
+
4262
4319
  .dy-admin-ui .media-preview-dialod-details-form div[style="min-width: 100%;display: table;"] {
4263
4320
  display: flex !important;
4264
4321
  }
@@ -4367,6 +4424,18 @@
4367
4424
  background: hsl(var(--card)) !important;
4368
4425
  }
4369
4426
 
4427
+ /* Bootstrap splash animations (see AdminSplash). */
4428
+
4429
+ @keyframes dy-splash-breathe {
4430
+ 0%, 100% { opacity: 0.55; transform: scale(0.98); }
4431
+ 50% { opacity: 1; transform: scale(1); }
4432
+ }
4433
+
4434
+ @keyframes dy-splash-slide {
4435
+ 0% { transform: translateX(-120%); }
4436
+ 100% { transform: translateX(340%); }
4437
+ }
4438
+
4370
4439
  .dy-admin-ui .hover\:dy-text-primary:hover {
4371
4440
  color: hsl(var(--intelligence));
4372
4441
  }
@@ -4692,6 +4761,10 @@
4692
4761
  padding-left: 1rem;
4693
4762
  }
4694
4763
 
4764
+ .last\:dy-border-b-0:last-child{
4765
+ border-bottom-width: 0px;
4766
+ }
4767
+
4695
4768
  .last\:dy-pr-4:last-child{
4696
4769
  padding-right: 1rem;
4697
4770
  }
@@ -4718,6 +4791,10 @@
4718
4791
  border-color: hsl(var(--primary) / 0.2);
4719
4792
  }
4720
4793
 
4794
+ .hover\:dy-border-primary\/30:hover{
4795
+ border-color: hsl(var(--primary) / 0.3);
4796
+ }
4797
+
4721
4798
  .hover\:dy-border-primary\/40:hover{
4722
4799
  border-color: hsl(var(--primary) / 0.4);
4723
4800
  }
@@ -4742,10 +4819,6 @@
4742
4819
  background-color: hsl(var(--background));
4743
4820
  }
4744
4821
 
4745
- .hover\:dy-bg-background\/40:hover{
4746
- background-color: hsl(var(--background) / 0.4);
4747
- }
4748
-
4749
4822
  .hover\:dy-bg-background\/80:hover{
4750
4823
  background-color: hsl(var(--background) / 0.8);
4751
4824
  }
@@ -4786,6 +4859,10 @@
4786
4859
  background-color: hsl(var(--muted) / 0.5);
4787
4860
  }
4788
4861
 
4862
+ .hover\:dy-bg-muted\/60:hover{
4863
+ background-color: hsl(var(--muted) / 0.6);
4864
+ }
4865
+
4789
4866
  .hover\:dy-bg-muted\/80:hover{
4790
4867
  background-color: hsl(var(--muted) / 0.8);
4791
4868
  }
@@ -4952,6 +5029,10 @@
4952
5029
  background-color: hsl(var(--background));
4953
5030
  }
4954
5031
 
5032
+ .focus-visible\:dy-opacity-100:focus-visible{
5033
+ opacity: 1;
5034
+ }
5035
+
4955
5036
  .focus-visible\:dy-shadow-md:focus-visible{
4956
5037
  --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
4957
5038
  --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
@@ -5057,10 +5138,18 @@
5057
5138
  background-color: hsl(var(--primary) / 0.1);
5058
5139
  }
5059
5140
 
5141
+ .dy-group:hover .group-hover\:dy-text-foreground{
5142
+ color: hsl(var(--foreground));
5143
+ }
5144
+
5060
5145
  .dy-group:hover .group-hover\:dy-text-primary{
5061
5146
  color: hsl(var(--primary));
5062
5147
  }
5063
5148
 
5149
+ .dy-group:hover .group-hover\:dy-opacity-100{
5150
+ opacity: 1;
5151
+ }
5152
+
5064
5153
  .dy-group.toaster .group-\[\.toaster\]\:dy-rounded-xl{
5065
5154
  border-radius: 0.75rem;
5066
5155
  }
@@ -5611,6 +5700,10 @@
5611
5700
  width: 6rem;
5612
5701
  }
5613
5702
 
5703
+ .sm\:dy-w-44{
5704
+ width: 11rem;
5705
+ }
5706
+
5614
5707
  .sm\:dy-w-7{
5615
5708
  width: 1.75rem;
5616
5709
  }
@@ -5903,10 +5996,6 @@
5903
5996
  display: block;
5904
5997
  }
5905
5998
 
5906
- .md\:dy-inline-block{
5907
- display: inline-block;
5908
- }
5909
-
5910
5999
  .md\:dy-flex{
5911
6000
  display: flex;
5912
6001
  }
@@ -5955,6 +6044,10 @@
5955
6044
  width: 20rem;
5956
6045
  }
5957
6046
 
6047
+ .md\:dy-max-w-4xl{
6048
+ max-width: 56rem;
6049
+ }
6050
+
5958
6051
  .md\:dy-max-w-5xl{
5959
6052
  max-width: 64rem;
5960
6053
  }
@@ -6021,9 +6114,9 @@
6021
6114
  padding: 1.5rem;
6022
6115
  }
6023
6116
 
6024
- .md\:dy-px-6{
6025
- padding-left: 1.5rem;
6026
- padding-right: 1.5rem;
6117
+ .md\:dy-px-4{
6118
+ padding-left: 1rem;
6119
+ padding-right: 1rem;
6027
6120
  }
6028
6121
 
6029
6122
  .md\:dy-pr-4{
@@ -6074,6 +6167,18 @@
6074
6167
  display: block;
6075
6168
  }
6076
6169
 
6170
+ .lg\:dy-flex{
6171
+ display: flex;
6172
+ }
6173
+
6174
+ .lg\:dy-hidden{
6175
+ display: none;
6176
+ }
6177
+
6178
+ .lg\:dy-w-0{
6179
+ width: 0px;
6180
+ }
6181
+
6077
6182
  .lg\:dy-w-1\/3{
6078
6183
  width: 33.333333%;
6079
6184
  }
@@ -6082,10 +6187,18 @@
6082
6187
  width: 66.666667%;
6083
6188
  }
6084
6189
 
6190
+ .lg\:dy-w-2\/6{
6191
+ width: 33.333333%;
6192
+ }
6193
+
6085
6194
  .lg\:dy-max-w-6xl{
6086
6195
  max-width: 72rem;
6087
6196
  }
6088
6197
 
6198
+ .lg\:dy-flex-1{
6199
+ flex: 1 1 0%;
6200
+ }
6201
+
6089
6202
  .lg\:dy-grid-cols-4{
6090
6203
  grid-template-columns: repeat(4, minmax(0, 1fr));
6091
6204
  }
@@ -6128,32 +6241,40 @@
6128
6241
  margin-bottom: calc(2rem * var(--tw-space-y-reverse));
6129
6242
  }
6130
6243
 
6244
+ .lg\:dy-border-r-0{
6245
+ border-right-width: 0px;
6246
+ }
6247
+
6248
+ .lg\:dy-px-4{
6249
+ padding-left: 1rem;
6250
+ padding-right: 1rem;
6251
+ }
6252
+
6131
6253
  .lg\:dy-px-6{
6132
6254
  padding-left: 1.5rem;
6133
6255
  padding-right: 1.5rem;
6134
6256
  }
6135
6257
 
6136
- .lg\:dy-px-8{
6137
- padding-left: 2rem;
6138
- padding-right: 2rem;
6139
- }
6140
-
6141
6258
  .lg\:dy-py-10{
6142
6259
  padding-top: 2.5rem;
6143
6260
  padding-bottom: 2.5rem;
6144
6261
  }
6145
6262
 
6146
- .lg\:dy-py-8{
6147
- padding-top: 2rem;
6148
- padding-bottom: 2rem;
6263
+ .lg\:dy-py-6{
6264
+ padding-top: 1.5rem;
6265
+ padding-bottom: 1.5rem;
6149
6266
  }
6150
- }
6151
6267
 
6152
- @media (min-width: 1280px){
6268
+ .lg\:dy-opacity-0{
6269
+ opacity: 0;
6270
+ }
6153
6271
 
6154
- .xl\:dy-max-w-3xl{
6155
- max-width: 48rem;
6272
+ .lg\:dy-opacity-100{
6273
+ opacity: 1;
6156
6274
  }
6275
+ }
6276
+
6277
+ @media (min-width: 1280px){
6157
6278
 
6158
6279
  .xl\:dy-max-w-4xl{
6159
6280
  max-width: 56rem;
@@ -18,5 +18,11 @@ interface FormEngineProps {
18
18
  */
19
19
  passwordChangeMode?: 'self' | 'admin' | null;
20
20
  documentId?: string;
21
+ /**
22
+ * Label for the implicit tab that collects fields without an `admin.tab`
23
+ * when the form uses tabs. Typically the collection's singular label
24
+ * (e.g. "Page"). Falls back to a capitalised collection slug.
25
+ */
26
+ defaultTabLabel?: string;
21
27
  }
22
- export declare function FormEngine({ collection, fields, defaultValues, onSubmit, onChange, isLoading, submitLabel, readOnly, onDataChange, passwordChangeMode, documentId, }: FormEngineProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function FormEngine(props: FormEngineProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,86 @@
1
+ import { default as React } from 'react';
2
+ export interface PathSegment {
3
+ /** Schema field name at this level (e.g. "body", "cta"). */
4
+ fieldName: string;
5
+ /**
6
+ * Cumulative RHF-resolvable path up to and including this segment
7
+ * (e.g. "body.2" or "body.2.items.1"). Used to disambiguate
8
+ * identically-named sub-arrays/objects that live inside different
9
+ * parent block types, and to correlate mutation reports back to a
10
+ * depth in activePath.
11
+ */
12
+ basePath: string;
13
+ /**
14
+ * Stable id from useFieldArray (`field.id`) if this segment is an
15
+ * item inside an array/blocks field. Undefined for object fields
16
+ * and the root.
17
+ */
18
+ stableId?: string;
19
+ /** Human-readable label for the breadcrumb (e.g. "Hero", "Button"). */
20
+ breadcrumbLabel: string;
21
+ }
22
+ export interface NestedEditorContextValue {
23
+ /**
24
+ * Whether drill-in (nested-form) navigation is active. When false, nested
25
+ * containers (blocks/array/object) render inline as a flat form instead of
26
+ * as drillable rows. Driven by the edit page's live-preview mode.
27
+ */
28
+ drillInEnabled: boolean;
29
+ /** Ordered path segments. Root = []. */
30
+ activePath: PathSegment[];
31
+ /**
32
+ * Push a segment. Called by BlockBuilder/ArrayFieldRenderer/ObjectFieldRenderer
33
+ * "Edit"/"Drill In" actions.
34
+ * The caller computes segment.basePath cumulatively:
35
+ * basePath = parentSegment.basePath + "." + index (for array/blocks items)
36
+ * basePath = parentSegment.basePath + "." + fieldName (for object fields)
37
+ */
38
+ drillInto: (segment: PathSegment) => void;
39
+ /**
40
+ * Navigate back to a specific depth. 0 = root. Called by breadcrumb clicks.
41
+ */
42
+ navigateTo: (depth: number) => void;
43
+ /**
44
+ * Called after move/remove/insert on a field array. Matches by
45
+ * segment.basePath (NOT bare fieldName) so identically-named sub-arrays
46
+ * in different block types are correctly disambiguated.
47
+ * If the active segment's stableId is no longer present in liveStableIds,
48
+ * pops back to the parent level.
49
+ */
50
+ reconcileAfterMutation: (basePath: string, liveStableIds: string[]) => void;
51
+ /**
52
+ * Imperatively navigate to a resolved container path. Called by the
53
+ * error-summary click handler and the preview click-to-edit handler.
54
+ */
55
+ navigateToPath: (resolvedSegments: PathSegment[]) => void;
56
+ /**
57
+ * Publish the live useFieldArray id list for a given basePath. Called by
58
+ * each drill-capable renderer (BlockBuilder, and ArrayFieldRenderer when
59
+ * drillIn is active) so top-level code can resolve stable ids by
60
+ * (basePath, index) without access to the nested field-array instances.
61
+ */
62
+ registerFieldArray: (basePath: string, ids: string[]) => void;
63
+ /** Remove a basePath's published ids (called on renderer unmount). */
64
+ unregisterFieldArray: (basePath: string) => void;
65
+ /**
66
+ * Resolve the stable useFieldArray id at (basePath, rawIndex) from the
67
+ * published registry. Returns undefined if the array isn't registered or
68
+ * the index is out of range. Passed to `resolveContainerPath`.
69
+ */
70
+ getStableId: (basePath: string, rawIndex: number) => string | undefined;
71
+ }
72
+ export declare const NestedEditorContext: React.Context<NestedEditorContextValue>;
73
+ export declare function NestedEditorProvider({ children, drillInEnabled, }: {
74
+ children: React.ReactNode;
75
+ drillInEnabled?: boolean;
76
+ }): import("react/jsx-runtime").JSX.Element;
77
+ export declare function useNestedEditor(): NestedEditorContextValue;
78
+ /**
79
+ * Returns true if the given basePath is at or below the current activePath.
80
+ * Used by renderers to decide whether to show list-view or focused sub-form.
81
+ */
82
+ export declare function isActiveOrChild(activePath: PathSegment[], basePath: string): boolean;
83
+ /**
84
+ * Returns true if the given basePath is the deepest active segment.
85
+ */
86
+ export declare function isDeepestActive(activePath: PathSegment[], basePath: string): boolean;
@@ -1,4 +1,5 @@
1
1
  import { Field as FieldSchema } from '@dyrected/sdk';
2
+ import { PathSegment } from './nested-editor-context';
2
3
  import * as z from "zod";
3
4
  /**
4
5
  * Normalises a field's `options` array to the canonical `{ label, value }` shape.
@@ -53,3 +54,21 @@ export declare function getFlatErrors(errors: Record<string, unknown>, path?: st
53
54
  * formatPath("items.0.name") // → "Items > Item 1 > Name"
54
55
  */
55
56
  export declare function formatPath(path: string): string;
57
+ /**
58
+ * Walks the schema tree alongside a dot-notation path (e.g. "body.2.cta.url")
59
+ * and returns the ordered PathSegments representing each drillable container
60
+ * boundary crossed. Drillable boundaries are:
61
+ * - `blocks` fields (always drillable)
62
+ * - `array` or `object` fields with `admin.drillIn === true`
63
+ * Leaf field names and raw numeric indices are consumed but not emitted.
64
+ *
65
+ * @param fields Top-level field schemas for the collection.
66
+ * @param path Dot-notation path, e.g. "body.2.cta.url"
67
+ * @param getStableId Resolves (basePath, rawIndex) → stableId from live
68
+ * useFieldArray state. Takes the full cumulative RHF path
69
+ * (e.g. "body.2.items"), not just the leaf field name, to
70
+ * disambiguate identically-named sub-arrays across block types.
71
+ * @returns Ordered PathSegment[] for the drill-in trail, or null if the path
72
+ * cannot be resolved against the schema.
73
+ */
74
+ export declare function resolveContainerPath(fields: FieldSchema[], path: string, getStableId: (basePath: string, rawIndex: number) => string | undefined): PathSegment[] | null;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A single, calm, branded full-screen loading state used everywhere the admin
3
+ * is bootstrapping (initial mount + auth resolution). Keeping one consistent
4
+ * splash — instead of a sequence of differently-worded loaders — makes the cold
5
+ * load feel like one smooth step rather than several flashes.
6
+ *
7
+ * Assumes it renders inside a themed `.dy-admin-ui` ancestor so the tokens
8
+ * (`--background`, `--foreground`, `--primary`) resolve for both light and dark.
9
+ */
10
+ export declare function AdminSplash({ className }: {
11
+ className?: string;
12
+ }): import("react/jsx-runtime").JSX.Element;