@coopdigital/react 0.36.0 → 0.38.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.
@@ -31,8 +31,8 @@ export interface CardProps extends HTMLAttributes<HTMLDivElement> {
31
31
  label?: string;
32
32
  /** **(Optional)** Specify the background color of the Card label. */
33
33
  labelBackground?: Lights;
34
- /** **(Optional)** Specify the layout of the Card. */
35
- layout?: "vertical" | "horizontal";
34
+ /** **(Optional)** Specify the orientation of the Card. */
35
+ orientation?: "vertical" | "horizontal";
36
36
  }
37
- export declare const Card: ({ as, background, badge, badgePosition, chevron, children, className, heading, headingLevel, href, image, imagePosition, label, labelBackground, layout, ...props }: CardProps) => JSX.Element;
37
+ export declare const Card: ({ as, background, badge, badgePosition, chevron, children, className, heading, headingLevel, href, image, imagePosition, label, labelBackground, orientation, ...props }: CardProps) => JSX.Element;
38
38
  export default Card;
@@ -18,7 +18,7 @@ function getCardLinkElement(as, href) {
18
18
  },
19
19
  };
20
20
  }
21
- const Card = ({ as, background = "white", badge, badgePosition = "inset", chevron = false, children, className, heading, headingLevel = "h3", href, image, imagePosition = "left", label = "", labelBackground, layout = "vertical", ...props }) => {
21
+ const Card = ({ as, background = "white", badge, badgePosition = "inset", chevron = false, children, className, heading, headingLevel = "h3", href, image, imagePosition = "left", label = "", labelBackground, orientation = "vertical", ...props }) => {
22
22
  const linkElement = getCardLinkElement(as, href);
23
23
  const imageProps = {
24
24
  crop: "wide",
@@ -28,7 +28,7 @@ const Card = ({ as, background = "white", badge, badgePosition = "inset", chevro
28
28
  className: clsx("coop-card", background && bgPropToClass(background, className), className),
29
29
  "data-badge-pos": badgePosition,
30
30
  "data-image-pos": imagePosition,
31
- "data-layout": layout !== "vertical" ? layout : undefined,
31
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
32
32
  ...props,
33
33
  };
34
34
  return (jsxs("article", { ...componentProps, children: [image && jsx(Image, { ...imageProps }), badge && jsx("div", { className: "coop-card--badge", children: badge }), jsxs("div", { className: "coop-card--inner", children: [jsxs("div", { className: "coop-card--content", children: [label && (jsx("span", { className: clsx("coop-card--label", labelBackground && bgPropToClass(labelBackground, className)), children: label })), React.createElement(linkElement.element, linkElement.props, React.createElement(headingLevel, { className: "coop-card--heading" }, heading)), children] }), chevron && (jsx("span", { "aria-hidden": "true", className: "coop-card--icon", role: "presentation", children: jsx(ChevronRightIcon, {}) }))] })] }));
@@ -3,6 +3,8 @@ import { FormFieldError, StandardSizes } from "../../../src/types";
3
3
  export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
4
4
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
5
5
  className?: string;
6
+ /** **(Optional)** Specify whether the Checkbox should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
7
+ disabled?: boolean;
6
8
  /** **(Optional)** Specify the Checkbox error state.
7
9
  *
8
10
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -26,5 +28,5 @@ export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement
26
28
  /** **(Optional)** Specify the Checkbox size. */
27
29
  size?: StandardSizes;
28
30
  }
29
- export declare const Checkbox: ({ className, error, hint, id, label, labelVisible, name, size, ...props }: CheckboxProps) => JSX.Element;
31
+ export declare const Checkbox: ({ className, disabled, error, hint, id, label, labelVisible, name, size, ...props }: CheckboxProps) => JSX.Element;
30
32
  export default Checkbox;
@@ -5,19 +5,21 @@ import { FieldError } from '../FieldError/FieldError.js';
5
5
  import { FieldHint } from '../FieldHint/FieldHint.js';
6
6
  import { FieldLabel } from '../FieldLabel/FieldLabel.js';
7
7
 
8
- const Checkbox = ({ className, error = false, hint, id, label, labelVisible = true, name, size = "md", ...props }) => {
8
+ const Checkbox = ({ className, disabled, error = false, hint, id, label, labelVisible = true, name, size = "md", ...props }) => {
9
9
  const internalId = useId();
10
10
  id = id !== null && id !== void 0 ? id : internalId;
11
11
  const componentProps = {
12
12
  className: clsx("coop-checkbox", className),
13
13
  "data-error": error ? "" : undefined,
14
14
  "data-size": size.length && size !== "md" ? size : undefined,
15
+ disabled,
15
16
  id,
16
17
  name,
17
18
  type: "checkbox",
18
19
  ...props,
19
20
  };
20
- return (jsxs("div", { className: "coop-form-item", children: [jsxs("div", { className: "coop-checkbox-wrapper", children: [jsx("input", { ...componentProps }), label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint })] }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message })] }));
21
+ const formItemProps = { "aria-disabled": disabled ? true : undefined };
22
+ return (jsxs("div", { className: "coop-form-item", ...formItemProps, children: [jsxs("div", { className: "coop-checkbox-wrapper", children: [jsx("input", { ...componentProps }), label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint })] }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message })] }));
21
23
  };
