@carlonicora/nextjs-jsonapi 1.123.2 → 1.124.1

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 (30) hide show
  1. package/dist/{BlockNoteEditor-FMTBHYZB.mjs → BlockNoteEditor-LN6P5CEQ.mjs} +2 -2
  2. package/dist/{BlockNoteEditor-6NV6WSQH.js → BlockNoteEditor-YIZGXB5K.js} +9 -9
  3. package/dist/{BlockNoteEditor-6NV6WSQH.js.map → BlockNoteEditor-YIZGXB5K.js.map} +1 -1
  4. package/dist/billing/index.js +299 -299
  5. package/dist/billing/index.mjs +1 -1
  6. package/dist/{chunk-63FZJ7UK.js → chunk-FOKYS5QE.js} +840 -587
  7. package/dist/chunk-FOKYS5QE.js.map +1 -0
  8. package/dist/{chunk-J2ACFNKE.mjs → chunk-NXRUJIU2.mjs} +3132 -2879
  9. package/dist/chunk-NXRUJIU2.mjs.map +1 -0
  10. package/dist/client/index.js +2 -2
  11. package/dist/client/index.mjs +1 -1
  12. package/dist/components/index.d.mts +179 -123
  13. package/dist/components/index.d.ts +179 -123
  14. package/dist/components/index.js +12 -2
  15. package/dist/components/index.js.map +1 -1
  16. package/dist/components/index.mjs +11 -1
  17. package/dist/contexts/index.js +2 -2
  18. package/dist/contexts/index.mjs +1 -1
  19. package/dist/features/help/index.js +30 -30
  20. package/dist/features/help/index.mjs +1 -1
  21. package/package.json +1 -1
  22. package/src/components/containers/RoundPageContainer.tsx +20 -20
  23. package/src/components/forms/EntityMultiSelector.tsx +15 -3
  24. package/src/components/forms/EntitySelector.tsx +256 -0
  25. package/src/components/forms/FormLayout.tsx +58 -0
  26. package/src/components/forms/index.ts +10 -8
  27. package/src/components/forms/useEditorDialog.ts +21 -4
  28. package/dist/chunk-63FZJ7UK.js.map +0 -1
  29. package/dist/chunk-J2ACFNKE.mjs.map +0 -1
  30. /package/dist/{BlockNoteEditor-FMTBHYZB.mjs.map → BlockNoteEditor-LN6P5CEQ.mjs.map} +0 -0
@@ -0,0 +1,58 @@
1
+ import { ReactNode } from "react";
2
+ import { cn } from "../../utils";
3
+
4
+ // FormBody — the rhythm container; replaces an editor's root <div className="flex w-full flex-col">
5
+ export function FormBody({ children, className }: { children: ReactNode; className?: string }) {
6
+ return <div className={cn("flex w-full flex-col gap-4", className)}>{children}</div>;
7
+ }
8
+
9
+ // FormSection — titled/untitled group; pt-4 (first:pt-0) yields 32px before the header
10
+ export function FormSection({
11
+ title,
12
+ children,
13
+ className,
14
+ }: {
15
+ title?: ReactNode;
16
+ children: ReactNode;
17
+ className?: string;
18
+ }) {
19
+ return (
20
+ <section className={cn("flex flex-col gap-4 pt-4 first:pt-0", className)}>
21
+ {title && <h3 className="text-lg font-semibold">{title}</h3>}
22
+ {children}
23
+ </section>
24
+ );
25
+ }
26
+
27
+ // FormRow — responsive column grid, both axes gapped
28
+ export function FormRow({
29
+ children,
30
+ columns = 2,
31
+ className,
32
+ }: {
33
+ children: ReactNode;
34
+ columns?: 2 | 3;
35
+ className?: string;
36
+ }) {
37
+ return (
38
+ <div
39
+ className={cn("grid grid-cols-1 gap-x-4 gap-y-4", columns === 3 ? "md:grid-cols-3" : "md:grid-cols-2", className)}
40
+ >
41
+ {children}
42
+ </div>
43
+ );
44
+ }
45
+
46
+ // FormCol — column span for a child inside FormRow (replaces <div className="md:col-span-2">)
47
+ export function FormCol({
48
+ children,
49
+ span = 1,
50
+ className,
51
+ }: {
52
+ children: ReactNode;
53
+ span?: 1 | 2 | 3;
54
+ className?: string;
55
+ }) {
56
+ const spanClass = span === 3 ? "md:col-span-3" : span === 2 ? "md:col-span-2" : "";
57
+ return <div className={cn(spanClass, className)}>{children}</div>;
58
+ }
@@ -1,22 +1,24 @@
1
+ export { FormFeatures } from "../../features/feature/components/forms/FormFeatures";
1
2
  export * from "./CommonAssociationForm";
