@uktrade/react-component-library 0.19.0 → 0.20.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.
@@ -0,0 +1,23 @@
1
+ import type { JSX, ReactNode } from "react";
2
+ type LabelAs = "h1" | "h2" | "h3" | "h4";
3
+ type LabelSize = "s" | "m" | "l" | "xl";
4
+ interface RadioItem {
5
+ value: string;
6
+ label: ReactNode;
7
+ hint?: ReactNode;
8
+ }
9
+ interface RadioGroupProps extends Omit<JSX.IntrinsicElements["input"], "id" | "type"> {
10
+ id: string;
11
+ name: string;
12
+ label: ReactNode;
13
+ hint?: ReactNode;
14
+ error?: string;
15
+ items: RadioItem[];
16
+ labelAs?: LabelAs;
17
+ labelSize?: LabelSize;
18
+ className?: string;
19
+ inline?: boolean;
20
+ }
21
+ export declare const RadioGroup: ({ id, name, label, hint, error, items, labelAs, labelSize, className, inline, ...props }: RadioGroupProps) => import("react/jsx-runtime").JSX.Element;
22
+ export {};
23
+ //# sourceMappingURL=RadioInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioInput.d.ts","sourceRoot":"","sources":["../../../../src/components/Inputs/RadioInput/RadioInput.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5C,KAAK,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,KAAK,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AAExC,UAAU,SAAS;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,UAAU,eACN,SAAQ,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,GAAI,0FAYxB,eAAe,4CAwGjB,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import clsx from "clsx";
4
+ import { createElement } from "react";
5
+ export const RadioGroup = ({ id, name, label, hint, error, items, labelAs, labelSize = "l", className, inline = false, ...props }) => {
6
+ const hasError = Boolean(error);
7
+ const hintId = hint ? `${id}-hint` : undefined;
8
+ const errorId = hasError ? `${id}-error` : undefined;
9
+ const ariaDescribedBy = [hintId, errorId].filter(Boolean).join(" ") || undefined;
10
+ const legendElement = (_jsx("legend", { className: clsx("govuk-fieldset__legend", `govuk-fieldset__legend--${labelSize}`), children: labelAs
11
+ ? createElement(labelAs, { className: "govuk-fieldset__heading" }, label)
12
+ : _jsx("span", { className: "govuk-fieldset__heading", children: label }) }));
13
+ return (_jsx("div", { className: clsx("govuk-form-group", {
14
+ "govuk-form-group--error": hasError,
15
+ }), children: _jsxs("fieldset", { className: "govuk-fieldset", "aria-describedby": ariaDescribedBy, children: [legendElement, hint && (_jsx("div", { id: hintId, className: "govuk-hint", children: hint })), hasError && (_jsxs("p", { id: errorId, className: "govuk-error-message", children: [_jsx("span", { className: "govuk-visually-hidden", children: "Error:" }), " ", error] })), _jsx("div", { className: clsx("govuk-radios", {
16
+ "govuk-radios--inline": inline,
17
+ "govuk-radios--error": hasError,
18
+ }, className), "data-module": "govuk-radios", children: items.map((item, index) => {
19
+ const itemId = `${id}-${index}`;
20
+ const itemHintId = item.hint ? `${itemId}-hint` : undefined;
21
+ const describedBy = [
22
+ ariaDescribedBy, // group hint + group error
23
+ itemHintId // per-item hint
24
+ ].filter(Boolean).join(" ") || undefined;
25
+ return (_jsxs("div", { className: "govuk-radios__item", children: [_jsx("input", { className: "govuk-radios__input", id: itemId, name: name, type: "radio", value: item.value, "aria-describedby": describedBy, ...props }), _jsx("label", { className: "govuk-label govuk-radios__label", htmlFor: itemId, children: item.label }), item.hint && (_jsx("div", { id: itemHintId, className: "govuk-hint govuk-radios__hint", children: item.hint }))] }, item.value));
26
+ }) })] }) }));
27
+ };
@@ -0,0 +1,16 @@
1
+ import type { ReactNode, JSX } from "react";
2
+ type LabelAs = "h1" | "h2" | "h3" | "h4";
3
+ type LabelSize = "s" | "m" | "l" | "xl";
4
+ interface TextareaInputProps extends Omit<JSX.IntrinsicElements["textarea"], "id"> {
5
+ id: string;
6
+ label: ReactNode;
7
+ hint?: ReactNode;
8
+ error?: string;
9
+ labelAs?: LabelAs;
10
+ labelSize?: LabelSize;
11
+ rows?: number;
12
+ className?: string;
13
+ }
14
+ export declare const TextAreaInput: ({ id, label, hint, error, labelAs, labelSize, rows, className, ...props }: TextareaInputProps) => import("react/jsx-runtime").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=TextAreaInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextAreaInput.d.ts","sourceRoot":"","sources":["../../../../src/components/Inputs/TextAreaInput/TextAreaInput.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5C,KAAK,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,KAAK,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AAExC,UAAU,kBACN,SAAQ,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,GAAI,2EAU3B,kBAAkB,4CA6DpB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import clsx from "clsx";
4
+ import { createElement } from "react";
5
+ export const TextAreaInput = ({ id, label, hint, error, labelAs, labelSize = "l", rows = 5, className, ...props }) => {
6
+ const hasError = Boolean(error);
7
+ const hintId = hint ? `${id}-hint` : undefined;
8
+ const errorId = hasError ? `${id}-error` : undefined;
9
+ const ariaDescribedBy = [
10
+ hintId,
11
+ errorId
12
+ ].filter(Boolean).join(" ") || undefined;
13
+ const labelElement = (_jsx("label", { htmlFor: id, className: clsx("govuk-label", {
14
+ [`govuk-label--${labelSize}`]: true,
15
+ }), children: label }));
16
+ return (_jsxs("div", { className: clsx("govuk-form-group", {
17
+ "govuk-form-group--error": hasError,
18
+ }), children: [labelAs
19
+ ? createElement(labelAs, { className: "govuk-label-wrapper" }, labelElement)
20
+ : labelElement, hint && (_jsx("div", { id: hintId, className: "govuk-hint", children: hint })), hasError && (_jsxs("p", { id: errorId, className: "govuk-error-message", children: [_jsx("span", { className: "govuk-visually-hidden", children: "Error:" }), " ", error] })), _jsx("textarea", { id: id, rows: rows, className: clsx("govuk-textarea", { "govuk-textarea--error": hasError }, className), "aria-describedby": ariaDescribedBy, ...props })] }));
21
+ };
@@ -1,4 +1,6 @@
1
1
  export * from "./TextInput/TextInput";