22
24
 
23
25
  export { Checkbox, Checkbox as default };
@@ -5,6 +5,8 @@ export interface CheckboxGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetE
5
5
  children?: React.ReactNode;
6
6
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
7
7
  className?: string;
8
+ /** **(Optional)** Specify whether the CheckboxGroup, and all of its descendents, should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
9
+ disabled?: boolean;
8
10
  /** **(Optional)** Specify the CheckboxGroup error state.
9
11
  *
10
12
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -19,8 +21,10 @@ export interface CheckboxGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetE
19
21
  label?: string;
20
22
  /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
21
23
  labelVisible?: boolean;
24
+ /** **(Optional)** Specify the CheckboxGroup orientation. */
25
+ orientation?: "horizontal" | "vertical";
22
26
  /** **(Optional)** Specify the CheckboxGroup size. */
23
27
  size?: StandardSizes;
24
28
  }
25
- export declare const CheckboxGroup: ({ children, className, error, hint, label, labelVisible, size, ...props }: CheckboxGroupProps) => JSX.Element;
29
+ export declare const CheckboxGroup: ({ children, className, error, hint, label, labelVisible, orientation, size, ...props }: CheckboxGroupProps) => JSX.Element;
26
30
  export default CheckboxGroup;
@@ -3,17 +3,18 @@ import { clsx } from '../../node_modules/clsx/dist/clsx.js';
3
3
  import { FieldError } from '../FieldError/FieldError.js';
4
4
  import { FieldHint } from '../FieldHint/FieldHint.js';
5
5
 
6
- const CheckboxGroup = ({ children, className, error = false, hint, label, labelVisible = true, size = "md", ...props }) => {
6
+ const CheckboxGroup = ({ children, className, error = false, hint, label, labelVisible = true, orientation = "vertical", size = "md", ...props }) => {
7
7
  const componentProps = {
8
8
  className: clsx("coop-fieldset", "coop-checkbox-group", className),
9
9
  "data-error": error ? "" : undefined,
10
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
10
11
  "data-size": size.length && size !== "md" ? size : undefined,
11
12
  ...props,
12
13
  };
13
14
  const legendProps = {
14
15
  className: clsx("coop-field-label", !labelVisible && "sr-only"),
15
16
  };
16
- return (jsxs("fieldset", { ...componentProps, children: [label && jsx("legend", { ...legendProps, children: label }), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), children] }));
17
+ return (jsxs("fieldset", { ...componentProps, children: [label && jsx("legend", { ...legendProps, children: label }), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsx("div", { className: "coop-checkbox-group-options", children: children })] }));
17
18
  };
18
19
 
19
20
  export { CheckboxGroup, CheckboxGroup as default };
@@ -1,8 +1,11 @@
1
1
  import { type InputHTMLAttributes, type JSX } from "react";
2
2
  import { FormFieldError, StandardSizes } from "src/types";
3
+ import { TagProps } from "../Tag";
3
4
  export interface RadioButtonProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
4
5
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
5
6
  className?: string;
7
+ /** **(Optional)** Specify whether the RadioButton should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
8
+ disabled?: boolean;
6
9
  /** **(Optional)** Specify the RadioButton error state.
7
10
  *
8
11
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -25,6 +28,12 @@ export interface RadioButtonProps extends Omit<InputHTMLAttributes<HTMLInputElem
25
28
  name: string;
26
29
  /** **(Optional)** Specify the RadioButton size. */
27
30
  size?: StandardSizes;
31
+ /** **(Optional)** Specify the RadioButton tag text. */
32
+ tag?: string;
33
+ /** **(Optional)** Specify the RadioButton tag background color. */
34
+ tagBackground?: TagProps["background"];
35
+ /** **(Optional)** Specify the RadioButton variant. */
36
+ variant?: "default" | "boxed";
28
37
  }
29
- export declare const RadioButton: ({ className, error, hint, id, label, labelVisible, name, size, ...props }: RadioButtonProps) => JSX.Element;
38
+ export declare const RadioButton: ({ className, disabled, error, hint, id, label, labelVisible, name, size, tag, tagBackground, variant, ...props }: RadioButtonProps) => JSX.Element;
30
39
  export default RadioButton;
@@ -4,20 +4,24 @@ import { useId } from 'react';
4
4
  import { FieldError } from '../FieldError/FieldError.js';
5
5
  import { FieldHint } from '../FieldHint/FieldHint.js';
6
6
  import { FieldLabel } from '../FieldLabel/FieldLabel.js';
7
+ import { Tag } from '../Tag/Tag.js';
7
8
 