2
- export * from "./EntityMultiSelector";
3
3
  export * from "./CommonDeleter";
4
4
  export * from "./CommonEditorButtons";
5
- export * from "./CommonEditorHeader";
6
5
  export * from "./CommonEditorDiscardDialog";
6
+ export * from "./CommonEditorHeader";
7
7
  export * from "./CommonEditorTrigger";
8
- export * from "./useEditorDialog";
9
- export * from "./EditorSheet";
8
+ export * from "./CurrencyInput";
10
9
  export * from "./DatePickerPopover";
11
10
  export * from "./DateRangeSelector";
11
+ export * from "./EditorSheet";
12
+ export * from "./EntityMultiSelector";
13
+ export { default as EntitySelector } from "./EntitySelector";
12
14
  export * from "./FileUploader";
13
- export * from "./CurrencyInput";
14
- export * from "./FormCheckbox";
15
15
  export * from "./FormBlockNote";
16
- export * from "./FormFieldWrapper";
16
+ export * from "./FormCheckbox";
17
17
  export * from "./FormDate";
18
18
  export * from "./FormDateTime";
19
+ export * from "./FormFieldWrapper";
19
20
  export * from "./FormInput";
21
+ export * from "./FormLayout";
20
22
  export * from "./FormPassword";
21
23
  export * from "./FormPlaceAutocomplete";
22
24
  export * from "./FormSelect";
@@ -26,4 +28,4 @@ export * from "./FormTextarea";
26
28
  export * from "./GdprConsentCheckbox";
27
29
  export * from "./MultiFileUploader";
28
30
  export * from "./PasswordInput";
29
- export { FormFeatures } from "../../features/feature/components/forms/FormFeatures";
31
+ export * from "./useEditorDialog";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
4
 
5
5
  type UseEditorDialogOptions = {
6
6
  dialogOpen?: boolean;
@@ -24,15 +24,32 @@ export function useEditorDialog(isFormDirty: () => boolean, options?: UseEditorD
24
24
  const [open, setOpen] = useState<boolean>(false);
25
25
  const [showDiscardConfirm, setShowDiscardConfirm] = useState<boolean>(false);
26
26
 
27
- // Sync open state from external dialogOpen prop
27
+ // Marks that the pending `open` change originated FROM the dialogOpen prop
28
+ // (the sync effect below), so the notify effect must not echo it back to the
29
+ // parent. Without this guard the two effects form an unguarded two-way
30
+ // binding: on mount `open` (false) and `dialogOpen` (true) disagree, so one
31
+ // effect pushes open→parent while the other pulls parent→open, and they chase
32
+ // each other every render → "Maximum update depth exceeded".
33
+ const syncingFromProp = useRef(false);
34
+
35
+ // Sync open state from external dialogOpen prop.
36
+ // `open` is intentionally NOT a dependency: this effect must run only when the
37
+ // prop changes. Adding `open` would re-fire on internal closes and immediately
38
+ // re-open the dialog (dialogOpen still true while open just went false).
28
39
  useEffect(() => {
29
- if (options?.dialogOpen !== undefined) {
40
+ if (options?.dialogOpen !== undefined && options.dialogOpen !== open) {
41
+ syncingFromProp.current = true;
30
42
  setOpen(options.dialogOpen);
31
43
  }
32
44
  }, [options?.dialogOpen]);
33
45
 
34
- // Notify parent when open state changes
46
+ // Notify parent when open state changes — but skip the echo when this change
47
+ // was driven by the dialogOpen prop above (otherwise it ping-pongs).
35
48
  useEffect(() => {
49
+ if (syncingFromProp.current) {
50
+ syncingFromProp.current = false;
51
+ return;
52
+ }
36
53
  if (typeof options?.onDialogOpenChange === "function") {
37
54
  options.onDialogOpenChange(open);
38
55
  }