@uktrade/react-component-library 0.10.1
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/LICENSE +21 -0
- package/Readme.md +64 -0
- package/dist/components/ApiBoundary/ApiBoundary.d.ts +10 -0
- package/dist/components/ApiBoundary/ApiBoundary.d.ts.map +1 -0
- package/dist/components/ApiBoundary/ApiBoundary.js +7 -0
- package/dist/components/ApiBoundary/ApiBoundary.module.css +30 -0
- package/dist/components/ApiQuery/ApiCreateClient.d.ts +3 -0
- package/dist/components/ApiQuery/ApiCreateClient.d.ts.map +1 -0
- package/dist/components/ApiQuery/ApiCreateClient.js +11 -0
- package/dist/components/ApiQuery/ApiCreateHooks.d.ts +25 -0
- package/dist/components/ApiQuery/ApiCreateHooks.d.ts.map +1 -0
- package/dist/components/ApiQuery/ApiCreateHooks.js +55 -0
- package/dist/components/ApiQuery/ApiProvider.d.ts +30 -0
- package/dist/components/ApiQuery/ApiProvider.d.ts.map +1 -0
- package/dist/components/ApiQuery/ApiProvider.js +59 -0
- package/dist/components/ApiQuery/index.d.ts +4 -0
- package/dist/components/ApiQuery/index.d.ts.map +1 -0
- package/dist/components/ApiQuery/index.js +3 -0
- package/dist/components/Arrow/Arrow.d.ts +8 -0
- package/dist/components/Arrow/Arrow.d.ts.map +1 -0
- package/dist/components/Arrow/Arrow.js +12 -0
- package/dist/components/Arrow/Arrow.module.css +21 -0
- package/dist/components/Arrows/Arrows.d.ts +7 -0
- package/dist/components/Arrows/Arrows.d.ts.map +1 -0
- package/dist/components/Arrows/Arrows.js +6 -0
- package/dist/components/Arrows/Arrows.module.css +25 -0
- package/dist/components/BackLink.d.ts +9 -0
- package/dist/components/BackLink.d.ts.map +1 -0
- package/dist/components/BackLink.js +6 -0
- package/dist/components/Button.d.ts +8 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +4 -0
- package/dist/components/ButtonGroup.d.ts +6 -0
- package/dist/components/ButtonGroup.d.ts.map +1 -0
- package/dist/components/ButtonGroup.js +6 -0
- package/dist/components/Colours.d.ts +20 -0
- package/dist/components/Colours.d.ts.map +1 -0
- package/dist/components/Colours.js +20 -0
- package/dist/components/LoadingSpinner/LoadingSpinner.d.ts +7 -0
- package/dist/components/LoadingSpinner/LoadingSpinner.d.ts.map +1 -0
- package/dist/components/LoadingSpinner/LoadingSpinner.js +6 -0
- package/dist/components/LoadingSpinner/LoadingSpinner.module.css +33 -0
- package/dist/components/SummaryItem/SummaryItem.d.ts +39 -0
- package/dist/components/SummaryItem/SummaryItem.d.ts.map +1 -0
- package/dist/components/SummaryItem/SummaryItem.js +25 -0
- package/dist/components/SummaryList/SummaryList.d.ts +17 -0
- package/dist/components/SummaryList/SummaryList.d.ts.map +1 -0
- package/dist/components/SummaryList/SummaryList.js +7 -0
- package/dist/components/SummaryList/SummaryList.module.css +14 -0
- package/dist/components/Tags/Tags.d.ts +16 -0
- package/dist/components/Tags/Tags.d.ts.map +1 -0
- package/dist/components/Tags/Tags.js +16 -0
- package/dist/components/Tags/Tags.module.css +17 -0
- package/dist/components/ViewFormItem/ViewFormItem.d.ts +11 -0
- package/dist/components/ViewFormItem/ViewFormItem.d.ts.map +1 -0
- package/dist/components/ViewFormItem/ViewFormItem.js +13 -0
- package/dist/components/ViewFormItem/ViewFormItem.module.css +11 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +3 -0
- package/package.json +78 -0
- package/src/components/ApiBoundary/ApiBoundary.module.css +30 -0
- package/src/components/ApiBoundary/ApiBoundary.tsx +44 -0
- package/src/components/Arrow/Arrow.module.css +21 -0
- package/src/components/Arrow/Arrow.tsx +41 -0
- package/src/components/Arrows/Arrows.module.css +25 -0
- package/src/components/Arrows/Arrows.tsx +26 -0
- package/src/components/BackLink.tsx +28 -0
- package/src/components/Button.tsx +18 -0
- package/src/components/ButtonGroup.tsx +16 -0
- package/src/components/Colours.tsx +20 -0
- package/src/components/Footer/.gitkeep +0 -0
- package/src/components/Header/.gitkeep +0 -0
- package/src/components/Hero/.gitkeep +0 -0
- package/src/components/LoadingSpinner/LoadingSpinner.module.css +33 -0
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +19 -0
- package/src/components/NavBar/.gitkeep +0 -0
- package/src/components/SummaryItem/SummaryItem.tsx +96 -0
- package/src/components/SummaryList/SummaryList.module.css +14 -0
- package/src/components/SummaryList/SummaryList.tsx +64 -0
- package/src/components/Tags/Tags.module.css +17 -0
- package/src/components/Tags/Tags.tsx +39 -0
- package/src/components/ViewFormItem/ViewFormItem.module.css +11 -0
- package/src/components/ViewFormItem/ViewFormItem.tsx +41 -0
- package/src/index.ts +12 -0
- package/src/types/custom.d.ts +4 -0
- package/src/utils/cn.ts +3 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
export interface SummaryItemConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
value: React.ReactNode;
|
|
5
|
+
actions?: SummaryListAction[];
|
|
6
|
+
}
|
|
7
|
+
export type SummaryListAction = {
|
|
8
|
+
text: string;
|
|
9
|
+
href: string;
|
|
10
|
+
visuallyHidden?: string;
|
|
11
|
+
};
|
|
12
|
+
export interface SummaryListActionProps {
|
|
13
|
+
action: SummaryListAction;
|
|
14
|
+
}
|
|
15
|
+
export interface SummaryListActionsListProps {
|
|
16
|
+
actions?: SummaryListAction[];
|
|
17
|
+
}
|
|
18
|
+
interface SummaryItemProps {
|
|
19
|
+
name: string;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
actions?: SummaryListAction[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Single action link
|
|
25
|
+
*/
|
|
26
|
+
export declare const SummaryListAction: ({ action, }: SummaryListActionProps) => React.JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* Actions container
|
|
29
|
+
* - Renders nothing if no actions
|
|
30
|
+
* - Renders a link if one action
|
|
31
|
+
* - Renders a list if multiple actions
|
|
32
|
+
*/
|
|
33
|
+
export declare const SummaryListActionsList: ({ actions, }: SummaryListActionsListProps) => React.JSX.Element | null;
|
|
34
|
+
/**
|
|
35
|
+
* Standard GOV.UK Summary List row
|
|
36
|
+
*/
|
|
37
|
+
export declare const SummaryItem: ({ name, children, actions, }: SummaryItemProps) => React.JSX.Element;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=SummaryItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryItem.d.ts","sourceRoot":"","sources":["../../../src/components/SummaryItem/SummaryItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,aAE/B,sBAAsB,KAAG,KAAK,CAAC,GAAG,CAAC,OAYrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,cAEpC,2BAA2B,KAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAqBpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,8BAIzB,gBAAgB,KAAG,KAAK,CAAC,GAAG,CAAC,OAQ/B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Single action link
|
|
5
|
+
*/
|
|
6
|
+
export const SummaryListAction = ({ action, }) => {
|
|
7
|
+
return (_jsxs("a", { className: "govuk-link", href: action.href, children: [action.text, action.visuallyHidden && (_jsxs("span", { className: "govuk-visually-hidden", children: [" ", action.visuallyHidden] }))] }));
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Actions container
|
|
11
|
+
* - Renders nothing if no actions
|
|
12
|
+
* - Renders a link if one action
|
|
13
|
+
* - Renders a list if multiple actions
|
|
14
|
+
*/
|
|
15
|
+
export const SummaryListActionsList = ({ actions, }) => {
|
|
16
|
+
if (!actions || actions.length === 0)
|
|
17
|
+
return null;
|
|
18
|
+
return (_jsx("dd", { className: "govuk-summary-list__actions", children: actions.length === 1 ? (_jsx(SummaryListAction, { action: actions[0] })) : (_jsx("ul", { className: "govuk-summary-list__actions-list", children: actions.map((action, index) => (_jsx("li", { className: "govuk-summary-list__actions-list-item", children: _jsx(SummaryListAction, { action: action }) }, `${action.href}-${index}`))) })) }));
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Standard GOV.UK Summary List row
|
|
22
|
+
*/
|
|
23
|
+
export const SummaryItem = ({ name, children, actions, }) => {
|
|
24
|
+
return (_jsxs("div", { className: "govuk-summary-list__row", children: [_jsx("dt", { className: "govuk-summary-list__key", children: name }), _jsx("dd", { className: "govuk-summary-list__value", children: children }), _jsx(SummaryListActionsList, { actions: actions })] }));
|
|
25
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { SummaryListAction } from "../SummaryItem/SummaryItem";
|
|
3
|
+
export interface SummaryListProps extends React.HTMLAttributes<HTMLDListElement> {
|
|
4
|
+
title: string;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
actions?: SummaryListAction[];
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const SummaryList: ({ title, children, className, ...props }: SummaryListProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export interface SummaryCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
11
|
+
title: string;
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
actions?: SummaryListAction[];
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const SummaryCard: ({ title, children, actions, className, ...props }: SummaryCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=SummaryList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryList.d.ts","sourceRoot":"","sources":["../../../src/components/SummaryList/SummaryList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAG/D,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,GAAI,0CAA0C,gBAAgB,4CAOrF,CAAC;AAEF,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,GAAI,mDAAmD,gBAAgB,4CAgC9F,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { SummaryListAction } from "../SummaryItem/SummaryItem";
|
|
5
|
+
import styles from "./SummaryList.module.css";
|
|
6
|
+
export const SummaryList = ({ title, children, className, ...props }) => (_jsxs(_Fragment, { children: [title && _jsx("h2", { className: "govuk-heading-l", children: title }), _jsx("dl", { className: clsx("govuk-summary-list", className), ...props, children: children })] }));
|
|
7
|
+
export const SummaryCard = ({ title, children, actions, className, ...props }) => (_jsx("div", { className: clsx(styles.root, className), children: _jsxs("div", { className: "govuk-summary-card govuk-body", ...props, children: [_jsxs("div", { className: "govuk-summary-card__title-wrapper", children: [_jsx("h2", { className: "govuk-summary-card__title", children: title }), actions && (_jsx("ul", { className: clsx("govuk-summary-card__actions", styles.summaryCardTitleActions), children: actions.map((action) => (_jsx("li", { className: "govuk-summary-card__action", children: _jsx(SummaryListAction, { action: action }) }, action.text))) }))] }), _jsx("div", { className: clsx("govuk-summary-card__content", styles.govukSummaryCardContent), children: children })] }) }));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { TagColours } from "../Colours";
|
|
3
|
+
export type TagProps = {
|
|
4
|
+
text: string;
|
|
5
|
+
colour: TagColours;
|
|
6
|
+
};
|
|
7
|
+
export declare const Tag: ({ text, colour }: TagProps) => React.JSX.Element;
|
|
8
|
+
export type TagsProps = {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
};
|
|
11
|
+
export declare const Tags: ({ children }: TagsProps) => React.JSX.Element;
|
|
12
|
+
export type TagsListProps = {
|
|
13
|
+
tags: TagProps[];
|
|
14
|
+
};
|
|
15
|
+
export declare const TagsList: ({ tags }: TagsListProps) => React.JSX.Element;
|
|
16
|
+
//# sourceMappingURL=Tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tags.d.ts","sourceRoot":"","sources":["../../../src/components/Tags/Tags.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,kBAAkB,QAAQ,KAAG,KAAK,CAAC,GAAG,CAAC,OAE1D,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,IAAI,GAAI,cAAc,SAAS,KAAG,KAAK,CAAC,GAAG,CAAC,OAExD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,UAAU,aAAa,KAAG,KAAK,CAAC,GAAG,CAAC,OAU5D,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { TagColours } from "../Colours";
|
|
5
|
+
import styles from "./Tags.module.css";
|
|
6
|
+
export const Tag = ({ text, colour }) => {
|
|
7
|
+
return _jsx("strong", { className: clsx("govuk-tag", colour, styles.tag), children: text });
|
|
8
|
+
};
|
|
9
|
+
export const Tags = ({ children }) => {
|
|
10
|
+
return _jsx("span", { className: clsx("govuk-tags", styles.root), children: children });
|
|
11
|
+
};
|
|
12
|
+
export const TagsList = ({ tags }) => {
|
|
13
|
+
if (!tags || tags.length === 0)
|
|
14
|
+
return _jsx(_Fragment, {});
|
|
15
|
+
return (_jsx(Tags, { children: tags.map((tag) => (_jsx(Tag, { text: tag.text, colour: tag.colour }, tag.text))) }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type TagProps } from "../Tags/Tags";
|
|
3
|
+
interface LinkAndTagItemProps {
|
|
4
|
+
name: string;
|
|
5
|
+
href: string;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
tags?: TagProps[];
|
|
8
|
+
}
|
|
9
|
+
export declare const ViewFormItem: ({ name, href, children, tags, }: LinkAndTagItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ViewFormItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewFormItem.d.ts","sourceRoot":"","sources":["../../../src/components/ViewFormItem/ViewFormItem.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIvD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,GAAI,iCAK1B,mBAAmB,4CAmBrB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { TagColours } from "../Colours";
|
|
5
|
+
import { TagsList } from "../Tags/Tags";
|
|
6
|
+
import styles from "./ViewFormItem.module.css";
|
|
7
|
+
export const ViewFormItem = ({ name, href, children, tags = [], }) => {
|
|
8
|
+
tags.push({
|
|
9
|
+
text: children ? "Completed" : "Not started",
|
|
10
|
+
colour: children ? TagColours.LightBlue : TagColours.Grey,
|
|
11
|
+
});
|
|
12
|
+
return (_jsxs("div", { className: clsx(styles.root, "view-form-item", "govuk-summary-list__row"), children: [_jsx("dt", { className: clsx(styles.key, "govuk-summary-list__key"), children: _jsx("a", { className: "govuk-link", href: href, children: name }) }), _jsx("dd", { className: "govuk-summary-list__value", children: children }), _jsx("dd", { className: clsx(styles.actions, "govuk-summary-list__actions"), children: _jsx(TagsList, { tags: tags }) })] }));
|
|
13
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./components/SummaryList/SummaryList";
|
|
2
|
+
export * from "./components/SummaryItem/SummaryItem";
|
|
3
|
+
export * from "./components/ViewFormItem/ViewFormItem";
|
|
4
|
+
export * from "./components/Arrow/Arrow";
|
|
5
|
+
export * from "./components/Arrows/Arrows";
|
|
6
|
+
export * from "./components/Tags/Tags";
|
|
7
|
+
export * from "./components/Colours";
|
|
8
|
+
export * from "./components/Button";
|
|
9
|
+
export * from "./components/ButtonGroup";
|
|
10
|
+
export * from "./components/BackLink";
|
|
11
|
+
export * from "./components/LoadingSpinner/LoadingSpinner";
|
|
12
|
+
export * from "./components/ApiBoundary/ApiBoundary";
|
|
13
|
+
export * from "./components/ApiQuery";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./components/SummaryList/SummaryList";
|
|
2
|
+
export * from "./components/SummaryItem/SummaryItem";
|
|
3
|
+
export * from "./components/ViewFormItem/ViewFormItem";
|
|
4
|
+
export * from "./components/Arrow/Arrow";
|
|
5
|
+
export * from "./components/Arrows/Arrows";
|
|
6
|
+
export * from "./components/Tags/Tags";
|
|
7
|
+
export * from "./components/Colours";
|
|
8
|
+
export * from "./components/Button";
|
|
9
|
+
export * from "./components/ButtonGroup";
|
|
10
|
+
export * from "./components/BackLink";
|
|
11
|
+
export * from "./components/LoadingSpinner/LoadingSpinner";
|
|
12
|
+
export * from "./components/ApiBoundary/ApiBoundary";
|
|
13
|
+
export * from "./components/ApiQuery";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../src/utils/cn.ts"],"names":[],"mappings":"AAAA,wBAAgB,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,EAAE,UAE5D"}
|
package/dist/utils/cn.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uktrade/react-component-library",
|
|
3
|
+
"version": "0.10.1",
|
|
4
|
+
"description": "A collection of reusable React components following GOV.UK design patterns.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"src"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc -p tsconfig.build.json && npm run copy:css",
|
|
13
|
+
"copy:css": "rsync -av --include='*/' --include='*.css' --exclude='*' src/ dist/",
|
|
14
|
+
"docs:build": "tsc -p docs/playground/tsconfig.docs.json",
|
|
15
|
+
"docs:start": "npx vite@latest docs/playground open",
|
|
16
|
+
"docs:vulnerability": "npx vite@latest --version && npm audit --audit-level=high",
|
|
17
|
+
"lint": "eslint .",
|
|
18
|
+
"lint:fix": "eslint . --fix",
|
|
19
|
+
"test": "vitest run --config tests/vitest.config.ts",
|
|
20
|
+
"test:watch": "vitest --watch --config tests/vitest.config.ts",
|
|
21
|
+
"test:ui": "vitest --ui --config tests/vitest.config.ts",
|
|
22
|
+
"coverage": "vitest run --coverage --config tests/vitest.config.ts"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/uktrade/react-component-library.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/uktrade/react-component-library/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/uktrade/react-component-library#readme",
|
|
38
|
+
"keywords": [
|
|
39
|
+
"react-components",
|
|
40
|
+
"govuk"
|
|
41
|
+
],
|
|
42
|
+
"author": "Mo",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"type": "module",
|
|
45
|
+
"private": false,
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": ">=19",
|
|
48
|
+
"react-dom": ">=19"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@eslint/js": "^9.39.2",
|
|
52
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
53
|
+
"@testing-library/react": "^16.3.2",
|
|
54
|
+
"@types/react": "^19.2.9",
|
|
55
|
+
"@types/react-dom": "^19.2.3",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
57
|
+
"@typescript-eslint/parser": "^8.53.1",
|
|
58
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
59
|
+
"@vitest/ui": "^4.0.18",
|
|
60
|
+
"eslint": "^9.39.2",
|
|
61
|
+
"eslint-plugin-react": "^7.37.5",
|
|
62
|
+
"globals": "^17.2.0",
|
|
63
|
+
"jsdom": "^27.4.0",
|
|
64
|
+
"openapi-typescript": "^7.10.1",
|
|
65
|
+
"typescript": "^5.9.3",
|
|
66
|
+
"typescript-eslint": "^8.53.1",
|
|
67
|
+
"vitest": "^4.0.18"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"npm": ">=11.6.2",
|
|
71
|
+
"node": ">=24.11.1"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"@tanstack/react-query": "^5.90.20",
|
|
75
|
+
"clsx": "^2.1.0",
|
|
76
|
+
"openapi-fetch": "^0.15.0"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
.hods-loading-spinner {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
padding-top: 1rem;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.hods-loading-spinner__spinner {
|
|
10
|
+
width: 80px;
|
|
11
|
+
height: 80px;
|
|
12
|
+
border: 12px solid #dee0e2;
|
|
13
|
+
border-top-color: #1d70b8; /* GOV.UK blue */
|
|
14
|
+
border-radius: 50%;
|
|
15
|
+
animation: hods-loading-spinner-rotate 1.5s linear infinite;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.hods-loading-spinner__content {
|
|
19
|
+
margin-top: 1rem;
|
|
20
|
+
text-align: center;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@keyframes hods-loading-spinner-rotate {
|
|
24
|
+
from {
|
|
25
|
+
transform: rotate(0deg);
|
|
26
|
+
}
|
|
27
|
+
to {
|
|
28
|
+
transform: rotate(360deg);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// import { LoadingBox } from "govuk-react";
|
|
2
|
+
import { LoadingSpinner } from "../LoadingSpinner/LoadingSpinner";
|
|
3
|
+
import styles from "./ApiBoundary.module.css";
|
|
4
|
+
import { Button } from "../Button";
|
|
5
|
+
|
|
6
|
+
interface ApiBoundaryProps {
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
isError: boolean;
|
|
9
|
+
error?: unknown;
|
|
10
|
+
onRetry?: () => void;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Boundary for API-related states: loading, success, and error */
|
|
15
|
+
export const ApiBoundary = ({
|
|
16
|
+
isLoading,
|
|
17
|
+
isError,
|
|
18
|
+
error,
|
|
19
|
+
onRetry,
|
|
20
|
+
children,
|
|
21
|
+
}: ApiBoundaryProps) => (
|
|
22
|
+
<div className={styles.root} aria-live="polite">
|
|
23
|
+
{isLoading && <LoadingSpinner />}
|
|
24
|
+
|
|
25
|
+
{!isLoading && !isError && children}
|
|
26
|
+
|
|
27
|
+
{isError && (
|
|
28
|
+
<>
|
|
29
|
+
<div className={styles.errorBackdrop} />
|
|
30
|
+
<section className={styles.error}>
|
|
31
|
+
<h2 className="govuk-heading-m">Error!</h2>
|
|
32
|
+
<pre className={styles.description}>
|
|
33
|
+
{typeof error === "string" ? error : JSON.stringify(error, null, 2)}
|
|
34
|
+
</pre>
|
|
35
|
+
|
|
36
|
+
{/* TODO: Make this button optional since it cannot always be required */}
|
|
37
|
+
<Button variant="warning" onClick={onRetry}>
|
|
38
|
+
Retry
|
|
39
|
+
</Button>
|
|
40
|
+
</section>
|
|
41
|
+
</>
|
|
42
|
+
)}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
margin-bottom: 0.5rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.arrow {
|
|
8
|
+
background: #f3f2f1;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
padding-left: 1rem;
|
|
13
|
+
font-weight: bold;
|
|
14
|
+
color: #333;
|
|
15
|
+
transition: background 0.2s ease;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.arrow.active {
|
|
19
|
+
background: #1d70b8;
|
|
20
|
+
color: white;
|
|
21
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import type React from "react";
|
|
4
|
+
import { cn } from "../../utils/cn";
|
|
5
|
+
import styles from "./Arrow.module.css";
|
|
6
|
+
|
|
7
|
+
export type ArrowProps = React.JSX.IntrinsicElements["div"] & {
|
|
8
|
+
variant?: "start" | "middle" | "end";
|
|
9
|
+
height?: number; // in px
|
|
10
|
+
active?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const Arrow = ({
|
|
14
|
+
className,
|
|
15
|
+
variant = "middle",
|
|
16
|
+
active = false,
|
|
17
|
+
height = 40,
|
|
18
|
+
children,
|
|
19
|
+
...props
|
|
20
|
+
}: ArrowProps) => {
|
|
21
|
+
const clipMap: Record<string, string> = {
|
|
22
|
+
start: "polygon(0% 0%, calc(100% - 20px) 0%, 100% 50%, calc(100% - 20px) 100%, 0% 100%)",
|
|
23
|
+
middle: "polygon(0% 0%, calc(100% - 20px) 0%, 100% 50%, calc(100% - 20px) 100%, 0% 100%, 20px 50%)",
|
|
24
|
+
end: "polygon(0% 0%, 100% 0%, 100% 50%, 100% 100%, 0% 100%, 20px 50%)",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
{...props}
|
|
30
|
+
className={cn(styles.root, className)}
|
|
31
|
+
style={{ height }}
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
className={cn(styles.arrow, active && styles.active)}
|
|
35
|
+
style={{ clipPath: clipMap[variant], height }}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
& > * {
|
|
3
|
+
display: none;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.active {
|
|
7
|
+
display: block;
|
|
8
|
+
+ *,
|
|
9
|
+
+ * + * {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@media (min-width: 30rem) {
|
|
15
|
+
& {
|
|
16
|
+
display: flex;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@media (min-width: 40rem) {
|
|
21
|
+
&& > * {
|
|
22
|
+
display: block;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import type React from "react";
|
|
5
|
+
import { Arrow } from "../Arrow/Arrow";
|
|
6
|
+
import styles from "./Arrows.module.css";
|
|
7
|
+
|
|
8
|
+
export type ArrowsProps = React.JSX.IntrinsicElements["div"] & {
|
|
9
|
+
arrows: string[];
|
|
10
|
+
activeIndex: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const Arrows = ({ className, arrows, activeIndex }: ArrowsProps) => (
|
|
14
|
+
<div className={clsx(styles.root, className)}>
|
|
15
|
+
{arrows.map((arrow, index) => (
|
|
16
|
+
<Arrow
|
|
17
|
+
key={arrow}
|
|
18
|
+
className={clsx(index === activeIndex && styles.active)}
|
|
19
|
+
active={index === activeIndex}
|
|
20
|
+
variant={index === 0 ? "start" : index === arrows.length - 1 ? "end" : "middle"}
|
|
21
|
+
>
|
|
22
|
+
{arrow}
|
|
23
|
+
</Arrow>
|
|
24
|
+
))}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import type { MouseEventHandler, ReactNode } from "react";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
|
|
6
|
+
export interface BackLinkProps {
|
|
7
|
+
text?: ReactNode;
|
|
8
|
+
href?: string;
|
|
9
|
+
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
10
|
+
className?: string; // ToDo: Improve additional classes, hard to override default styles
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function BackLink({
|
|
14
|
+
text = "Back",
|
|
15
|
+
href = "/",
|
|
16
|
+
onClick,
|
|
17
|
+
className,
|
|
18
|
+
}: BackLinkProps) {
|
|
19
|
+
return (
|
|
20
|
+
<a
|
|
21
|
+
href={href}
|
|
22
|
+
onClick={onClick}
|
|
23
|
+
className={clsx("govuk-back-link", className)}
|
|
24
|
+
>
|
|
25
|
+
{text}
|
|
26
|
+
</a>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import type { JSX, ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
type Props = JSX.IntrinsicElements["button"] & {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
variant?: "primary" | "secondary" | "warning";
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const Button = ({ variant = "primary", className, ...props }: Props) => (
|
|
12
|
+
<button
|
|
13
|
+
className={clsx("govuk-button", `govuk-button--${variant}`, className)}
|
|
14
|
+
aria-disabled={props.disabled}
|
|
15
|
+
data-module="govuk-button"
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import type { ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
export type ButtonGroupProps = React.JSX.IntrinsicElements["div"] & {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const ButtonGroup = ({ className, children, ...props }: ButtonGroupProps): React.JSX.Element => {
|
|
11
|
+
return (
|
|
12
|
+
<div className={clsx("govuk-button-group", className)} {...props}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export enum TagColours {
|
|
2
|
+
Grey = "govuk-tag--grey",
|
|
3
|
+
Green = "govuk-tag--green",
|
|
4
|
+
Turquoise = "govuk-tag--turquoise",
|
|
5
|
+
Blue = "govuk-tag--blue",
|
|
6
|
+
LightBlue = "govuk-tag--light-blue",
|
|
7
|
+
Purple = "govuk-tag--purple",
|
|
8
|
+
Pink = "govuk-tag--pink",
|
|
9
|
+
Red = "govuk-tag--red",
|
|
10
|
+
Orange = "govuk-tag--orange",
|
|
11
|
+
Yellow = "govuk-tag--yellow",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type BackgroundType = "default" | "light" | "muted" | "white";
|
|
15
|
+
export enum BackgroundColours {
|
|
16
|
+
transparent = "transparent",
|
|
17
|
+
light = "#f8f8f8",
|
|
18
|
+
muted = "#eef1f5",
|
|
19
|
+
white = "#ffffff",
|
|
20
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|