8
- const RadioButton = ({ className, error = false, hint, id, label, labelVisible = true, name, size = "md", ...props }) => {
9
+ const RadioButton = ({ className, disabled, error = false, hint, id, label, labelVisible = true, name, size = "md", tag, tagBackground, variant = "default", ...props }) => {
9
10
  const internalId = useId();
10
11
  id = id !== null && id !== void 0 ? id : internalId;
11
12
  const componentProps = {
12
13
  className: clsx("coop-radio-button", className),
13
14
  "data-error": error ? "" : undefined,
14
15
  "data-size": size.length && size !== "md" ? size : undefined,
16
+ "data-variant": variant !== "default" ? variant : undefined,
17
+ disabled,
15
18
  id,
16
19
  name,
17
20
  type: "radio",
18
21
  ...props,
19
22
  };
20
- return (jsxs("div", { className: "coop-form-item", children: [jsxs("div", { className: "coop-radio-button-wrapper", children: [jsx("input", { ...componentProps }), label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint })] }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message })] }));
23
+ const formItemProps = { "aria-disabled": disabled ? true : undefined };
24
+ return (jsxs("div", { className: "coop-form-item", ...formItemProps, children: [jsxs("div", { className: "coop-radio-button-wrapper", children: [jsx("input", { ...componentProps }), label && (jsxs(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: [jsx("span", { children: label }), " ", tag && (jsx(Tag, { background: tagBackground, size: "sm", children: tag }))] })), hint && jsx(FieldHint, { children: hint })] }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message })] }));
21
25
  };
22
26
 
23
27
  export { RadioButton, RadioButton as default };
@@ -5,6 +5,8 @@ export interface RadioButtonGroupProps extends FieldsetHTMLAttributes<HTMLFieldS
5
5
  children?: React.ReactNode;
6
6
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
7
7
  className?: string;
8
+ /** **(Optional)** Specify whether the RadioButtonGroup, and all of its descendents, should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
9
+ disabled?: boolean;
8
10
  /** **(Optional)** Specify the RadioButtonGroup error state.
9
11
  *
10
12
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -19,8 +21,12 @@ export interface RadioButtonGroupProps extends FieldsetHTMLAttributes<HTMLFieldS
19
21
  label?: string;
20
22
  /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
21
23
  labelVisible?: boolean;
24
+ /** **(Optional)** Specify the RadioButtonGroup orientation. */
25
+ orientation?: "horizontal" | "vertical";
22
26
  /** **(Optional)** Specify the RadioButtonGroup size. */
23
27
  size?: StandardSizes;
28
+ /** **(Optional)** Specify the RadioButtonGroup variant. */
29
+ variant?: "default" | "boxed";
24
30
  }
25
- export declare const RadioButtonGroup: ({ children, className, error, hint, label, labelVisible, size, ...props }: RadioButtonGroupProps) => JSX.Element;
31
+ export declare const RadioButtonGroup: ({ children, className, error, hint, label, labelVisible, orientation, size, variant, ...props }: RadioButtonGroupProps) => JSX.Element;
26
32
  export default RadioButtonGroup;
@@ -3,17 +3,19 @@ import { clsx } from '../../node_modules/clsx/dist/clsx.js';
3
3
  import { FieldError } from '../FieldError/FieldError.js';
4
4
  import { FieldHint } from '../FieldHint/FieldHint.js';
5
5
 
6
- const RadioButtonGroup = ({ children, className, error = false, hint, label, labelVisible = true, size = "md", ...props }) => {
6
+ const RadioButtonGroup = ({ children, className, error = false, hint, label, labelVisible = true, orientation = "vertical", size = "md", variant = "default", ...props }) => {
7
7
  const componentProps = {
8
8
  className: clsx("coop-fieldset", "coop-radio-button-group", className),
9
9
  "data-error": error ? "" : undefined,
10
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
10
11
  "data-size": size.length && size !== "md" ? size : undefined,
12
+ "data-variant": variant !== "default" ? variant : undefined,
11
13
  ...props,
12
14
  };
13
15
  const legendProps = {
14
16
  className: clsx("coop-field-label", !labelVisible && "sr-only"),
15
17
  };
16
- return (jsxs("fieldset", { ...componentProps, children: [label && jsx("legend", { ...legendProps, children: label }), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), children] }));
18
+ return (jsxs("fieldset", { ...componentProps, children: [label && jsx("legend", { ...legendProps, children: label }), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsx("div", { className: "coop-radio-button-group-options", children: children })] }));
17
19
  };
18
20
 
19
21
  export { RadioButtonGroup, RadioButtonGroup as default };
@@ -12,6 +12,8 @@ export interface TagProps extends HTMLAttributes<HTMLAnchorElement> {
12
12
  className?: string;
13
13
  /** **(Optional)** Specify the URL that the Tag component will link to when clicked. */
14
14
  href?: string;
15
+ /** **(Optional)** Specify the Tag size. */
16
+ size?: "sm" | "md";
15
17
  }
