@trackunit/react-modal 1.11.18 → 1.11.19

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.
package/index.cjs.js CHANGED
@@ -308,8 +308,36 @@ const cvaModalBodyContainer = cssClassVarianceUtilities.cvaMerge([
308
308
  /**
309
309
  * Modal body container.
310
310
  *
311
- * Renders children inside a scrollable flex container.
311
+ * Renders children inside a scrollable flex container. Use this component to wrap
312
+ * the main content of a modal, which automatically handles overflow scrolling.
312
313
  *
314
+ * @example Modal body with form content
315
+ * ```tsx
316
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
317
+ * import { TextField } from "@trackunit/react-form-components";
318
+ *
319
+ * const EditAssetModal = () => {
320
+ * const modal = useModal();
321
+ *
322
+ * return (
323
+ * <Modal {...modal} size="medium">
324
+ * <ModalHeader heading="Edit Asset" onClose={modal.close} />
325
+ * <ModalBody>
326
+ * <div className="flex flex-col gap-4">
327
+ * <TextField label="Asset Name" name="name" />
328
+ * <TextField label="Serial Number" name="serial" />
329
+ * </div>
330
+ * </ModalBody>
331
+ * <ModalFooter
332
+ * cancelLabel="Cancel"
333
+ * onCancel={modal.close}
334
+ * primaryLabel="Save"
335
+ * primaryAction={() => console.log("Save")}
336
+ * />
337
+ * </Modal>
338
+ * );
339
+ * };
340
+ * ```
313
341
  * @param {ModalBodyProps} props Component props.
314
342
  * @param {ReactNode | null} props.children Content to render inside the modal body.
315
343
  * @param {string} [props."data-testid"] Optional test id for the container.
@@ -338,6 +366,55 @@ function isCustom(props) {
338
366
  /**
339
367
  * Modal footer with action buttons.
340
368
  *
369
+ * Provides a consistent footer layout with cancel, secondary, and primary action buttons.
370
+ * Supports loading states and automatic button disabling during async operations.
371
+ *
372
+ * @example Standard modal footer with actions
373
+ * ```tsx
374
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
375
+ *
376
+ * const ConfirmModal = () => {
377
+ * const modal = useModal();
378
+ * const [isLoading, setIsLoading] = useState(false);
379
+ *
380
+ * return (
381
+ * <Modal {...modal} size="small">
382
+ * <ModalHeader heading="Confirm Delete" onClose={modal.close} />
383
+ * <ModalBody>Are you sure you want to delete this asset?</ModalBody>
384
+ * <ModalFooter
385
+ * cancelLabel="Cancel"
386
+ * onCancel={modal.close}
387
+ * primaryLabel="Delete"
388
+ * primaryVariant="primary-danger"
389
+ * primaryLoading={isLoading}
390
+ * primaryAction={() => {
391
+ * setIsLoading(true);
392
+ * // handle delete
393
+ * }}
394
+ * />
395
+ * </Modal>
396
+ * );
397
+ * };
398
+ * ```
399
+ * @example Custom footer with children
400
+ * ```tsx
401
+ * import { Modal, ModalFooter, useModal } from "@trackunit/react-modal";
402
+ * import { Button } from "@trackunit/react-components";
403
+ *
404
+ * const CustomFooterModal = () => {
405
+ * const modal = useModal();
406
+ *
407
+ * return (
408
+ * <Modal {...modal} size="medium">
409
+ * <ModalFooter>
410
+ * <Button variant="ghost-neutral" onClick={modal.close}>Skip</Button>
411
+ * <Button variant="secondary">Save Draft</Button>
412
+ * <Button variant="primary">Publish</Button>
413
+ * </ModalFooter>
414
+ * </Modal>
415
+ * );
416
+ * };
417
+ * ```
341
418
  * @param props Component props.
342
419
  * @param props.cancelLabel Text for the Cancel button.
343
420
  * @param props.onCancel Optional handler invoked when the Cancel button is clicked (alias to onClose, if provided).
@@ -369,6 +446,46 @@ const cvaIconContainer = cssClassVarianceUtilities.cvaMerge(["flex", "place-item
369
446
  * Modal header section.
370
447
  * Displays a main heading, optional subheading, and a close button.
371
448
  *
449
+ * Use inside a Modal component to provide consistent header styling with a title, subtitle, and close button.
450
+ *
451
+ * @example Basic modal header
452
+ * ```tsx
453
+ * import { Modal, ModalHeader, ModalBody, useModal } from "@trackunit/react-modal";
454
+ *
455
+ * const MyModal = () => {
456
+ * const modal = useModal();
457
+ *
458
+ * return (
459
+ * <Modal {...modal} size="medium">
460
+ * <ModalHeader
461
+ * heading="Confirm Action"
462
+ * subHeading="Please review the details below"
463
+ * onClose={modal.close}
464
+ * />
465
+ * <ModalBody>Modal content here</ModalBody>
466
+ * </Modal>
467
+ * );
468
+ * };
469
+ * ```
470
+ * @example Modal header with accessories
471
+ * ```tsx
472
+ * import { Modal, ModalHeader, useModal } from "@trackunit/react-modal";
473
+ * import { Tag } from "@trackunit/react-components";
474
+ *
475
+ * const StatusModal = () => {
476
+ * const modal = useModal();
477
+ *
478
+ * return (
479
+ * <Modal {...modal} size="medium">
480
+ * <ModalHeader
481
+ * heading="Asset Details"
482
+ * onClose={modal.close}
483
+ * accessories={<Tag color="success">Active</Tag>}
484
+ * />
485
+ * </Modal>
486
+ * );
487
+ * };
488
+ * ```
372
489
  * @param {ModalHeaderProps} props Component props.
373
490
  * @param {string} [props.heading] Main heading text.
374
491
  * @param {string} [props.subHeading] Optional subheading content.
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { registerTranslations } from '@trackunit/i18n-library-translation';
3
- import { FloatingFocusManager, useFloating, autoUpdate, shift, useDismiss, useInteractions } from '@floating-ui/react';
3
+ import { FloatingFocusManager, useFloating, shift, autoUpdate, useDismiss, useInteractions } from '@floating-ui/react';
4
4
  import { Portal, Card, Button, Heading, Text, IconButton, Icon, useScrollBlock } from '@trackunit/react-components';
5
5
  import { zIndex } from '@trackunit/ui-design-tokens';
6
6
  import { useRef, useLayoutEffect, forwardRef, useState, useContext, useEffect, useCallback, useMemo } from 'react';
@@ -306,8 +306,36 @@ const cvaModalBodyContainer = cvaMerge([
306
306
  /**
307
307
  * Modal body container.
308
308
  *
309
- * Renders children inside a scrollable flex container.
309
+ * Renders children inside a scrollable flex container. Use this component to wrap
310
+ * the main content of a modal, which automatically handles overflow scrolling.
310
311
  *
312
+ * @example Modal body with form content
313
+ * ```tsx
314
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
315
+ * import { TextField } from "@trackunit/react-form-components";
316
+ *
317
+ * const EditAssetModal = () => {
318
+ * const modal = useModal();
319
+ *
320
+ * return (
321
+ * <Modal {...modal} size="medium">
322
+ * <ModalHeader heading="Edit Asset" onClose={modal.close} />
323
+ * <ModalBody>
324
+ * <div className="flex flex-col gap-4">
325
+ * <TextField label="Asset Name" name="name" />
326
+ * <TextField label="Serial Number" name="serial" />
327
+ * </div>
328
+ * </ModalBody>
329
+ * <ModalFooter
330
+ * cancelLabel="Cancel"
331
+ * onCancel={modal.close}
332
+ * primaryLabel="Save"
333
+ * primaryAction={() => console.log("Save")}
334
+ * />
335
+ * </Modal>
336
+ * );
337
+ * };
338
+ * ```
311
339
  * @param {ModalBodyProps} props Component props.
312
340
  * @param {ReactNode | null} props.children Content to render inside the modal body.
313
341
  * @param {string} [props."data-testid"] Optional test id for the container.
@@ -336,6 +364,55 @@ function isCustom(props) {
336
364
  /**
337
365
  * Modal footer with action buttons.
338
366
  *
367
+ * Provides a consistent footer layout with cancel, secondary, and primary action buttons.
368
+ * Supports loading states and automatic button disabling during async operations.
369
+ *
370
+ * @example Standard modal footer with actions
371
+ * ```tsx
372
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
373
+ *
374
+ * const ConfirmModal = () => {
375
+ * const modal = useModal();
376
+ * const [isLoading, setIsLoading] = useState(false);
377
+ *
378
+ * return (
379
+ * <Modal {...modal} size="small">
380
+ * <ModalHeader heading="Confirm Delete" onClose={modal.close} />
381
+ * <ModalBody>Are you sure you want to delete this asset?</ModalBody>
382
+ * <ModalFooter
383
+ * cancelLabel="Cancel"
384
+ * onCancel={modal.close}
385
+ * primaryLabel="Delete"
386
+ * primaryVariant="primary-danger"
387
+ * primaryLoading={isLoading}
388
+ * primaryAction={() => {
389
+ * setIsLoading(true);
390
+ * // handle delete
391
+ * }}
392
+ * />
393
+ * </Modal>
394
+ * );
395
+ * };
396
+ * ```
397
+ * @example Custom footer with children
398
+ * ```tsx
399
+ * import { Modal, ModalFooter, useModal } from "@trackunit/react-modal";
400
+ * import { Button } from "@trackunit/react-components";
401
+ *
402
+ * const CustomFooterModal = () => {
403
+ * const modal = useModal();
404
+ *
405
+ * return (
406
+ * <Modal {...modal} size="medium">
407
+ * <ModalFooter>
408
+ * <Button variant="ghost-neutral" onClick={modal.close}>Skip</Button>
409
+ * <Button variant="secondary">Save Draft</Button>
410
+ * <Button variant="primary">Publish</Button>
411
+ * </ModalFooter>
412
+ * </Modal>
413
+ * );
414
+ * };
415
+ * ```
339
416
  * @param props Component props.
340
417
  * @param props.cancelLabel Text for the Cancel button.
341
418
  * @param props.onCancel Optional handler invoked when the Cancel button is clicked (alias to onClose, if provided).
@@ -367,6 +444,46 @@ const cvaIconContainer = cvaMerge(["flex", "place-items-center"]);
367
444
  * Modal header section.
368
445
  * Displays a main heading, optional subheading, and a close button.
369
446
  *
447
+ * Use inside a Modal component to provide consistent header styling with a title, subtitle, and close button.
448
+ *
449
+ * @example Basic modal header
450
+ * ```tsx
451
+ * import { Modal, ModalHeader, ModalBody, useModal } from "@trackunit/react-modal";
452
+ *
453
+ * const MyModal = () => {
454
+ * const modal = useModal();
455
+ *
456
+ * return (
457
+ * <Modal {...modal} size="medium">
458
+ * <ModalHeader
459
+ * heading="Confirm Action"
460
+ * subHeading="Please review the details below"
461
+ * onClose={modal.close}
462
+ * />
463
+ * <ModalBody>Modal content here</ModalBody>
464
+ * </Modal>
465
+ * );
466
+ * };
467
+ * ```
468
+ * @example Modal header with accessories
469
+ * ```tsx
470
+ * import { Modal, ModalHeader, useModal } from "@trackunit/react-modal";
471
+ * import { Tag } from "@trackunit/react-components";
472
+ *
473
+ * const StatusModal = () => {
474
+ * const modal = useModal();
475
+ *
476
+ * return (
477
+ * <Modal {...modal} size="medium">
478
+ * <ModalHeader
479
+ * heading="Asset Details"
480
+ * onClose={modal.close}
481
+ * accessories={<Tag color="success">Active</Tag>}
482
+ * />
483
+ * </Modal>
484
+ * );
485
+ * };
486
+ * ```
370
487
  * @param {ModalHeaderProps} props Component props.
371
488
  * @param {string} [props.heading] Main heading text.
372
489
  * @param {string} [props.subHeading] Optional subheading content.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-modal",
3
- "version": "1.11.18",
3
+ "version": "1.11.19",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -8,14 +8,14 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "react": "19.0.0",
11
- "@trackunit/react-components": "1.14.18",
12
- "@trackunit/css-class-variance-utilities": "1.10.15",
13
- "@trackunit/i18n-library-translation": "1.10.15",
11
+ "@trackunit/react-components": "1.14.19",
12
+ "@trackunit/css-class-variance-utilities": "1.10.16",
13
+ "@trackunit/i18n-library-translation": "1.10.16",
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "@floating-ui/react-dom": "2.1.2",
16
- "@trackunit/ui-design-tokens": "1.10.15",
17
- "@trackunit/react-core-contexts-api": "1.11.15",
18
- "@trackunit/shared-utils": "1.12.15"
16
+ "@trackunit/ui-design-tokens": "1.10.16",
17
+ "@trackunit/react-core-contexts-api": "1.11.16",
18
+ "@trackunit/shared-utils": "1.12.16"
19
19
  },
20
20
  "module": "./index.esm.js",
21
21
  "main": "./index.cjs.js",
@@ -15,8 +15,36 @@ export interface ModalBodyProps extends CommonProps {
15
15
  /**
16
16
  * Modal body container.
17
17
  *
18
- * Renders children inside a scrollable flex container.
18
+ * Renders children inside a scrollable flex container. Use this component to wrap
19
+ * the main content of a modal, which automatically handles overflow scrolling.
19
20
  *
21
+ * @example Modal body with form content
22
+ * ```tsx
23
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
24
+ * import { TextField } from "@trackunit/react-form-components";
25
+ *
26
+ * const EditAssetModal = () => {
27
+ * const modal = useModal();
28
+ *
29
+ * return (
30
+ * <Modal {...modal} size="medium">
31
+ * <ModalHeader heading="Edit Asset" onClose={modal.close} />
32
+ * <ModalBody>
33
+ * <div className="flex flex-col gap-4">
34
+ * <TextField label="Asset Name" name="name" />
35
+ * <TextField label="Serial Number" name="serial" />
36
+ * </div>
37
+ * </ModalBody>
38
+ * <ModalFooter
39
+ * cancelLabel="Cancel"
40
+ * onCancel={modal.close}
41
+ * primaryLabel="Save"
42
+ * primaryAction={() => console.log("Save")}
43
+ * />
44
+ * </Modal>
45
+ * );
46
+ * };
47
+ * ```
20
48
  * @param {ModalBodyProps} props Component props.
21
49
  * @param {ReactNode | null} props.children Content to render inside the modal body.
22
50
  * @param {string} [props."data-testid"] Optional test id for the container.
@@ -89,6 +89,55 @@ export type ModalFooterProps = ModalFooterBuiltInProps | ModalFooterCustomProps;
89
89
  /**
90
90
  * Modal footer with action buttons.
91
91
  *
92
+ * Provides a consistent footer layout with cancel, secondary, and primary action buttons.
93
+ * Supports loading states and automatic button disabling during async operations.
94
+ *
95
+ * @example Standard modal footer with actions
96
+ * ```tsx
97
+ * import { Modal, ModalHeader, ModalBody, ModalFooter, useModal } from "@trackunit/react-modal";
98
+ *
99
+ * const ConfirmModal = () => {
100
+ * const modal = useModal();
101
+ * const [isLoading, setIsLoading] = useState(false);
102
+ *
103
+ * return (
104
+ * <Modal {...modal} size="small">
105
+ * <ModalHeader heading="Confirm Delete" onClose={modal.close} />
106
+ * <ModalBody>Are you sure you want to delete this asset?</ModalBody>
107
+ * <ModalFooter
108
+ * cancelLabel="Cancel"
109
+ * onCancel={modal.close}
110
+ * primaryLabel="Delete"
111
+ * primaryVariant="primary-danger"
112
+ * primaryLoading={isLoading}
113
+ * primaryAction={() => {
114
+ * setIsLoading(true);
115
+ * // handle delete
116
+ * }}
117
+ * />
118
+ * </Modal>
119
+ * );
120
+ * };
121
+ * ```
122
+ * @example Custom footer with children
123
+ * ```tsx
124
+ * import { Modal, ModalFooter, useModal } from "@trackunit/react-modal";
125
+ * import { Button } from "@trackunit/react-components";
126
+ *
127
+ * const CustomFooterModal = () => {
128
+ * const modal = useModal();
129
+ *
130
+ * return (
131
+ * <Modal {...modal} size="medium">
132
+ * <ModalFooter>
133
+ * <Button variant="ghost-neutral" onClick={modal.close}>Skip</Button>
134
+ * <Button variant="secondary">Save Draft</Button>
135
+ * <Button variant="primary">Publish</Button>
136
+ * </ModalFooter>
137
+ * </Modal>
138
+ * );
139
+ * };
140
+ * ```
92
141
  * @param props Component props.
93
142
  * @param props.cancelLabel Text for the Cancel button.
94
143
  * @param props.onCancel Optional handler invoked when the Cancel button is clicked (alias to onClose, if provided).
@@ -31,6 +31,46 @@ export interface ModalHeaderProps extends CommonProps {
31
31
  * Modal header section.
32
32
  * Displays a main heading, optional subheading, and a close button.
33
33
  *
34
+ * Use inside a Modal component to provide consistent header styling with a title, subtitle, and close button.
35
+ *
36
+ * @example Basic modal header
37
+ * ```tsx
38
+ * import { Modal, ModalHeader, ModalBody, useModal } from "@trackunit/react-modal";
39
+ *
40
+ * const MyModal = () => {
41
+ * const modal = useModal();
42
+ *
43
+ * return (
44
+ * <Modal {...modal} size="medium">
45
+ * <ModalHeader
46
+ * heading="Confirm Action"
47
+ * subHeading="Please review the details below"
48
+ * onClose={modal.close}
49
+ * />
50
+ * <ModalBody>Modal content here</ModalBody>
51
+ * </Modal>
52
+ * );
53
+ * };
54
+ * ```
55
+ * @example Modal header with accessories
56
+ * ```tsx
57
+ * import { Modal, ModalHeader, useModal } from "@trackunit/react-modal";
58
+ * import { Tag } from "@trackunit/react-components";
59
+ *
60
+ * const StatusModal = () => {
61
+ * const modal = useModal();
62
+ *
63
+ * return (
64
+ * <Modal {...modal} size="medium">
65
+ * <ModalHeader
66
+ * heading="Asset Details"
67
+ * onClose={modal.close}
68
+ * accessories={<Tag color="success">Active</Tag>}
69
+ * />
70
+ * </Modal>
71
+ * );
72
+ * };
73
+ * ```
34
74
  * @param {ModalHeaderProps} props Component props.
35
75
  * @param {string} [props.heading] Main heading text.
36
76
  * @param {string} [props.subHeading] Optional subheading content.