@sproutsocial/seeds-react-modal 2.1.1 → 2.2.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
- ESM dist/esm/v1/index.js 165.00 B
11
+ CJS dist/index.js 59.82 KB
12
+ CJS dist/v1/index.js 9.86 KB
13
+ CJS dist/v2/index.js 51.80 KB
14
+ CJS dist/index.js.map 203.91 KB
15
+ CJS dist/v1/index.js.map 13.03 KB
16
+ CJS dist/v2/index.js.map 190.56 KB
17
+ CJS ⚡️ Build success in 422ms
12
18
  ESM dist/esm/index.js 583.00 B
19
+ ESM dist/esm/v1/index.js 165.00 B
13
20
  ESM dist/esm/v2/index.js 596.00 B
14
21
  ESM dist/esm/chunk-IYDY4OPB.js 7.12 KB
15
- ESM dist/esm/chunk-ETVICNHP.js 45.64 KB
16
- ESM dist/esm/v1/index.js.map 71.00 B
22
+ ESM dist/esm/chunk-52SXX6AG.js 46.97 KB
17
23
  ESM dist/esm/index.js.map 1.05 KB
24
+ ESM dist/esm/v1/index.js.map 71.00 B
18
25
  ESM dist/esm/v2/index.js.map 71.00 B
19
26
  ESM dist/esm/chunk-IYDY4OPB.js.map 12.85 KB
20
- ESM dist/esm/chunk-ETVICNHP.js.map 187.52 KB
21
- ESM ⚡️ Build success in 307ms
22
- CJS dist/v1/index.js 9.86 KB
23
- CJS dist/v2/index.js 50.48 KB
24
- CJS dist/index.js 58.46 KB
25
- CJS dist/v1/index.js.map 13.03 KB
26
- CJS dist/v2/index.js.map 188.43 KB
27
- CJS dist/index.js.map 201.74 KB
28
- CJS ⚡️ Build success in 322ms
27
+ ESM dist/esm/chunk-52SXX6AG.js.map 189.66 KB
28
+ ESM ⚡️ Build success in 426ms
29
29
  DTS Build start
30
- DTS ⚡️ Build success in 12362ms
30
+ DTS ⚡️ Build success in 11636ms
31
31
  DTS dist/index.d.ts 975.00 B
32
32
  DTS dist/v1/index.d.ts 413.00 B
33
33
  DTS dist/v2/index.d.ts 1021.00 B
34
34
  DTS dist/Modal-ki8oiGbC.d.ts 2.52 KB
35
- DTS dist/ModalAction-BB7qJtQj.d.ts 17.39 KB
35
+ DTS dist/ModalAction-gIgCE73I.d.ts 15.19 KB
36
36
  DTS dist/index.d.mts 978.00 B
37
37
  DTS dist/v1/index.d.mts 415.00 B
38
38
  DTS dist/v2/index.d.mts 1022.00 B
39
39
  DTS dist/Modal-ki8oiGbC.d.mts 2.52 KB
40
- DTS dist/ModalAction-BB7qJtQj.d.mts 17.39 KB
41
- Done in 15.36s.
40
+ DTS dist/ModalAction-gIgCE73I.d.mts 15.19 KB
41
+ Done in 14.48s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @sproutsocial/seeds-react-modal
2
2
 
3
+ ## 2.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fa7579a: **Modal V2 Enhancements:**
8
+
9
+ - **closeButtonProps API**: Added `closeButtonProps` prop to customize the default floating close button with advanced options like `onClick`, `id`, `disabled`, `className`, `iconName`, and other button attributes
10
+ - **zIndex prop**: Added `zIndex` prop (defaults to 6) to control the modal's z-index, matching Modal v1 behavior
11
+ - **Improved accessibility**: Made `aria-label` optional on Modal root when using ModalHeader as children
12
+ - **Required aria-label for close button**: TypeScript now enforces that the close button always has an accessible label through either `closeButtonAriaLabel` or `closeButtonProps["aria-label"]`
13
+ - **Required aria-label for actions**: All action buttons in the floating rail now require an `aria-label` for accessibility
14
+ - **Cleaned up types**: Reorganized and streamlined ModalTypes.ts for better readability and maintainability
15
+ - **Simplified Modal Action colors**: Removed draggable-specific color variations; action buttons now consistently use overlay button colors
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [fa7579a]
20
+ - @sproutsocial/seeds-react-theme@3.2.1
21
+ - @sproutsocial/seeds-react-box@1.1.7
22
+ - @sproutsocial/seeds-react-icon@2.0.1
23
+ - @sproutsocial/seeds-react-button@1.3.6
24
+
25
+ ## 2.1.2
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [40248a0]
30
+ - @sproutsocial/seeds-react-icon@2.0.0
31
+ - @sproutsocial/seeds-react-button@1.3.5
32
+
3
33
  ## 2.1.1