16
- export declare const Tag: ({ as, background, children, className, href, ...props }: TagProps) => JSX.Element;
18
+ export declare const Tag: ({ as, background, children, className, href, size, ...props }: TagProps) => JSX.Element;
17
19
  export default Tag;
@@ -2,10 +2,11 @@ import { clsx } from '../../node_modules/clsx/dist/clsx.js';
2
2
  import React from 'react';
3
3
  import { bgPropToClass } from '../../utils/index.js';
4
4
 
5
- const Tag = ({ as, background = "tint-grey", children, className, href, ...props }) => {
5
+ const Tag = ({ as, background = "tint-grey", children, className, href, size = "md", ...props }) => {
6
6
  let element = href ? "a" : "span";
7
7
  const componentProps = {
8
8
  className: clsx("coop-tag", bgPropToClass(background, className), className),
9
+ "data-size": size.length && size !== "md" ? size : undefined,
9
10
  href,
10
11
  ...props,
11
12
  };
@@ -0,0 +1,5 @@
1
+ import { Tag } from './Tag.js';
2
+
3
+
4
+
5
+ export { Tag, Tag as default };
@@ -3,6 +3,8 @@ import { FormFieldError, StandardSizes } from "../../../src/types";
3
3
  export interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
4
4
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
5
5
  className?: string;
6
+ /** **(Optional)** Specify whether the TextInput should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
7
+ disabled?: boolean;
6
8
  /** **(Optional)** Specify the TextInput error state.
7
9
  *
8
10
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -34,5 +36,5 @@ export interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElemen
34
36
  /** **(Optional)** Specify the TextInput type. */
35
37
  type?: "text" | "email" | "number" | "password" | "search" | "tel" | "url";
36
38
  }
37
- export declare const TextInput: ({ "aria-placeholder": ariaPlaceholder, className, error, hint, id, label, labelVisible, name, placeholder, prefix, size, suffix, type, ...props }: TextInputProps) => JSX.Element;
39
+ export declare const TextInput: ({ "aria-placeholder": ariaPlaceholder, className, disabled, error, hint, id, label, labelVisible, name, placeholder, prefix, size, suffix, type, ...props }: TextInputProps) => JSX.Element;
38
40
  export default TextInput;
@@ -5,7 +5,7 @@ import { FieldError } from '../FieldError/FieldError.js';
5
5
  import { FieldHint } from '../FieldHint/FieldHint.js';
6
6
  import { FieldLabel } from '../FieldLabel/FieldLabel.js';
7
7
 
8
- const TextInput = ({ "aria-placeholder": ariaPlaceholder, className, error = false, hint, id, label, labelVisible = true, name, placeholder, prefix, size = "md", suffix, type = "text", ...props }) => {
8
+ const TextInput = ({ "aria-placeholder": ariaPlaceholder, className, disabled, error = false, hint, id, label, labelVisible = true, name, placeholder, prefix, size = "md", suffix, type = "text", ...props }) => {
9
9
  var _a;
10
10
  const internalId = useId();
11
11
  id = id !== null && id !== void 0 ? id : internalId;
@@ -14,13 +14,15 @@ const TextInput = ({ "aria-placeholder": ariaPlaceholder, className, error = fal
14
14
  className: clsx("coop-text-input", className),
15
15
  "data-error": error ? "" : undefined,
16
16
  "data-size": size.length && size !== "md" ? size : undefined,
17
+ disabled,
17
18
  id,
18
19
  name,
19
20
  placeholder,
20
21
  type,
21
22
  ...props,
22
23
  };
23
- return (jsxs("div", { className: "coop-form-item", children: [label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsxs("div", { className: "coop-text-input-wrapper", children: [prefix && jsx("span", { className: "coop-text-input--prefix", children: prefix }), jsx("input", { ...componentProps }), suffix && jsx("span", { className: "coop-text-input--suffix", children: suffix })] })] }));
24
+ const formItemProps = { "aria-disabled": disabled ? true : undefined };
25
+ return (jsxs("div", { className: "coop-form-item", ...formItemProps, children: [label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsxs("div", { className: "coop-text-input-wrapper", children: [prefix && jsx("span", { className: "coop-text-input--prefix", children: prefix }), jsx("input", { ...componentProps }), suffix && jsx("span", { className: "coop-text-input--suffix", children: suffix })] })] }));
24
26
  };
25
27
 
26
28
  export { TextInput, TextInput as default };
@@ -14,6 +14,8 @@ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElemen
14
14
  * Remember it is still your responsibility to handle validation on submission, this is simply a hint for the user.
15
15
  */
16
16
  cutoff?: boolean;
17
+ /** **(Optional)** Specify whether the Textarea should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
18
+ disabled?: boolean;
17
19
  /** **(Optional)** Specify the Textarea error state.
18
20
  *
19
21
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -43,5 +45,5 @@ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElemen
43
45
  /** **(Optional)** Specify the Textarea size. */
44
46
  size?: StandardSizes;
45
47
  }
46
- export declare const Textarea: ({ "aria-placeholder": ariaPlaceholder, className, cols, counter, cutoff, error, hint, id, label, labelVisible, maxLength, name, onChange: userOnChange, placeholder, rows, size, ...props }: TextareaProps) => JSX.Element;
48
+ export declare const Textarea: ({ "aria-placeholder": ariaPlaceholder, className, cols, counter, cutoff, disabled, error, hint, id, label, labelVisible, maxLength, name, onChange: userOnChange, placeholder, rows, size, ...props }: TextareaProps) => JSX.Element;
47
49
  export default Textarea;
@@ -10,7 +10,7 @@ const DEBOUNCE_DELAY = 750;
10
10
  const charCountMessage = (remaining) => {
11
11
  return `You have ${Math.abs(remaining).toLocaleString()} ${Math.abs(remaining) === 1 ? "character" : "characters"} ${remaining < 0 ? "too many" : "remaining"}`;
12
12
  };
13
- const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, counter = false, cutoff = false, error = false, hint, id, label, labelVisible = true, maxLength, name, onChange: userOnChange = undefined, placeholder, rows = 4, size = "md", ...props }) => {
13
+ const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, counter = false, cutoff = false, disabled = false, error = false, hint, id, label, labelVisible = true, maxLength, name, onChange: userOnChange = undefined, placeholder, rows = 4, size = "md", ...props }) => {
14
14
  var _a;
15
15
  const internalId = useId();
16
16
  id = id !== null && id !== void 0 ? id : internalId;
@@ -20,6 +20,7 @@ const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, c
20
20
  cols,
21
21
  "data-error": error ? "" : undefined,
22
22
  "data-size": size.length && size !== "md" ? size : undefined,
23
+ disabled,
23
24
  id,
24
25
  maxLength: cutoff ? maxLength : undefined,
25
26
  name,
@@ -32,10 +33,11 @@ const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, c
32
33
  const handleChange = (e) => {
33
34
  maxLength && e.target && setRemaining(maxLength - e.target.value.length);
34
35
  };
35
- return (jsxs("div", { className: "coop-form-item", children: [label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsx("textarea", { ...componentProps, onChange: (e) => {
36
+ const formItemProps = { "aria-disabled": disabled ? true : undefined };
37
+ return (jsxs("div", { className: "coop-form-item", ...formItemProps, children: [label && (jsx(FieldLabel, { htmlFor: id, isVisible: labelVisible, children: label })), hint && jsx(FieldHint, { children: hint }), typeof error === "object" && (error === null || error === void 0 ? void 0 : error.message) && jsx(FieldError, { children: error.message }), jsx("textarea", { ...componentProps, onChange: (e) => {
36
38
  userOnChange === null || userOnChange === void 0 ? void 0 : userOnChange(e);
37
39
  handleChange(e);
38
- } }), counter && maxLength && remaining != null && debouncedRemaining != null && (jsxs(Fragment, { children: [jsx("small", { "aria-hidden": "true", className: "coop-textarea-counter", ...(remaining < 0 && { "data-error": "" }), children: charCountMessage(remaining) }), jsx("span", { "aria-live": "polite", className: "sr-only", children: charCountMessage(debouncedRemaining) })] }))] }));
40
+ } }), !disabled && counter && maxLength && remaining != null && debouncedRemaining != null && (jsxs(Fragment, { children: [jsx("small", { "aria-hidden": "true", className: "coop-textarea-counter", ...(remaining < 0 && { "data-error": "" }), children: charCountMessage(remaining) }), jsx("span", { "aria-live": "polite", className: "sr-only", children: charCountMessage(debouncedRemaining) })] }))] }));
39
41
  };
