@i-dot-ai-npm/component-library-react 0.0.8 → 0.0.10
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/package.json +4 -2
- package/src/footer/Footer.tsx +3 -3
- package/src/index.ts +4 -0
- package/src/modal/Modal.tsx +49 -0
- package/src/modal/ModalBody.tsx +16 -0
- package/src/modal/ModalFooter.tsx +18 -0
- package/src/modal/ModalTitle.tsx +18 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i-dot-ai-npm/component-library-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "React components for i.AI GOV.UK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
23
|
"peerDependencies": {
|
|
24
|
+
"@i-dot-ai-npm/component-library-frontend": ">=0.0.9",
|
|
24
25
|
"govuk-frontend": ">=6",
|
|
25
26
|
"react": ">=18",
|
|
26
27
|
"react-dom": ">=18"
|
|
27
28
|
},
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/i-dot-ai/
|
|
31
|
+
"url": "git+https://github.com/i-dot-ai/design-kit.git",
|
|
31
32
|
"directory": "packages/react"
|
|
32
33
|
},
|
|
33
34
|
"publishConfig": {
|
|
@@ -36,6 +37,7 @@
|
|
|
36
37
|
},
|
|
37
38
|
"license": "MIT",
|
|
38
39
|
"devDependencies": {
|
|
40
|
+
"@i-dot-ai-npm/component-library-frontend": "workspace:*",
|
|
39
41
|
"@types/react": "^19.3.0",
|
|
40
42
|
"govuk-frontend": "^6.5.0",
|
|
41
43
|
"react": "^19.3.0",
|
package/src/footer/Footer.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
|
2
2
|
|
|
3
3
|
type FooterLink = { href?: string; text?: string; attributes?: Record<string, string> };
|
|
4
4
|
|
|
5
|
-
type FooterProps = ComponentPropsWithoutRef<'
|
|
5
|
+
type FooterProps = ComponentPropsWithoutRef<'footer'> & {
|
|
6
6
|
/** Support links shown in the inline list (e.g. Accessibility statement, Cookies, Privacy). */
|
|
7
7
|
links?: FooterLink[];
|
|
8
8
|
/** Visually-hidden heading above the support links. */
|
|
@@ -26,7 +26,7 @@ export default function Footer({
|
|
|
26
26
|
.join(' ');
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
|
-
<
|
|
29
|
+
<footer className={classes} {...rest}>
|
|
30
30
|
<div className={containerClass}>
|
|
31
31
|
<div className="govuk-footer__meta">
|
|
32
32
|
<div className="govuk-footer__meta-item govuk-footer__meta-item--grow">
|
|
@@ -58,6 +58,6 @@ export default function Footer({
|
|
|
58
58
|
<div className="govuk-footer__meta-item">{children}</div>
|
|
59
59
|
</div>
|
|
60
60
|
</div>
|
|
61
|
-
</
|
|
61
|
+
</footer>
|
|
62
62
|
);
|
|
63
63
|
}
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,10 @@ export { default as LanguageNavigation } from "./language-navigation/LanguageNav
|
|
|
64
64
|
export { default as Link } from "./link/Link";
|
|
65
65
|
export { default as ListItem } from "./list/ListItem";
|
|
66
66
|
export { default as List } from "./list/List";
|
|
67
|
+
export { default as ModalTitle } from "./modal/ModalTitle";
|
|
68
|
+
export { default as ModalBody } from "./modal/ModalBody";
|
|
69
|
+
export { default as ModalFooter } from "./modal/ModalFooter";
|
|
70
|
+
export { default as Modal } from "./modal/Modal";
|
|
67
71
|
export { default as NotificationBannerContent } from "./notification-banner/NotificationBannerContent";
|
|
68
72
|
export { default as NotificationBannerHeader } from "./notification-banner/NotificationBannerHeader";
|
|
69
73
|
export { default as NotificationBannerHeading } from "./notification-banner/NotificationBannerHeading";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
3
|
+
import { initModal, openModal, closeModal } from "@i-dot-ai-npm/component-library-frontend";
|
|
4
|
+
|
|
5
|
+
type ModalProps = Omit<ComponentPropsWithoutRef<"dialog">, "onClose"> & {
|
|
6
|
+
class?: string;
|
|
7
|
+
/** Controls whether the modal is open. */
|
|
8
|
+
open?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Called when the modal requests to close (Esc, backdrop click, or a
|
|
11
|
+
* `[data-iai-modal-close]` button). Update your `open` state here.
|
|
12
|
+
*/
|
|
13
|
+
onClose?: () => void;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default function Modal({
|
|
18
|
+
class: className,
|
|
19
|
+
open = false,
|
|
20
|
+
onClose,
|
|
21
|
+
children,
|
|
22
|
+
...rest
|
|
23
|
+
}: ModalProps) {
|
|
24
|
+
const ref = useRef<HTMLDialogElement>(null);
|
|
25
|
+
|
|
26
|
+
const classes = ["iai-modal", className ?? ""].filter(Boolean).join(" ");
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const dialog = ref.current;
|
|
30
|
+
if (!dialog) return;
|
|
31
|
+
initModal(dialog);
|
|
32
|
+
if (open) openModal(dialog);
|
|
33
|
+
else closeModal(dialog);
|
|
34
|
+
}, [open]);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const dialog = ref.current;
|
|
38
|
+
if (!dialog || !onClose) return;
|
|
39
|
+
const handler = () => onClose();
|
|
40
|
+
dialog.addEventListener("close", handler);
|
|
41
|
+
return () => dialog.removeEventListener("close", handler);
|
|
42
|
+
}, [onClose]);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<dialog ref={ref} className={classes} tabIndex={-1} data-module="iai-modal" {...rest}>
|
|
46
|
+
<div className="iai-modal__container">{children}</div>
|
|
47
|
+
</dialog>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
type ModalBodyProps = ComponentPropsWithoutRef<"div"> & {
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function ModalBody({ class: className, children, ...rest }: ModalBodyProps) {
|
|
9
|
+
const classes = ["iai-modal__body", className ?? ""].filter(Boolean).join(" ");
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className={classes} {...rest}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
type ModalFooterProps = ComponentPropsWithoutRef<"div"> & {
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function ModalFooter({ class: className, children, ...rest }: ModalFooterProps) {
|
|
9
|
+
const classes = ["iai-modal__footer", "govuk-button-group", className ?? ""]
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.join(" ");
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className={classes} {...rest}>
|
|
15
|
+
{children}
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
type ModalTitleProps = ComponentPropsWithoutRef<"h2"> & {
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function ModalTitle({ class: className, children, ...rest }: ModalTitleProps) {
|
|
9
|
+
const classes = ["govuk-heading-m", "iai-modal__title", className ?? ""]
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.join(" ");
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<h2 className={classes} {...rest}>
|
|
15
|
+
{children}
|
|
16
|
+
</h2>
|
|
17
|
+
);
|
|
18
|
+
}
|