4
34
 
5
35
  ### Patch Changes
@@ -9,295 +9,269 @@ import { TypeIconName } from '@sproutsocial/seeds-react-icon';
9
9
  /**
10
10
  * Props for ModalHeader component.
11
11
  *
12
- * Renders the modal's header with title and optional subtitle. Supports draggable functionality
13
- * when the modal has draggable enabled.
12
+ * Renders the modal's header with title and optional subtitle.
13
+ * Supports draggable functionality when the modal has draggable enabled.
14
14
  *
15
- * Note: This component only supports slots (title/subtitle props). For custom headers,
16
- * use ModalCustomHeader instead.
15
+ * Note: This component only supports slots (title/subtitle props).
16
+ * For custom headers, use ModalCustomHeader instead.
17
17
  */
18
18
  interface TypeModalHeaderProps extends TypeBoxProps {
19
19
  /** Modal title text displayed as a headline */
20
20
  title?: string;
21
21
  /**
22
22
  * Modal subtitle text.
23
- *
24
- * This is automatically wrapped in `Dialog.Description` from Radix UI,
25
- * which provides accessible description text for screen readers. The subtitle
26
- * provides additional context about the modal and is announced alongside
27
- * the title when the dialog opens. Radix UI automatically connects this to
28
- * the dialog via ARIA attributes (typically `aria-describedby` on the dialog root).
23
+ * Automatically wrapped in Dialog.Description for accessibility.
29
24
  */
30
25
  subtitle?: string;
31
- /** Additional props for the Dialog.Title when title is provided */
26
+ /** Additional props for Dialog.Title when title is provided */
32
27
  titleProps?: Omit<React.ComponentPropsWithoutRef<typeof Dialog.Title>, "asChild" | "children">;
33
- /**
34
- * Additional props for the Dialog.Description when subtitle is provided.
35
- *
36
- * Dialog.Description provides accessible description text for the modal that
37
- * screen readers announce when the dialog opens. It complements Dialog.Title
38
- * by providing additional context about the modal. Radix UI automatically
39
- * connects this to the dialog via ARIA attributes.
40
- */
28
+ /** Additional props for Dialog.Description when subtitle is provided */
41
29
  subtitleProps?: Omit<React.ComponentPropsWithoutRef<typeof Dialog.Description>, "asChild" | "children">;
42
30
  }
43
31
  /**
44
- * Props for ModalFooter component.
45
- *
46
- * Provides automatic button wrapping and layout management. At least one action
47
- * (cancelButton, primaryButton, or leftAction) must be provided.
48
- *
49
- * Note: This component only supports slots (button props). For custom footers,
50
- * use ModalCustomFooter instead.
32
+ * Props for ModalBody component.
51
33
  *
52
- * @example
53
- * // ✅ Valid - has primary button
54
- * <ModalFooter primaryButton={<Button>Save</Button>} />
34
+ * Renders the scrollable main content area of the modal.
35
+ */
36
+ interface TypeModalBodyProps extends TypeBoxProps {
37
+ /** The main content of the modal body */
38
+ children?: React.ReactNode;
39
+ }
40
+ /**
41
+ * Props for ModalDescription component.
55
42
  *
56
- * @example
57
- * // ✅ Valid - has cancel and primary
58
- * <ModalFooter
59
- * cancelButton={<Button>Cancel</Button>}
60
- * primaryButton={<Button>Save</Button>}
61
- * />
43
+ * Wraps content with Dialog.Description for accessible descriptions.
44
+ */
45
+ interface TypeModalDescriptionProps extends TypeBoxProps {
46
+ /** The description text content */
47
+ children: React.ReactNode;
48
+ /** Additional props for Dialog.Description */
49
+ descriptionProps?: Omit<React.ComponentPropsWithoutRef<typeof Dialog.Description>, "asChild" | "children">;
50
+ }
51
+ /**
52
+ * Props for ModalFooter component.
62
53
  *
63
- * @example
64
- * // Valid - left action only
65
- * <ModalFooter leftAction={<Button>Delete</Button>} />
54
+ * Provides automatic button wrapping and layout management.
55
+ * At least one action (cancelButton, primaryButton, or leftAction) must be provided.
66
56
  *
67
- * @example
68
- * // TypeScript Error - no actions provided
69
- * <ModalFooter />
57
+ * Note: This component only supports slots (button props).
58
+ * For custom footers, use ModalCustomFooter instead.
70
59
  */