40
42
 
41
43
  export { Textarea, Textarea as default };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coopdigital/react",
3
3
  "type": "module",
4
- "version": "0.36.0",
4
+ "version": "0.38.0",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -56,11 +56,11 @@
56
56
  "description": "",
57
57
  "devDependencies": {
58
58
  "@axe-core/playwright": "^4.10.2",
59
- "@playwright/test": "^1.55.0",
60
- "@storybook/addon-a11y": "^9.1.5",
61
- "@storybook/addon-docs": "^9.1.5",
62
- "@storybook/addon-onboarding": "^9.1.5",
63
- "@storybook/react-vite": "^9.1.5",
59
+ "@playwright/test": "^1.55.1",
60
+ "@storybook/addon-a11y": "^9.1.8",
61
+ "@storybook/addon-docs": "^9.1.8",
62
+ "@storybook/addon-onboarding": "^9.1.8",
63
+ "@storybook/react-vite": "^9.1.8",
64
64
  "@testing-library/jest-dom": "^6.8.0",
65
65
  "@testing-library/react": "^16.3.0",
66
66
  "@types/react": "^19.1.13",
@@ -69,7 +69,7 @@
69
69
  "react": "^19.1.1",
70
70
  "react-dom": "^19.1.1",
71
71
  "serve": "^14.2.5",
72
- "storybook": "^9.1.5"
72
+ "storybook": "^9.1.8"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "clsx": "^2.1.1",
@@ -80,7 +80,7 @@
80
80
  "storybook": "$storybook"
81
81
  },
