@questpie/admin 3.5.1 → 3.5.3

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.
Files changed (94) hide show
  1. package/dist/client/builder/types/collection-types.d.mts +9 -0
  2. package/dist/client/components/actions/action-dialog.mjs +5 -0
  3. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +7 -0
  4. package/dist/client/components/fields/rich-text-editor/extensions.mjs +17 -1
  5. package/dist/client/components/fields/rich-text-editor/index.d.mts +2 -1
  6. package/dist/client/components/fields/rich-text-editor/index.mjs +35 -74
  7. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +30 -7
  8. package/dist/client/components/fields/rich-text-editor/toolbar.mjs +1 -312
  9. package/dist/client/components/fields/rich-text-editor/types.d.mts +4 -0
  10. package/dist/client/components/fields/rich-text-editor/types.mjs +1 -1
  11. package/dist/client/components/fields/rich-text-editor/utils.mjs +6 -12
  12. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +75 -22
  13. package/dist/client/components/ui/dropdown-menu.mjs +1 -34
  14. package/dist/client/hooks/query-access.d.mts +9 -0
  15. package/dist/client/hooks/query-access.mjs +20 -0
  16. package/dist/client/hooks/typed-hooks.d.mts +4 -2
  17. package/dist/client/hooks/typed-hooks.mjs +30 -29
  18. package/dist/client/hooks/use-reactive-fields.d.mts +1 -0
  19. package/dist/client/hooks/use-reactive-fields.mjs +16 -1
  20. package/dist/client/hooks/use-server-actions.mjs +12 -1
  21. package/dist/client/hooks/use-view-state.mjs +15 -7
  22. package/dist/client/lib/view-filter-utils.mjs +30 -0
  23. package/dist/client/preview/block-scope-context.d.mts +2 -2
  24. package/dist/client/preview/preview-banner.d.mts +2 -2
  25. package/dist/client/preview/preview-field.d.mts +4 -4
  26. package/dist/client/scope/picker.d.mts +2 -2
  27. package/dist/client/scope/provider.d.mts +2 -2
  28. package/dist/client/styles/base.css +69 -77
  29. package/dist/client/utils/build-field-definitions-from-schema.mjs +1 -0
  30. package/dist/client/views/collection/auto-form-fields.mjs +3 -2
  31. package/dist/client/views/collection/cells/primitive-cells.mjs +9 -6
  32. package/dist/client/views/collection/columns/build-columns.mjs +3 -1
  33. package/dist/client/views/collection/field-renderer.mjs +11 -3
  34. package/dist/client/views/collection/form-view.mjs +207 -202
  35. package/dist/client/views/collection/list-view.mjs +581 -183
  36. package/dist/client/views/collection/outline.mjs +44 -19
  37. package/dist/client/views/collection/quick-filter-bar.mjs +45 -0
  38. package/dist/client/views/collection/table-view.mjs +60 -16
  39. package/dist/client/views/globals/global-form-view.mjs +12 -9
  40. package/dist/client/views/layout/admin-layout.mjs +1 -1
  41. package/dist/client/views/layout/admin-sidebar.mjs +20 -14
  42. package/dist/client/views/layout/admin-theme.mjs +5 -4
  43. package/dist/client.mjs +1 -1
  44. package/dist/components/rich-text/rich-text-renderer.d.mts +5 -5
  45. package/dist/components/rich-text/rich-text-renderer.mjs +5 -2
  46. package/dist/index.mjs +1 -1
  47. package/dist/modules/admin.d.mts +1 -1
  48. package/dist/server/augmentation/actions.d.mts +4 -3
  49. package/dist/server/augmentation/dashboard.d.mts +11 -11
  50. package/dist/server/augmentation/form-layout.d.mts +11 -6
  51. package/dist/server/augmentation/index.d.mts +7 -0
  52. package/dist/server/augmentation/sidebar.d.mts +8 -8
  53. package/dist/server/codegen/admin-client-template.mjs +55 -38
  54. package/dist/server/fields/index.d.mts +1 -1
  55. package/dist/server/fields/rich-text.d.mts +16 -17
  56. package/dist/server/fields/rich-text.mjs +18 -7
  57. package/dist/server/i18n/messages/cs.mjs +2 -0
  58. package/dist/server/i18n/messages/de.mjs +2 -0
  59. package/dist/server/i18n/messages/en.mjs +4 -0
  60. package/dist/server/i18n/messages/es.mjs +2 -0
  61. package/dist/server/i18n/messages/fr.mjs +2 -0
  62. package/dist/server/i18n/messages/pl.mjs +2 -0
  63. package/dist/server/i18n/messages/pt.mjs +2 -0
  64. package/dist/server/i18n/messages/sk.mjs +2 -0
  65. package/dist/server/modules/admin/block/block-builder.d.mts +0 -8
  66. package/dist/server/modules/admin/block/introspection.d.mts +2 -2
  67. package/dist/server/modules/admin/collections/account.d.mts +53 -52
  68. package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -56
  69. package/dist/server/modules/admin/collections/admin-preferences.d.mts +3 -2
  70. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -49
  71. package/dist/server/modules/admin/collections/apikey.d.mts +72 -71
  72. package/dist/server/modules/admin/collections/assets.d.mts +42 -41
  73. package/dist/server/modules/admin/collections/session.d.mts +46 -45
  74. package/dist/server/modules/admin/collections/user.d.mts +67 -66
  75. package/dist/server/modules/admin/collections/verification.d.mts +39 -38
  76. package/dist/server/modules/admin/index.d.mts +3 -3
  77. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  78. package/dist/server/modules/admin/routes/admin-config.mjs +39 -23
  79. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  80. package/dist/server/modules/admin/routes/execute-action.mjs +28 -8
  81. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  82. package/dist/server/modules/admin/routes/reactive.mjs +2 -2
  83. package/dist/server/modules/admin/routes/route-helpers.d.mts +11 -7
  84. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  85. package/dist/server/modules/admin/routes/widget-data.mjs +12 -4
  86. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
  87. package/dist/server/modules/audit/.generated/module.d.mts +6 -6
  88. package/dist/server/modules/audit/collections/audit-log.d.mts +40 -39
  89. package/dist/server/plugin.mjs +3 -3
  90. package/dist/server.d.mts +1 -1
  91. package/dist/shared/types/index.d.mts +1 -0
  92. package/dist/shared/types/saved-views.types.d.mts +14 -7
  93. package/dist/shared.d.mts +3 -2
  94. package/package.json +4 -3