71
60
  type TypeModalFooterProps = TypeBoxProps & ({
72
- /** Primary action button - automatically wrapped in ModalCloseWrapper to close the modal */
61
+ /** Primary action button - automatically wrapped in ModalCloseWrapper */
73
62
  primaryButton: React.ReactNode;
74
- /** Cancel/secondary button - automatically wrapped in ModalCloseWrapper to close the modal */
63
+ /** Cancel/secondary button - automatically wrapped in ModalCloseWrapper */
75
64
  cancelButton?: React.ReactNode;
76
- /** Optional action on the far left (e.g., Delete button) - NOT automatically wrapped */
65
+ /** Optional action on the far left (e.g., Delete) - NOT automatically wrapped */
77
66
  leftAction?: React.ReactNode;
78
67
  } | {
79
- /** Primary action button - automatically wrapped in ModalCloseWrapper to close the modal */
80
68
  primaryButton?: React.ReactNode;
81
- /** Cancel/secondary button - automatically wrapped in ModalCloseWrapper to close the modal */
82
69
  cancelButton: React.ReactNode;
83
- /** Optional action on the far left (e.g., Delete button) - NOT automatically wrapped */
84
70
  leftAction?: React.ReactNode;
85
71
  } | {
86
- /** Primary action button - automatically wrapped in ModalCloseWrapper to close the modal */
87
72
  primaryButton?: React.ReactNode;
88
- /** Cancel/secondary button - automatically wrapped in ModalCloseWrapper to close the modal */
89
73
  cancelButton?: React.ReactNode;
90
- /** Optional action on the far left (e.g., Delete button) - NOT automatically wrapped */
91
74
  leftAction: React.ReactNode;
92
75
  });
93
76
  /**
94
- * Props for ModalBody component.
77
+ * Props for ModalRail component.
95
78
  *
96
- * Renders the scrollable main content area of the modal between the header and footer.
79
+ * Container for floating action buttons displayed alongside the modal.
97
80
  */
98
- interface TypeModalBodyProps extends TypeBoxProps {
99
- /** The main content of the modal body */
81
+ type TypeModalRailProps = {
82
+ /** ModalAction components to display in the rail */
100
83
  children?: React.ReactNode;
101
- }
84
+ };
102
85
  /**
103
- * Props for ModalDescription component.
86
+ * Props for ModalAction component.
87
+ *
88
+ * Action buttons that appear in the floating rail.
89
+ * Supports two action types:
90
+ * - "close": Automatically closes the modal (uses Dialog.Close)
91
+ * - "button": Custom action with user-defined onClick handler
104
92
  *
105
- * Wraps content with Radix UI's Dialog.Description for accessible modal descriptions
106
- * that are announced by screen readers.
93
+ * **IMPORTANT**: aria-label is required for accessibility.
107
94
  */
