@sproutsocial/seeds-react-modal 2.2.5 → 2.4.0

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.
@@ -8,34 +8,34 @@ $ tsup --dts
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.js 37.00 KB
12
- CJS dist/v1/index.js 9.86 KB
13
- CJS dist/v2/index.js 28.98 KB
14
- CJS dist/index.js.map 66.80 KB
15
- CJS dist/v1/index.js.map 13.03 KB
16
- CJS dist/v2/index.js.map 53.42 KB
17
- CJS ⚡️ Build success in 212ms
18
- ESM dist/esm/v1/index.js 165.00 B
19
- ESM dist/esm/v2/index.js 596.00 B
20
11
  ESM dist/esm/index.js 583.00 B
12
+ ESM dist/esm/v1/index.js 165.00 B
13
+ ESM dist/esm/v2/index.js 746.00 B
21
14
  ESM dist/esm/chunk-IYDY4OPB.js 7.12 KB
22
- ESM dist/esm/chunk-UP2XQN57.js 24.15 KB
15
+ ESM dist/esm/chunk-TQ44T5IM.js 26.85 KB
16
+ ESM dist/esm/index.js.map 1.05 KB
23
17
  ESM dist/esm/v1/index.js.map 71.00 B
24
18
  ESM dist/esm/v2/index.js.map 71.00 B
25
- ESM dist/esm/index.js.map 1.05 KB
26
19
  ESM dist/esm/chunk-IYDY4OPB.js.map 12.85 KB
27
- ESM dist/esm/chunk-UP2XQN57.js.map 52.53 KB
28
- ESM ⚡️ Build success in 217ms
20
+ ESM dist/esm/chunk-TQ44T5IM.js.map 63.46 KB
21
+ ESM ⚡️ Build success in 280ms
22
+ CJS dist/index.js 39.00 KB
23
+ CJS dist/v1/index.js 9.86 KB
24
+ CJS dist/v2/index.js 31.92 KB
25
+ CJS dist/index.js.map 77.26 KB
26
+ CJS dist/v1/index.js.map 13.03 KB
27
+ CJS dist/v2/index.js.map 64.54 KB
28
+ CJS ⚡️ Build success in 284ms
29
29
  DTS Build start
30
- DTS ⚡️ Build success in 16936ms
30
+ DTS ⚡️ Build success in 19209ms
31
31
  DTS dist/index.d.ts 975.00 B
32
32
  DTS dist/v1/index.d.ts 413.00 B
33
- DTS dist/v2/index.d.ts 1021.00 B
33
+ DTS dist/v2/index.d.ts 3.72 KB
34
34
  DTS dist/Modal-ki8oiGbC.d.ts 2.52 KB
35
- DTS dist/ModalAction-gIgCE73I.d.ts 15.19 KB
35
+ DTS dist/ModalAction-BHG3Zbd9.d.ts 20.46 KB
36
36
  DTS dist/index.d.mts 978.00 B
37
37
  DTS dist/v1/index.d.mts 415.00 B
38
- DTS dist/v2/index.d.mts 1022.00 B
38
+ DTS dist/v2/index.d.mts 3.72 KB
39
39
  DTS dist/Modal-ki8oiGbC.d.mts 2.52 KB
40
- DTS dist/ModalAction-gIgCE73I.d.mts 15.19 KB
41
- Done in 19.68s.
40
+ DTS dist/ModalAction-BHG3Zbd9.d.mts 20.46 KB
41
+ Done in 22.38s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @sproutsocial/seeds-react-modal
2
2
 