2
2
  export * from "./CheckBoxesInput/CheckBoxGroupInput";
3
3
  export * from "./SelectInput/SelectInput";
4
+ export * from "./TextAreaInput/TextAreaInput";
5
+ export * from "./RadioInput/RadioInput";
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Inputs/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Inputs/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC"}
@@ -1,3 +1,5 @@
1
1
  export * from "./TextInput/TextInput";
2
2
  export * from "./CheckBoxesInput/CheckBoxGroupInput";
3
3
  export * from "./SelectInput/SelectInput";
4
+ export * from "./TextAreaInput/TextAreaInput";
5
+ export * from "./RadioInput/RadioInput";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uktrade/react-component-library",
3
- "version": "0.19.0",
3
+ "version": "0.20.1",
4
4
  "description": "A collection of reusable React components following GOV.UK design patterns.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -0,0 +1,146 @@
1
+ "use client";
2
+
3
+ import clsx from "clsx";
4
+ import type { JSX, ReactNode } from "react";
5
+ import { createElement } from "react";
6
+
7
+ type LabelAs = "h1" | "h2" | "h3" | "h4";
8
+ type LabelSize = "s" | "m" | "l" | "xl";
9
+
10
+ interface RadioItem {
11
+ value: string;
12
+ label: ReactNode;
13
+ hint?: ReactNode;
14
+ }
15
+
16
+ interface RadioGroupProps
17
+ extends Omit<JSX.IntrinsicElements["input"], "id" | "type"> {
18
+ id: string;
19
+ name: string;
20
+ label: ReactNode;
21
+ hint?: ReactNode;
22
+ error?: string;
23
+ items: RadioItem[];
24
+ labelAs?: LabelAs;
25
+ labelSize?: LabelSize;
26
+ className?: string;
27
+ inline?: boolean;
28
+ }
29
+
30
+ export const RadioGroup = ({
31
+ id,
32
+ name,
33
+ label,
34
+ hint,
35
+ error,
36
+ items,
37
+ labelAs,
38
+ labelSize = "l",
39
+ className,
40
+ inline = false,
41
+ ...props
42
+ }: RadioGroupProps) => {
43
+ const hasError = Boolean(error);
44
+
45
+ const hintId = hint ? `${id}-hint` : undefined;
46
+ const errorId = hasError ? `${id}-error` : undefined;
47
+
48
+ const ariaDescribedBy =
49
+ [hintId, errorId].filter(Boolean).join(" ") || undefined;
50
+
51
+ const legendElement = (
52
+ <legend
53
+ className={clsx(
54
+ "govuk-fieldset__legend",
55
+ `govuk-fieldset__legend--${labelSize}`
56
+ )}
57
+ >
58
+ {labelAs
59
+ ? createElement(
60
+ labelAs,
61
+ { className: "govuk-fieldset__heading" },
62
+ label
63
+ )
64
+ : <span className="govuk-fieldset__heading">{label}</span>}
65
+ </legend>
66
+ );
67
+
68
+ return (
69
+ <div
70
+ className={clsx("govuk-form-group", {
71
+ "govuk-form-group--error": hasError,
72
+ })}
73
+ >
74
+ <fieldset
75
+ className="govuk-fieldset"
76
+ aria-describedby={ariaDescribedBy}
77
+ >
78
+ {legendElement}
79
+
80
+ {hint && (
81
+ <div id={hintId} className="govuk-hint">
82
+ {hint}
83
+ </div>
84
+ )}
85
+
86
+ {hasError && (
87
+ <p id={errorId} className="govuk-error-message">
88
+ <span className="govuk-visually-hidden">Error:</span>{" "}
89
+ {error}
90
+ </p>
91
+ )}
92
+
93
+ <div
94
+ className={clsx(
95
+ "govuk-radios",
96
+ {
97
+ "govuk-radios--inline": inline,
98
+ "govuk-radios--error": hasError,
99
+ },
100
+ className
101
+ )}
102
+ data-module="govuk-radios"
103
+ >
104
+ {items.map((item, index) => {
105
+ const itemId = `${id}-${index}`;
106
+ const itemHintId = item.hint ? `${itemId}-hint` : undefined;
107
+ const describedBy = [
108
+ ariaDescribedBy, // group hint + group error
109
+ itemHintId // per-item hint
110
+ ].filter(Boolean).join(" ") || undefined;
111
+
112
+ return (
113
+ <div className="govuk-radios__item" key={item.value}>
114
+ <input
115
+ className="govuk-radios__input"
116
+ id={itemId}
117
+ name={name}
118
+ type="radio"
119
+ value={item.value}
120
+ aria-describedby={describedBy}
121
+ {...props}
122
+ />
123
+
124
+ <label
125
+ className="govuk-label govuk-radios__label"
126
+ htmlFor={itemId}
127
+ >
128
+ {item.label}
129
+ </label>
130
+
131
+ {item.hint && (
132
+ <div
133
+ id={itemHintId}
134
+ className="govuk-hint govuk-radios__hint"
135
+ >
136
+ {item.hint}
137
+ </div>
138
+ )}
139
+ </div>
140
+ );
141
+ })}
142
+ </div>
143
+ </fieldset>
144
+ </div>
145
+ );
146
+ };
@@ -0,0 +1,93 @@
1
+ "use client";
2
+
3
+ import clsx from "clsx";
4
+ import type { ReactNode, JSX } from "react";
5
+ import { createElement } from "react";
6
+
7
+ type LabelAs = "h1" | "h2" | "h3" | "h4";
8
+ type LabelSize = "s" | "m" | "l" | "xl";
9
+
10
+ interface TextareaInputProps
11
+ extends Omit<JSX.IntrinsicElements["textarea"], "id"> {
12
+ id: string;
13
+ label: ReactNode;
14
+ hint?: ReactNode;
15
+ error?: string;
16
+ labelAs?: LabelAs;
17
+ labelSize?: LabelSize;
18
+ rows?: number;
19
+ className?: string;
20
+ }
21
+
22
+ export const TextAreaInput = ({
23
+ id,
24
+ label,
25
+ hint,
26
+ error,
27
+ labelAs,
28
+ labelSize = "l",
29
+ rows = 5,
30
+ className,
31
+ ...props
32
+ }: TextareaInputProps) => {
33
+ const hasError = Boolean(error);
34
+
35
+ const hintId = hint ? `${id}-hint` : undefined;
36
+ const errorId = hasError ? `${id}-error` : undefined;
37
+
38
+ const ariaDescribedBy = [
39
+ hintId,
40
+ errorId
41
+ ].filter(Boolean).join(" ") || undefined;
42
+
43
+ const labelElement = (
44
+ <label
45
+ htmlFor={id}
46
+ className={clsx("govuk-label", {
47
+ [`govuk-label--${labelSize}`]: true,
48
+ })}
49
+ >
50
+ {label}
51
+ </label>
52
+ );
53
+
54
+ return (
55
+ <div
56
+ className={clsx("govuk-form-group", {
57
+ "govuk-form-group--error": hasError,
58
+ })}
59
+ >
60
+ {labelAs
61
+ ? createElement(
62
+ labelAs,
63
+ { className: "govuk-label-wrapper" },
64
+ labelElement
65
+ )
66
+ : labelElement}
67
+
68
+ {hint && (
69
+ <div id={hintId} className="govuk-hint">
70
+ {hint}
71
+ </div>
72
+ )}
73
+
74
+ {hasError && (
75
+ <p id={errorId} className="govuk-error-message">
76
+ <span className="govuk-visually-hidden">Error:</span> {error}
77
+ </p>
78
+ )}
79
+
80
+ <textarea
81
+ id={id}
82
+ rows={rows}
83
+ className={clsx(
84
+ "govuk-textarea",
85
+ { "govuk-textarea--error": hasError },
86
+ className
87
+ )}
88
+ aria-describedby={ariaDescribedBy}
89
+ {...props}
90
+ />
91
+ </div>
92
+ );
93
+ };
@@ -1,3 +1,5 @@
1
1
  export * from "./TextInput/TextInput";
2
2
  export * from "./CheckBoxesInput/CheckBoxGroupInput";
3
- export * from "./SelectInput/SelectInput";
3
+ export * from "./SelectInput/SelectInput";
4
+ export * from "./TextAreaInput/TextAreaInput";
5
+ export * from "./RadioInput/RadioInput";
File without changes