@@ -4,6 +4,8 @@
4
4
  @import "@fontsource-variable/geist";
5
5
  @import "@fontsource-variable/jetbrains-mono";
6
6
 
7
+ @source "../**/*.{js,jsx,ts,tsx}";
8
+
7
9
  /* ================================================================
8
10
  QUESTPIE ADMIN THEME — Base
9
11
  ================================================================
@@ -361,46 +363,19 @@
361
363
  }
362
364
 
363
365
  /* =============================================================================
364
- Rich Text Editor Styles
366
+ Rich Text Editor Styles — Notion-like document editor
365
367
  ============================================================================= */
366
368
 
367
369
  .qp-rich-text-editor {
368
370
  position: relative;
369
- border-color: var(--border-subtle);
370
- background: var(--surface-low);
371
- transition-property: background-color, border-color, box-shadow;
372
- transition-duration: var(--motion-duration-base);
373
- transition-timing-function: var(--motion-ease-standard);
374
- }
375
-
376
- .qp-rich-text-editor:focus-within {
377
- border-color: var(--border-strong);
378
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
379
- }
380
-
381
- .qp-rich-text-editor [data-rich-text-toolbar-button] {
382
- flex: 0 0 auto;
383
- }
384
-
385
- .qp-rich-text-editor__toolbar {
386
- scrollbar-width: none;
387
- -webkit-overflow-scrolling: touch;
388
- }
389
-
390
- .qp-rich-text-editor__toolbar::-webkit-scrollbar {
391
- display: none;
392
- }
393
-
394
- .qp-rich-text-editor__toolbar > [role="group"] {
395
- flex: 0 0 auto;
396
371
  }