3
+ ## 2.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4a7f66e: Add external trigger helpers for Modal V2:
8
+
9
+ - Add `useModalExternalTrigger` hook that manages refs and provides ARIA attributes and focus restoration callback for external triggers
10
+ - Add `ModalExternalTrigger` component (Button wrapper with automatic ARIA attributes for external triggers)
11
+ - Update Modal V2 documentation with external trigger patterns and composition proposal
12
+
13
+ ## 2.3.0
14
+
15
+ ### Minor Changes
16
+
17
+ - c76c353: Add modal interaction control to Modal v2 with both convenience props and Radix UI event handlers.
18
+
19
+ Convenience Boolean Props (recommended for simple cases):
20
+
21
+ - `disableOutsideClickClose`: Prevents modal from closing when clicking outside. Custom `onInteractOutside` handlers still fire for side effects.
22
+ - `disableEscapeKeyClose`: Prevents modal from closing when pressing Escape key. Custom `onEscapeKeyDown` handlers still fire for side effects.
23
+
24
+ Radix UI Dialog.Content Event Handlers (for granular control):
25
+
26
+ - `onInteractOutside`: Control behavior when user interacts outside the modal
27
+ - `onEscapeKeyDown`: Control behavior when Escape key is pressed
28
+ - `onPointerDownOutside`: Handle pointer down events outside the modal
29
+ - `onFocusOutside`: Handle focus moving outside the modal
30
+ - `onOpenAutoFocus`: Handle focus behavior when modal opens
31
+ - `onCloseAutoFocus`: Handle focus behavior when modal closes
32
+
33
+ Boolean props can be combined with event handlers - the boolean prevents closing while the handler adds custom side effects like analytics or warnings.
34
+
35
+ Draggable Modal Restrictions: `disableOutsideClickClose` and `onInteractOutside` are not supported for draggable modals (TypeScript will error) as they conflict with the draggable UX. All other props including `disableEscapeKeyClose` work with draggable modals. This is enforced through TypeScript discriminated union types.
36
+
37
+ ### Patch Changes
38
+
39
+ - @sproutsocial/seeds-react-theme@3.3.2
40
+ - @sproutsocial/seeds-react-box@1.1.10
41
+ - @sproutsocial/seeds-react-icon@2.1.1
42
+ - @sproutsocial/seeds-react-button@1.3.12
43
+
3
44
  ## 2.2.5
4
45
 
5
46
  ### Patch Changes
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
2
3
  import * as styled_components from 'styled-components';
3
4
  import * as _sproutsocial_seeds_react_box from '@sproutsocial/seeds-react-box';
4
5
  import { TypeContainerProps, TypeBoxProps } from '@sproutsocial/seeds-react-box';
5
- import * as React from 'react';
6
6
  import * as Dialog from '@radix-ui/react-dialog';
7
7
  import { TypeIconName } from '@sproutsocial/seeds-react-icon';
8
8
 
@@ -111,6 +111,16 @@ type TypeModalActionProps = ({
111
111
  /** Click handler for the button */
112
112
  onClick?: () => void;
113
113
  } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick">);
114
+ /**
115
+ * Event handler props from Radix UI Dialog.Content.
116
+ * These control modal interaction behavior like closing on outside clicks or escape key.
117
+ */
118
+ type DialogContentEventHandlers = Pick<React.ComponentPropsWithoutRef<typeof Dialog.Content>, "onOpenAutoFocus" | "onCloseAutoFocus" | "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside">;
119
+ /**
120
+ * Dialog.Content event handlers excluding onInteractOutside.
121
+ * Used for draggable modals where onInteractOutside conflicts with the draggable UX.
122
+ */
123
+ type DialogContentEventHandlersWithoutInteractOutside = Omit<DialogContentEventHandlers, "onInteractOutside">;
114
124
  /**
115
125
  * Base common props shared by all modal variants (without close button props).
116
126
  */
@@ -139,6 +149,16 @@ type TypeModalCommonPropsBase = TypeContainerProps & Omit<React.ComponentPropsWi
139
149
  actions?: TypeModalActionProps[];
140
150
  /** Controls the z-index CSS property (defaults to 6 to match Modal v1) */
141
151
  zIndex?: number;
152
+ /**
153
+ * Prevents the modal from closing when clicking outside.
154
+ * The onInteractOutside handler will still be called if provided.
155
+ */
156
+ disableOutsideClickClose?: boolean;
157
+ /**
158
+ * Prevents the modal from closing when pressing the Escape key.
159
+ * The onEscapeKeyDown handler will still be called if provided.
160
+ */
161
+ disableEscapeKeyClose?: boolean;
142
162
  };
143
163
  /**
144
164
  * Common props with close button accessibility enforcement.
@@ -194,13 +214,23 @@ type TypeModalCommonProps = (TypeModalCommonPropsBase & {
194
214
  /**
195
215
  * Base props with draggable and showOverlay relationship enforced.
196
216
  *
197
- * When draggable is true, showOverlay must be false because the overlay
198
- * would block interaction with content behind the modal.
217
+ * When draggable is true:
218
+ * - showOverlay must be false (overlay would block interaction with content behind the modal)
219
+ * - onInteractOutside is not allowed (conflicts with draggable UX which needs to keep modal open)
220
+ * - disableOutsideClickClose is not allowed (since onInteractOutside is not supported)
221
+ *
222
+ * When draggable is false (or undefined):
223
+ * - All Dialog.Content event handlers are available including onInteractOutside
224
+ * - disableOutsideClickClose can be used
199
225
  */
