@propriety/court-calendar 1.0.158 → 1.0.159

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,11 @@
1
1
  import { ReactNode } from 'react';
2
- export default function PortalFab({ in: visible, tooltip, icon, onClick, badgeContent, containerId, bottom, right, color, }: {
2
+ export default function PortalFab({ in: visible, tooltip, icon, onClick, disabled, badgeContent, containerId, bottom, right, color, }: {
3
3
  in: boolean;
4
4
  tooltip: string;
5
5
  icon: ReactNode;
6
6
  onClick: (e: React.MouseEvent<HTMLElement>) => void;
7
+ /** Blocks the FAB while its action is running — a Fab is clickable for as long as it is visible. */
8
+ disabled?: boolean;
7
9
  badgeContent?: number;
8
10
  containerId?: string;
9
11
  bottom?: number;
@@ -1,8 +1,8 @@
1
1
  import { ModalMode } from '../types';
2
2
  export default function ModalActions({ modalMode, onDelete, onSave, setModalMode, setIsOpen, isAdmin, createdBy, createdOn, }: {
3
3
  modalMode: ModalMode;
4
- onDelete: () => void;
5
- onSave: () => void;
4
+ onDelete: () => void | Promise<unknown>;
5
+ onSave: () => void | Promise<unknown>;
6
6
  setModalMode: (mode: ModalMode) => void;
7
7
  setIsOpen: (isOpen: boolean) => void;
8
8
  isAdmin: boolean;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Wraps an async action so a second click cannot start it while the first is still running.
3
+ *
4
+ * Every mutating button in this app is a multi-second round trip with no feedback of its own,
5
+ * which makes clicking again the natural response to "nothing happened". Creating a court date
6
+ * that way sent a second POST for the same date, and the server — whose duplicate check could
7
+ * not see a date it had not committed yet — inserted it again and answered 500, over a date
8
+ * that had in fact been created correctly.
9
+ *
10
+ * The guarantee is the ref, not `busy`: two clicks can land before React re-renders with the
11
+ * new state, and both would read `busy === false`. `busy` exists only to drive the button's
12
+ * disabled state and label. Deliberately no `useCallback` — the ref persists across renders
13
+ * whatever `run`'s identity is, so a stable identity would buy nothing.
14
+ *
15
+ * An action that throws is reported rather than left as an unhandled rejection: these run from
16
+ * click handlers, which have nowhere to propagate to but the console.
17
+ *
18
+ * @param action The work to run. Its promise is awaited, so the guard covers the whole call.
19
+ * @param operation What the user was trying to do, for the error report ("Delete court date").
20
+ * @returns `[busy, run]` — `busy` for `disabled`/label, `run` for `onClick`.
21
+ */
22
+ export declare function useGuardedAction(action: () => void | Promise<unknown>, operation: string): [boolean, () => Promise<void>];