397
372
 
398
373
  .qp-rich-text-editor__bubble {
399
374
  display: flex;
400
375
  align-items: center;
401
- gap: 0.25rem;
402
- padding: 0.25rem;
403
- border-radius: calc(var(--control-radius-inner) + 0.25rem);
376
+ gap: 0.375rem;
377
+ padding: 0.375rem;
378
+ border-radius: var(--floating-radius);
404
379
  }
405
380
 
406
381
  .qp-rich-text-editor__bubble-block {
@@ -411,7 +386,8 @@
411
386
 
412
387
  .qp-rich-text-editor__bubble-separator {
413
388
  width: 1px;
414
- height: 1.5rem;
389
+ height: 1.25rem;
390
+ margin: 0 0.125rem;
415
391
  background: var(--border-subtle);
416
392
  }
417
393
 
@@ -419,8 +395,8 @@
419
395
  display: grid;
420
396
  grid-template-columns: auto minmax(12rem, 18rem) auto auto;
421
397
  align-items: center;
422
- gap: 0.375rem;
423
- padding: 0.125rem;
398
+ gap: 0.5rem;
399
+ padding: 0.25rem;
424
400
  }
425
401
 
426
402
  .qp-rich-text-editor__link-input {
@@ -446,13 +422,14 @@
446
422
  font-size: 0.75rem;
447
423
  }
448
424
 
425
+ /* Content area — document editor feel */
449
426
  .qp-rich-text-editor__content {
450
427
  min-height: 240px;
451
- padding: 1rem 1.25rem 1.25rem;
428
+ padding: 1.25rem 1.5rem 1.5rem;
452
429
  outline: none;
453
430
  color: var(--foreground);
454
- font-size: 0.9375rem;
455
- line-height: 1.65;
431
+ font-size: 1rem;
432
+ line-height: 1.7;
456
433
  text-wrap: pretty;
457
434
  caret-color: var(--foreground);
458
435
  }
@@ -478,30 +455,30 @@
478
455
  }
479
456
 
480
457
  .qp-rich-text-editor__content p {
481
- margin: 0 0 0.8rem;
458
+ margin: 0 0 0.5em;
482
459
  }
483
460
 
484
461
  .qp-rich-text-editor__content h1 {
485
- margin: 1.5rem 0 0.85rem;
486
- font-size: 1.625rem;
487
- font-weight: 650;
488
- letter-spacing: 0;
462
+ margin: 1.75em 0 0.4em;
463
+ font-size: 1.875rem;
464
+ font-weight: 700;
465
+ letter-spacing: -0.02em;
489
466
  line-height: 1.2;
490
467
  text-wrap: balance;
491
468
  }
492
469
 
493
470
  .qp-rich-text-editor__content h2 {
494
- margin: 1.35rem 0 0.75rem;
495
- font-size: 1.375rem;
471
+ margin: 1.5em 0 0.35em;
472
+ font-size: 1.5rem;
496
473
  font-weight: 650;
497
- letter-spacing: 0;
474
+ letter-spacing: -0.01em;
498
475
  line-height: 1.25;
499
476
  text-wrap: balance;
500
477
  }
501
478
 