200
- type TypeModalBaseProps = (TypeModalCommonProps & {
226
+ type TypeModalBaseProps = (TypeModalCommonProps & DialogContentEventHandlersWithoutInteractOutside & {
201
227
  draggable: true;
202
228
  showOverlay?: false;
203
- }) | (TypeModalCommonProps & {
229
+ /** onInteractOutside is not supported for draggable modals */
230
+ onInteractOutside?: never;
231
+ /** disableOutsideClickClose is not supported for draggable modals */
232
+ disableOutsideClickClose?: never;
233
+ }) | (TypeModalCommonProps & DialogContentEventHandlers & {
204
234
  draggable?: false;
205
235
  showOverlay?: boolean;
206
236
  });
@@ -303,6 +333,121 @@ type TypeModalProps = TypeModalPropsWithTitle | TypeModalPropsWithSubtitleOnly |
303
333
  * </Modal>
304
334
  */
305
335
  declare const Modal: (props: TypeModalProps) => react_jsx_runtime.JSX.Element;
336
+ /**
337
+ * Hook for adding proper ARIA attributes to external modal triggers.
338
+ *
339
+ * ⚠️ **NOT RECOMMENDED** - Prefer using modalTrigger prop or ModalTrigger component.
340
+ * Use this hook ONLY as a last resort when architectural constraints prevent keeping
341
+ * the trigger inside the Modal component tree.
342
+ *
343
+ * **Important Limitations:**
344
+ * - This hook only provides ARIA attributes (aria-haspopup, aria-expanded)
345
+ * - Focus restoration is NOT automatic - you must manually handle it with refs
346
+ * - Radix UI cannot track external triggers for proper accessibility
347
+ *
348
+ * **Why modalTrigger prop is better:**
349
+ * - Automatic ARIA attributes
350
+ * - Automatic focus restoration
351
+ * - Better touch device support
352
+ * - Follows WAI-ARIA Dialog best practices
353
+ *
354
+ * @param isOpen - Current open state of the modal
355
+ * @param modalId - Optional ID of the modal element for aria-controls
356
+ * @returns Object with ARIA attributes to spread onto trigger element
357
+ *
358
+ * @example
359
+ * ```tsx
360
+ * // Manual focus restoration required
361
+ * const [isOpen, setIsOpen] = useState(false);
362
+ * const triggerRef = useRef<HTMLButtonElement>(null);
363
+ * const triggerProps = useModalTriggerProps(isOpen);
364
+ *
365
+ * return (
366
+ * <>
367
+ * <Button
368
+ * ref={triggerRef}
369
+ * {...triggerProps}
370
+ * onClick={() => setIsOpen(true)}
371
+ * >
372
+ * Open Modal
373
+ * </Button>
374
+ * <Modal
375
+ * open={isOpen}
376
+ * onOpenChange={setIsOpen}
377
+ * onCloseAutoFocus={(e) => {
378
+ * e.preventDefault();
379
+ * triggerRef.current?.focus();
380
+ * }}
381
+ * >
382
+ * <ModalBody>Content</ModalBody>
383
+ * </Modal>
384
+ * </>
385
+ * );
386
+ * ```
387
+ */
388
+ declare function useModalTriggerProps(isOpen: boolean, modalId?: string): {
389
+ "aria-haspopup": "dialog";
390
+ "aria-expanded": boolean;
391
+ "aria-controls"?: string;
392
+ };
393
+ /**
394
+ * Hook for managing external modal triggers with automatic focus restoration.
395
+ *
396
+ * ⚠️ **NOT RECOMMENDED** - Prefer using modalTrigger prop or ModalTrigger component.
397
+ * Use this hook ONLY as a last resort when architectural constraints prevent keeping
398
+ * the trigger inside the Modal component tree.
399
+ *
400
+ * This hook improves upon useModalTriggerProps by managing the trigger ref internally
401
+ * and providing the onCloseAutoFocus callback, eliminating the need for manual
402
+ * focus restoration boilerplate.
403
+ *
404
+ * **Improvements over useModalTriggerProps:**
405
+ * - ✅ No manual ref creation
406
+ * - ✅ Automatic focus restoration via onCloseAutoFocus callback
407
+ * - ✅ Automatic ARIA attributes
408
+ *
409
+ * **Why modalTrigger prop is still better:**
410
+ * - Better touch device support
411
+ * - Follows WAI-ARIA Dialog best practices
412
+ * - Less boilerplate overall
413
+ *
414
+ * @param modalId - Optional ID of the modal element for aria-controls
415
+ * @returns Object with triggerRef, ARIA props, and onCloseAutoFocus callback
416
+ *
417
+ * @example
418
+ * ```tsx
419
+ * const [isOpen, setIsOpen] = useState(false);
420
+ * const { triggerRef, triggerProps, onCloseAutoFocus } = useModalExternalTrigger();
421
+ *
422
+ * return (
423
+ * <>
424
+ * <Button
425
+ * ref={triggerRef}
426
+ * {...triggerProps(isOpen)}
427
+ * onClick={() => setIsOpen(true)}
428
+ * >
429
+ * Open Modal
430
+ * </Button>
431
+ * <Modal
432
+ * open={isOpen}
433
+ * onOpenChange={setIsOpen}
434
+ * onCloseAutoFocus={onCloseAutoFocus}
435
+ * >
436
+ * <ModalBody>Content</ModalBody>
437
+ * </Modal>
438
+ * </>
439
+ * );
440
+ * ```
441
+ */
442
+ declare function useModalExternalTrigger<T extends HTMLElement = HTMLButtonElement>(modalId?: string): {
443
+ triggerRef: React.RefObject<T>;
444
+ triggerProps: (isOpen: boolean) => {
445
+ "aria-controls"?: string | undefined;
446
+ "aria-haspopup": "dialog";
447
+ "aria-expanded": boolean;
448
+ };
449
+ onCloseAutoFocus: (e: Event) => void;
450
+ };
306
451
 
307
452
  interface HeaderProps {
308
453
  draggable?: boolean;
@@ -416,4 +561,4 @@ declare const ModalRail: React.FC<TypeModalRailProps>;
416
561
 
417
562
  declare const ModalAction: React.FC<TypeModalActionProps>;
418
563
 
419
- export { Modal as M, type TypeModalProps as T, ModalDescription as a, ModalHeader as b, ModalFooter as c, ModalBody as d, ModalCloseWrapper as e, ModalRail as f, ModalAction as g, ModalCustomHeader as h, ModalCustomFooter as i, type TypeModalHeaderProps as j, type TypeModalFooterProps as k, type TypeModalBodyProps as l, type TypeModalDescriptionProps as m, type TypeModalRailProps as n, type TypeModalActionProps as o, type ModalCloseWrapperProps as p };
564
+ export { Modal as M, type TypeModalProps as T, ModalDescription as a, ModalHeader as b, ModalFooter as c, ModalBody as d, ModalCloseWrapper as e, ModalRail as f, ModalAction as g, ModalCustomHeader as h, ModalCustomFooter as i, type TypeModalHeaderProps as j, type TypeModalFooterProps as k, type TypeModalBodyProps as l, type TypeModalDescriptionProps as m, type TypeModalRailProps as n, type TypeModalActionProps as o, type ModalCloseWrapperProps as p, useModalExternalTrigger as q, useModalTriggerProps as u };
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
2
3
  import * as styled_components from 'styled-components';
3
4
  import * as _sproutsocial_seeds_react_box from '@sproutsocial/seeds-react-box';
4
5
  import { TypeContainerProps, TypeBoxProps } from '@sproutsocial/seeds-react-box';
5
- import * as React from 'react';
6
6
  import * as Dialog from '@radix-ui/react-dialog';
7
7
  import { TypeIconName } from '@sproutsocial/seeds-react-icon';
8
8
 
@@ -111,6 +111,16 @@ type TypeModalActionProps = ({
111
111
  /** Click handler for the button */
112
112
  onClick?: () => void;
113
113
  } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick">);
114
+ /**
115
+ * Event handler props from Radix UI Dialog.Content.
116
+ * These control modal interaction behavior like closing on outside clicks or escape key.
117
+ */
118
+ type DialogContentEventHandlers = Pick<React.ComponentPropsWithoutRef<typeof Dialog.Content>, "onOpenAutoFocus" | "onCloseAutoFocus" | "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside">;
119
+ /**
120
+ * Dialog.Content event handlers excluding onInteractOutside.
121
+ * Used for draggable modals where onInteractOutside conflicts with the draggable UX.
122
+ */
123
+ type DialogContentEventHandlersWithoutInteractOutside = Omit<DialogContentEventHandlers, "onInteractOutside">;
114
124
  /**
115
125
  * Base common props shared by all modal variants (without close button props).
116
126
  */
@@ -139,6 +149,16 @@ type TypeModalCommonPropsBase = TypeContainerProps & Omit<React.ComponentPropsWi
139
149
  actions?: TypeModalActionProps[];
140
150
  /** Controls the z-index CSS property (defaults to 6 to match Modal v1) */
141
151
  zIndex?: number;
152
+ /**
153
+ * Prevents the modal from closing when clicking outside.
154
+ * The onInteractOutside handler will still be called if provided.
155
+ */
156
+ disableOutsideClickClose?: boolean;
157
+ /**
158
+ * Prevents the modal from closing when pressing the Escape key.
159
+ * The onEscapeKeyDown handler will still be called if provided.
160
+ */
161
+ disableEscapeKeyClose?: boolean;
142
162
  };
143
163
  /**
144
164
  * Common props with close button accessibility enforcement.
@@ -194,13 +214,23 @@ type TypeModalCommonProps = (TypeModalCommonPropsBase & {
194
214
  /**
195
215
  * Base props with draggable and showOverlay relationship enforced.
196
216
  *
197
- * When draggable is true, showOverlay must be false because the overlay
198
- * would block interaction with content behind the modal.
217
+ * When draggable is true:
218
+ * - showOverlay must be false (overlay would block interaction with content behind the modal)
219
+ * - onInteractOutside is not allowed (conflicts with draggable UX which needs to keep modal open)
220
+ * - disableOutsideClickClose is not allowed (since onInteractOutside is not supported)
221
+ *
222
+ * When draggable is false (or undefined):
223
+ * - All Dialog.Content event handlers are available including onInteractOutside
224
+ * - disableOutsideClickClose can be used
199
225
  */
200
- type TypeModalBaseProps = (TypeModalCommonProps & {
226
+ type TypeModalBaseProps = (TypeModalCommonProps & DialogContentEventHandlersWithoutInteractOutside & {
201
227
  draggable: true;
202
228
  showOverlay?: false;
203
- }) | (TypeModalCommonProps & {
229
+ /** onInteractOutside is not supported for draggable modals */
230
+ onInteractOutside?: never;
231
+ /** disableOutsideClickClose is not supported for draggable modals */
232
+ disableOutsideClickClose?: never;
233
+ }) | (TypeModalCommonProps & DialogContentEventHandlers & {
204
234
  draggable?: false;
205
235
  showOverlay?: boolean;
206
236
  });
@@ -303,6 +333,121 @@ type TypeModalProps = TypeModalPropsWithTitle | TypeModalPropsWithSubtitleOnly |
303
333
  * </Modal>
304
334
  */
305
335
  declare const Modal: (props: TypeModalProps) => react_jsx_runtime.JSX.Element;
336
+ /**
337
+ * Hook for adding proper ARIA attributes to external modal triggers.
338
+ *
339
+ * ⚠️ **NOT RECOMMENDED** - Prefer using modalTrigger prop or ModalTrigger component.
340
+ * Use this hook ONLY as a last resort when architectural constraints prevent keeping
341
+ * the trigger inside the Modal component tree.
342
+ *
343
+ * **Important Limitations:**
344
+ * - This hook only provides ARIA attributes (aria-haspopup, aria-expanded)
345
+ * - Focus restoration is NOT automatic - you must manually handle it with refs
346
+ * - Radix UI cannot track external triggers for proper accessibility
347
+ *
348
+ * **Why modalTrigger prop is better:**
349
+ * - Automatic ARIA attributes
350
+ * - Automatic focus restoration
351
+ * - Better touch device support
352
+ * - Follows WAI-ARIA Dialog best practices
353
+ *
354
+ * @param isOpen - Current open state of the modal
355
+ * @param modalId - Optional ID of the modal element for aria-controls
356
+ * @returns Object with ARIA attributes to spread onto trigger element
357
+ *
358
+ * @example
359
+ * ```tsx
360
+ * // Manual focus restoration required
361
+ * const [isOpen, setIsOpen] = useState(false);
362
+ * const triggerRef = useRef<HTMLButtonElement>(null);
363
+ * const triggerProps = useModalTriggerProps(isOpen);
364
+ *
365
+ * return (
366
+ * <>
367
+ * <Button
368
+ * ref={triggerRef}
369
+ * {...triggerProps}
370
+ * onClick={() => setIsOpen(true)}
371
+ * >
372
+ * Open Modal
373
+ * </Button>
374
+ * <Modal
375
+ * open={isOpen}
376
+ * onOpenChange={setIsOpen}
377
+ * onCloseAutoFocus={(e) => {
378
+ * e.preventDefault();
379
+ * triggerRef.current?.focus();
380
+ * }}
381
+ * >
382
+ * <ModalBody>Content</ModalBody>
383
+ * </Modal>
384
+ * </>
385
+ * );
386
+ * ```
387
+ */
388
+ declare function useModalTriggerProps(isOpen: boolean, modalId?: string): {
389
+ "aria-haspopup": "dialog";
390
+ "aria-expanded": boolean;
391
+ "aria-controls"?: string;
392
+ };
393
+ /**
394
+ * Hook for managing external modal triggers with automatic focus restoration.
395
+ *
396
+ * ⚠️ **NOT RECOMMENDED** - Prefer using modalTrigger prop or ModalTrigger component.
397
+ * Use this hook ONLY as a last resort when architectural constraints prevent keeping
398
+ * the trigger inside the Modal component tree.
399
+ *
400
+ * This hook improves upon useModalTriggerProps by managing the trigger ref internally
401
+ * and providing the onCloseAutoFocus callback, eliminating the need for manual
402
+ * focus restoration boilerplate.
403
+ *
404
+ * **Improvements over useModalTriggerProps:**
405
+ * - ✅ No manual ref creation
406
+ * - ✅ Automatic focus restoration via onCloseAutoFocus callback
407
+ * - ✅ Automatic ARIA attributes
408
+ *
409
+ * **Why modalTrigger prop is still better:**
410
+ * - Better touch device support
411
+ * - Follows WAI-ARIA Dialog best practices
412
+ * - Less boilerplate overall
413
+ *
414
+ * @param modalId - Optional ID of the modal element for aria-controls
415
+ * @returns Object with triggerRef, ARIA props, and onCloseAutoFocus callback
416
+ *
417
+ * @example
418
+ * ```tsx
419
+ * const [isOpen, setIsOpen] = useState(false);
420
+ * const { triggerRef, triggerProps, onCloseAutoFocus } = useModalExternalTrigger();
421
+ *
422
+ * return (
423
+ * <>
424
+ * <Button
425
+ * ref={triggerRef}
426
+ * {...triggerProps(isOpen)}
427
+ * onClick={() => setIsOpen(true)}
428
+ * >
429
+ * Open Modal
430
+ * </Button>
431
+ * <Modal
432
+ * open={isOpen}
433
+ * onOpenChange={setIsOpen}
434
+ * onCloseAutoFocus={onCloseAutoFocus}
435
+ * >
436
+ * <ModalBody>Content</ModalBody>
437
+ * </Modal>
438
+ * </>
439
+ * );
440
+ * ```
441
+ */
442
+ declare function useModalExternalTrigger<T extends HTMLElement = HTMLButtonElement>(modalId?: string): {
443
+ triggerRef: React.RefObject<T>;
444
+ triggerProps: (isOpen: boolean) => {
445
+ "aria-controls"?: string | undefined;
446
+ "aria-haspopup": "dialog";
447
+ "aria-expanded": boolean;
448
+ };
449
+ onCloseAutoFocus: (e: Event) => void;
450
+ };
306
451
 
307
452
  interface HeaderProps {
308
453
  draggable?: boolean;
@@ -416,4 +561,4 @@ declare const ModalRail: React.FC<TypeModalRailProps>;
416
561
 
417
562
  declare const ModalAction: React.FC<TypeModalActionProps>;
418
563
 
419
- export { Modal as M, type TypeModalProps as T, ModalDescription as a, ModalHeader as b, ModalFooter as c, ModalBody as d, ModalCloseWrapper as e, ModalRail as f, ModalAction as g, ModalCustomHeader as h, ModalCustomFooter as i, type TypeModalHeaderProps as j, type TypeModalFooterProps as k, type TypeModalBodyProps as l, type TypeModalDescriptionProps as m, type TypeModalRailProps as n, type TypeModalActionProps as o, type ModalCloseWrapperProps as p };
564
+ export { Modal as M, type TypeModalProps as T, ModalDescription as a, ModalHeader as b, ModalFooter as c, ModalBody as d, ModalCloseWrapper as e, ModalRail as f, ModalAction as g, ModalCustomHeader as h, ModalCustomFooter as i, type TypeModalHeaderProps as j, type TypeModalFooterProps as k, type TypeModalBodyProps as l, type TypeModalDescriptionProps as m, type TypeModalRailProps as n, type TypeModalActionProps as o, type ModalCloseWrapperProps as p, useModalExternalTrigger as q, useModalTriggerProps as u };