82
82
  "dependencies": {
83
- "@coopdigital/styles": "^0.31.1"
83
+ "@coopdigital/styles": "^0.33.0"
84
84
  },
85
- "gitHead": "a88bc2694b91f0c180f02d39786a1323e6632254"
85
+ "gitHead": "a944468d589dbae7fda45baab60dc9eac0c83032"
86
86
  }
@@ -39,8 +39,8 @@ export interface CardProps extends HTMLAttributes<HTMLDivElement> {
39
39
  label?: string
40
40
  /** **(Optional)** Specify the background color of the Card label. */
41
41
  labelBackground?: Lights
42
- /** **(Optional)** Specify the layout of the Card. */
43
- layout?: "vertical" | "horizontal"
42
+ /** **(Optional)** Specify the orientation of the Card. */
43
+ orientation?: "vertical" | "horizontal"
44
44
  }
45
45
 
46
46
  function getCardLinkElement(as: CardProps["as"], href?: string) {
@@ -74,7 +74,7 @@ export const Card = ({
74
74
  imagePosition = "left",
75
75
  label = "",
76
76
  labelBackground,
77
- layout = "vertical",
77
+ orientation = "vertical",
78
78
  ...props
79
79
  }: CardProps): JSX.Element => {
80
80
  const linkElement = getCardLinkElement(as, href)
@@ -88,7 +88,7 @@ export const Card = ({
88
88
  className: clsx("coop-card", background && bgPropToClass(background, className), className),
89
89
  "data-badge-pos": badgePosition,
90
90
  "data-image-pos": imagePosition,
91
- "data-layout": layout !== "vertical" ? layout : undefined,
91
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
92
92
  ...props,
93
93
  }
94
94
 
@@ -12,6 +12,8 @@ export interface CheckboxProps
12
12
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
13
13
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
14
14
  className?: string
15
+ /** **(Optional)** Specify whether the Checkbox should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
16
+ disabled?: boolean
15
17
  /** **(Optional)** Specify the Checkbox error state.
16
18
  *
17
19
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -38,6 +40,7 @@ export interface CheckboxProps
38
40
 
39
41
  export const Checkbox = ({
40
42
  className,
43
+ disabled,
41
44
  error = false,
42
45
  hint,
43
46
  id,
@@ -55,14 +58,15 @@ export const Checkbox = ({
55
58
  className: clsx("coop-checkbox", className),
56
59
  "data-error": error ? "" : undefined,
57
60
  "data-size": size.length && size !== "md" ? size : undefined,
61
+ disabled,
58
62
  id,
59
63
  name,
60
64
  type: "checkbox",
61
65
  ...props,
62
66
  }
63
-
67
+ const formItemProps = { "aria-disabled": disabled ? true : undefined }
64
68
  return (
65
- <div className="coop-form-item">
69
+ <div className="coop-form-item" {...formItemProps}>
66
70
  <div className="coop-checkbox-wrapper">
67
71
  <input {...componentProps} />
68
72
 
@@ -11,6 +11,8 @@ export interface CheckboxGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetE
11
11
  children?: React.ReactNode
12
12
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
13
13
  className?: string
14
+ /** **(Optional)** Specify whether the CheckboxGroup, and all of its descendents, should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
15
+ disabled?: boolean
14
16
  /** **(Optional)** Specify the CheckboxGroup error state.
15
17
  *
16
18
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -25,6 +27,8 @@ export interface CheckboxGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetE
25
27
  label?: string
26
28
  /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
27
29
  labelVisible?: boolean
30
+ /** **(Optional)** Specify the CheckboxGroup orientation. */
31
+ orientation?: "horizontal" | "vertical"
28
32
  /** **(Optional)** Specify the CheckboxGroup size. */
29
33
  size?: StandardSizes
30
34
  }
@@ -36,12 +40,14 @@ export const CheckboxGroup = ({
36
40
  hint,
37
41
  label,
38
42
  labelVisible = true,
43
+ orientation = "vertical",
39
44
  size = "md",
40
45
  ...props
41
46
  }: CheckboxGroupProps): JSX.Element => {
42
47
  const componentProps = {
43
48
  className: clsx("coop-fieldset", "coop-checkbox-group", className),
44
49
  "data-error": error ? "" : undefined,
50
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
45
51
  "data-size": size.length && size !== "md" ? size : undefined,
46
52
  ...props,
47
53
  }
@@ -55,7 +61,7 @@ export const CheckboxGroup = ({
55
61
  {label && <legend {...legendProps}>{label}</legend>}
56
62
  {hint && <FieldHint>{hint}</FieldHint>}
57
63
  {typeof error === "object" && error?.message && <FieldError>{error.message}</FieldError>}
58
- {children}
64
+ <div className="coop-checkbox-group-options">{children}</div>
59
65
  </fieldset>
60
66
  )
61
67
  }
@@ -5,11 +5,14 @@ import { FormFieldError, StandardSizes } from "src/types"
5
5
  import { FieldError } from "../FieldError"
6
6
  import { FieldHint } from "../FieldHint"
7
7
  import { FieldLabel } from "../FieldLabel"
8
+ import Tag, { TagProps } from "../Tag"
8
9
 
9
10
  export interface RadioButtonProps
10
11
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
11
12
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
12
13
  className?: string
14
+ /** **(Optional)** Specify whether the RadioButton should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
15
+ disabled?: boolean
13
16
  /** **(Optional)** Specify the RadioButton error state.
14
17
  *
15
18
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -32,10 +35,17 @@ export interface RadioButtonProps
32
35
  name: string
33
36
  /** **(Optional)** Specify the RadioButton size. */
34
37
  size?: StandardSizes
38
+ /** **(Optional)** Specify the RadioButton tag text. */
39
+ tag?: string
40
+ /** **(Optional)** Specify the RadioButton tag background color. */
41
+ tagBackground?: TagProps["background"]
42
+ /** **(Optional)** Specify the RadioButton variant. */
43
+ variant?: "default" | "boxed"
35
44
  }
36
45
 
37
46
  export const RadioButton = ({
38
47
  className,
48
+ disabled,
39
49
  error = false,
40
50
  hint,
41
51
  id,
@@ -43,6 +53,9 @@ export const RadioButton = ({
43
53
  labelVisible = true,
44
54
  name,
45
55
  size = "md",
56
+ tag,
57
+ tagBackground,
58
+ variant = "default",
46
59
  ...props
47
60
  }: RadioButtonProps): JSX.Element => {
48
61
  const internalId = useId()
@@ -53,20 +66,27 @@ export const RadioButton = ({
53
66
  className: clsx("coop-radio-button", className),
54
67
  "data-error": error ? "" : undefined,
55
68
  "data-size": size.length && size !== "md" ? size : undefined,
69
+ "data-variant": variant !== "default" ? variant : undefined,
70
+ disabled,
56
71
  id,
57
72
  name,
58
73
  type: "radio",
59
74
  ...props,
60
75
  }
61
-
76
+ const formItemProps = { "aria-disabled": disabled ? true : undefined }
62
77
  return (
63
- <div className="coop-form-item">
78
+ <div className="coop-form-item" {...formItemProps}>
64
79
  <div className="coop-radio-button-wrapper">
65
80
  <input {...componentProps} />
66
81
 
67
82
  {label && (
68
83
  <FieldLabel htmlFor={id} isVisible={labelVisible}>
69
- {label}
84
+ <span>{label}</span>{" "}
85
+ {tag && (
86
+ <Tag background={tagBackground} size="sm">
87
+ {tag}
88
+ </Tag>
89
+ )}
70
90
  </FieldLabel>
71
91
  )}
72
92
  {hint && <FieldHint>{hint}</FieldHint>}
@@ -11,6 +11,8 @@ export interface RadioButtonGroupProps extends FieldsetHTMLAttributes<HTMLFieldS
11
11
  children?: React.ReactNode
12
12
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
13
13
  className?: string
14
+ /** **(Optional)** Specify whether the RadioButtonGroup, and all of its descendents, should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
15
+ disabled?: boolean
14
16
  /** **(Optional)** Specify the RadioButtonGroup error state.
15
17
  *
16
18
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -25,8 +27,12 @@ export interface RadioButtonGroupProps extends FieldsetHTMLAttributes<HTMLFieldS
25
27
  label?: string
26
28
  /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
27
29
  labelVisible?: boolean
30
+ /** **(Optional)** Specify the RadioButtonGroup orientation. */
31
+ orientation?: "horizontal" | "vertical"
28
32
  /** **(Optional)** Specify the RadioButtonGroup size. */
29
33
  size?: StandardSizes
34
+ /** **(Optional)** Specify the RadioButtonGroup variant. */
35
+ variant?: "default" | "boxed"
30
36
  }
31
37
 
32
38
  export const RadioButtonGroup = ({
@@ -36,13 +42,17 @@ export const RadioButtonGroup = ({
36
42
  hint,
37
43
  label,
38
44
  labelVisible = true,
45
+ orientation = "vertical",
39
46
  size = "md",
47
+ variant = "default",
40
48
  ...props
41
49
  }: RadioButtonGroupProps): JSX.Element => {
42
50
  const componentProps = {
43
51
  className: clsx("coop-fieldset", "coop-radio-button-group", className),
44
52
  "data-error": error ? "" : undefined,
53
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
45
54
  "data-size": size.length && size !== "md" ? size : undefined,
55
+ "data-variant": variant !== "default" ? variant : undefined,
46
56
  ...props,
47
57
  }
48
58
 
@@ -55,7 +65,7 @@ export const RadioButtonGroup = ({
55
65
  {label && <legend {...legendProps}>{label}</legend>}
56
66
  {hint && <FieldHint>{hint}</FieldHint>}
57
67
  {typeof error === "object" && error?.message && <FieldError>{error.message}</FieldError>}
58
- {children}
68
+ <div className="coop-radio-button-group-options">{children}</div>
59
69
  </fieldset>
60
70
  )
61
71
  }
@@ -19,6 +19,8 @@ export interface TagProps extends HTMLAttributes<HTMLAnchorElement> {
19
19
  className?: string
20
20
  /** **(Optional)** Specify the URL that the Tag component will link to when clicked. */
21
21
  href?: string
22
+ /** **(Optional)** Specify the Tag size. */
23
+ size?: "sm" | "md"
22
24
  }
23
25
 
24
26
  export const Tag = ({
@@ -27,12 +29,15 @@ export const Tag = ({
27
29
  children,
28
30
  className,
29
31
  href,
32
+ size = "md",
30
33
  ...props
31
34
  }: TagProps): JSX.Element => {
32
35
  let element: TagProps["as"] = href ? "a" : "span"
33
36
  const componentProps = {
34
37
  className: clsx("coop-tag", bgPropToClass(background, className), className),
38
+ "data-size": size.length && size !== "md" ? size : undefined,
35
39
  href,
40
+
36
41
  ...props,
37
42
  }
38
43
  if (as) {
@@ -12,6 +12,8 @@ export interface TextInputProps
12
12
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
13
13
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
14
14
  className?: string
15
+ /** **(Optional)** Specify whether the TextInput should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
16
+ disabled?: boolean
15
17
  /** **(Optional)** Specify the TextInput error state.
16
18
  *
17
19
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -47,6 +49,7 @@ export interface TextInputProps
47
49
  export const TextInput = ({
48
50
  "aria-placeholder": ariaPlaceholder,
49
51
  className,
52
+ disabled,
50
53
  error = false,
51
54
  hint,
52
55
  id,
@@ -69,15 +72,16 @@ export const TextInput = ({
69
72
  className: clsx("coop-text-input", className),
70
73
  "data-error": error ? "" : undefined,
71
74
  "data-size": size.length && size !== "md" ? size : undefined,
75
+ disabled,
72
76
  id,
73
77
  name,
74
78
  placeholder,
75
79
  type,
76
80
  ...props,
77
81
  }
78
-
82
+ const formItemProps = { "aria-disabled": disabled ? true : undefined }
79
83
  return (
80
- <div className="coop-form-item">
84
+ <div className="coop-form-item" {...formItemProps}>
81
85
  {label && (
82
86
  <FieldLabel htmlFor={id} isVisible={labelVisible}>
83
87
  {label}
@@ -29,6 +29,8 @@ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElemen
29
29
  * Remember it is still your responsibility to handle validation on submission, this is simply a hint for the user.
30
30
  */
31
31
  cutoff?: boolean
32
+ /** **(Optional)** Specify whether the Textarea should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
33
+ disabled?: boolean
32
34
  /** **(Optional)** Specify the Textarea error state.
33
35
  *
34
36
  * This is an instance of `FormFieldError`. You can provide either an object with a `message` key, or a boolean value if you need to render the message independently.
@@ -65,6 +67,7 @@ export const Textarea = ({
65
67
  cols = 30,
66
68
  counter = false,
67
69
  cutoff = false,
70
+ disabled = false,
68
71
  error = false,
69
72
  hint,
70
73
  id,
@@ -88,6 +91,7 @@ export const Textarea = ({
88
91
  cols,
89
92
  "data-error": error ? "" : undefined,
90
93
  "data-size": size.length && size !== "md" ? size : undefined,
94
+ disabled,
91
95
  id,
92
96
  maxLength: cutoff ? maxLength : undefined,
93
97
  name,
@@ -102,9 +106,9 @@ export const Textarea = ({
102
106
  const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
103
107
  maxLength && e.target && setRemaining(maxLength - e.target.value.length)
104
108
  }
105
-
109
+ const formItemProps = { "aria-disabled": disabled ? true : undefined }
106
110
  return (
107
- <div className="coop-form-item">
111
+ <div className="coop-form-item" {...formItemProps}>
108
112
  {label && (
109
113
  <FieldLabel htmlFor={id} isVisible={labelVisible}>
110
114
  {label}
@@ -123,7 +127,7 @@ export const Textarea = ({
123
127
  }}
124
128
  ></textarea>
125
129
 
126
- {counter && maxLength && remaining != null && debouncedRemaining != null && (
130
+ {!disabled && counter && maxLength && remaining != null && debouncedRemaining != null && (
127
131
  <>
128
132
  <small
129
133
  aria-hidden="true"