502
479
  .qp-rich-text-editor__content h3 {
503
- margin: 1.15rem 0 0.65rem;
504
- font-size: 1.125rem;
480
+ margin: 1.25em 0 0.3em;
481
+ font-size: 1.25rem;
505
482
  font-weight: 650;
506
483
  letter-spacing: 0;
507
484
  line-height: 1.3;
@@ -511,36 +488,40 @@
511
488
  .qp-rich-text-editor__content h4,
512
489
  .qp-rich-text-editor__content h5,
513
490
  .qp-rich-text-editor__content h6 {
514
- margin: 1rem 0 0.5rem;
491
+ margin: 1.15em 0 0.25em;
515
492
  font-size: 1rem;
516
493
  font-weight: 650;
517
494
  letter-spacing: 0;
518
- line-height: 1.35;
495
+ line-height: 1.4;
519
496
  text-wrap: balance;
520
497
  }
521
498
 
522
499
  .qp-rich-text-editor__content ul,
523
500
  .qp-rich-text-editor__content ol {
524
- margin: 0.75rem 0;
525
- padding-left: 1.35rem;
501
+ margin: 0.75em 0;
502
+ padding-left: 1.5rem;
526
503
  }
527
504
 
528
505
  .qp-rich-text-editor__content li {
529
- margin: 0.25rem 0;
530
- padding-left: 0.15rem;
506
+ margin: 0.35em 0;
507
+ padding-left: 0.25rem;
508
+ }
509
+
510
+ .qp-rich-text-editor__content li p {
511
+ margin: 0;
531
512
  }
532
513
 
533
514
  .qp-rich-text-editor__content blockquote {
534
- margin: 1rem 0;
515
+ margin: 1.25em 0;
535
516
  border-left: 3px solid var(--border-strong);
536
- padding: 0.15rem 0 0.15rem 0.85rem;
517
+ padding: 0.25em 0 0.25em 1rem;
537
518
  color: var(--muted-foreground);
538
519
  }
539
520
 
540
521
  .qp-rich-text-editor__content code {
541
522
  background: var(--muted);
542
523
  border-radius: var(--radius-xs);
543
- padding: 0.1rem 0.3rem;
524
+ padding: 0.15em 0.35em;
544
525
  font-size: 0.875em;
545
526
  font-family: var(--font-mono);
546
527
  }
@@ -548,11 +529,11 @@
548
529
  .qp-rich-text-editor__content pre {
549
530
  background: var(--muted);
550
531
  border-radius: var(--control-radius-inner);
551
- margin: 1rem 0;
552
- padding: 0.875rem 1rem;
532
+ margin: 1.25em 0;
533
+ padding: 1rem 1.25rem;
553
534
  font-family: var(--font-mono);
554
535
  font-size: 0.8125rem;
555
- line-height: 1.6;
536
+ line-height: 1.65;
556
537
  overflow-x: auto;
557
538
  }
558
539
 
@@ -565,14 +546,14 @@
565
546
  .qp-rich-text-editor__content hr {
566
547
  border: none;
567
548
  border-top: 1px solid var(--border-subtle);
568
- margin: 1.25rem 0;
549
+ margin: 1.75em 0;
569
550
  }
570
551
 
571
552
  .qp-rich-text-editor__content img {
572
553
  display: block;
573
554
  max-width: 100%;
574
555
  height: auto;
575
- margin: 1rem 0;
556
+ margin: 1.25em 0;
576
557
  border-radius: var(--control-radius-inner);
577
558
  outline: 1px solid rgba(255, 255, 255, 0.1);
578
559
  outline-offset: -1px;
@@ -585,7 +566,7 @@
585
566
 
586
567
  .qp-rich-text-editor__content table {
587
568
  border-collapse: collapse;
588
- margin: 1rem 0;
569
+ margin: 1.25em 0;
589
570
  width: 100%;
590
571
  font-size: 0.875rem;
591
572
  }
@@ -593,7 +574,7 @@
593
574
  .qp-rich-text-editor__content th,
594
575
  .qp-rich-text-editor__content td {
595
576
  border: 1px solid var(--border-subtle);
596
- padding: 0.5rem 0.625rem;
577
+ padding: 0.5rem 0.75rem;
597
578
  text-align: left;
598
579
  vertical-align: top;
599
580
  }
@@ -615,13 +596,14 @@
615
596
  padding: 0;
616
597
  }
617
598
 
599
+ /* Slash command menu — generous spacing */
618
600
  .qp-rich-text-editor__slash {
619
601
  display: flex;
620
602
  flex-direction: column;
621
603
  gap: 0.25rem;
622
- min-width: 280px;
623
- max-width: min(360px, calc(100vw - 2rem));
624
- padding: 0.35rem;
604
+ min-width: 300px;
605
+ max-width: min(380px, calc(100vw - 2rem));
606
+ padding: 0.5rem;
625
607
  }
626
608
 
627
609
  .qp-rich-text-editor__slash-item {
@@ -629,14 +611,14 @@
629
611
  width: 100%;
630
612
  min-height: 3rem;
631
613
  align-items: center;
632
- gap: 0.625rem;
614
+ gap: 0.75rem;
633
615
  border: 1px solid transparent;
634
616
  border-radius: var(--control-radius-inner);
635
617
  background: transparent;
636
- padding: 0.45rem 0.55rem;
618
+ padding: 0.5rem 0.625rem;
637
619
  color: var(--foreground);
638
620
  font-size: 0.8125rem;
639
- line-height: 1.2;
621
+ line-height: 1.3;
640
622
  text-align: left;
641
623
  transition:
642
624
  background-color 150ms ease,
@@ -653,14 +635,15 @@
653
635
 
654
636
  .qp-rich-text-editor__slash-icon {
655
637
  display: inline-flex;
656
- width: 2rem;
657
- height: 2rem;
638
+ width: 2.25rem;
639
+ height: 2.25rem;
658
640
  flex: 0 0 auto;
659
641
  align-items: center;
660
642
  justify-content: center;
661
- border-radius: var(--radius-xs);
643
+ border-radius: var(--radius-sm);
662
644
  background: var(--surface-mid);
663
645
  color: var(--muted-foreground);
646
+ font-size: 1.125rem;
664
647
  }
665
648
 
666
649
  .qp-rich-text-editor__slash-copy {
@@ -683,14 +666,23 @@
683
666
  white-space: nowrap;
684
667
  }
685
668
 
669
+ .qp-rich-text-editor__slash-group {
670
+ padding: 0.375rem 0.625rem 0.125rem;
671
+ font-family: var(--font-chrome);
672
+ font-size: 0.6875rem;
673
+ font-weight: 600;
674
+ letter-spacing: 0.04em;
675
+ text-transform: uppercase;
676
+ color: var(--muted-foreground);
677
+ }
678
+
686
679
  .qp-rich-text-editor__slash-empty {
687
- padding: 0.5rem;
688
- font-size: 0.75rem;
680
+ padding: 0.75rem;
681
+ font-size: 0.8125rem;
689
682
  color: var(--muted-foreground);
690
683
  }
691
684
 
692
685
  @media (prefers-reduced-motion: reduce) {
693
- .qp-rich-text-editor,
694
686
  .qp-rich-text-editor__bubble,
695
687
  .qp-rich-text-editor__slash-item {
696
688
  transition: none;
@@ -700,7 +692,7 @@
700
692
  @media (max-width: 640px) {
701
693
  .qp-rich-text-editor__content {
702
694
  min-height: 200px;
703
- padding: 0.875rem 1rem 1rem;
695
+ padding: 1rem 1rem 1.25rem;
704
696
  }
705
697
 
706
698
  .qp-rich-text-editor__bubble {
@@ -714,7 +706,7 @@
714
706
  }
715
707
 
716
708
  .qp-rich-text-editor__slash {
717
- min-width: min(280px, calc(100vw - 2rem));
709
+ min-width: min(300px, calc(100vw - 2rem));
718
710
  }
719
711
  }
720
712
 
@@ -205,6 +205,7 @@ function applyRichTextConfig(config, metadata) {
205
205
  if (metadata.placeholder !== void 0) config.placeholder = metadata.placeholder;
206
206
  if (metadata.allowImages !== void 0) config.enableImages = metadata.allowImages;
207
207
  if (metadata.imageCollection !== void 0) config.imageCollection = metadata.imageCollection;
208
+ if (metadata.outputMode !== void 0) config.outputMode = metadata.outputMode;
208
209
  }
209
210
  function buildNestedFieldDefinitions(nestedFields, relations, registry) {
210
211
  const result = {};
@@ -5,6 +5,7 @@ import { getGridColumnsClass } from "../../components/fields/field-utils.mjs";
5
5
  import { getFieldName, isFieldReference } from "../../builder/types/field-types.mjs";
6
6
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../../components/ui/accordion.mjs";
7
7
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs.mjs";
8
+ import { adminCollectionKey } from "../../hooks/query-access.mjs";
8
9
  import { useCollectionFields } from "../../hooks/use-collection-fields.mjs";
9
10
  import { useCollectionMeta } from "../../hooks/use-collection-meta.mjs";
10
11
  import { useGlobalFields } from "../../hooks/use-global-fields.mjs";
@@ -393,8 +394,8 @@ function AutoFormFields({ app: _cms, collection, mode = "collection", config, re
393
394
  schemaQueryOptions: { enabled: mode === "collection" && !isActionForm && shouldFetchSchema }
394
395
  });
395
396
  const globalResult = useGlobalFields(mode === "global" ? collection : "", { schemaQueryOptions: { enabled: mode === "global" && shouldFetchSchema } });
396
- const { data: collectionMeta } = useCollectionMeta(collection, { enabled: mode === "collection" && !isActionForm });
397
- const { data: globalMeta } = useGlobalMeta(collection, { enabled: mode === "global" });
397
+ const { data: collectionMeta } = useCollectionMeta(adminCollectionKey(collection), { enabled: mode === "collection" && !isActionForm });
398
+ const { data: globalMeta } = useGlobalMeta(adminCollectionKey(collection), { enabled: mode === "global" });
398
399
  const resolvedFields = mode === "global" ? {
399
400
  ...providedFields ?? globalResult.fields,
400
401
  ...config?.fields
@@ -104,6 +104,13 @@ function DateCell({ value }) {
104
104
  children: date.toLocaleDateString()
105
105
  });
106
106
  }
107
+ function formatShortDate(date) {
108
+ const now = /* @__PURE__ */ new Date();
109
+ const sameYear = date.getFullYear() === now.getFullYear();
110
+ const month = date.toLocaleDateString(void 0, { month: "short" });
111
+ const day = date.getDate();
112
+ return sameYear ? `${month} ${day}` : `${month} ${day}, ${date.getFullYear()}`;
113
+ }
107
114
  /**
108
115
  * DateTime cell - formatted date and time display
109
116
  */
@@ -117,13 +124,9 @@ function DateTimeCell({ value }) {
117
124
  className: "text-muted-foreground",
118
125
  children: String(value)
119
126
  });
120
- return /* @__PURE__ */ jsxs("span", {
127
+ return /* @__PURE__ */ jsx("span", {
121
128
  className: "tabular-nums",
122
- children: [
123
- date.toLocaleDateString(),
124
- " ",
125
- date.toLocaleTimeString()
126
- ]
129
+ children: formatShortDate(date)
127
130
  });
128
131
  }
129
132
  /**
@@ -2,7 +2,7 @@ import { useResolveText } from "../../../i18n/hooks.mjs";
2
2
  import { useSafeContentLocales } from "../../../runtime/content-locales-provider.mjs";
3
3
  import { useScopedLocale } from "../../../runtime/locale-scope.mjs";
4
4
  import { LocaleSwitcher } from "../../../components/locale-switcher.mjs";
5
- import { DefaultCell, TextCell } from "../cells/primitive-cells.mjs";
5
+ import { DateCell, DateTimeCell, DefaultCell, TextCell } from "../cells/primitive-cells.mjs";
6
6
  import { normalizeColumnConfig } from "../../../builder/types/collection-types.mjs";
7
7
  import { computeDefaultColumns, formatHeader } from "./column-defaults.mjs";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -133,6 +133,8 @@ function buildColumns(options) {
133
133
  let CellComponent;
134
134
  if (normalized.cell) CellComponent = normalized.cell;
135
135
  else if (fieldDef?.cell) CellComponent = fieldDef.cell;
136
+ else if (fieldType === "datetime") CellComponent = DateTimeCell;
137
+ else if (fieldType === "date") CellComponent = DateCell;
136
138
  else CellComponent = DefaultCell;
137
139
  const needsFieldDef = FIELD_TYPES_NEEDING_FIELD_DEF.has(fieldType);
138
140
  const accessorKey = (fieldType === "relation" || fieldType === "upload" || fieldType === "uploadMany") && fieldOptions.relationName ? fieldOptions.relationName : fieldName;
@@ -6,6 +6,7 @@ import { Skeleton } from "../../components/ui/skeleton.mjs";
6
6
  import { scopeDependencies, trackDependencies } from "../../utils/dependency-tracker.mjs";
7
7
  import { buildComponentProps, getFieldContext, getFieldOptions, getFullFieldName } from "./field-context.mjs";
8
8
  import { useFieldHooks } from "../../hooks/use-field-hooks.mjs";
9
+ import { mergeReactiveFieldState, useReactiveFieldState } from "../../hooks/use-reactive-fields.mjs";
9
10
  import { useReactiveProps } from "../../hooks/use-reactive-prop.mjs";
10
11
  import * as React from "react";
11
12
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -178,6 +179,12 @@ function FieldRenderer({ fieldName, fieldDef, collection, mode = "collection", r
178
179
  entityMeta: entityMetaProp,
179
180
  formValues
180
181
  });
182
+ const reactiveFieldState = useReactiveFieldState(fullFieldName);
183
+ const effectiveFieldState = mergeReactiveFieldState({
184
+ hidden: context.isHidden,
185
+ readOnly: context.isReadOnly,
186
+ disabled: context.isDisabled
187
+ }, reactiveFieldState);
181
188
  const { Component: resolvedComponent, loading: componentLoading } = useLazyComponent(context.component);
182
189
  const clientSideCompute = typeof fieldOptions.compute === "function" ? fieldOptions.compute : void 0;
183
190
  const { handleChange, computedValue, isComputed, options: hookOptions, optionsLoading } = useFieldHooks({
@@ -200,9 +207,9 @@ function FieldRenderer({ fieldName, fieldDef, collection, mode = "collection", r
200
207
  ...stripFieldUiOptions(getFieldOptions(fieldDef)),
201
208
  ...extraProps ?? {}
202
209
  }), [fieldDef, extraProps]),
203
- enabled: !context.isHidden && !!fieldDef
210
+ enabled: !effectiveFieldState.hidden && !!fieldDef
204
211
  });
205
- if (context.isHidden) return null;
212
+ if (effectiveFieldState.hidden) return null;
206
213
  if (!fieldDef) return renderConfigError(`Field "${fieldName}" not found in ${mode === "global" ? "global" : "collection"} "${collection}" config.`);
207
214
  const fieldValue = isComputed ? computedValue : watchedFieldValue === void 0 ? rawComponentProps.value : watchedFieldValue;
208
215
  const componentProps = {
@@ -212,7 +219,8 @@ function FieldRenderer({ fieldName, fieldDef, collection, mode = "collection", r
212
219
  onChange: handleChange,
213
220
  options: resolvedOptions,
214
221
  optionsLoading,
215
- readOnly: rawComponentProps.readOnly || isComputed,
222
+ readOnly: effectiveFieldState.readOnly || isComputed,
223
+ disabled: effectiveFieldState.disabled === true,
216
224
  label: resolveText(rawComponentProps.label, "", formValues),
217
225
  description: resolveText(rawComponentProps.description, "", formValues),
218
226
  placeholder: resolveText(rawComponentProps.placeholder, "", formValues)