108
- interface TypeModalDescriptionProps extends TypeBoxProps {
109
- /** The description text content */
95
+ type TypeModalActionProps = ({
96
+ /** Action type - close triggers modal close */
97
+ actionType: "close";
98
+ /** REQUIRED: Accessible label for the button */
99
+ "aria-label": string;
100
+ /** Icon name from the Seeds icon set */
101
+ iconName?: TypeIconName;
102
+ /** Optional click handler called before closing */
103
+ onClick?: () => void;
104
+ } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick">) | ({
105
+ /** Action type - button for custom actions (default) */
106
+ actionType?: "button";
107
+ /** REQUIRED: Accessible label for the button */
108
+ "aria-label": string;
109
+ /** Icon name from the Seeds icon set */
110
+ iconName?: TypeIconName;
111
+ /** Click handler for the button */
112
+ onClick?: () => void;
113
+ } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick">);
114
+ /**
115
+ * Base common props shared by all modal variants (without close button props).
116
+ */
117
+ type TypeModalCommonPropsBase = TypeContainerProps & Omit<React.ComponentPropsWithoutRef<"div">, keyof TypeContainerProps> & {
118
+ /** Modal content */
110
119
  children: React.ReactNode;
111
- /** Additional props for the Dialog.Description */
112
- descriptionProps?: Omit<React.ComponentPropsWithoutRef<typeof Dialog.Description>, "asChild" | "children">;
113
- }
114
- /** Common props shared by all modal variants */
115
- type TypeModalCommonProps = TypeContainerProps & Omit<React.ComponentPropsWithoutRef<"div">, keyof TypeContainerProps> & {
116
120
  /** Controls whether the modal is open (controlled mode) */
117
121
  open?: boolean;
118
122
  /** Default open state for uncontrolled mode */
119
123
  defaultOpen?: boolean;
120
- /** body content of the modal */
121
- children: React.ReactNode;
122
124
  /** Callback when open state changes */
123
125
  onOpenChange?: (open: boolean) => void;
124
- /** The element that will trigger the modal when clicked.
125
- * Can be any React element like a button, link, or custom component. */
126
+ /**
127
+ * Element that triggers the modal when clicked.
128
+ * Can be any React element like a button, link, or custom component.
129
+ */
126
130
  modalTrigger?: React.ReactElement<any>;
127
- /** Simplified API: Modal description (automatically wrapped in Dialog.Description) */
131
+ /** Modal description (automatically wrapped in Dialog.Description) */
128
132
  description?: string;
129
133
  /**
130
- * Custom attributes to be added to the modals container
131
- * Each key will be prepended with "data-" when rendered in the DOM
134
+ * Custom data attributes added to the modal container.
135
+ * Each key will be prepended with "data-" when rendered.
132
136
  */
133
137
  data?: Record<string, string | boolean | number>;
134
- /** Optional quick actions to render on a modal side rail */
138
+ /** Quick actions to render on the modal side rail */
135
139
  actions?: TypeModalActionProps[];
136
- /** Accessible label for the close button in the rail (defaults to "Close") */
137
- closeButtonAriaLabel?: string;
140
+ /** Controls the z-index CSS property (defaults to 6 to match Modal v1) */
141
+ zIndex?: number;
138
142
  };
143
+ /**
144
+ * Common props with close button accessibility enforcement.
145
+ *
146
+ * Ensures close button always has an accessible label through either:
147
+ * - closeButtonAriaLabel prop (required unless closeButtonProps has aria-label)
148
+ * - closeButtonProps with aria-label
149
+ *
150
+ * @example
151
+ * // ✅ Valid - has closeButtonAriaLabel
152
+ * <Modal closeButtonAriaLabel="Close dialog" />
153
+ *
154
+ * @example
155
+ * // ✅ Valid - has aria-label in closeButtonProps
156
+ * <Modal closeButtonProps={{ "aria-label": "Close dialog", onClick: handler }} />
157
+ *
158
+ * @example
159
+ * // ✅ Valid - has both (closeButtonProps aria-label takes precedence)
160
+ * <Modal
161
+ * closeButtonAriaLabel="Close"
162
+ * closeButtonProps={{ onClick: handler }}
163
+ * />
164
+ *
165
+ * @example
166
+ * // ❌ TypeScript Error - missing aria-label in both places
167
+ * <Modal closeButtonProps={{ onClick: handler }} />
168
+ */
169
+ type TypeModalCommonProps = (TypeModalCommonPropsBase & {
170
+ /**
171
+ * Accessible label for the close button.
172
+ * Required unless closeButtonProps includes aria-label.
173
+ */
174
+ closeButtonAriaLabel: string;
175
+ /**
176
+ * Props to pass to the default floating close button.
177
+ * Use this for advanced customization; for simple aria-label changes, use closeButtonAriaLabel instead.
178
+ */
179
+ closeButtonProps?: Omit<TypeModalActionProps, "actionType" | "aria-label">;
180
+ }) | (TypeModalCommonPropsBase & {
181
+ /**
182
+ * Accessible label for the close button.
183
+ * Optional when closeButtonProps includes aria-label.
184
+ */
185
+ closeButtonAriaLabel?: string;
186
+ /**
187
+ * Props to pass to the default floating close button.
188
+ * Must include aria-label when closeButtonAriaLabel is not provided.
189
+ */
190
+ closeButtonProps: Omit<TypeModalActionProps, "actionType"> & {
191
+ "aria-label": string;
192
+ };
193
+ });
139
194
  /**
140
195
  * Base props with draggable and showOverlay relationship enforced.
141
196
  *
142
- * When draggable is true, showOverlay must be false or undefined because
143
- * the overlay would block interaction with content behind the modal,
144
- * defeating the purpose of being able to drag the modal aside.
197
+ * When draggable is true, showOverlay must be false because the overlay
198
+ * would block interaction with content behind the modal.
145
199
  */
146
200
  type TypeModalBaseProps = (TypeModalCommonProps & {
147
- /** Enable draggable functionality */
148
201
  draggable: true;
149
- /**
150
- * Whether to show the background overlay.
151
- * Must be false when draggable is true to allow interaction with background content.
152
- */
153
202
  showOverlay?: false;
154
203
  }) | (TypeModalCommonProps & {
155
- /** Enable draggable functionality */
156
204
  draggable?: false;
157
- /** Whether to show the background overlay (defaults to true) */
158
205
  showOverlay?: boolean;
159
206
  });
160
207
  /**
161
208
  * Modal props with title provided.
162
- * aria-label is optional since Dialog.Title can serve as the accessible name.
163
209
  */
164
210
  type TypeModalPropsWithTitle = TypeModalBaseProps & {
165
- /** Simplified API: Modal title (creates ModalHeader automatically) */
211
+ /** Modal title (creates ModalHeader automatically) */
166
212
  title: string;
167
- /**
168
- * Simplified API: Modal subtitle (creates ModalHeader automatically).
169
- *
170
- * This is automatically wrapped in `Dialog.Description` from Radix UI,
171
- * which provides accessible description text for screen readers. The subtitle
172
- * provides additional context about the modal and is announced alongside
173
- * the title when the dialog opens.
174
- */
213
+ /** Modal subtitle (creates ModalHeader automatically) */
175
214
  subtitle?: string;
176
- /** Accessible label for the modal dialog (optional when title or subtitle is provided) */
215
+ /** Accessible label for the modal dialog (optional when title is provided) */
177
216
  "aria-label"?: string;
178
217
  };
179
218
  /**
180
- * Modal props with subtitle provided but no title.
181
- * aria-label is optional since Dialog.Description can help identify the modal.
219
+ * Modal props with subtitle only (no title).
182
220
  */
183
221
  type TypeModalPropsWithSubtitleOnly = TypeModalBaseProps & {
184
- /** Simplified API: Modal title (creates ModalHeader automatically) */
185
222
  title?: never;
186
- /**
187
- * Simplified API: Modal subtitle (creates ModalHeader automatically).
188
- *
189
- * This is automatically wrapped in `Dialog.Description` from Radix UI,
190
- * which provides accessible description text for screen readers. The subtitle
191
- * provides additional context about the modal and is announced alongside
192
- * the title when the dialog opens.
193
- */
223
+ /** Modal subtitle (creates ModalHeader automatically) */
194
224
  subtitle: string;
195
- /** Accessible label for the modal dialog (optional when title or subtitle is provided) */
225
+ /** Accessible label for the modal dialog (optional when subtitle is provided) */
196
226
  "aria-label"?: string;
197
227
  };
198
228
  /**
199
229
  * Modal props without title or subtitle.
200
230
  *
201
- * **IMPORTANT**: When no header (title or subtitle) is provided,
202
- * `aria-label` is REQUIRED for accessibility compliance.
231
+ * aria-label is optional because users can provide accessible labeling through:
232
+ * - ModalHeader component as children
233
+ * - Dialog.Title or Dialog.Description components
234
+ * - Custom accessible content
203
235
  *
204
- * Without a visible header, screen readers need `aria-label` to identify
205
- * what the modal dialog is about.
206
- *
207
- * @example
208
- * // ✅ Valid - provides aria-label when no header
209
- * <Modal aria-label="Delete confirmation dialog">
210
- * <p>Are you sure you want to delete this item?</p>
211
- * </Modal>
212
- *
213
- * @example
214
- * // ❌ Invalid - missing required aria-label
215
- * <Modal>
216
- * <p>Are you sure you want to delete this item?</p>
217
- * </Modal>
236
+ * However, for best accessibility, provide one of:
237
+ * - `aria-label` prop
238
+ * - ModalHeader component with title
239
+ * - Dialog.Title component in children
218
240
  */
219
241
  type TypeModalPropsWithoutHeader = TypeModalBaseProps & {
220
- /** Simplified API: Modal title (creates ModalHeader automatically) - not allowed when no header */
221
242
  title?: never;
222
- /** Simplified API: Modal subtitle (creates ModalHeader automatically) - not allowed when no header */
223
243
  subtitle?: never;
224
244
  /**
225
- * **REQUIRED: aria-label must be provided when no title or subtitle is given**
226
- *
227
- * Accessible label for the modal dialog. This is required for accessibility
228
- * when the modal has no visible header. Screen readers use this to announce
229
- * what the modal is about.
230
- *
231
- * **Error**: If you see a TypeScript error saying this property is missing,
232
- * it means you need to either:
233
- * 1. Provide `aria-label` (required when no header), OR
234
- * 2. Provide `title` or `subtitle` (which makes aria-label optional)
235
- *
236
- * If you have a title or subtitle, this prop is optional.
245
+ * Accessible label for the modal dialog.
246
+ * Optional, but recommended when no title/subtitle props are provided.
237
247
  */
238
- "aria-label": string;
248
+ "aria-label"?: string;
239
249
  };
240
250
  /**
241
- * Modal component props with discriminated union based on header presence.
242
- *
243
- * **Accessibility Requirements:**
244
- * - ✅ **With header** (title or subtitle provided): `aria-label` is optional
245
- * - ❌ **Without header** (no title, no subtitle): `aria-label` is **REQUIRED**
251
+ * Modal component props.
246
252
  *
247
- * TypeScript will error if you forget to provide `aria-label` when no header is present.
248
- * This ensures accessibility compliance and better screen reader support.
253
+ * **Accessibility Recommendations:**
254
+ * - With title/subtitle props: aria-label is optional (automatically accessible)
255
+ * - With ModalHeader as children: aria-label is optional (header provides labeling)
256
+ * - Without header props or components: aria-label is optional but strongly recommended
249
257
  *
250
258
  * @example
251
- * // Valid - has title, aria-label optional
259
+ * // With title prop
252
260
  * <Modal title="Delete Item" />
253
261
  *
254
262
  * @example
255
- * // Valid - has subtitle only, aria-label optional
256
- * <Modal subtitle="Confirmation" />
257
- *
258
- * @example
259
- * // ✅ Valid - no header, aria-label provided
260
- * <Modal aria-label="Delete confirmation dialog" />
263
+ * // With ModalHeader as children
264
+ * <Modal>
265
+ * <ModalHeader title="Delete Item" />
266
+ * </Modal>
261
267
  *
262
268
  * @example
263
- * // TypeScript Error - no header and missing required aria-label
264
- * <Modal /> // Error: Property 'aria-label' is missing
269
+ * // With aria-label
270
+ * <Modal aria-label="Delete confirmation">
271
+ * <ModalBody>Are you sure?</ModalBody>
272
+ * </Modal>
265
273
  */
266
274
  type TypeModalProps = TypeModalPropsWithTitle | TypeModalPropsWithSubtitleOnly | TypeModalPropsWithoutHeader;
267
- /**
268
- * Props for ModalRail component.
269
- *
270
- * Container for floating action buttons displayed alongside the modal.
271
- */
272
- type TypeModalRailProps = {
273
- /** ModalAction components to display in the rail */
274
- children?: React.ReactNode;
275
- };
276
- /**
277
- * Base props for modal action buttons.
278
- *
279
- * Extends standard button HTML attributes with modal-specific properties.
280
- */
281
- type ModalActionBase = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick"> & {
282
- /** Icon name from the Seeds icon set */
283
- iconName?: TypeIconName;
284
- /** Optional click handler; ignored for type "close" */
285
- onClick?: () => void;
286
- /** Accessible name for the action button */
287
- "aria-label": string;
288
- };
289
- /**
290
- * Props for ModalAction component.
291
- *
292
- * Discriminated union supporting two action types:
293
- * - "close": Automatically closes the modal when clicked (uses Dialog.Close)
294
- * - "button": Custom action with user-defined onClick handler
295
- */
296
- type TypeModalActionProps = (ModalActionBase & {
297
- actionType: "close";
298
- }) | (ModalActionBase & {
299
- actionType?: "button";
300
- });
301
275
 
302
276
  /**
303
277
  * Accessible modal dialog component built on Radix UI Dialog primitives.